Re: [PATCH] clk: scmi: Fix the rounding of clock rate
Hi, On Fri, Jul 27, 2018 at 10:07 PM, Stephen Boyd wrote: > Quoting Amit Daniel Kachhap (2018-07-27 07:01:52) >> This fix rounds the clock rate properly by using quotient and not >> remainder in the calculation. This issue was found while testing HDMI >> in the Juno platform. >> >> Signed-off-by: Amit Daniel Kachhap > > Any Fixes: tag here? Yes, This patch is tested with Linux v4.18-rc6 tag. > >> --- >> drivers/clk/clk-scmi.c | 5 ++--- >> 1 file changed, 2 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c >> index bb2a6f2..a985bf5 100644 >> --- a/drivers/clk/clk-scmi.c >> +++ b/drivers/clk/clk-scmi.c >> @@ -60,9 +59,9 @@ static long scmi_clk_round_rate(struct clk_hw *hw, >> unsigned long rate, >> >> ftmp = rate - fmin; >> ftmp += clk->info->range.step_size - 1; /* to round up */ >> - step = do_div(ftmp, clk->info->range.step_size); >> + do_div(ftmp, clk->info->range.step_size); >> >> - return step * clk->info->range.step_size + fmin; >> + return ftmp * clk->info->range.step_size + fmin; > > Good catch. Thanks. > Regards, Amit
Re: [PATCH] clk: scmi: Fix the rounding of clock rate
Hi, On Fri, Jul 27, 2018 at 10:07 PM, Stephen Boyd wrote: > Quoting Amit Daniel Kachhap (2018-07-27 07:01:52) >> This fix rounds the clock rate properly by using quotient and not >> remainder in the calculation. This issue was found while testing HDMI >> in the Juno platform. >> >> Signed-off-by: Amit Daniel Kachhap > > Any Fixes: tag here? Yes, This patch is tested with Linux v4.18-rc6 tag. > >> --- >> drivers/clk/clk-scmi.c | 5 ++--- >> 1 file changed, 2 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c >> index bb2a6f2..a985bf5 100644 >> --- a/drivers/clk/clk-scmi.c >> +++ b/drivers/clk/clk-scmi.c >> @@ -60,9 +59,9 @@ static long scmi_clk_round_rate(struct clk_hw *hw, >> unsigned long rate, >> >> ftmp = rate - fmin; >> ftmp += clk->info->range.step_size - 1; /* to round up */ >> - step = do_div(ftmp, clk->info->range.step_size); >> + do_div(ftmp, clk->info->range.step_size); >> >> - return step * clk->info->range.step_size + fmin; >> + return ftmp * clk->info->range.step_size + fmin; > > Good catch. Thanks. > Regards, Amit
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Trent and Andy, > From: Trent Piepho [mailto:tpie...@impinj.com] > Sent: Friday, July 27, 2018 2:02 AM > To: andy.shevche...@gmail.com; Hayashibara, Keiji/林原 啓二 > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > On Thu, 2018-07-26 at 11:46 +0300, Andy Shevchenko wrote: > > > + > > > + /* > > > +* the supported rates are even numbers from 4 to 254. > > > (4,6,8...254) > > > +* round up as we look for equal or less speed > > > +*/ > > > + ckrat = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); > > > + ckrat = roundup(ckrat, 2); > > > > ckrat += ckrat & 1; > > Either way, the compiler produces the same code: > > add r0, r0, #1 > bic r0, r0, #1 > > I.e., ckrat = (ckrat + 1) & ~1, one "add" and one "and". > > Might as well use the macro so it's clear. There is also round_up(x,y), which > I believe is intended to be used > only with power of 2 values of y. I confirmed round_up() macro. This macro is optimized to power of 2 argument, and it matches to this case and clear. I will replace to round_up() macro. Thank you. - Best Regards, Keiji Hayashibara
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Trent and Andy, > From: Trent Piepho [mailto:tpie...@impinj.com] > Sent: Friday, July 27, 2018 2:02 AM > To: andy.shevche...@gmail.com; Hayashibara, Keiji/林原 啓二 > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > On Thu, 2018-07-26 at 11:46 +0300, Andy Shevchenko wrote: > > > + > > > + /* > > > +* the supported rates are even numbers from 4 to 254. > > > (4,6,8...254) > > > +* round up as we look for equal or less speed > > > +*/ > > > + ckrat = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); > > > + ckrat = roundup(ckrat, 2); > > > > ckrat += ckrat & 1; > > Either way, the compiler produces the same code: > > add r0, r0, #1 > bic r0, r0, #1 > > I.e., ckrat = (ckrat + 1) & ~1, one "add" and one "and". > > Might as well use the macro so it's clear. There is also round_up(x,y), which > I believe is intended to be used > only with power of 2 values of y. I confirmed round_up() macro. This macro is optimized to power of 2 argument, and it matches to this case and clear. I will replace to round_up() macro. Thank you. - Best Regards, Keiji Hayashibara
Re: [PATCH] sched/fair: sync expires_seq in distribute_cfs_runtime()
Hi Cong, On 7/28/18 8:24 AM, Cong Wang wrote: > Each time we sync cfs_rq->runtime_expires with cfs_b->runtime_expires, > we should sync its ->expires_seq too. However it is missing > for distribute_cfs_runtime(), especially the slack timer call path. I don't think it's a problem, as expires_seq will get synced in assign_cfs_rq_runtime(). Thanks, Xunlei > > Fixes: 512ac999d275 ("sched/fair: Fix bandwidth timer clock drift condition") > Cc: Xunlei Pang > Cc: Ben Segall > Cc: Linus Torvalds > Cc: Peter Zijlstra > Cc: Thomas Gleixner > Signed-off-by: Cong Wang > --- > kernel/sched/fair.c | 12 > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > index 2f0a0be4d344..910c50db3d74 100644 > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -4857,7 +4857,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) > } > > static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b, > - u64 remaining, u64 expires) > + u64 remaining, u64 expires, int expires_seq) > { > struct cfs_rq *cfs_rq; > u64 runtime; > @@ -4880,6 +4880,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth > *cfs_b, > > cfs_rq->runtime_remaining += runtime; > cfs_rq->runtime_expires = expires; > + cfs_rq->expires_seq = expires_seq; > > /* we check whether we're throttled above */ > if (cfs_rq->runtime_remaining > 0) > @@ -4905,7 +4906,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth > *cfs_b, > static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int > overrun) > { > u64 runtime, runtime_expires; > - int throttled; > + int throttled, expires_seq; > > /* no need to continue the timer with no bandwidth constraint */ > if (cfs_b->quota == RUNTIME_INF) > @@ -4933,6 +4934,7 @@ static int do_sched_cfs_period_timer(struct > cfs_bandwidth *cfs_b, int overrun) > cfs_b->nr_throttled += overrun; > > runtime_expires = cfs_b->runtime_expires; > + expires_seq = cfs_b->expires_seq; > > /* >* This check is repeated as we are holding onto the new bandwidth while > @@ -4946,7 +4948,7 @@ static int do_sched_cfs_period_timer(struct > cfs_bandwidth *cfs_b, int overrun) > raw_spin_unlock(_b->lock); > /* we can't nest cfs_b->lock while distributing bandwidth */ > runtime = distribute_cfs_runtime(cfs_b, runtime, > - runtime_expires); > + runtime_expires, expires_seq); > raw_spin_lock(_b->lock); > > throttled = !list_empty(_b->throttled_cfs_rq); > @@ -5055,6 +5057,7 @@ static __always_inline void > return_cfs_rq_runtime(struct cfs_rq *cfs_rq) > static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) > { > u64 runtime = 0, slice = sched_cfs_bandwidth_slice(); > + int expires_seq; > u64 expires; > > /* confirm we're still not at a refresh boundary */ > @@ -5068,12 +5071,13 @@ static void do_sched_cfs_slack_timer(struct > cfs_bandwidth *cfs_b) > runtime = cfs_b->runtime; > > expires = cfs_b->runtime_expires; > + expires_seq = cfs_b->expires_seq; > raw_spin_unlock(_b->lock); > > if (!runtime) > return; > > - runtime = distribute_cfs_runtime(cfs_b, runtime, expires); > + runtime = distribute_cfs_runtime(cfs_b, runtime, expires, expires_seq); > > raw_spin_lock(_b->lock); > if (expires == cfs_b->runtime_expires) >
Re: [PATCH] sched/fair: sync expires_seq in distribute_cfs_runtime()
Hi Cong, On 7/28/18 8:24 AM, Cong Wang wrote: > Each time we sync cfs_rq->runtime_expires with cfs_b->runtime_expires, > we should sync its ->expires_seq too. However it is missing > for distribute_cfs_runtime(), especially the slack timer call path. I don't think it's a problem, as expires_seq will get synced in assign_cfs_rq_runtime(). Thanks, Xunlei > > Fixes: 512ac999d275 ("sched/fair: Fix bandwidth timer clock drift condition") > Cc: Xunlei Pang > Cc: Ben Segall > Cc: Linus Torvalds > Cc: Peter Zijlstra > Cc: Thomas Gleixner > Signed-off-by: Cong Wang > --- > kernel/sched/fair.c | 12 > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > index 2f0a0be4d344..910c50db3d74 100644 > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -4857,7 +4857,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) > } > > static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b, > - u64 remaining, u64 expires) > + u64 remaining, u64 expires, int expires_seq) > { > struct cfs_rq *cfs_rq; > u64 runtime; > @@ -4880,6 +4880,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth > *cfs_b, > > cfs_rq->runtime_remaining += runtime; > cfs_rq->runtime_expires = expires; > + cfs_rq->expires_seq = expires_seq; > > /* we check whether we're throttled above */ > if (cfs_rq->runtime_remaining > 0) > @@ -4905,7 +4906,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth > *cfs_b, > static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int > overrun) > { > u64 runtime, runtime_expires; > - int throttled; > + int throttled, expires_seq; > > /* no need to continue the timer with no bandwidth constraint */ > if (cfs_b->quota == RUNTIME_INF) > @@ -4933,6 +4934,7 @@ static int do_sched_cfs_period_timer(struct > cfs_bandwidth *cfs_b, int overrun) > cfs_b->nr_throttled += overrun; > > runtime_expires = cfs_b->runtime_expires; > + expires_seq = cfs_b->expires_seq; > > /* >* This check is repeated as we are holding onto the new bandwidth while > @@ -4946,7 +4948,7 @@ static int do_sched_cfs_period_timer(struct > cfs_bandwidth *cfs_b, int overrun) > raw_spin_unlock(_b->lock); > /* we can't nest cfs_b->lock while distributing bandwidth */ > runtime = distribute_cfs_runtime(cfs_b, runtime, > - runtime_expires); > + runtime_expires, expires_seq); > raw_spin_lock(_b->lock); > > throttled = !list_empty(_b->throttled_cfs_rq); > @@ -5055,6 +5057,7 @@ static __always_inline void > return_cfs_rq_runtime(struct cfs_rq *cfs_rq) > static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b) > { > u64 runtime = 0, slice = sched_cfs_bandwidth_slice(); > + int expires_seq; > u64 expires; > > /* confirm we're still not at a refresh boundary */ > @@ -5068,12 +5071,13 @@ static void do_sched_cfs_slack_timer(struct > cfs_bandwidth *cfs_b) > runtime = cfs_b->runtime; > > expires = cfs_b->runtime_expires; > + expires_seq = cfs_b->expires_seq; > raw_spin_unlock(_b->lock); > > if (!runtime) > return; > > - runtime = distribute_cfs_runtime(cfs_b, runtime, expires); > + runtime = distribute_cfs_runtime(cfs_b, runtime, expires, expires_seq); > > raw_spin_lock(_b->lock); > if (expires == cfs_b->runtime_expires) >
Re: [PATCH] x86: czc-tablet: add driver that fixes the buttons on CZC P10T tablet
Hi. Many thanks for the response! Some replies inline. On Sun, 2018-07-22 at 22:42 +0300, Andy Shevchenko wrote: > On Sun, Jul 22, 2018 at 1:36 AM, Lubomir Rintel > wrote: > > This driver switches the P10T tablet to "Android" mode, where the > > Home > > button sends a single sancode instead of a Windows-specific key > > combination and the other button doesn't disable the Wi-Fi. > > > > The driver also supports the ViewSonic ViewPad 10 which is almost > > identical > > to P10T. > > > > Complementary hwdb patch with the scan code mapping: > > https://github.com/systemd/systemd/commit/40a3078b.patch > > First of all, thanks for the driver. > > While I have several comments against style, the main one is about > necessity to have this driver in the first place. > > > +/* > > + * The device boots up in "Windows 7" mode, when the home button > > sends a > > + * Windows specific key sequence (Left Meta + D) and the second > > button > > + * sends an unknown one while also toggling the Radio Kill Switch. > > + * This is a surprising behavior when the second button is labeled > > "Back". > > I'm not sure switching to Android mode is what we want. Most of the > laptops are trying to be kept compatible with Windows as much as > possible (thus, for example, we utilize Windows Management > Instrumentation for many of laptops and tablets). Yes. On the other hand, this one is not really a laptop. It's a tablet and Windows doesn't seem to be that well supported first-class citizen here. The versions of the tablet that ship with Windows seem to have the back button labeled with a Wi-Fi button (Source: Internet) and the manual states that the button is indeed used to disable wireless on those models. This behavior is too confusing on the Android models. > > + * The vendor-supplied Android-x86 build switches the device to a > > "Android" > > + * mode by writing value 0x63 to the I/O port 0x68. This just > > seems to just > > + * set bit 6 on address 0x96 in the EC region; switching the bit > > directly > > + * seems to achieve the same result. It uses a "p10t_switcher" to > > do the > > + * job. It doesn't seem to be able to do anything else, and no > > other use > > + * of the port 0x68 is known. > > Does it have it in ACPI as a method? No. The relevant bit doesn't even have a name in the EmbeddedControl region. I've done some poking around with the nearby bits of the EC, but none of them seem to do anything relevant. (The very next one seems to turn the key to enter though, it seems to be used by the AWY0001 so that the button could be used for wake from away mode or something...) > How exectly it does this? Via /dev/port. > > + * In the Android mode, the home button sends just a single > > scancode, > > + * which can be handled in Linux userspace more reasonably and the > > back > > + * button only sends a scancode without toggling the kill switch. > > + * The scancode can then be mapped either to Back or RF Kill > > functionality > > + * in userspace, depending on how the button is labeled on that > > particular > > + * model. > > + */ > > + outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT); > > This is basically "the driver". The question here, what prevents > userspace to have few liner C-code to perform the same. IOW, why this > is necessary to have in kernel space? Yes. That, and the DMI match. What I'm concerned about is for any stock Linux distro to work well on these machines. The current behavior is much too frustrating. I don't feel too well about a separate driver for this, but I had a difficult time finding the right spot to do the switch. I thought udev could do the match, but it doesn't seem to be the right place to access hardware directly. Perhaps it's not that terrible to have a separate driver for this. It's easily disabled and doesn't do anything for people that don't have the hardware. Thank you Lubo
Re: [PATCH] x86: czc-tablet: add driver that fixes the buttons on CZC P10T tablet
Hi. Many thanks for the response! Some replies inline. On Sun, 2018-07-22 at 22:42 +0300, Andy Shevchenko wrote: > On Sun, Jul 22, 2018 at 1:36 AM, Lubomir Rintel > wrote: > > This driver switches the P10T tablet to "Android" mode, where the > > Home > > button sends a single sancode instead of a Windows-specific key > > combination and the other button doesn't disable the Wi-Fi. > > > > The driver also supports the ViewSonic ViewPad 10 which is almost > > identical > > to P10T. > > > > Complementary hwdb patch with the scan code mapping: > > https://github.com/systemd/systemd/commit/40a3078b.patch > > First of all, thanks for the driver. > > While I have several comments against style, the main one is about > necessity to have this driver in the first place. > > > +/* > > + * The device boots up in "Windows 7" mode, when the home button > > sends a > > + * Windows specific key sequence (Left Meta + D) and the second > > button > > + * sends an unknown one while also toggling the Radio Kill Switch. > > + * This is a surprising behavior when the second button is labeled > > "Back". > > I'm not sure switching to Android mode is what we want. Most of the > laptops are trying to be kept compatible with Windows as much as > possible (thus, for example, we utilize Windows Management > Instrumentation for many of laptops and tablets). Yes. On the other hand, this one is not really a laptop. It's a tablet and Windows doesn't seem to be that well supported first-class citizen here. The versions of the tablet that ship with Windows seem to have the back button labeled with a Wi-Fi button (Source: Internet) and the manual states that the button is indeed used to disable wireless on those models. This behavior is too confusing on the Android models. > > + * The vendor-supplied Android-x86 build switches the device to a > > "Android" > > + * mode by writing value 0x63 to the I/O port 0x68. This just > > seems to just > > + * set bit 6 on address 0x96 in the EC region; switching the bit > > directly > > + * seems to achieve the same result. It uses a "p10t_switcher" to > > do the > > + * job. It doesn't seem to be able to do anything else, and no > > other use > > + * of the port 0x68 is known. > > Does it have it in ACPI as a method? No. The relevant bit doesn't even have a name in the EmbeddedControl region. I've done some poking around with the nearby bits of the EC, but none of them seem to do anything relevant. (The very next one seems to turn the key to enter though, it seems to be used by the AWY0001 so that the button could be used for wake from away mode or something...) > How exectly it does this? Via /dev/port. > > + * In the Android mode, the home button sends just a single > > scancode, > > + * which can be handled in Linux userspace more reasonably and the > > back > > + * button only sends a scancode without toggling the kill switch. > > + * The scancode can then be mapped either to Back or RF Kill > > functionality > > + * in userspace, depending on how the button is labeled on that > > particular > > + * model. > > + */ > > + outb(CZC_EC_ANDROID_KEYS, CZC_EC_EXTRA_PORT); > > This is basically "the driver". The question here, what prevents > userspace to have few liner C-code to perform the same. IOW, why this > is necessary to have in kernel space? Yes. That, and the DMI match. What I'm concerned about is for any stock Linux distro to work well on these machines. The current behavior is much too frustrating. I don't feel too well about a separate driver for this, but I had a difficult time finding the right spot to do the switch. I thought udev could do the match, but it doesn't seem to be the right place to access hardware directly. Perhaps it's not that terrible to have a separate driver for this. It's easily disabled and doesn't do anything for people that don't have the hardware. Thank you Lubo
Contact my secretary in Burkina-Faso
Dear Friend, Good day, this is Mr. Henri Zongo, I'm happy to inform you about my success in getting the fund $29.6Million transferred under the co-operation of a new partner from Dubai, Presently I'm in Dubai for investment projects with my own share of the total sum. Meanwhile,I didn't forget your past efforts and attempts to assist me in transferring those funds despite that it failed us some how. Now contact my secretary in Burkina-Faso, his name is Mr. Leonard Kabore and his email address is (leonard_kab...@outlook.com) and ask him to send you VISA ATM CARD which has loaded the sum of USD$1,000,000.00 (One Million United States Dollars issued in your name by our Bank (BOA) headquarter, this is for your compensation for all the past efforts and attempts to assist me in this matter. Note, you will withdraw your money in an ATM MACHINE in any part of the world, but the maximum is ($5,000) Fifteen Thousand Us Dollars in three transactions per day. So feel free and get in touched with my secretary and instruct him where to send the VISA ATM CARD to you. Please do let me know immediately you receive the ATM CARD so that we can share the joy. Please my main reason to compensate you with this amount is for you to keep your mouth shut, do not allow anybody to know about this deal ever, let it to be sealed between us because I don't want to have any problem in the future please!. This is how we contributed for your compensation, I contributed $600,000 dollars out of my own share while my new partner contributed, $400,000 dollars to make the total of $1,000,000.00 USD,please let the deal be sealed ok! delete every message you received so far concerning this deal in your mailbox. In the moment, I am very busy here because of the investment projects which me and the new partner are having at hand, finally, remember that I had forwarded instruction to my secretary on your behalf to receive that VISA ATM CARD, so feel free to get in touch with him and he will help you to send it to your address. I will be traveling to Qatar this evening with my partner for an investment project. Regards, Mr. Henri Zongo. Contact my secretary in Burkina-Faso
Contact my secretary in Burkina-Faso
Dear Friend, Good day, this is Mr. Henri Zongo, I'm happy to inform you about my success in getting the fund $29.6Million transferred under the co-operation of a new partner from Dubai, Presently I'm in Dubai for investment projects with my own share of the total sum. Meanwhile,I didn't forget your past efforts and attempts to assist me in transferring those funds despite that it failed us some how. Now contact my secretary in Burkina-Faso, his name is Mr. Leonard Kabore and his email address is (leonard_kab...@outlook.com) and ask him to send you VISA ATM CARD which has loaded the sum of USD$1,000,000.00 (One Million United States Dollars issued in your name by our Bank (BOA) headquarter, this is for your compensation for all the past efforts and attempts to assist me in this matter. Note, you will withdraw your money in an ATM MACHINE in any part of the world, but the maximum is ($5,000) Fifteen Thousand Us Dollars in three transactions per day. So feel free and get in touched with my secretary and instruct him where to send the VISA ATM CARD to you. Please do let me know immediately you receive the ATM CARD so that we can share the joy. Please my main reason to compensate you with this amount is for you to keep your mouth shut, do not allow anybody to know about this deal ever, let it to be sealed between us because I don't want to have any problem in the future please!. This is how we contributed for your compensation, I contributed $600,000 dollars out of my own share while my new partner contributed, $400,000 dollars to make the total of $1,000,000.00 USD,please let the deal be sealed ok! delete every message you received so far concerning this deal in your mailbox. In the moment, I am very busy here because of the investment projects which me and the new partner are having at hand, finally, remember that I had forwarded instruction to my secretary on your behalf to receive that VISA ATM CARD, so feel free to get in touch with him and he will help you to send it to your address. I will be traveling to Qatar this evening with my partner for an investment project. Regards, Mr. Henri Zongo. Contact my secretary in Burkina-Faso
Re: [PATCH 03/16] vfs: don't evict uninitialized inode
On Mon, Jul 30, 2018 at 1:04 AM, Al Viro wrote: > From: Miklos Szeredi > > iput() ends up calling ->evict() on new inode, which is not yet initialized > by owning fs. So use destroy_inode() instead. > > Add to sb->s_inodes list only if inode is not in I_CREATING state (meaning > that it wasn't allocated with new_inode(), which already does the > insertion). > > Reported-by: Al Viro > Signed-off-by: Miklos Szeredi > Fixes: 80ea09a002bf ("vfs: factor out inode_insert5()") Backport hint: this patch depends on the patch ("new primitive: discard_new_inode()") currently commit 22dc9a168272 in Al's for-next. Still trying to figure out the best format to channel this information to stable maintainers... Thanks, Amir.
Re: [PATCH 03/16] vfs: don't evict uninitialized inode
On Mon, Jul 30, 2018 at 1:04 AM, Al Viro wrote: > From: Miklos Szeredi > > iput() ends up calling ->evict() on new inode, which is not yet initialized > by owning fs. So use destroy_inode() instead. > > Add to sb->s_inodes list only if inode is not in I_CREATING state (meaning > that it wasn't allocated with new_inode(), which already does the > insertion). > > Reported-by: Al Viro > Signed-off-by: Miklos Szeredi > Fixes: 80ea09a002bf ("vfs: factor out inode_insert5()") Backport hint: this patch depends on the patch ("new primitive: discard_new_inode()") currently commit 22dc9a168272 in Al's for-next. Still trying to figure out the best format to channel this information to stable maintainers... Thanks, Amir.
Re: [PATCH v3 1/3] dmaengine: imx-sdma: add SDMA_BD_MAX_CNT to replace '0xffff'
On 24-07-18, 01:46, Robin Gong wrote: > Add macro SDMA_BD_MAX_CNT to replace '0x'. Applied, thanks -- ~Vinod
Re: [PATCH v3 2/3] dmaengine: imx-sdma: add memcpy interface
On 24-07-18, 01:46, Robin Gong wrote: > Add MEMCPY capability for imx-sdma driver. Applied, thanks -- ~Vinod
Re: [PATCH v3 1/3] dmaengine: imx-sdma: add SDMA_BD_MAX_CNT to replace '0xffff'
On 24-07-18, 01:46, Robin Gong wrote: > Add macro SDMA_BD_MAX_CNT to replace '0x'. Applied, thanks -- ~Vinod
Re: [PATCH v3 2/3] dmaengine: imx-sdma: add memcpy interface
On 24-07-18, 01:46, Robin Gong wrote: > Add MEMCPY capability for imx-sdma driver. Applied, thanks -- ~Vinod
Re: [PATCH] fs/buffer: Convert return type int to vm_fault_t
On Sat, Jul 28, 2018 at 8:34 PM, Jens Axboe wrote: > On 7/28/18 3:50 AM, Souptick Joarder wrote: >> out_unlock: >> unlock_page(page); >> + ret = block_page_mkwrite_return(err); >> return ret; > > return block_page_mkwrite_return(err); > > -- > Jens Axboe > OK, I will post v2.
Re: [PATCH] fs/buffer: Convert return type int to vm_fault_t
On Sat, Jul 28, 2018 at 8:34 PM, Jens Axboe wrote: > On 7/28/18 3:50 AM, Souptick Joarder wrote: >> out_unlock: >> unlock_page(page); >> + ret = block_page_mkwrite_return(err); >> return ret; > > return block_page_mkwrite_return(err); > > -- > Jens Axboe > OK, I will post v2.
Re: [PATCH v2 00/10] ASoC: Add support to WCD9335 Audio Codec
On 27-07-18, 13:17, Srinivas Kandagatla wrote: > Thankyou for reviewing v1 patchset, here is v2 addressing comments from v1. > > Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC. > It is integrated in multiple Qualcomm SoCs like: MSM8996, MSM8976, > and MSM8956 chipsets. > > WCD9335 had multiple functional blocks, like: Soundwire controller, > interrupt mux, pin controller, Audio codec, MBHC, MAD(Mic activity Detection), > Ultrasonic proximity and pen detection, Battery-voltage monitoring and > Codec processing engine. > > Currently this patchset has been only tested with SLIMbus interface due > to hardware avaiablity, but it can be easily made to work with both SLIMbus > and I2C/I2S. > > This patchset adds very basic playback and capture support witout much > fancy features. New features will be added once the basic support is in. > This patchset is tested on top of linux-next on DB820c for both playback > and capture paths. > > This patchset also depends on the SLIMbus Stream apis which is already merged > via char-misc tree for 4.19. > > Some parts of the code has been inherited from Qualcomm andriod kernel, > so credits to various authors. > > WCD9335 can be interfaced via I2S/I2C or SLIMbus. > > Here is my test branch incase someone want to try this out: > https://git.linaro.org/people/srinivas.kandagatla/linux.git/log/?h=wcd9335 Apart from the few nitpicks I noticed, this looks good to me, so: Reviewed-by: Vinod Koul -- ~Vinod
Re: [PATCH v2 00/10] ASoC: Add support to WCD9335 Audio Codec
On 27-07-18, 13:17, Srinivas Kandagatla wrote: > Thankyou for reviewing v1 patchset, here is v2 addressing comments from v1. > > Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC. > It is integrated in multiple Qualcomm SoCs like: MSM8996, MSM8976, > and MSM8956 chipsets. > > WCD9335 had multiple functional blocks, like: Soundwire controller, > interrupt mux, pin controller, Audio codec, MBHC, MAD(Mic activity Detection), > Ultrasonic proximity and pen detection, Battery-voltage monitoring and > Codec processing engine. > > Currently this patchset has been only tested with SLIMbus interface due > to hardware avaiablity, but it can be easily made to work with both SLIMbus > and I2C/I2S. > > This patchset adds very basic playback and capture support witout much > fancy features. New features will be added once the basic support is in. > This patchset is tested on top of linux-next on DB820c for both playback > and capture paths. > > This patchset also depends on the SLIMbus Stream apis which is already merged > via char-misc tree for 4.19. > > Some parts of the code has been inherited from Qualcomm andriod kernel, > so credits to various authors. > > WCD9335 can be interfaced via I2S/I2C or SLIMbus. > > Here is my test branch incase someone want to try this out: > https://git.linaro.org/people/srinivas.kandagatla/linux.git/log/?h=wcd9335 Apart from the few nitpicks I noticed, this looks good to me, so: Reviewed-by: Vinod Koul -- ~Vinod
Re: [PATCH v2 02/10] mfd: wcd9335: add support to wcd9335 core
On 27-07-18, 13:17, Srinivas Kandagatla wrote: > +obj-$(CONFIG_MFD_WCD9335)+= wcd9335.o > +wcd9335-objs := wcd9335-core.o > + no slimbus objs? > +static int wcd9335_bring_up(struct wcd9335 *wcd) > +{ > + struct regmap *rm = wcd->regmap; > + int val, byte0; > + int ret = 0; > + > + regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, ); > + regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, ); > + > + if ((val < 0) || (byte0 < 0)) { > + dev_err(wcd->dev, "wcd9335 codec version detection fail!\n"); > + return -EINVAL; > + } > + > + if (byte0 == 0x1) { > + dev_info(wcd->dev, "wcd9335 codec version is v2.0\n"); > + wcd->version = WCD9335_VERSION_2_0; > + regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01); > + regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00); > + regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F); > + regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); > + regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3); > + } else { > + dev_err(wcd->dev, "wcd9335 codec version not supported\n"); > + ret = -EINVAL; > + } > + > + return ret; we can do return 0 and remove the variable as it is not used anywhere else. > +static int wcd9335_slim_probe(struct slim_device *slim) > +{ > + struct device *dev = >dev; > + struct wcd9335 *wcd; > + int ret = 0; > + > + /* Interface device */ > + if (slim->e_addr.dev_index == 0) > + return 0; > + > + wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); > + if (!wcd) > + return -ENOMEM; ^^ double space -- ~Vinod
Re: [PATCH v2 02/10] mfd: wcd9335: add support to wcd9335 core
On 27-07-18, 13:17, Srinivas Kandagatla wrote: > +obj-$(CONFIG_MFD_WCD9335)+= wcd9335.o > +wcd9335-objs := wcd9335-core.o > + no slimbus objs? > +static int wcd9335_bring_up(struct wcd9335 *wcd) > +{ > + struct regmap *rm = wcd->regmap; > + int val, byte0; > + int ret = 0; > + > + regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, ); > + regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, ); > + > + if ((val < 0) || (byte0 < 0)) { > + dev_err(wcd->dev, "wcd9335 codec version detection fail!\n"); > + return -EINVAL; > + } > + > + if (byte0 == 0x1) { > + dev_info(wcd->dev, "wcd9335 codec version is v2.0\n"); > + wcd->version = WCD9335_VERSION_2_0; > + regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01); > + regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00); > + regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F); > + regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); > + regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); > + regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3); > + } else { > + dev_err(wcd->dev, "wcd9335 codec version not supported\n"); > + ret = -EINVAL; > + } > + > + return ret; we can do return 0 and remove the variable as it is not used anywhere else. > +static int wcd9335_slim_probe(struct slim_device *slim) > +{ > + struct device *dev = >dev; > + struct wcd9335 *wcd; > + int ret = 0; > + > + /* Interface device */ > + if (slim->e_addr.dev_index == 0) > + return 0; > + > + wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); > + if (!wcd) > + return -ENOMEM; ^^ double space -- ~Vinod
RE: [PATCH] pinctrl: uniphier: add spi pin-mux settings
Hello Linus, I have sent modified patch for this bag as v2. Please refer to the following. [PATCH v2] https://patchwork.kernel.org/patch/10533929/ [Changes since v1] diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c -index 0f921a6..f912999 100644 +index 0f921a6..f086083 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c @@ -504,6 +504,8 @@ static const unsigned nand_cs1_pins[] = {22, 23}; @@ -390,7 +393,7 @@ static const char * const i2c3_groups[] = {"i2c3"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; -+static const char * const spi_groups[] = {"spi0"}; ++static const char * const spi0_groups[] = {"spi0"}; static const char * const system_bus_groups[] = {"system_bus", "system_bus_cs1", "system_bus_cs2", I mistook "spi0_groups" with " spi_groups", so there was an undeclared error. - Best Regards, Keiji Hayashibara > -Original Message- > From: Linus Walleij [mailto:linus.wall...@linaro.org] > Sent: Monday, July 30, 2018 5:47 AM > To: Hayashibara, Keiji/林原 啓二 > Cc: Yamada, Masahiro/山田 真弘 ; open list:GPIO > SUBSYSTEM > ; Linux ARM > ; Masami Hiramatsu > ; Jassi Brar ; > linux-kernel@vger.kernel.org; Hayashi, > Kunihiko/林 邦彦 > Subject: Re: [PATCH] pinctrl: uniphier: add spi pin-mux settings > > On Thu, Jul 19, 2018 at 8:21 AM Keiji Hayashibara > wrote: > > > From: Kunihiko Hayashi > > > > Add pin-mux settings for spi controller. > > > > Signed-off-by: Kunihiko Hayashi > > Signed-off-by: Keiji Hayashibara > > There is some problem with the test robot, can you comment/followup? > > Yours, > Linus Walleij
RE: [PATCH] pinctrl: uniphier: add spi pin-mux settings
Hello Linus, I have sent modified patch for this bag as v2. Please refer to the following. [PATCH v2] https://patchwork.kernel.org/patch/10533929/ [Changes since v1] diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c -index 0f921a6..f912999 100644 +index 0f921a6..f086083 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c @@ -504,6 +504,8 @@ static const unsigned nand_cs1_pins[] = {22, 23}; @@ -390,7 +393,7 @@ static const char * const i2c3_groups[] = {"i2c3"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; -+static const char * const spi_groups[] = {"spi0"}; ++static const char * const spi0_groups[] = {"spi0"}; static const char * const system_bus_groups[] = {"system_bus", "system_bus_cs1", "system_bus_cs2", I mistook "spi0_groups" with " spi_groups", so there was an undeclared error. - Best Regards, Keiji Hayashibara > -Original Message- > From: Linus Walleij [mailto:linus.wall...@linaro.org] > Sent: Monday, July 30, 2018 5:47 AM > To: Hayashibara, Keiji/林原 啓二 > Cc: Yamada, Masahiro/山田 真弘 ; open list:GPIO > SUBSYSTEM > ; Linux ARM > ; Masami Hiramatsu > ; Jassi Brar ; > linux-kernel@vger.kernel.org; Hayashi, > Kunihiko/林 邦彦 > Subject: Re: [PATCH] pinctrl: uniphier: add spi pin-mux settings > > On Thu, Jul 19, 2018 at 8:21 AM Keiji Hayashibara > wrote: > > > From: Kunihiko Hayashi > > > > Add pin-mux settings for spi controller. > > > > Signed-off-by: Kunihiko Hayashi > > Signed-off-by: Keiji Hayashibara > > There is some problem with the test robot, can you comment/followup? > > Yours, > Linus Walleij
[no subject]
Hi My name is Wang Shengkun, i am a software programmer and i work with a lottery company over here in the United States. I can give you the winning numbers in our admin to play and win the lottery and we will share the proceeds 50% each. If you are interested , kindly write me back at : 2148972...@qq.com Thanks Wang Shengkun.
[no subject]
Hi My name is Wang Shengkun, i am a software programmer and i work with a lottery company over here in the United States. I can give you the winning numbers in our admin to play and win the lottery and we will share the proceeds 50% each. If you are interested , kindly write me back at : 2148972...@qq.com Thanks Wang Shengkun.
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
On Mon, 30 Jul 2018 03:11:59 + Matthew Leon wrote: > >> Hey Jisheng, > > >Hi, > > >> > > >In LKML, we'd better not top post. > > Noted. My apologies. > > >> Shouldn't we be splitting until all DMA blocks are less than 128M > boundary? > >> I am a noob, but I think we should be prepared for boundaries that when > >> split in two, will still be greater than 128M. Feel free to disagree but > >> please explain why I may be wrong. Thank-you. > > >the limitation is "DMA addr can't span 128MB boundary" rather than "must be > >less than 128MB", they are different. > > >And the max transfer size of one DMA desc is 64KB. > > >thanks > > I have misspoken. What if the DMA transfer size is 1024M? If we split in > two, then we have 2 transfers, each of which span 512M. So wouldn't we need > to split again to have 4 transfers, each of which span 128M? > the max transfer size of each desc is 64KB, how could it be 1024MB?
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
On Mon, 30 Jul 2018 03:11:59 + Matthew Leon wrote: > >> Hey Jisheng, > > >Hi, > > >> > > >In LKML, we'd better not top post. > > Noted. My apologies. > > >> Shouldn't we be splitting until all DMA blocks are less than 128M > boundary? > >> I am a noob, but I think we should be prepared for boundaries that when > >> split in two, will still be greater than 128M. Feel free to disagree but > >> please explain why I may be wrong. Thank-you. > > >the limitation is "DMA addr can't span 128MB boundary" rather than "must be > >less than 128MB", they are different. > > >And the max transfer size of one DMA desc is 64KB. > > >thanks > > I have misspoken. What if the DMA transfer size is 1024M? If we split in > two, then we have 2 transfers, each of which span 512M. So wouldn't we need > to split again to have 4 transfers, each of which span 128M? > the max transfer size of each desc is 64KB, how could it be 1024MB?
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
>> Hey Jisheng, >Hi, >> >In LKML, we'd better not top post. Noted. My apologies. >> Shouldn't we be splitting until all DMA blocks are less than 128M boundary? >> I am a noob, but I think we should be prepared for boundaries that when >> split in two, will still be greater than 128M. Feel free to disagree but >> please explain why I may be wrong. Thank-you. >the limitation is "DMA addr can't span 128MB boundary" rather than "must be >less than 128MB", they are different. >And the max transfer size of one DMA desc is 64KB. >thanks I have misspoken. What if the DMA transfer size is 1024M? If we split in two, then we have 2 transfers, each of which span 512M. So wouldn't we need to split again to have 4 transfers, each of which span 128M? Sincerely, Matthew Leon On Sun, Jul 29, 2018 at 10:59 PM, Jisheng Zhang wrote: > On Mon, 30 Jul 2018 02:56:20 + Matthew Leon > wrote: > > > Hey Jisheng, > > Hi, > > > > > In LKML, we'd better not top post. > > > Shouldn't we be splitting until all DMA blocks are less than 128M > boundary? > > I am a noob, but I think we should be prepared for boundaries that when > > split in two, will still be greater than 128M. Feel free to disagree but > > please explain why I may be wrong. Thank-you. > > the limitation is "DMA addr can't span 128MB boundary" rather than "must be > less than 128MB", they are different. > > And the max transfer size of one DMA desc is 64KB. > > thanks > > > > > Sincerely, > > Matthew Leon > > > > On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang < > jisheng.zh...@synaptics.com > > > wrote: > > > > > When using DMA, if the DMA addr spans 128MB boundary, we have to split > > > the DMA transfer into two so that each one doesn't exceed the boundary. > > > > > > Signed-off-by: Jisheng Zhang > > > --- > > > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 > + > > > 1 file changed, 43 insertions(+) > > > > > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > > > b/drivers/mmc/host/sdhci-of-dwcmshc.c > > > index 1b7cd144fb01..e890fc8f5284 100644 > > > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > > > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > > > @@ -8,21 +8,52 @@ > > > */ > > > > > > #include > > > +#include > > > #include > > > #include > > > +#include > > > > > > #include "sdhci-pltfm.h" > > > > > > +#define BOUNDARY_OK(addr, len) \ > > > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > > > + > > > struct dwcmshc_priv { > > > struct clk *bus_clk; > > > }; > > > > > > +/* > > > + * if DMA addr spans 128MB boundary, we split the DMA transfer into > two > > > + * so that the DMA transfer doesn't exceed the boundary. > > > + */ > > > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > > > + void *desc, dma_addr_t > addr, > > > + int len, unsigned int cmd) > > > +{ > > > + int tmplen, offset; > > > + > > > + if (likely(!len || BOUNDARY_OK(addr, len))) > > > + return _sdhci_adma_write_desc(host, desc, addr, len, > cmd); > > > + > > > + offset = addr & (SZ_128M - 1); > > > + tmplen = SZ_128M - offset; > > > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > > > + > > > + addr += tmplen; > > > + len -= tmplen; > > > + desc += host->desc_sz; > > > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > > + > > > + return host->desc_sz * 2; > > > +} > > > + > > > static const struct sdhci_ops sdhci_dwcmshc_ops = { > > > .set_clock = sdhci_set_clock, > > > .set_bus_width = sdhci_set_bus_width, > > > .set_uhs_signaling = sdhci_set_uhs_signaling, > > > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > > > .reset = sdhci_reset, > > > + .adma_write_desc= dwcmshc_adma_write_desc, > > > }; > > > > > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > > > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device > *pdev) > > > struct sdhci_host *host; > > > struct dwcmshc_priv *priv; > > > int err; > > > + u32 extra; > > > > > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > > > sizeof(struct dwcmshc_priv)); > > > if (IS_ERR(host)) > > > return PTR_ERR(host); > > > > > > + /* > > > +* The DMA descriptor table number is calculated as the maximum > > > +* number of segments times 2, to allow for an alignment > > > +* descriptor for each segment, plus 1 for a nop end > descriptor, > > > +* plus extra number for cross 128M boundary handling. > > > +*/ > > > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > > > + if (extra > SDHCI_MAX_SEGS) > > > + extra = SDHCI_MAX_SEGS; > > > +
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
>> Hey Jisheng, >Hi, >> >In LKML, we'd better not top post. Noted. My apologies. >> Shouldn't we be splitting until all DMA blocks are less than 128M boundary? >> I am a noob, but I think we should be prepared for boundaries that when >> split in two, will still be greater than 128M. Feel free to disagree but >> please explain why I may be wrong. Thank-you. >the limitation is "DMA addr can't span 128MB boundary" rather than "must be >less than 128MB", they are different. >And the max transfer size of one DMA desc is 64KB. >thanks I have misspoken. What if the DMA transfer size is 1024M? If we split in two, then we have 2 transfers, each of which span 512M. So wouldn't we need to split again to have 4 transfers, each of which span 128M? Sincerely, Matthew Leon On Sun, Jul 29, 2018 at 10:59 PM, Jisheng Zhang wrote: > On Mon, 30 Jul 2018 02:56:20 + Matthew Leon > wrote: > > > Hey Jisheng, > > Hi, > > > > > In LKML, we'd better not top post. > > > Shouldn't we be splitting until all DMA blocks are less than 128M > boundary? > > I am a noob, but I think we should be prepared for boundaries that when > > split in two, will still be greater than 128M. Feel free to disagree but > > please explain why I may be wrong. Thank-you. > > the limitation is "DMA addr can't span 128MB boundary" rather than "must be > less than 128MB", they are different. > > And the max transfer size of one DMA desc is 64KB. > > thanks > > > > > Sincerely, > > Matthew Leon > > > > On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang < > jisheng.zh...@synaptics.com > > > wrote: > > > > > When using DMA, if the DMA addr spans 128MB boundary, we have to split > > > the DMA transfer into two so that each one doesn't exceed the boundary. > > > > > > Signed-off-by: Jisheng Zhang > > > --- > > > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 > + > > > 1 file changed, 43 insertions(+) > > > > > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > > > b/drivers/mmc/host/sdhci-of-dwcmshc.c > > > index 1b7cd144fb01..e890fc8f5284 100644 > > > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > > > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > > > @@ -8,21 +8,52 @@ > > > */ > > > > > > #include > > > +#include > > > #include > > > #include > > > +#include > > > > > > #include "sdhci-pltfm.h" > > > > > > +#define BOUNDARY_OK(addr, len) \ > > > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > > > + > > > struct dwcmshc_priv { > > > struct clk *bus_clk; > > > }; > > > > > > +/* > > > + * if DMA addr spans 128MB boundary, we split the DMA transfer into > two > > > + * so that the DMA transfer doesn't exceed the boundary. > > > + */ > > > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > > > + void *desc, dma_addr_t > addr, > > > + int len, unsigned int cmd) > > > +{ > > > + int tmplen, offset; > > > + > > > + if (likely(!len || BOUNDARY_OK(addr, len))) > > > + return _sdhci_adma_write_desc(host, desc, addr, len, > cmd); > > > + > > > + offset = addr & (SZ_128M - 1); > > > + tmplen = SZ_128M - offset; > > > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > > > + > > > + addr += tmplen; > > > + len -= tmplen; > > > + desc += host->desc_sz; > > > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > > + > > > + return host->desc_sz * 2; > > > +} > > > + > > > static const struct sdhci_ops sdhci_dwcmshc_ops = { > > > .set_clock = sdhci_set_clock, > > > .set_bus_width = sdhci_set_bus_width, > > > .set_uhs_signaling = sdhci_set_uhs_signaling, > > > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > > > .reset = sdhci_reset, > > > + .adma_write_desc= dwcmshc_adma_write_desc, > > > }; > > > > > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > > > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device > *pdev) > > > struct sdhci_host *host; > > > struct dwcmshc_priv *priv; > > > int err; > > > + u32 extra; > > > > > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > > > sizeof(struct dwcmshc_priv)); > > > if (IS_ERR(host)) > > > return PTR_ERR(host); > > > > > > + /* > > > +* The DMA descriptor table number is calculated as the maximum > > > +* number of segments times 2, to allow for an alignment > > > +* descriptor for each segment, plus 1 for a nop end > descriptor, > > > +* plus extra number for cross 128M boundary handling. > > > +*/ > > > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > > > + if (extra > SDHCI_MAX_SEGS) > > > + extra = SDHCI_MAX_SEGS; > > > +
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
On Mon, 30 Jul 2018 02:56:20 + Matthew Leon wrote: > Hey Jisheng, Hi, > In LKML, we'd better not top post. > Shouldn't we be splitting until all DMA blocks are less than 128M boundary? > I am a noob, but I think we should be prepared for boundaries that when > split in two, will still be greater than 128M. Feel free to disagree but > please explain why I may be wrong. Thank-you. the limitation is "DMA addr can't span 128MB boundary" rather than "must be less than 128MB", they are different. And the max transfer size of one DMA desc is 64KB. thanks > > Sincerely, > Matthew Leon > > On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang > wrote: > > > When using DMA, if the DMA addr spans 128MB boundary, we have to split > > the DMA transfer into two so that each one doesn't exceed the boundary. > > > > Signed-off-by: Jisheng Zhang > > --- > > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + > > 1 file changed, 43 insertions(+) > > > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > > b/drivers/mmc/host/sdhci-of-dwcmshc.c > > index 1b7cd144fb01..e890fc8f5284 100644 > > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > > @@ -8,21 +8,52 @@ > > */ > > > > #include > > +#include > > #include > > #include > > +#include > > > > #include "sdhci-pltfm.h" > > > > +#define BOUNDARY_OK(addr, len) \ > > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > > + > > struct dwcmshc_priv { > > struct clk *bus_clk; > > }; > > > > +/* > > + * if DMA addr spans 128MB boundary, we split the DMA transfer into two > > + * so that the DMA transfer doesn't exceed the boundary. > > + */ > > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > > + void *desc, dma_addr_t addr, > > + int len, unsigned int cmd) > > +{ > > + int tmplen, offset; > > + > > + if (likely(!len || BOUNDARY_OK(addr, len))) > > + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > + > > + offset = addr & (SZ_128M - 1); > > + tmplen = SZ_128M - offset; > > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > > + > > + addr += tmplen; > > + len -= tmplen; > > + desc += host->desc_sz; > > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > + > > + return host->desc_sz * 2; > > +} > > + > > static const struct sdhci_ops sdhci_dwcmshc_ops = { > > .set_clock = sdhci_set_clock, > > .set_bus_width = sdhci_set_bus_width, > > .set_uhs_signaling = sdhci_set_uhs_signaling, > > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > > .reset = sdhci_reset, > > + .adma_write_desc= dwcmshc_adma_write_desc, > > }; > > > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) > > struct sdhci_host *host; > > struct dwcmshc_priv *priv; > > int err; > > + u32 extra; > > > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > > sizeof(struct dwcmshc_priv)); > > if (IS_ERR(host)) > > return PTR_ERR(host); > > > > + /* > > +* The DMA descriptor table number is calculated as the maximum > > +* number of segments times 2, to allow for an alignment > > +* descriptor for each segment, plus 1 for a nop end descriptor, > > +* plus extra number for cross 128M boundary handling. > > +*/ > > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > > + if (extra > SDHCI_MAX_SEGS) > > + extra = SDHCI_MAX_SEGS; > > + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; > > + > > pltfm_host = sdhci_priv(host); > > priv = sdhci_pltfm_priv(pltfm_host); > > > > -- > > 2.18.0 > > > >
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
On Mon, 30 Jul 2018 02:56:20 + Matthew Leon wrote: > Hey Jisheng, Hi, > In LKML, we'd better not top post. > Shouldn't we be splitting until all DMA blocks are less than 128M boundary? > I am a noob, but I think we should be prepared for boundaries that when > split in two, will still be greater than 128M. Feel free to disagree but > please explain why I may be wrong. Thank-you. the limitation is "DMA addr can't span 128MB boundary" rather than "must be less than 128MB", they are different. And the max transfer size of one DMA desc is 64KB. thanks > > Sincerely, > Matthew Leon > > On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang > wrote: > > > When using DMA, if the DMA addr spans 128MB boundary, we have to split > > the DMA transfer into two so that each one doesn't exceed the boundary. > > > > Signed-off-by: Jisheng Zhang > > --- > > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + > > 1 file changed, 43 insertions(+) > > > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > > b/drivers/mmc/host/sdhci-of-dwcmshc.c > > index 1b7cd144fb01..e890fc8f5284 100644 > > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > > @@ -8,21 +8,52 @@ > > */ > > > > #include > > +#include > > #include > > #include > > +#include > > > > #include "sdhci-pltfm.h" > > > > +#define BOUNDARY_OK(addr, len) \ > > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > > + > > struct dwcmshc_priv { > > struct clk *bus_clk; > > }; > > > > +/* > > + * if DMA addr spans 128MB boundary, we split the DMA transfer into two > > + * so that the DMA transfer doesn't exceed the boundary. > > + */ > > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > > + void *desc, dma_addr_t addr, > > + int len, unsigned int cmd) > > +{ > > + int tmplen, offset; > > + > > + if (likely(!len || BOUNDARY_OK(addr, len))) > > + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > + > > + offset = addr & (SZ_128M - 1); > > + tmplen = SZ_128M - offset; > > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > > + > > + addr += tmplen; > > + len -= tmplen; > > + desc += host->desc_sz; > > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > > + > > + return host->desc_sz * 2; > > +} > > + > > static const struct sdhci_ops sdhci_dwcmshc_ops = { > > .set_clock = sdhci_set_clock, > > .set_bus_width = sdhci_set_bus_width, > > .set_uhs_signaling = sdhci_set_uhs_signaling, > > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > > .reset = sdhci_reset, > > + .adma_write_desc= dwcmshc_adma_write_desc, > > }; > > > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) > > struct sdhci_host *host; > > struct dwcmshc_priv *priv; > > int err; > > + u32 extra; > > > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > > sizeof(struct dwcmshc_priv)); > > if (IS_ERR(host)) > > return PTR_ERR(host); > > > > + /* > > +* The DMA descriptor table number is calculated as the maximum > > +* number of segments times 2, to allow for an alignment > > +* descriptor for each segment, plus 1 for a nop end descriptor, > > +* plus extra number for cross 128M boundary handling. > > +*/ > > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > > + if (extra > SDHCI_MAX_SEGS) > > + extra = SDHCI_MAX_SEGS; > > + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; > > + > > pltfm_host = sdhci_priv(host); > > priv = sdhci_pltfm_priv(pltfm_host); > > > > -- > > 2.18.0 > > > >
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
Hey Jisheng, Shouldn't we be splitting until all DMA blocks are less than 128M boundary? I am a noob, but I think we should be prepared for boundaries that when split in two, will still be greater than 128M. Feel free to disagree but please explain why I may be wrong. Thank-you. Sincerely, Matthew Leon On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang wrote: > When using DMA, if the DMA addr spans 128MB boundary, we have to split > the DMA transfer into two so that each one doesn't exceed the boundary. > > Signed-off-by: Jisheng Zhang > --- > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + > 1 file changed, 43 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > b/drivers/mmc/host/sdhci-of-dwcmshc.c > index 1b7cd144fb01..e890fc8f5284 100644 > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > @@ -8,21 +8,52 @@ > */ > > #include > +#include > #include > #include > +#include > > #include "sdhci-pltfm.h" > > +#define BOUNDARY_OK(addr, len) \ > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > + > struct dwcmshc_priv { > struct clk *bus_clk; > }; > > +/* > + * if DMA addr spans 128MB boundary, we split the DMA transfer into two > + * so that the DMA transfer doesn't exceed the boundary. > + */ > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > + void *desc, dma_addr_t addr, > + int len, unsigned int cmd) > +{ > + int tmplen, offset; > + > + if (likely(!len || BOUNDARY_OK(addr, len))) > + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + offset = addr & (SZ_128M - 1); > + tmplen = SZ_128M - offset; > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > + > + addr += tmplen; > + len -= tmplen; > + desc += host->desc_sz; > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + return host->desc_sz * 2; > +} > + > static const struct sdhci_ops sdhci_dwcmshc_ops = { > .set_clock = sdhci_set_clock, > .set_bus_width = sdhci_set_bus_width, > .set_uhs_signaling = sdhci_set_uhs_signaling, > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > .reset = sdhci_reset, > + .adma_write_desc= dwcmshc_adma_write_desc, > }; > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) > struct sdhci_host *host; > struct dwcmshc_priv *priv; > int err; > + u32 extra; > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > sizeof(struct dwcmshc_priv)); > if (IS_ERR(host)) > return PTR_ERR(host); > > + /* > +* The DMA descriptor table number is calculated as the maximum > +* number of segments times 2, to allow for an alignment > +* descriptor for each segment, plus 1 for a nop end descriptor, > +* plus extra number for cross 128M boundary handling. > +*/ > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > + if (extra > SDHCI_MAX_SEGS) > + extra = SDHCI_MAX_SEGS; > + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; > + > pltfm_host = sdhci_priv(host); > priv = sdhci_pltfm_priv(pltfm_host); > > -- > 2.18.0 > >
Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
Hey Jisheng, Shouldn't we be splitting until all DMA blocks are less than 128M boundary? I am a noob, but I think we should be prepared for boundaries that when split in two, will still be greater than 128M. Feel free to disagree but please explain why I may be wrong. Thank-you. Sincerely, Matthew Leon On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang wrote: > When using DMA, if the DMA addr spans 128MB boundary, we have to split > the DMA transfer into two so that each one doesn't exceed the boundary. > > Signed-off-by: Jisheng Zhang > --- > drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + > 1 file changed, 43 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c > b/drivers/mmc/host/sdhci-of-dwcmshc.c > index 1b7cd144fb01..e890fc8f5284 100644 > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c > @@ -8,21 +8,52 @@ > */ > > #include > +#include > #include > #include > +#include > > #include "sdhci-pltfm.h" > > +#define BOUNDARY_OK(addr, len) \ > + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) > + > struct dwcmshc_priv { > struct clk *bus_clk; > }; > > +/* > + * if DMA addr spans 128MB boundary, we split the DMA transfer into two > + * so that the DMA transfer doesn't exceed the boundary. > + */ > +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, > + void *desc, dma_addr_t addr, > + int len, unsigned int cmd) > +{ > + int tmplen, offset; > + > + if (likely(!len || BOUNDARY_OK(addr, len))) > + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + offset = addr & (SZ_128M - 1); > + tmplen = SZ_128M - offset; > + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); > + > + addr += tmplen; > + len -= tmplen; > + desc += host->desc_sz; > + _sdhci_adma_write_desc(host, desc, addr, len, cmd); > + > + return host->desc_sz * 2; > +} > + > static const struct sdhci_ops sdhci_dwcmshc_ops = { > .set_clock = sdhci_set_clock, > .set_bus_width = sdhci_set_bus_width, > .set_uhs_signaling = sdhci_set_uhs_signaling, > .get_max_clock = sdhci_pltfm_clk_get_max_clock, > .reset = sdhci_reset, > + .adma_write_desc= dwcmshc_adma_write_desc, > }; > > static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { > @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) > struct sdhci_host *host; > struct dwcmshc_priv *priv; > int err; > + u32 extra; > > host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, > sizeof(struct dwcmshc_priv)); > if (IS_ERR(host)) > return PTR_ERR(host); > > + /* > +* The DMA descriptor table number is calculated as the maximum > +* number of segments times 2, to allow for an alignment > +* descriptor for each segment, plus 1 for a nop end descriptor, > +* plus extra number for cross 128M boundary handling. > +*/ > + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); > + if (extra > SDHCI_MAX_SEGS) > + extra = SDHCI_MAX_SEGS; > + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; > + > pltfm_host = sdhci_priv(host); > priv = sdhci_pltfm_priv(pltfm_host); > > -- > 2.18.0 > >
[PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
When using DMA, if the DMA addr spans 128MB boundary, we have to split the DMA transfer into two so that each one doesn't exceed the boundary. Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + 1 file changed, 43 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 1b7cd144fb01..e890fc8f5284 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -8,21 +8,52 @@ */ #include +#include #include #include +#include #include "sdhci-pltfm.h" +#define BOUNDARY_OK(addr, len) \ + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) + struct dwcmshc_priv { struct clk *bus_clk; }; +/* + * if DMA addr spans 128MB boundary, we split the DMA transfer into two + * so that the DMA transfer doesn't exceed the boundary. + */ +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, + void *desc, dma_addr_t addr, + int len, unsigned int cmd) +{ + int tmplen, offset; + + if (likely(!len || BOUNDARY_OK(addr, len))) + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); + + offset = addr & (SZ_128M - 1); + tmplen = SZ_128M - offset; + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); + + addr += tmplen; + len -= tmplen; + desc += host->desc_sz; + _sdhci_adma_write_desc(host, desc, addr, len, cmd); + + return host->desc_sz * 2; +} + static const struct sdhci_ops sdhci_dwcmshc_ops = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, .set_uhs_signaling = sdhci_set_uhs_signaling, .get_max_clock = sdhci_pltfm_clk_get_max_clock, .reset = sdhci_reset, + .adma_write_desc= dwcmshc_adma_write_desc, }; static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) struct sdhci_host *host; struct dwcmshc_priv *priv; int err; + u32 extra; host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, sizeof(struct dwcmshc_priv)); if (IS_ERR(host)) return PTR_ERR(host); + /* +* The DMA descriptor table number is calculated as the maximum +* number of segments times 2, to allow for an alignment +* descriptor for each segment, plus 1 for a nop end descriptor, +* plus extra number for cross 128M boundary handling. +*/ + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); + if (extra > SDHCI_MAX_SEGS) + extra = SDHCI_MAX_SEGS; + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; + pltfm_host = sdhci_priv(host); priv = sdhci_pltfm_priv(pltfm_host); -- 2.18.0
[PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation
When using DMA, if the DMA addr spans 128MB boundary, we have to split the DMA transfer into two so that each one doesn't exceed the boundary. Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci-of-dwcmshc.c | 43 + 1 file changed, 43 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 1b7cd144fb01..e890fc8f5284 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -8,21 +8,52 @@ */ #include +#include #include #include +#include #include "sdhci-pltfm.h" +#define BOUNDARY_OK(addr, len) \ + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1))) + struct dwcmshc_priv { struct clk *bus_clk; }; +/* + * if DMA addr spans 128MB boundary, we split the DMA transfer into two + * so that the DMA transfer doesn't exceed the boundary. + */ +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host, + void *desc, dma_addr_t addr, + int len, unsigned int cmd) +{ + int tmplen, offset; + + if (likely(!len || BOUNDARY_OK(addr, len))) + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); + + offset = addr & (SZ_128M - 1); + tmplen = SZ_128M - offset; + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd); + + addr += tmplen; + len -= tmplen; + desc += host->desc_sz; + _sdhci_adma_write_desc(host, desc, addr, len, cmd); + + return host->desc_sz * 2; +} + static const struct sdhci_ops sdhci_dwcmshc_ops = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, .set_uhs_signaling = sdhci_set_uhs_signaling, .get_max_clock = sdhci_pltfm_clk_get_max_clock, .reset = sdhci_reset, + .adma_write_desc= dwcmshc_adma_write_desc, }; static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev) struct sdhci_host *host; struct dwcmshc_priv *priv; int err; + u32 extra; host = sdhci_pltfm_init(pdev, _dwcmshc_pdata, sizeof(struct dwcmshc_priv)); if (IS_ERR(host)) return PTR_ERR(host); + /* +* The DMA descriptor table number is calculated as the maximum +* number of segments times 2, to allow for an alignment +* descriptor for each segment, plus 1 for a nop end descriptor, +* plus extra number for cross 128M boundary handling. +*/ + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE); + if (extra > SDHCI_MAX_SEGS) + extra = SDHCI_MAX_SEGS; + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra; + pltfm_host = sdhci_priv(host); priv = sdhci_pltfm_priv(pltfm_host); -- 2.18.0
Re: [PATCH v3 5/5] arm64: dts: actions: Add pinctrl node for Actions Semi S700
Hi Saravanan, Thank you for the patch! Yet something to improve: [auto build test ERROR on pinctrl/devel] [also build test ERROR on next-20180727] [cannot apply to v4.18-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Saravanan-Sekar/Add-Actions-Semi-S700-pinctrl-support/20180730-040252 base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel config: arm64-allmodconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=arm64 All errors (new ones prefixed by >>): Error: arch/arm64/boot/dts/actions/s700.dtsi:172.19-20 syntax error >> FATAL ERROR: Unable to parse input tree --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v3 5/5] arm64: dts: actions: Add pinctrl node for Actions Semi S700
Hi Saravanan, Thank you for the patch! Yet something to improve: [auto build test ERROR on pinctrl/devel] [also build test ERROR on next-20180727] [cannot apply to v4.18-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Saravanan-Sekar/Add-Actions-Semi-S700-pinctrl-support/20180730-040252 base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel config: arm64-allmodconfig (attached as .config) compiler: aarch64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=arm64 All errors (new ones prefixed by >>): Error: arch/arm64/boot/dts/actions/s700.dtsi:172.19-20 syntax error >> FATAL ERROR: Unable to parse input tree --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH mmc-next v3 2/3] mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops
Add this hook so that it can be overridden with driver specific implementations. We also rename the original sdhci_adma_write_desc() to _sdhci_adma_write_desc() and export it, so that it could be reused by driver's specific implementations. Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci.c | 31 +++ drivers/mmc/host/sdhci.h | 6 ++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 14dd4a49e03b..50c846d99182 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -554,8 +554,8 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) local_irq_restore(*flags); } -static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, - dma_addr_t addr, int len, unsigned cmd) +unsigned int _sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, unsigned int cmd) { struct sdhci_adma2_64_desc *dma_desc = desc; @@ -566,6 +566,19 @@ static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, if (host->flags & SDHCI_USE_64_BIT_DMA) dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); + + return host->desc_sz; +} +EXPORT_SYMBOL_GPL(_sdhci_adma_write_desc); + +static unsigned int sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd) +{ + if (host->ops->adma_write_desc) + return host->ops->adma_write_desc(host, desc, addr, len, cmd); + + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); } static void sdhci_adma_mark_end(void *desc) @@ -585,6 +598,7 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, void *desc, *align; char *buffer; int len, offset, i; + unsigned int desc_sz; /* * The spec does not specify endianness of descriptor table. @@ -618,15 +632,16 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, } /* tran, valid */ - sdhci_adma_write_desc(host, desc, align_addr, offset, - ADMA2_TRAN_VALID); + desc_sz = sdhci_adma_write_desc(host, desc, + align_addr, offset, + ADMA2_TRAN_VALID); BUG_ON(offset > 65536); align += SDHCI_ADMA2_ALIGN; align_addr += SDHCI_ADMA2_ALIGN; - desc += host->desc_sz; + desc += desc_sz; addr += offset; len -= offset; @@ -636,9 +651,9 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, if (len) { /* tran, valid */ - sdhci_adma_write_desc(host, desc, addr, len, - ADMA2_TRAN_VALID); - desc += host->desc_sz; + desc_sz = sdhci_adma_write_desc(host, desc, addr, len, + ADMA2_TRAN_VALID); + desc += desc_sz; } /* diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d55fd7033e93..0aad0ee8f63b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -605,6 +605,9 @@ struct sdhci_ops { void(*adma_workaround)(struct sdhci_host *host, u32 intmask); void(*card_event)(struct sdhci_host *host); void(*voltage_switch)(struct sdhci_host *host); + unsigned int(*adma_write_desc)(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS @@ -735,6 +738,9 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios); void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable); +unsigned int _sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd); #ifdef CONFIG_PM int sdhci_suspend_host(struct sdhci_host *host); -- 2.18.0
[PATCH mmc-next v3 2/3] mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops
Add this hook so that it can be overridden with driver specific implementations. We also rename the original sdhci_adma_write_desc() to _sdhci_adma_write_desc() and export it, so that it could be reused by driver's specific implementations. Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci.c | 31 +++ drivers/mmc/host/sdhci.h | 6 ++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 14dd4a49e03b..50c846d99182 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -554,8 +554,8 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) local_irq_restore(*flags); } -static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, - dma_addr_t addr, int len, unsigned cmd) +unsigned int _sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, unsigned int cmd) { struct sdhci_adma2_64_desc *dma_desc = desc; @@ -566,6 +566,19 @@ static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, if (host->flags & SDHCI_USE_64_BIT_DMA) dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); + + return host->desc_sz; +} +EXPORT_SYMBOL_GPL(_sdhci_adma_write_desc); + +static unsigned int sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd) +{ + if (host->ops->adma_write_desc) + return host->ops->adma_write_desc(host, desc, addr, len, cmd); + + return _sdhci_adma_write_desc(host, desc, addr, len, cmd); } static void sdhci_adma_mark_end(void *desc) @@ -585,6 +598,7 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, void *desc, *align; char *buffer; int len, offset, i; + unsigned int desc_sz; /* * The spec does not specify endianness of descriptor table. @@ -618,15 +632,16 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, } /* tran, valid */ - sdhci_adma_write_desc(host, desc, align_addr, offset, - ADMA2_TRAN_VALID); + desc_sz = sdhci_adma_write_desc(host, desc, + align_addr, offset, + ADMA2_TRAN_VALID); BUG_ON(offset > 65536); align += SDHCI_ADMA2_ALIGN; align_addr += SDHCI_ADMA2_ALIGN; - desc += host->desc_sz; + desc += desc_sz; addr += offset; len -= offset; @@ -636,9 +651,9 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, if (len) { /* tran, valid */ - sdhci_adma_write_desc(host, desc, addr, len, - ADMA2_TRAN_VALID); - desc += host->desc_sz; + desc_sz = sdhci_adma_write_desc(host, desc, addr, len, + ADMA2_TRAN_VALID); + desc += desc_sz; } /* diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d55fd7033e93..0aad0ee8f63b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -605,6 +605,9 @@ struct sdhci_ops { void(*adma_workaround)(struct sdhci_host *host, u32 intmask); void(*card_event)(struct sdhci_host *host); void(*voltage_switch)(struct sdhci_host *host); + unsigned int(*adma_write_desc)(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS @@ -735,6 +738,9 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios); void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable); +unsigned int _sdhci_adma_write_desc(struct sdhci_host *host, void *desc, + dma_addr_t addr, int len, + unsigned int cmd); #ifdef CONFIG_PM int sdhci_suspend_host(struct sdhci_host *host); -- 2.18.0
[PATCH mmc-next v3 1/3] mmc: sdhci: add adma_table_num member to struct sdhci_host
This patch adds adma_table_num member to struct sdhci_host to give more flexibility to drivers to control the ADMA table number. Default value of adma_table_num is set to (SDHCI_MAX_SEGS * 2 + 1). Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci.c | 17 + drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a7b5602ef6f7..14dd4a49e03b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3316,6 +3316,13 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, host->sdma_boundary = SDHCI_DEFAULT_BOUNDARY_ARG; + /* +* The DMA descriptor table number is calculated as the maximum +* number of segments times 2, to allow for an alignment +* descriptor for each segment, plus 1 for a nop end descriptor. +*/ + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1; + return host; } @@ -3561,18 +3568,12 @@ int sdhci_setup_host(struct sdhci_host *host) dma_addr_t dma; void *buf; - /* -* The DMA descriptor table size is calculated as the maximum -* number of segments times 2, to allow for an alignment -* descriptor for each segment, plus 1 for a nop end descriptor, -* all multipled by the descriptor size. -*/ if (host->flags & SDHCI_USE_64_BIT_DMA) { - host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * + host->adma_table_sz = host->adma_table_num * SDHCI_ADMA2_64_DESC_SZ; host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; } else { - host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * + host->adma_table_sz = host->adma_table_num * SDHCI_ADMA2_32_DESC_SZ; host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 23966f887da6..d55fd7033e93 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -563,6 +563,8 @@ struct sdhci_host { /* Host SDMA buffer boundary. */ u32 sdma_boundary; + u32 adma_table_num; + u64 data_timeout; unsigned long private[0] cacheline_aligned; -- 2.18.0
[PATCH mmc-next v3 1/3] mmc: sdhci: add adma_table_num member to struct sdhci_host
This patch adds adma_table_num member to struct sdhci_host to give more flexibility to drivers to control the ADMA table number. Default value of adma_table_num is set to (SDHCI_MAX_SEGS * 2 + 1). Signed-off-by: Jisheng Zhang --- drivers/mmc/host/sdhci.c | 17 + drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index a7b5602ef6f7..14dd4a49e03b 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3316,6 +3316,13 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, host->sdma_boundary = SDHCI_DEFAULT_BOUNDARY_ARG; + /* +* The DMA descriptor table number is calculated as the maximum +* number of segments times 2, to allow for an alignment +* descriptor for each segment, plus 1 for a nop end descriptor. +*/ + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1; + return host; } @@ -3561,18 +3568,12 @@ int sdhci_setup_host(struct sdhci_host *host) dma_addr_t dma; void *buf; - /* -* The DMA descriptor table size is calculated as the maximum -* number of segments times 2, to allow for an alignment -* descriptor for each segment, plus 1 for a nop end descriptor, -* all multipled by the descriptor size. -*/ if (host->flags & SDHCI_USE_64_BIT_DMA) { - host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * + host->adma_table_sz = host->adma_table_num * SDHCI_ADMA2_64_DESC_SZ; host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; } else { - host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * + host->adma_table_sz = host->adma_table_num * SDHCI_ADMA2_32_DESC_SZ; host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 23966f887da6..d55fd7033e93 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -563,6 +563,8 @@ struct sdhci_host { /* Host SDMA buffer boundary. */ u32 sdma_boundary; + u32 adma_table_num; + u64 data_timeout; unsigned long private[0] cacheline_aligned; -- 2.18.0
[PATCH mmc-next v3 0/3] solve SDHCI DWC MSHC 128MB DMA boundary limitation
When using DMA, if the DMA addr spans 128MB boundary, we have to split the DMA transfer into two so that each one doesn't exceed the boundary. patch1 adds adma_table_num to struct sdhci_host so that driver can control the ADMA table number. patch2 introduces adma_write_desc() hook to struct sdhci_ops so that driver can override it. patch3 finally solves the 128MB boundary limitation. since v2: - make use of "likely" to check (!len || BOUNDARY_OK(addr, len)) - explictly include for SZ_128M since v1: - fix BOUNDARY_OK macro if addr+len is aligned to 128MB - use DIV_ROUND_UP to cal extra desc num - fix !len for dwcmshc_adma_write_desc() Jisheng Zhang (3): mmc: sdhci: add adma_table_num member to struct sdhci_host mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation drivers/mmc/host/sdhci-of-dwcmshc.c | 43 ++ drivers/mmc/host/sdhci.c| 48 +++-- drivers/mmc/host/sdhci.h| 8 + 3 files changed, 83 insertions(+), 16 deletions(-) -- 2.18.0
[PATCH mmc-next v3 0/3] solve SDHCI DWC MSHC 128MB DMA boundary limitation
When using DMA, if the DMA addr spans 128MB boundary, we have to split the DMA transfer into two so that each one doesn't exceed the boundary. patch1 adds adma_table_num to struct sdhci_host so that driver can control the ADMA table number. patch2 introduces adma_write_desc() hook to struct sdhci_ops so that driver can override it. patch3 finally solves the 128MB boundary limitation. since v2: - make use of "likely" to check (!len || BOUNDARY_OK(addr, len)) - explictly include for SZ_128M since v1: - fix BOUNDARY_OK macro if addr+len is aligned to 128MB - use DIV_ROUND_UP to cal extra desc num - fix !len for dwcmshc_adma_write_desc() Jisheng Zhang (3): mmc: sdhci: add adma_table_num member to struct sdhci_host mmc: sdhci: introduce adma_write_desc() hook to struct sdhci_ops mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation drivers/mmc/host/sdhci-of-dwcmshc.c | 43 ++ drivers/mmc/host/sdhci.c| 48 +++-- drivers/mmc/host/sdhci.h| 8 + 3 files changed, 83 insertions(+), 16 deletions(-) -- 2.18.0
[PATCH v2] arm64: dts: rockchip: add support for ROC-RK3399-PC board
From: Levin Du ROC-RK3399-PC is a power efficient 4GB LPDDR4 single board computer with USB 3.0 and Gigabit Ethernet in a form factor compatible with the Raspberry Pi. It is based on the Rockchip RK3399 SoC, powered by the Type-C port. The devicetree currently supports peripherals of: - Ethernet - HDMI - SD Card - UART2 debug - Type-C - eMMC USB3 in Type-C port currently only works with normal orientation, not flip one. Signed-off-by: Levin Du --- Changes in v2: - remove custom brightness-levels (use calculated one in pwm_bl driver) - remove redundant 'dr_mode="otg"' in usbdrd_dwc3_0 Changes in v1: - remove bootargs - use interpolation for brightness level - add vcc_vbus_typec1 regulator - fix phy-supply of u2phy0_otg and u2phy1_otg - remove vcc_hub_en dummy regualtor - add hub_rst (changed to output high) to pinctrl status of vcc5v0_host - remove vsel-gpios props in fan53xx - remove mp8859 in i2c - fusb302: fix interrupt setting - fusb302: add vbus-supply - remove extcon in tcphy0 and tcphy1 - remove #sound-dai-cells in i2s* - use RK_PXX style bit number for cd-gpios in SDMMC - clean commented status lines Documentation/devicetree/bindings/arm/rockchip.txt | 4 + arch/arm64/boot/dts/rockchip/Makefile | 1 + arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts | 682 + 3 files changed, 687 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index acfd3c7..ab5fde8 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -59,6 +59,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328"; +- Firefly ROC-RK3399-PC board: +Required root node properties: + - compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + - ChipSPARK PopMetal-RK3288 board: Required root node properties: - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index b0092d9..06028db 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -14,5 +14,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts new file mode 100644 index 000..13dc99c --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd + */ + +/dts-v1/; +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Firefly ROC-RK3399-PC Board"; + compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + + chosen { + stdout-path = "serial2:150n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = < 0 25000 0>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <12500>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = < 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <_enable_h>; + + /* +* On the module itself this is one of these (depending +* on the actual card populated): +* - SDIO_RESET_L_WL_REG_ON +* - PDN (power down when low) +*/ + reset-gpios = < RK_PB2 GPIO_ACTIVE_LOW>; + }; + + vcc_vbus_typec0: vcc-vbus-typec0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_vbus_typec0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + }; + + /* +* should be placed inside mp8859, but not until mp8859 has +* its own dt-binding. +*/ + vcc12v_sys: mp8859-dcdc1 { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_sys"; + regulator-always-on; + regulator-boot-on; +
[PATCH v2] arm64: dts: rockchip: add support for ROC-RK3399-PC board
From: Levin Du ROC-RK3399-PC is a power efficient 4GB LPDDR4 single board computer with USB 3.0 and Gigabit Ethernet in a form factor compatible with the Raspberry Pi. It is based on the Rockchip RK3399 SoC, powered by the Type-C port. The devicetree currently supports peripherals of: - Ethernet - HDMI - SD Card - UART2 debug - Type-C - eMMC USB3 in Type-C port currently only works with normal orientation, not flip one. Signed-off-by: Levin Du --- Changes in v2: - remove custom brightness-levels (use calculated one in pwm_bl driver) - remove redundant 'dr_mode="otg"' in usbdrd_dwc3_0 Changes in v1: - remove bootargs - use interpolation for brightness level - add vcc_vbus_typec1 regulator - fix phy-supply of u2phy0_otg and u2phy1_otg - remove vcc_hub_en dummy regualtor - add hub_rst (changed to output high) to pinctrl status of vcc5v0_host - remove vsel-gpios props in fan53xx - remove mp8859 in i2c - fusb302: fix interrupt setting - fusb302: add vbus-supply - remove extcon in tcphy0 and tcphy1 - remove #sound-dai-cells in i2s* - use RK_PXX style bit number for cd-gpios in SDMMC - clean commented status lines Documentation/devicetree/bindings/arm/rockchip.txt | 4 + arch/arm64/boot/dts/rockchip/Makefile | 1 + arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts | 682 + 3 files changed, 687 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index acfd3c7..ab5fde8 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -59,6 +59,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "firefly,roc-rk3328-cc", "rockchip,rk3328"; +- Firefly ROC-RK3399-PC board: +Required root node properties: + - compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + - ChipSPARK PopMetal-RK3288 board: Required root node properties: - compatible = "chipspark,popmetal-rk3288", "rockchip,rk3288"; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index b0092d9..06028db 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -14,5 +14,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts new file mode 100644 index 000..13dc99c --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 T-Chip Intelligent Technology Co., Ltd + */ + +/dts-v1/; +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + model = "Firefly ROC-RK3399-PC Board"; + compatible = "firefly,roc-rk3399-pc", "rockchip,rk3399"; + + chosen { + stdout-path = "serial2:150n8"; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = < 0 25000 0>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <12500>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = < 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <_enable_h>; + + /* +* On the module itself this is one of these (depending +* on the actual card populated): +* - SDIO_RESET_L_WL_REG_ON +* - PDN (power down when low) +*/ + reset-gpios = < RK_PB2 GPIO_ACTIVE_LOW>; + }; + + vcc_vbus_typec0: vcc-vbus-typec0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_vbus_typec0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + }; + + /* +* should be placed inside mp8859, but not until mp8859 has +* its own dt-binding. +*/ + vcc12v_sys: mp8859-dcdc1 { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_sys"; + regulator-always-on; + regulator-boot-on; +
linux-next: build warning after merge of the pm tree
Hi Rafael, After merging the pm tree, today's linux-next build (x86_64 allmodconfig) produced this warning: drivers/media/i2c/mt9v111.c: In function 'mt9v111_set_format': drivers/media/i2c/mt9v111.c:887:15: warning: 'idx' may be used uninitialized in this function [-Wmaybe-uninitialized] unsigned int idx; ^~~ Introduced by commit aab7ed1c3927 ("media: i2c: Add driver for Aptina MT9V111") Looks like a false positive, but not something that gcc can easily see. -- Cheers, Stephen Rothwell pgpvDEXyAXR88.pgp Description: OpenPGP digital signature
linux-next: build warning after merge of the pm tree
Hi Rafael, After merging the pm tree, today's linux-next build (x86_64 allmodconfig) produced this warning: drivers/media/i2c/mt9v111.c: In function 'mt9v111_set_format': drivers/media/i2c/mt9v111.c:887:15: warning: 'idx' may be used uninitialized in this function [-Wmaybe-uninitialized] unsigned int idx; ^~~ Introduced by commit aab7ed1c3927 ("media: i2c: Add driver for Aptina MT9V111") Looks like a false positive, but not something that gcc can easily see. -- Cheers, Stephen Rothwell pgpvDEXyAXR88.pgp Description: OpenPGP digital signature
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Andy, > -Original Message- > From: linux-kernel-ow...@vger.kernel.org > [mailto:linux-kernel-ow...@vger.kernel.org] On Behalf Of Andy > Shevchenko > Sent: Thursday, July 26, 2018 10:44 PM > To: Hayashibara, Keiji/林原 啓二 > Cc: Mark Brown ; Rob Herring ; Mark > Rutland ; > Yamada, Masahiro/山田 真弘 ; linux-spi > ; linux-arm > Mailing List ; devicetree > ; Masami Hiramatsu > ; Jassi Brar ; Linux > Kernel Mailing List > ; Hayashi, Kunihiko/林 邦彦 > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > On Thu, Jul 26, 2018 at 12:38 PM, Keiji Hayashibara > wrote: > > >> > + /* check if requested speed is too small */ > >> > + if (ckrat > SSI_MAX_CLK_DIVIDER) > >> > >> > + return -EINVAL; > >> > >> So, does this critical? > > > > If set the value to SSI_MAX_CLK_DIVIDER, the clock frequency will be set > > high. > > I don't change it to high frequency, and it is daringly an error. > > On the other hand, when changing to low frequency, I will change it > > automatically. > > No. My point is, if somehow user asks for that condition to be happened you > bail out, while when using clamp_val() > you may continue to work at maximum limit, though issue warning to user, for > example. Thank you. I understood what you pointed out. However, I found this code unnecessary as pointed out by Radu, so I will delete it. > >> > + > >> > + if (ckrat < SSI_MIN_CLK_DIVIDER) > >> > + ckrat = SSI_MIN_CLK_DIVIDER; > >> > >> clamp_val() / max() ? > > > > I will modify it to use max(). > > See above. This is also the same as above. > -- > With Best Regards, > Andy Shevchenko - Best Regards, Keiji Hayashibara
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Andy, > -Original Message- > From: linux-kernel-ow...@vger.kernel.org > [mailto:linux-kernel-ow...@vger.kernel.org] On Behalf Of Andy > Shevchenko > Sent: Thursday, July 26, 2018 10:44 PM > To: Hayashibara, Keiji/林原 啓二 > Cc: Mark Brown ; Rob Herring ; Mark > Rutland ; > Yamada, Masahiro/山田 真弘 ; linux-spi > ; linux-arm > Mailing List ; devicetree > ; Masami Hiramatsu > ; Jassi Brar ; Linux > Kernel Mailing List > ; Hayashi, Kunihiko/林 邦彦 > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > On Thu, Jul 26, 2018 at 12:38 PM, Keiji Hayashibara > wrote: > > >> > + /* check if requested speed is too small */ > >> > + if (ckrat > SSI_MAX_CLK_DIVIDER) > >> > >> > + return -EINVAL; > >> > >> So, does this critical? > > > > If set the value to SSI_MAX_CLK_DIVIDER, the clock frequency will be set > > high. > > I don't change it to high frequency, and it is daringly an error. > > On the other hand, when changing to low frequency, I will change it > > automatically. > > No. My point is, if somehow user asks for that condition to be happened you > bail out, while when using clamp_val() > you may continue to work at maximum limit, though issue warning to user, for > example. Thank you. I understood what you pointed out. However, I found this code unnecessary as pointed out by Radu, so I will delete it. > >> > + > >> > + if (ckrat < SSI_MIN_CLK_DIVIDER) > >> > + ckrat = SSI_MIN_CLK_DIVIDER; > >> > >> clamp_val() / max() ? > > > > I will modify it to use max(). > > See above. This is also the same as above. > -- > With Best Regards, > Andy Shevchenko - Best Regards, Keiji Hayashibara
Re: [PATCH] HID: intel_ish-hid: tx_buf memory leak on probe/remove
On Tue, 2018-07-24 at 17:34 +0300, Anton Vasilyev wrote: > ish_dev_init() allocates 512*176 bytes memory for tx_buf and stores > it at > >wr_free_list_head.link list on ish_probe(). > But there is no deallocation of this memory in ish_remove() and in > ish_probe() error path. > So current intel-ish-ipc provides 88 KB memory leak for each > probe/release. > > The patch replaces kzalloc allocation by devm_kzalloc and removes > ishtp_device *dev deallocation by kfree. > > Found by Linux Driver Verification project (linuxtesting.org). > I prefer align with "(" for the next line for multi line statements even if character /line > slightly over 80. If you can do that resubmit with my ACK below. > Signed-off-by: Anton Vasilyev Acked-by: Srinivas Pandruvada > --- > drivers/hid/intel-ish-hid/ipc/ipc.c | 7 +-- > drivers/hid/intel-ish-hid/ipc/pci-ish.c | 2 -- > 2 files changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel- > ish-hid/ipc/ipc.c > index 9a60ec13cb10..2f8e5402b450 100644 > --- a/drivers/hid/intel-ish-hid/ipc/ipc.c > +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c > @@ -907,7 +907,8 @@ struct ishtp_device *ish_dev_init(struct pci_dev > *pdev) > struct ishtp_device *dev; > int i; > > - dev = kzalloc(sizeof(struct ishtp_device) + sizeof(struct > ish_hw), > + dev = devm_kzalloc(>dev, > + sizeof(struct ishtp_device) + sizeof(struct ish_hw), > GFP_KERNEL); > if (!dev) > return NULL; > @@ -925,7 +926,9 @@ struct ishtp_device *ish_dev_init(struct pci_dev > *pdev) > for (i = 0; i < IPC_TX_FIFO_SIZE; ++i) { > struct wr_msg_ctl_info *tx_buf; > > - tx_buf = kzalloc(sizeof(struct wr_msg_ctl_info), > GFP_KERNEL); > + tx_buf = devm_kzalloc(>dev, > + sizeof(struct wr_msg_ctl_info), > + GFP_KERNEL); > if (!tx_buf) { > /* >* IPC buffers may be limited or not > available > diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c > b/drivers/hid/intel-ish-hid/ipc/pci-ish.c > index a2c53ea3b5ed..81d035a480bc 100644 > --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c > +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c > @@ -172,7 +172,6 @@ static int ish_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > free_irq(pdev->irq, dev); > free_device: > pci_iounmap(pdev, hw->mem_addr); > - kfree(dev); > release_regions: > pci_release_regions(pdev); > disable_device: > @@ -202,7 +201,6 @@ static void ish_remove(struct pci_dev *pdev) > pci_release_regions(pdev); > pci_clear_master(pdev); > pci_disable_device(pdev); > - kfree(ishtp_dev); > } > > static struct device __maybe_unused *ish_resume_device;
Re: [PATCH] HID: intel_ish-hid: tx_buf memory leak on probe/remove
On Tue, 2018-07-24 at 17:34 +0300, Anton Vasilyev wrote: > ish_dev_init() allocates 512*176 bytes memory for tx_buf and stores > it at > >wr_free_list_head.link list on ish_probe(). > But there is no deallocation of this memory in ish_remove() and in > ish_probe() error path. > So current intel-ish-ipc provides 88 KB memory leak for each > probe/release. > > The patch replaces kzalloc allocation by devm_kzalloc and removes > ishtp_device *dev deallocation by kfree. > > Found by Linux Driver Verification project (linuxtesting.org). > I prefer align with "(" for the next line for multi line statements even if character /line > slightly over 80. If you can do that resubmit with my ACK below. > Signed-off-by: Anton Vasilyev Acked-by: Srinivas Pandruvada > --- > drivers/hid/intel-ish-hid/ipc/ipc.c | 7 +-- > drivers/hid/intel-ish-hid/ipc/pci-ish.c | 2 -- > 2 files changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c b/drivers/hid/intel- > ish-hid/ipc/ipc.c > index 9a60ec13cb10..2f8e5402b450 100644 > --- a/drivers/hid/intel-ish-hid/ipc/ipc.c > +++ b/drivers/hid/intel-ish-hid/ipc/ipc.c > @@ -907,7 +907,8 @@ struct ishtp_device *ish_dev_init(struct pci_dev > *pdev) > struct ishtp_device *dev; > int i; > > - dev = kzalloc(sizeof(struct ishtp_device) + sizeof(struct > ish_hw), > + dev = devm_kzalloc(>dev, > + sizeof(struct ishtp_device) + sizeof(struct ish_hw), > GFP_KERNEL); > if (!dev) > return NULL; > @@ -925,7 +926,9 @@ struct ishtp_device *ish_dev_init(struct pci_dev > *pdev) > for (i = 0; i < IPC_TX_FIFO_SIZE; ++i) { > struct wr_msg_ctl_info *tx_buf; > > - tx_buf = kzalloc(sizeof(struct wr_msg_ctl_info), > GFP_KERNEL); > + tx_buf = devm_kzalloc(>dev, > + sizeof(struct wr_msg_ctl_info), > + GFP_KERNEL); > if (!tx_buf) { > /* >* IPC buffers may be limited or not > available > diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c > b/drivers/hid/intel-ish-hid/ipc/pci-ish.c > index a2c53ea3b5ed..81d035a480bc 100644 > --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c > +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c > @@ -172,7 +172,6 @@ static int ish_probe(struct pci_dev *pdev, const > struct pci_device_id *ent) > free_irq(pdev->irq, dev); > free_device: > pci_iounmap(pdev, hw->mem_addr); > - kfree(dev); > release_regions: > pci_release_regions(pdev); > disable_device: > @@ -202,7 +201,6 @@ static void ish_remove(struct pci_dev *pdev) > pci_release_regions(pdev); > pci_clear_master(pdev); > pci_disable_device(pdev); > - kfree(ishtp_dev); > } > > static struct device __maybe_unused *ish_resume_device;
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Radu, > From: Radu Pirea [mailto:radu.pi...@microchip.com] > Sent: Thursday, July 26, 2018 7:58 PM > To: Hayashibara, Keiji/林原 啓二 ; 'Andy > Shevchenko' > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > > > On 07/26/2018 12:38 PM, Keiji Hayashibara wrote: > > Hello Andy, > > > > Thank you for your check! > > > > > >> From: Andy Shevchenko [mailto:andy.shevche...@gmail.com] > >> Sent: Thursday, July 26, 2018 5:46 PM > >> To: Hayashibara, Keiji/林原 啓二 > >> Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for > >> UniPhier SoC > >> > >> On Thu, Jul 26, 2018 at 10:09 AM, Keiji Hayashibara > >> wrote: > >>> Add SPI controller driver implemented in Socionext UniPhier SoCs. > >>> > >>> UniPhier SoCs have two types SPI controllers; SCSSI supports a > >>> single channel, and MCSSI supports multiple channels. > >>> This driver supports SCSSI only. > >>> > >>> This controller has 32bit TX/RX FIFO with depth of eight entry, and > >>> supports the SPI master mode only. > >>> > >>> This commit is implemented in PIO transfer mode, not DMA transfer. > >> > >> Few style realted comments. > >> > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >> > >> Slightly better to keep them in order and put asm/* at the last. > > > > I see. I will modify this. > > > > > >>> +#define SSI_TIMEOUT2000/* ms */ > >> > >> SSI_TIMEOUT_MS ? > >> > >>> +#define SSI_CTL0x0 > >> > >> Slightly better to keep same width for the addresses, like 0x00 here. > >> > >>> +#define SSI_CKS0x4 > >> > >>> +#define SSI_TXWDS 0x8 > >> > >>> +#define SSI_RXWDS 0xc > >> > >> Ditto. > > > > I will modify about above. > > > >> > >>> +static int uniphier_spi_set_baudrate(struct spi_device *spi, > >>> +unsigned int speed) { > >>> + struct uniphier_spi_priv *priv = > >>> spi_master_get_devdata(spi->master); > >>> + u32 val, ckrat; > >>> + > >>> + /* > >>> +* the supported rates are even numbers from 4 to 254. > >>> (4,6,8...254) > >>> +* round up as we look for equal or less speed > >>> +*/ > >>> + ckrat = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); > >> > >>> + ckrat = roundup(ckrat, 2); > >> > >> ckrat += ckrat & 1; > >> > >> ? > > > > It's simple. I will modify. > > > > > >>> + /* check if requested speed is too small */ > >>> + if (ckrat > SSI_MAX_CLK_DIVIDER) > >> > >>> + return -EINVAL; > >> > >> So, does this critical? > > > > If set the value to SSI_MAX_CLK_DIVIDER, the clock frequency will be set > > high. > > I don't change it to high frequency, and it is daringly an error. > > On the other hand, when changing to low frequency, I will change it > > automatically. > > > >>> + > >>> + if (ckrat < SSI_MIN_CLK_DIVIDER) > >>> + ckrat = SSI_MIN_CLK_DIVIDER; > > In fact you don't need this checks. You already set in probe function this. > master->max_speed_hz = DIV_ROUND_UP(clksrc, SSI_MIN_CLK_DIVIDER); > master->min_speed_hz = DIV_ROUND_UP(clksrc, SSI_MAX_CLK_DIVIDER); > > The SPI core will check if transfer speed is higher than controller speed and > if is, will set the transfer speed > to master->max_speed_hz. In case of master->min_speed_hz, if transfer speed > is lower than > master->min_speed_hz __spi_validate(drivers/spi/spi.c) will return -EINVAL. I see. I confirmed __spi_validate() and understood that this check code is unnecessary. I will remove this check code. Thank you. > >> > >> clamp_val() / max() ? > > > > I will modify it to use max(). > > > >> > >>> + val = readl(priv->base + SSI_CKS); > >>> + val &= ~SSI_CKS_CKRAT_MASK; > >>> + val |= ckrat & SSI_CKS_CKRAT_MASK; > >>> + writel(val, priv->base + SSI_CKS); > >>> + > >>> + return 0; > >>> +} > >> > >>> + priv->irq = platform_get_irq(pdev, 0); > >>> + if (priv->irq < 0) { > >>> + dev_err(>dev, "failed to get IRQ\n"); > >> > >>> + ret = -ENXIO; > >> > >> What's wrong with > >> > >> ret = priv->irq; > >> > >> ? > > > > I will modify it. > > > >>> + goto out_disable_clk; > >>> + } > >> > >>> +static const struct of_device_id uniphier_spi_match[] = { > >>> + { .compatible = "socionext,uniphier-scssi", }, > >> > >>> + { /* sentinel */ }, > >> > >> Slightly better without comma. > > > > OK. I will modify this. > > > > - > > Best Regards, > > Keiji Hayashibara > > > > > > > >>> +}; > >>> +MODULE_DEVICE_TABLE(of, uniphier_spi_match); > >> > >> -- > >> With Best Regards, > >> Andy Shevchenko > > - Best Regards, Keiji Hayashibara
RE: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC
Hello Radu, > From: Radu Pirea [mailto:radu.pi...@microchip.com] > Sent: Thursday, July 26, 2018 7:58 PM > To: Hayashibara, Keiji/林原 啓二 ; 'Andy > Shevchenko' > > Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for UniPhier SoC > > > > On 07/26/2018 12:38 PM, Keiji Hayashibara wrote: > > Hello Andy, > > > > Thank you for your check! > > > > > >> From: Andy Shevchenko [mailto:andy.shevche...@gmail.com] > >> Sent: Thursday, July 26, 2018 5:46 PM > >> To: Hayashibara, Keiji/林原 啓二 > >> Subject: Re: [PATCH v2 2/2] spi: add SPI controller driver for > >> UniPhier SoC > >> > >> On Thu, Jul 26, 2018 at 10:09 AM, Keiji Hayashibara > >> wrote: > >>> Add SPI controller driver implemented in Socionext UniPhier SoCs. > >>> > >>> UniPhier SoCs have two types SPI controllers; SCSSI supports a > >>> single channel, and MCSSI supports multiple channels. > >>> This driver supports SCSSI only. > >>> > >>> This controller has 32bit TX/RX FIFO with depth of eight entry, and > >>> supports the SPI master mode only. > >>> > >>> This commit is implemented in PIO transfer mode, not DMA transfer. > >> > >> Few style realted comments. > >> > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >> > >> Slightly better to keep them in order and put asm/* at the last. > > > > I see. I will modify this. > > > > > >>> +#define SSI_TIMEOUT2000/* ms */ > >> > >> SSI_TIMEOUT_MS ? > >> > >>> +#define SSI_CTL0x0 > >> > >> Slightly better to keep same width for the addresses, like 0x00 here. > >> > >>> +#define SSI_CKS0x4 > >> > >>> +#define SSI_TXWDS 0x8 > >> > >>> +#define SSI_RXWDS 0xc > >> > >> Ditto. > > > > I will modify about above. > > > >> > >>> +static int uniphier_spi_set_baudrate(struct spi_device *spi, > >>> +unsigned int speed) { > >>> + struct uniphier_spi_priv *priv = > >>> spi_master_get_devdata(spi->master); > >>> + u32 val, ckrat; > >>> + > >>> + /* > >>> +* the supported rates are even numbers from 4 to 254. > >>> (4,6,8...254) > >>> +* round up as we look for equal or less speed > >>> +*/ > >>> + ckrat = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); > >> > >>> + ckrat = roundup(ckrat, 2); > >> > >> ckrat += ckrat & 1; > >> > >> ? > > > > It's simple. I will modify. > > > > > >>> + /* check if requested speed is too small */ > >>> + if (ckrat > SSI_MAX_CLK_DIVIDER) > >> > >>> + return -EINVAL; > >> > >> So, does this critical? > > > > If set the value to SSI_MAX_CLK_DIVIDER, the clock frequency will be set > > high. > > I don't change it to high frequency, and it is daringly an error. > > On the other hand, when changing to low frequency, I will change it > > automatically. > > > >>> + > >>> + if (ckrat < SSI_MIN_CLK_DIVIDER) > >>> + ckrat = SSI_MIN_CLK_DIVIDER; > > In fact you don't need this checks. You already set in probe function this. > master->max_speed_hz = DIV_ROUND_UP(clksrc, SSI_MIN_CLK_DIVIDER); > master->min_speed_hz = DIV_ROUND_UP(clksrc, SSI_MAX_CLK_DIVIDER); > > The SPI core will check if transfer speed is higher than controller speed and > if is, will set the transfer speed > to master->max_speed_hz. In case of master->min_speed_hz, if transfer speed > is lower than > master->min_speed_hz __spi_validate(drivers/spi/spi.c) will return -EINVAL. I see. I confirmed __spi_validate() and understood that this check code is unnecessary. I will remove this check code. Thank you. > >> > >> clamp_val() / max() ? > > > > I will modify it to use max(). > > > >> > >>> + val = readl(priv->base + SSI_CKS); > >>> + val &= ~SSI_CKS_CKRAT_MASK; > >>> + val |= ckrat & SSI_CKS_CKRAT_MASK; > >>> + writel(val, priv->base + SSI_CKS); > >>> + > >>> + return 0; > >>> +} > >> > >>> + priv->irq = platform_get_irq(pdev, 0); > >>> + if (priv->irq < 0) { > >>> + dev_err(>dev, "failed to get IRQ\n"); > >> > >>> + ret = -ENXIO; > >> > >> What's wrong with > >> > >> ret = priv->irq; > >> > >> ? > > > > I will modify it. > > > >>> + goto out_disable_clk; > >>> + } > >> > >>> +static const struct of_device_id uniphier_spi_match[] = { > >>> + { .compatible = "socionext,uniphier-scssi", }, > >> > >>> + { /* sentinel */ }, > >> > >> Slightly better without comma. > > > > OK. I will modify this. > > > > - > > Best Regards, > > Keiji Hayashibara > > > > > > > >>> +}; > >>> +MODULE_DEVICE_TABLE(of, uniphier_spi_match); > >> > >> -- > >> With Best Regards, > >> Andy Shevchenko > > - Best Regards, Keiji Hayashibara
tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent word size. Check asm/bitsperlong.h
Hi Alexei, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: acb1872577b346bd15ab3a3f8dff780d6cca4b70 commit: 819dd92b9c0bc7bce9097d8c1f14240f471bb386 bpfilter: switch to CC from HOSTCC date: 8 weeks ago config: alpha-allmodconfig (attached as .config) compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 819dd92b9c0bc7bce9097d8c1f14240f471bb386 # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=alpha All errors (new ones prefixed by >>): In file included from tools/include/uapi/asm/bitsperlong.h:17:0, from /usr/alpha-linux-gnu/include/asm-generic/int-l64.h:11, from /usr/alpha-linux-gnu/include/asm/types.h:12, from tools/include/linux/types.h:10, from ./include/uapi/linux/bpf.h:11, from net//bpfilter/main.c:9: >> tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent >> word size. Check asm/bitsperlong.h #error Inconsistent word size. Check asm/bitsperlong.h ^ vim +14 tools/include/asm-generic/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 12 2a00f026 Arnaldo Carvalho de Melo 2016-07-13 13 #if BITS_PER_LONG != __BITS_PER_LONG bb970707 Arnaldo Carvalho de Melo 2016-07-12 @14 #error Inconsistent word size. Check asm/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 15 #endif bb970707 Arnaldo Carvalho de Melo 2016-07-12 16 :: The code at line 14 was first introduced by commit :: bb9707077b4ee5f77bc9939b057ff8a0d410296f tools: Copy the bitsperlong.h files from the kernel :: TO: Arnaldo Carvalho de Melo :: CC: Arnaldo Carvalho de Melo --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent word size. Check asm/bitsperlong.h
Hi Alexei, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: acb1872577b346bd15ab3a3f8dff780d6cca4b70 commit: 819dd92b9c0bc7bce9097d8c1f14240f471bb386 bpfilter: switch to CC from HOSTCC date: 8 weeks ago config: alpha-allmodconfig (attached as .config) compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 819dd92b9c0bc7bce9097d8c1f14240f471bb386 # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=alpha All errors (new ones prefixed by >>): In file included from tools/include/uapi/asm/bitsperlong.h:17:0, from /usr/alpha-linux-gnu/include/asm-generic/int-l64.h:11, from /usr/alpha-linux-gnu/include/asm/types.h:12, from tools/include/linux/types.h:10, from ./include/uapi/linux/bpf.h:11, from net//bpfilter/main.c:9: >> tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent >> word size. Check asm/bitsperlong.h #error Inconsistent word size. Check asm/bitsperlong.h ^ vim +14 tools/include/asm-generic/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 12 2a00f026 Arnaldo Carvalho de Melo 2016-07-13 13 #if BITS_PER_LONG != __BITS_PER_LONG bb970707 Arnaldo Carvalho de Melo 2016-07-12 @14 #error Inconsistent word size. Check asm/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 15 #endif bb970707 Arnaldo Carvalho de Melo 2016-07-12 16 :: The code at line 14 was first introduced by commit :: bb9707077b4ee5f77bc9939b057ff8a0d410296f tools: Copy the bitsperlong.h files from the kernel :: TO: Arnaldo Carvalho de Melo :: CC: Arnaldo Carvalho de Melo --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver
Hi Linus, On 30 July 2018 at 00:59, Linus Walleij wrote: > On Thu, Jul 26, 2018 at 2:01 AM Tomer Maimon wrote: > > > I initialize bgpio as follow: > > > > ret = bgpio_init(>gpio_bank[id].gc, > > pctrl->dev, 4, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_DIN, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_DOUT, > > NULL, > > NULL, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_IEM, > > BGPIOF_READ_OUTPUT_REG_SET); > > (...) > > The problem occur when reading the GPIO value from bgpio_get_set > function, > > because the directions value are inverse it reading the wrong I/O > registers > > > > For direction out it reading dat register (instead of set register) > > > > For direction in it calling set register (instead of dat register) > > Hm I don't quite get it... sorry. Maybe if you show your fix and what > you expect to happen I can understand better? > Of course, in the last patch sent three days a go (V3 - https://patchwork.ozlabs.org/patch/949942/) I did as follow to workaround the issue: int (*get)(struct gpio_chip *chip, unsigned offset); int (*get_multiple)(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits); .. static int npcmgpio_get_value(struct gpio_chip *chip, unsigned int offset) { struct npcm7xx_gpio *bank = gpiochip_get_data(chip); unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir; int val; /* * sets bgpio_dir parameter value to the opposite value * for calling the right registers in bgpio_get_set * function */ * bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val = bank->get(chip, offset); bank->gc.bgpio_dir = tmp_bgpio_dir;* return val; } static int npcmgpio_get_multiple_value(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct npcm7xx_gpio *bank = gpiochip_get_data(chip); unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir; int val; /* * sets bgpio_dir parameter value to the opposite value * for calling the right registers in bgpio_get_set_multiple * function */ * bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val = bank->get_multiple(chip, mask, bits); bank->gc.bgpio_dir = tmp_bgpio_dir;* return val; } .. pctrl->gpio_bank[id].get = pctrl->gpio_bank[id].gc.get; pctrl->gpio_bank[id].gc.get = npcmgpio_get_value; pctrl->gpio_bank[id].get_multiple = ptrl->gpio_bank[id].gc.get_mul tiple; pctrl->gpio_bank[id].gc.get_multiple = npcmgpio_get_multiple_value; but it is not that good solution, because the bold commands are not atomic (locked) operations. > > Do you mean that because you write the inverse value to > IEM this happens, and the BGPIO code assumes that > you always write 1 to set a line as input and 0 to set it > as output? > yes, because of it the bgpio_get_set and bgpio_get_set_multiple setting the opposite data registers . > > I would say if this causes the problem we should just add > a new BGPIOF_INVERTED_REG_DIR with comment in > include/linux/gpio/driver.h and make the necessary fix to > respect this flag in the gpio-mmio.c core so it works right. > > If you do this as a separate patch I would be grateful :) > Sure, I will send a separate patch later on to overcome it. > > Yours, > Linus Walleij > Thanks, Tomer
Re: [PATCH v2 2/2] pinctrl: nuvoton: add NPCM7xx pinctrl and GPIO driver
Hi Linus, On 30 July 2018 at 00:59, Linus Walleij wrote: > On Thu, Jul 26, 2018 at 2:01 AM Tomer Maimon wrote: > > > I initialize bgpio as follow: > > > > ret = bgpio_init(>gpio_bank[id].gc, > > pctrl->dev, 4, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_DIN, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_DOUT, > > NULL, > > NULL, > > pctrl->gpio_bank[id].base + > > NPCM7XX_GP_N_IEM, > > BGPIOF_READ_OUTPUT_REG_SET); > > (...) > > The problem occur when reading the GPIO value from bgpio_get_set > function, > > because the directions value are inverse it reading the wrong I/O > registers > > > > For direction out it reading dat register (instead of set register) > > > > For direction in it calling set register (instead of dat register) > > Hm I don't quite get it... sorry. Maybe if you show your fix and what > you expect to happen I can understand better? > Of course, in the last patch sent three days a go (V3 - https://patchwork.ozlabs.org/patch/949942/) I did as follow to workaround the issue: int (*get)(struct gpio_chip *chip, unsigned offset); int (*get_multiple)(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits); .. static int npcmgpio_get_value(struct gpio_chip *chip, unsigned int offset) { struct npcm7xx_gpio *bank = gpiochip_get_data(chip); unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir; int val; /* * sets bgpio_dir parameter value to the opposite value * for calling the right registers in bgpio_get_set * function */ * bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val = bank->get(chip, offset); bank->gc.bgpio_dir = tmp_bgpio_dir;* return val; } static int npcmgpio_get_multiple_value(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits) { struct npcm7xx_gpio *bank = gpiochip_get_data(chip); unsigned long tmp_bgpio_dir = bank->gc.bgpio_dir; int val; /* * sets bgpio_dir parameter value to the opposite value * for calling the right registers in bgpio_get_set_multiple * function */ * bank->gc.bgpio_dir = ~bank->gc.bgpio_dir; val = bank->get_multiple(chip, mask, bits); bank->gc.bgpio_dir = tmp_bgpio_dir;* return val; } .. pctrl->gpio_bank[id].get = pctrl->gpio_bank[id].gc.get; pctrl->gpio_bank[id].gc.get = npcmgpio_get_value; pctrl->gpio_bank[id].get_multiple = ptrl->gpio_bank[id].gc.get_mul tiple; pctrl->gpio_bank[id].gc.get_multiple = npcmgpio_get_multiple_value; but it is not that good solution, because the bold commands are not atomic (locked) operations. > > Do you mean that because you write the inverse value to > IEM this happens, and the BGPIO code assumes that > you always write 1 to set a line as input and 0 to set it > as output? > yes, because of it the bgpio_get_set and bgpio_get_set_multiple setting the opposite data registers . > > I would say if this causes the problem we should just add > a new BGPIOF_INVERTED_REG_DIR with comment in > include/linux/gpio/driver.h and make the necessary fix to > respect this flag in the gpio-mmio.c core so it works right. > > If you do this as a separate patch I would be grateful :) > Sure, I will send a separate patch later on to overcome it. > > Yours, > Linus Walleij > Thanks, Tomer
Re: KASAN: use-after-free Read in generic_perform_write
syzbot has found a reproducer for the following crash on: HEAD commit:d1e0b8e0cb7a Add linux-next specific files for 20180725 git tree: linux-next console output: https://syzkaller.appspot.com/x/log.txt?x=10eff97840 kernel config: https://syzkaller.appspot.com/x/.config?x=eef3552c897e4d33 dashboard link: https://syzkaller.appspot.com/bug?extid=b173e77096a8ba815511 compiler: gcc (GCC) 8.0.1 20180413 (experimental) syzkaller repro:https://syzkaller.appspot.com/x/repro.syz?x=171d957840 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=132d14b440 IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+b173e77096a8ba815...@syzkaller.appspotmail.com RDX: 0030 RSI: 20011fd2 RDI: 0004 RBP: 006dbc40 R08: 006dbc40 R09: R10: 7fc1cd74ccf0 R11: 0246 R12: 006dbc4c R13: 7fffabd5ea5f R14: 7fc1cd74d9c0 R15: 006dbd4c == BUG: KASAN: use-after-free in memcpy include/linux/string.h:345 [inline] BUG: KASAN: use-after-free in iov_iter_copy_from_user_atomic+0xb8d/0xfa0 lib/iov_iter.c:916 Read of size 21 at addr 8801ad780d60 by task kworker/0:1/13 CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.18.0-rc6-next-20180725+ #18 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events p9_write_work Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x30d mm/kasan/report.c:412 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267 memcpy+0x23/0x50 mm/kasan/kasan.c:302 memcpy include/linux/string.h:345 [inline] iov_iter_copy_from_user_atomic+0xb8d/0xfa0 lib/iov_iter.c:916 generic_perform_write+0x469/0x6c0 mm/filemap.c:3147 __generic_file_write_iter+0x26e/0x630 mm/filemap.c:3264 ext4_file_write_iter+0x390/0x1450 fs/ext4/file.c:266 call_write_iter include/linux/fs.h:1807 [inline] new_sync_write fs/read_write.c:474 [inline] __vfs_write+0x6af/0x9d0 fs/read_write.c:487 vfs_write+0x1fc/0x560 fs/read_write.c:549 kernel_write+0xab/0x120 fs/read_write.c:526 p9_fd_write net/9p/trans_fd.c:432 [inline] p9_write_work+0x6f1/0xd50 net/9p/trans_fd.c:481 process_one_work+0xc73/0x1ba0 kernel/workqueue.c:2153 worker_thread+0x189/0x13c0 kernel/workqueue.c:2296 kthread+0x345/0x410 kernel/kthread.c:246 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:415 Allocated by task 4438: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553 __do_kmalloc mm/slab.c:3718 [inline] __kmalloc+0x14e/0x760 mm/slab.c:3727 kmalloc include/linux/slab.h:518 [inline] p9_fcall_alloc+0x1e/0x90 net/9p/client.c:237 p9_tag_alloc net/9p/client.c:266 [inline] p9_client_prepare_req.part.8+0x107/0xa00 net/9p/client.c:647 p9_client_prepare_req net/9p/client.c:682 [inline] p9_client_rpc+0x247/0x1420 net/9p/client.c:682 p9_client_version net/9p/client.c:897 [inline] p9_client_create+0xd76/0x1631 net/9p/client.c:981 v9fs_session_init+0x21a/0x1a80 fs/9p/v9fs.c:400 v9fs_mount+0x7c/0x900 fs/9p/vfs_super.c:135 legacy_get_tree+0x131/0x460 fs/fs_context.c:674 vfs_get_tree+0x1cb/0x5c0 fs/super.c:1762 do_new_mount fs/namespace.c:2629 [inline] do_mount+0x6f2/0x1e20 fs/namespace.c:2953 ksys_mount+0x12d/0x140 fs/namespace.c:3169 __do_sys_mount fs/namespace.c:3183 [inline] __se_sys_mount fs/namespace.c:3180 [inline] __x64_sys_mount+0xbe/0x150 fs/namespace.c:3180 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 4438: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521 kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 __cache_free mm/slab.c:3498 [inline] kfree+0xd9/0x260 mm/slab.c:3813 p9_free_req+0xb5/0x120 net/9p/client.c:338 p9_client_rpc+0xb20/0x1420 net/9p/client.c:746 p9_client_version net/9p/client.c:897 [inline] p9_client_create+0xd76/0x1631 net/9p/client.c:981 v9fs_session_init+0x21a/0x1a80 fs/9p/v9fs.c:400 v9fs_mount+0x7c/0x900 fs/9p/vfs_super.c:135 legacy_get_tree+0x131/0x460 fs/fs_context.c:674 vfs_get_tree+0x1cb/0x5c0 fs/super.c:1762 do_new_mount fs/namespace.c:2629 [inline] do_mount+0x6f2/0x1e20 fs/namespace.c:2953 ksys_mount+0x12d/0x140 fs/namespace.c:3169 __do_sys_mount fs/namespace.c:3183 [inline] __se_sys_mount fs/namespace.c:3180 [inline] __x64_sys_mount+0xbe/0x150 fs/namespace.c:3180 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at 8801ad780d40 which belongs to the cache
Re: KASAN: use-after-free Read in generic_perform_write
syzbot has found a reproducer for the following crash on: HEAD commit:d1e0b8e0cb7a Add linux-next specific files for 20180725 git tree: linux-next console output: https://syzkaller.appspot.com/x/log.txt?x=10eff97840 kernel config: https://syzkaller.appspot.com/x/.config?x=eef3552c897e4d33 dashboard link: https://syzkaller.appspot.com/bug?extid=b173e77096a8ba815511 compiler: gcc (GCC) 8.0.1 20180413 (experimental) syzkaller repro:https://syzkaller.appspot.com/x/repro.syz?x=171d957840 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=132d14b440 IMPORTANT: if you fix the bug, please add the following tag to the commit: Reported-by: syzbot+b173e77096a8ba815...@syzkaller.appspotmail.com RDX: 0030 RSI: 20011fd2 RDI: 0004 RBP: 006dbc40 R08: 006dbc40 R09: R10: 7fc1cd74ccf0 R11: 0246 R12: 006dbc4c R13: 7fffabd5ea5f R14: 7fc1cd74d9c0 R15: 006dbd4c == BUG: KASAN: use-after-free in memcpy include/linux/string.h:345 [inline] BUG: KASAN: use-after-free in iov_iter_copy_from_user_atomic+0xb8d/0xfa0 lib/iov_iter.c:916 Read of size 21 at addr 8801ad780d60 by task kworker/0:1/13 CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 4.18.0-rc6-next-20180725+ #18 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events p9_write_work Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1c9/0x2b4 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x30d mm/kasan/report.c:412 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267 memcpy+0x23/0x50 mm/kasan/kasan.c:302 memcpy include/linux/string.h:345 [inline] iov_iter_copy_from_user_atomic+0xb8d/0xfa0 lib/iov_iter.c:916 generic_perform_write+0x469/0x6c0 mm/filemap.c:3147 __generic_file_write_iter+0x26e/0x630 mm/filemap.c:3264 ext4_file_write_iter+0x390/0x1450 fs/ext4/file.c:266 call_write_iter include/linux/fs.h:1807 [inline] new_sync_write fs/read_write.c:474 [inline] __vfs_write+0x6af/0x9d0 fs/read_write.c:487 vfs_write+0x1fc/0x560 fs/read_write.c:549 kernel_write+0xab/0x120 fs/read_write.c:526 p9_fd_write net/9p/trans_fd.c:432 [inline] p9_write_work+0x6f1/0xd50 net/9p/trans_fd.c:481 process_one_work+0xc73/0x1ba0 kernel/workqueue.c:2153 worker_thread+0x189/0x13c0 kernel/workqueue.c:2296 kthread+0x345/0x410 kernel/kthread.c:246 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:415 Allocated by task 4438: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553 __do_kmalloc mm/slab.c:3718 [inline] __kmalloc+0x14e/0x760 mm/slab.c:3727 kmalloc include/linux/slab.h:518 [inline] p9_fcall_alloc+0x1e/0x90 net/9p/client.c:237 p9_tag_alloc net/9p/client.c:266 [inline] p9_client_prepare_req.part.8+0x107/0xa00 net/9p/client.c:647 p9_client_prepare_req net/9p/client.c:682 [inline] p9_client_rpc+0x247/0x1420 net/9p/client.c:682 p9_client_version net/9p/client.c:897 [inline] p9_client_create+0xd76/0x1631 net/9p/client.c:981 v9fs_session_init+0x21a/0x1a80 fs/9p/v9fs.c:400 v9fs_mount+0x7c/0x900 fs/9p/vfs_super.c:135 legacy_get_tree+0x131/0x460 fs/fs_context.c:674 vfs_get_tree+0x1cb/0x5c0 fs/super.c:1762 do_new_mount fs/namespace.c:2629 [inline] do_mount+0x6f2/0x1e20 fs/namespace.c:2953 ksys_mount+0x12d/0x140 fs/namespace.c:3169 __do_sys_mount fs/namespace.c:3183 [inline] __se_sys_mount fs/namespace.c:3180 [inline] __x64_sys_mount+0xbe/0x150 fs/namespace.c:3180 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 4438: save_stack+0x43/0xd0 mm/kasan/kasan.c:448 set_track mm/kasan/kasan.c:460 [inline] __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521 kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528 __cache_free mm/slab.c:3498 [inline] kfree+0xd9/0x260 mm/slab.c:3813 p9_free_req+0xb5/0x120 net/9p/client.c:338 p9_client_rpc+0xb20/0x1420 net/9p/client.c:746 p9_client_version net/9p/client.c:897 [inline] p9_client_create+0xd76/0x1631 net/9p/client.c:981 v9fs_session_init+0x21a/0x1a80 fs/9p/v9fs.c:400 v9fs_mount+0x7c/0x900 fs/9p/vfs_super.c:135 legacy_get_tree+0x131/0x460 fs/fs_context.c:674 vfs_get_tree+0x1cb/0x5c0 fs/super.c:1762 do_new_mount fs/namespace.c:2629 [inline] do_mount+0x6f2/0x1e20 fs/namespace.c:2953 ksys_mount+0x12d/0x140 fs/namespace.c:3169 __do_sys_mount fs/namespace.c:3183 [inline] __se_sys_mount fs/namespace.c:3180 [inline] __x64_sys_mount+0xbe/0x150 fs/namespace.c:3180 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at 8801ad780d40 which belongs to the cache
Re: [PATCH] Staging: octeon: Fixing coding style for minor notices.
Thank you, i found a few case on this module i will try to fix them and send a new patch series. On Sun, 29 Jul 2018 at 20:33, Joe Perches wrote: > > On Sun, 2018-07-29 at 17:43 +0300, Georgios Tsotsos wrote: > > Fixing coding style for a few lines that were reported to check from > > checkpatch.pl in minor cases for alignment and ending with parenthesis. > > > > Signed-off-by: Georgios Tsotsos > > --- > > drivers/staging/octeon/ethernet.c | 10 +- > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/staging/octeon/ethernet.c > > b/drivers/staging/octeon/ethernet.c > > index 9b15c9ed844b..1e258deecacc 100644 > > --- a/drivers/staging/octeon/ethernet.c > > +++ b/drivers/staging/octeon/ethernet.c > > @@ -141,8 +141,8 @@ static void cvm_oct_periodic_worker(struct work_struct > > *work) > > if (priv->poll) > > priv->poll(cvm_oct_device[priv->port]); > > > > - cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats( > > - cvm_oct_device[priv->port]); > > + cvm_oct_device[priv->port]->netdev_ops > > + ->ndo_get_stats(cvm_oct_device[priv->port]); > > > > if (!atomic_read(_oct_poll_queue_stopping)) > > schedule_delayed_work(>port_periodic_work, HZ); > > Probably more sensible to use a temporary. Something like: > --- > drivers/staging/octeon/ethernet.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/staging/octeon/ethernet.c > b/drivers/staging/octeon/ethernet.c > index 9b15c9ed844b..2febf1229587 100644 > --- a/drivers/staging/octeon/ethernet.c > +++ b/drivers/staging/octeon/ethernet.c > @@ -137,12 +137,12 @@ static void cvm_oct_periodic_worker(struct work_struct > *work) > struct octeon_ethernet *priv = container_of(work, > struct octeon_ethernet, > port_periodic_work.work); > + struct net_device *ndev = cvm_oct_device[priv->port]; > > if (priv->poll) > - priv->poll(cvm_oct_device[priv->port]); > + priv->poll(ndev); > > - cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats( > - cvm_oct_device[priv->port]); > + ndev->netdev_ops->ndo_get_stats(ndev); > > if (!atomic_read(_oct_poll_queue_stopping)) > schedule_delayed_work(>port_periodic_work, HZ); > > -- Best regards! Georgios Tsotsos Greece-Evia-Chalkida tsot...@linux.com skype: tsotsos Georgios Tsotsos *Greece - Evia - Chalkida* tsotsos[at]linux.com skype: tsotsos
Re: [PATCH] Staging: octeon: Fixing coding style for minor notices.
Thank you, i found a few case on this module i will try to fix them and send a new patch series. On Sun, 29 Jul 2018 at 20:33, Joe Perches wrote: > > On Sun, 2018-07-29 at 17:43 +0300, Georgios Tsotsos wrote: > > Fixing coding style for a few lines that were reported to check from > > checkpatch.pl in minor cases for alignment and ending with parenthesis. > > > > Signed-off-by: Georgios Tsotsos > > --- > > drivers/staging/octeon/ethernet.c | 10 +- > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/staging/octeon/ethernet.c > > b/drivers/staging/octeon/ethernet.c > > index 9b15c9ed844b..1e258deecacc 100644 > > --- a/drivers/staging/octeon/ethernet.c > > +++ b/drivers/staging/octeon/ethernet.c > > @@ -141,8 +141,8 @@ static void cvm_oct_periodic_worker(struct work_struct > > *work) > > if (priv->poll) > > priv->poll(cvm_oct_device[priv->port]); > > > > - cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats( > > - cvm_oct_device[priv->port]); > > + cvm_oct_device[priv->port]->netdev_ops > > + ->ndo_get_stats(cvm_oct_device[priv->port]); > > > > if (!atomic_read(_oct_poll_queue_stopping)) > > schedule_delayed_work(>port_periodic_work, HZ); > > Probably more sensible to use a temporary. Something like: > --- > drivers/staging/octeon/ethernet.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/staging/octeon/ethernet.c > b/drivers/staging/octeon/ethernet.c > index 9b15c9ed844b..2febf1229587 100644 > --- a/drivers/staging/octeon/ethernet.c > +++ b/drivers/staging/octeon/ethernet.c > @@ -137,12 +137,12 @@ static void cvm_oct_periodic_worker(struct work_struct > *work) > struct octeon_ethernet *priv = container_of(work, > struct octeon_ethernet, > port_periodic_work.work); > + struct net_device *ndev = cvm_oct_device[priv->port]; > > if (priv->poll) > - priv->poll(cvm_oct_device[priv->port]); > + priv->poll(ndev); > > - cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats( > - cvm_oct_device[priv->port]); > + ndev->netdev_ops->ndo_get_stats(ndev); > > if (!atomic_read(_oct_poll_queue_stopping)) > schedule_delayed_work(>port_periodic_work, HZ); > > -- Best regards! Georgios Tsotsos Greece-Evia-Chalkida tsot...@linux.com skype: tsotsos Georgios Tsotsos *Greece - Evia - Chalkida* tsotsos[at]linux.com skype: tsotsos
[PATCH v5] Staging: octeon-usb: Using defined error codes and applying coding style.
Replaced -1 with defined error code EINVAL Signed-off-by: Georgios Tsotsos --- v2: Apply coding style to function cvmx_usb_poll_channel v3: Break down function cvmx_usb_poll_channel v4: Return defined error code and applying coding style for function calls v5: Fixing wrong patch applied before with typo on dev_err and applying coding style as suggested on v3 drivers/staging/octeon-usb/octeon-hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index c9fbff93bed4..dd73fd48e12e 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -2587,10 +2587,10 @@ static void cvmx_usb_transfer_isoc(struct octeon_hcd *usb, } } else { pipe->next_tx_frame += pipe->interval; - cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_OK); } } + /** * Handles channels halt in non DMA mode * @hcchar_chena: @@ -2629,7 +2629,7 @@ static int cvmx_usb_dma_halt(u32 hcchar_chena, u32 hcint_xfercompl, * Channel halt isn't needed. */ } else { - dev_err(dev, "USB%d: Channel %d interrupt without halt\n", + dev_err(dev, "USB%d: Channel %d interrupt without halt\n", usb->index, channel); return -EINVAL; } -- 2.16.4
[PATCH v5] Staging: octeon-usb: Using defined error codes and applying coding style.
Replaced -1 with defined error code EINVAL Signed-off-by: Georgios Tsotsos --- v2: Apply coding style to function cvmx_usb_poll_channel v3: Break down function cvmx_usb_poll_channel v4: Return defined error code and applying coding style for function calls v5: Fixing wrong patch applied before with typo on dev_err and applying coding style as suggested on v3 drivers/staging/octeon-usb/octeon-hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index c9fbff93bed4..dd73fd48e12e 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -2587,10 +2587,10 @@ static void cvmx_usb_transfer_isoc(struct octeon_hcd *usb, } } else { pipe->next_tx_frame += pipe->interval; - cvmx_usb_complete(usb, pipe, transaction, CVMX_USB_STATUS_OK); } } + /** * Handles channels halt in non DMA mode * @hcchar_chena: @@ -2629,7 +2629,7 @@ static int cvmx_usb_dma_halt(u32 hcchar_chena, u32 hcint_xfercompl, * Channel halt isn't needed. */ } else { - dev_err(dev, "USB%d: Channel %d interrupt without halt\n", + dev_err(dev, "USB%d: Channel %d interrupt without halt\n", usb->index, channel); return -EINVAL; } -- 2.16.4
[PATCH v5] Staging: octeon-usb: Changes macro CVMX_WAIT_FOR_FIELD32 to function call
Replacing CVMX_WAIT_FOR_FIELD32 macro with equivalent function, and used simpler approach for new function's parameters. Signed-off-by: Georgios Tsotsos --- v3: Changed CVMX_WAIT_FOR_FIELD32 macro to function according as refereed in commit message and suggested by Greg Kroah-Hartman v4: Added patch version text v5: Fix parameters issue and simplify new function. drivers/staging/octeon-usb/octeon-hcd.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index edf87d1b3609..c9fbff93bed4 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -574,18 +574,15 @@ static inline int cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe) * Loop through register until txfflsh or rxfflsh become zero. * * @usb: USB block - * @address: 64bit address to read - * @timeout_usec: Timeout * @fflsh_type:Indicates fflsh type, 0 for txfflsh, 1 for rxfflsh * */ -static int cvmx_wait_for_field32(struct octeon_hcd *usb, u64 address, -u64 timeout_usec, int fflsh_type) +static int cvmx_wait_tx_rx(struct octeon_hcd *usb, int fflsh_type) { int result; - u64 done = cvmx_get_cycle() + timeout_usec * + u64 address = CVMX_USBCX_GRSTCTL(usb->index); + u64 done = cvmx_get_cycle() + 100 * (u64)octeon_get_clock_rate / 100; - union cvmx_usbcx_grstctl c; while (1) { @@ -648,9 +645,9 @@ static void cvmx_fifo_setup(struct octeon_hcd *usb) /* Flush all FIFOs */ USB_SET_FIELD32(address, cvmx_usbcx_grstctl, txfnum, 0x10); USB_SET_FIELD32(address, cvmx_usbcx_grstctl, txfflsh, 1); - cvmx_wait_for_field32(usb, address, 0, 100); + cvmx_wait_tx_rx(usb, 0); USB_SET_FIELD32(address, cvmx_usbcx_grstctl, rxfflsh, 1); - cvmx_wait_for_field32(usb, address, 1, 100); + cvmx_wait_tx_rx(usb, 1); } /** -- 2.16.4
[PATCH v5] Staging: octeon-usb: Changes macro CVMX_WAIT_FOR_FIELD32 to function call
Replacing CVMX_WAIT_FOR_FIELD32 macro with equivalent function, and used simpler approach for new function's parameters. Signed-off-by: Georgios Tsotsos --- v3: Changed CVMX_WAIT_FOR_FIELD32 macro to function according as refereed in commit message and suggested by Greg Kroah-Hartman v4: Added patch version text v5: Fix parameters issue and simplify new function. drivers/staging/octeon-usb/octeon-hcd.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index edf87d1b3609..c9fbff93bed4 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c @@ -574,18 +574,15 @@ static inline int cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe) * Loop through register until txfflsh or rxfflsh become zero. * * @usb: USB block - * @address: 64bit address to read - * @timeout_usec: Timeout * @fflsh_type:Indicates fflsh type, 0 for txfflsh, 1 for rxfflsh * */ -static int cvmx_wait_for_field32(struct octeon_hcd *usb, u64 address, -u64 timeout_usec, int fflsh_type) +static int cvmx_wait_tx_rx(struct octeon_hcd *usb, int fflsh_type) { int result; - u64 done = cvmx_get_cycle() + timeout_usec * + u64 address = CVMX_USBCX_GRSTCTL(usb->index); + u64 done = cvmx_get_cycle() + 100 * (u64)octeon_get_clock_rate / 100; - union cvmx_usbcx_grstctl c; while (1) { @@ -648,9 +645,9 @@ static void cvmx_fifo_setup(struct octeon_hcd *usb) /* Flush all FIFOs */ USB_SET_FIELD32(address, cvmx_usbcx_grstctl, txfnum, 0x10); USB_SET_FIELD32(address, cvmx_usbcx_grstctl, txfflsh, 1); - cvmx_wait_for_field32(usb, address, 0, 100); + cvmx_wait_tx_rx(usb, 0); USB_SET_FIELD32(address, cvmx_usbcx_grstctl, rxfflsh, 1); - cvmx_wait_for_field32(usb, address, 1, 100); + cvmx_wait_tx_rx(usb, 1); } /** -- 2.16.4
Linux 4.18-rc7
So unless something odd happens, this should be the last rc for 4.18. Nothing particularly odd happened this last week - we got the usual random set of various minor fixes all over. About two thirds of it is drivers - networking, staging and usb stands out, but there's a little bit of stuff all over (clk, block, gpu, nvme..). Outside of drivers, the bulk is some core networking stuff, with random changes elsewhere (minor arch updates, filesystems, core kernel, test scripts). The appended shortlog gives a flavor of the details. Linus --- Adam Thomson (1): usb: typec: tcpm: Fix sink PDO starting index for PPS APDO selection Aleksander Morgado (1): qmi_wwan: fix interface number for DW5821e production firmware Alexander Sverdlin (1): i2c: davinci: Avoid zero value of CLKH Amar Singhal (1): cfg80211: never ignore user regulatory hint Anssi Hannula (7): can: xilinx_can: fix device dropping off bus on RX overrun can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK can: xilinx_can: fix recovery from error states not being propagated can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting can: xilinx_can: fix RX overflow interrupt not being enabled can: xilinx_can: fix incorrect clear of non-processed interrupts can: xilinx_can: fix power management handling Antti Seppälä (2): usb: dwc2: Fix DMA alignment to start at allocated boundary usb: dwc2: Fix inefficient copy of unaligned buffers Ariel Levkovich (1): net/mlx5: Adjust clock overflow work period Arnd Bergmann (2): kasan: only select SLUB_DEBUG with SYSFS=y include/linux/eventfd.h: include linux/errno.h Artem Savkov (1): tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure Benjamin Herrenschmidt (4): clk: aspeed: Treat a gate in reset as disabled usb: gadget: aspeed-vhub: Fix SETUP packets with OUT data phase usb: gadget: Fix OS descriptors support usb: gadget: aspeed: Workaround memory ordering issue Bernd Edlinger (1): nl80211: Add a missing break in parse_station_flags Bin Liu (1): usb: core: handle hub C_PORT_OVER_CURRENT condition Carlos Maiolino (1): xfs: Initialize variables in xfs_alloc_get_rec before using them Chen-Yu Tsai (1): Input: i8042 - add Lenovo LaVie Z to the i8042 reset list Clint Taylor (1): drm/i915/glk: Add Quirk for GLK NUC HDMI port issues. Colin Ian King (1): usb: dwc3: gadget: remove redundant variable maxpacket Dan Williams (1): mm: fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL Daniel Borkmann (3): bpf, ppc64: fix unexpected r0=0 exit path inside bpf_xadd bpf: test case to check whether src/dst regs got mangled by xadd sock: fix sg page frag coalescing in sk_alloc_sg Dave Jiang (1): mm: disallow mappings that conflict for devm_memremap_pages() David Ahern (1): net/ipv6: Fix linklocal to global address with VRF Davidlohr Bueso (1): ipc/sem.c: prevent queue.status tearing in semop Denis Kenzior (1): nl80211/mac80211: allow non-linear skb in rx_control_port Dirk Mueller (1): arm64: Check for errata before evaluating cpu features Dmitry Torokhov (1): usb: dwc2: host: do not delay retries for CONTROL IN transfers Donald Shanty III (1): Input: elan_i2c - add ACPI ID for lenovo ideapad 330 Doron Roberts-Kedes (1): tls: check RCV_SHUTDOWN in tls_wait_data Enric Balletbo i Serra (1): usb: dwc3: rockchip: Fix PHY documentation links. Eran Ben Elisha (2): net/mlx5e: Fix quota counting in aRFS expire flow net/mlx5e: Don't allow aRFS for encapsulated packets Eric Dumazet (6): net: skb_segment() should not return NULL tcp: free batches of packets in tcp_prune_ofo_queue() tcp: avoid collapses in tcp_prune_queue() if possible tcp: detect malicious patterns in tcp_collapse_ofo_queue() tcp: call tcp_drop() from tcp_data_queue_ofo() tcp: add tcp_ooo_try_coalesce() helper Eric Sandeen (1): xfs: properly handle free inodes in extent hint validators Esben Haabendal (1): i2c: imx: Fix reinit_completion() use Eugeniu Rosca (3): usb: gadget: f_uac2: fix error handling in afunc_bind (again) usb: gadget: u_audio: fix pcm/card naming in g_audio_setup() usb: gadget: f_uac2: fix endianness of 'struct cntrl_*_lay3' Fabio Estevam (1): usb: chipidea: Always build ULPI code Faiz Abbas (2): can: m_can: Fix runtime resume call can: m_can: Move accessing of message ram to after clocks are enabled Felix Fietkau (1): MIPS: ath79: fix register address in ath79_ddr_wb_flush() Florian Westphal (7): netfilter: nf_tables: use dev->name directly netfilter: nf_tables: free flow table struct too netfilter: nf_tables: fix memory leaks on chain rename netfilter: nf_tables: don't allow to rename to
Linux 4.18-rc7
So unless something odd happens, this should be the last rc for 4.18. Nothing particularly odd happened this last week - we got the usual random set of various minor fixes all over. About two thirds of it is drivers - networking, staging and usb stands out, but there's a little bit of stuff all over (clk, block, gpu, nvme..). Outside of drivers, the bulk is some core networking stuff, with random changes elsewhere (minor arch updates, filesystems, core kernel, test scripts). The appended shortlog gives a flavor of the details. Linus --- Adam Thomson (1): usb: typec: tcpm: Fix sink PDO starting index for PPS APDO selection Aleksander Morgado (1): qmi_wwan: fix interface number for DW5821e production firmware Alexander Sverdlin (1): i2c: davinci: Avoid zero value of CLKH Amar Singhal (1): cfg80211: never ignore user regulatory hint Anssi Hannula (7): can: xilinx_can: fix device dropping off bus on RX overrun can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK can: xilinx_can: fix recovery from error states not being propagated can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting can: xilinx_can: fix RX overflow interrupt not being enabled can: xilinx_can: fix incorrect clear of non-processed interrupts can: xilinx_can: fix power management handling Antti Seppälä (2): usb: dwc2: Fix DMA alignment to start at allocated boundary usb: dwc2: Fix inefficient copy of unaligned buffers Ariel Levkovich (1): net/mlx5: Adjust clock overflow work period Arnd Bergmann (2): kasan: only select SLUB_DEBUG with SYSFS=y include/linux/eventfd.h: include linux/errno.h Artem Savkov (1): tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure Benjamin Herrenschmidt (4): clk: aspeed: Treat a gate in reset as disabled usb: gadget: aspeed-vhub: Fix SETUP packets with OUT data phase usb: gadget: Fix OS descriptors support usb: gadget: aspeed: Workaround memory ordering issue Bernd Edlinger (1): nl80211: Add a missing break in parse_station_flags Bin Liu (1): usb: core: handle hub C_PORT_OVER_CURRENT condition Carlos Maiolino (1): xfs: Initialize variables in xfs_alloc_get_rec before using them Chen-Yu Tsai (1): Input: i8042 - add Lenovo LaVie Z to the i8042 reset list Clint Taylor (1): drm/i915/glk: Add Quirk for GLK NUC HDMI port issues. Colin Ian King (1): usb: dwc3: gadget: remove redundant variable maxpacket Dan Williams (1): mm: fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL Daniel Borkmann (3): bpf, ppc64: fix unexpected r0=0 exit path inside bpf_xadd bpf: test case to check whether src/dst regs got mangled by xadd sock: fix sg page frag coalescing in sk_alloc_sg Dave Jiang (1): mm: disallow mappings that conflict for devm_memremap_pages() David Ahern (1): net/ipv6: Fix linklocal to global address with VRF Davidlohr Bueso (1): ipc/sem.c: prevent queue.status tearing in semop Denis Kenzior (1): nl80211/mac80211: allow non-linear skb in rx_control_port Dirk Mueller (1): arm64: Check for errata before evaluating cpu features Dmitry Torokhov (1): usb: dwc2: host: do not delay retries for CONTROL IN transfers Donald Shanty III (1): Input: elan_i2c - add ACPI ID for lenovo ideapad 330 Doron Roberts-Kedes (1): tls: check RCV_SHUTDOWN in tls_wait_data Enric Balletbo i Serra (1): usb: dwc3: rockchip: Fix PHY documentation links. Eran Ben Elisha (2): net/mlx5e: Fix quota counting in aRFS expire flow net/mlx5e: Don't allow aRFS for encapsulated packets Eric Dumazet (6): net: skb_segment() should not return NULL tcp: free batches of packets in tcp_prune_ofo_queue() tcp: avoid collapses in tcp_prune_queue() if possible tcp: detect malicious patterns in tcp_collapse_ofo_queue() tcp: call tcp_drop() from tcp_data_queue_ofo() tcp: add tcp_ooo_try_coalesce() helper Eric Sandeen (1): xfs: properly handle free inodes in extent hint validators Esben Haabendal (1): i2c: imx: Fix reinit_completion() use Eugeniu Rosca (3): usb: gadget: f_uac2: fix error handling in afunc_bind (again) usb: gadget: u_audio: fix pcm/card naming in g_audio_setup() usb: gadget: f_uac2: fix endianness of 'struct cntrl_*_lay3' Fabio Estevam (1): usb: chipidea: Always build ULPI code Faiz Abbas (2): can: m_can: Fix runtime resume call can: m_can: Move accessing of message ram to after clocks are enabled Felix Fietkau (1): MIPS: ath79: fix register address in ath79_ddr_wb_flush() Florian Westphal (7): netfilter: nf_tables: use dev->name directly netfilter: nf_tables: free flow table struct too netfilter: nf_tables: fix memory leaks on chain rename netfilter: nf_tables: don't allow to rename to
[PATCH 06/16] udf: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/udf/namei.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index c586026508db..061d049c2620 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -608,8 +608,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode) fi = udf_add_entry(dir, dentry, , , ); if (unlikely(!fi)) { inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); @@ -700,8 +699,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) fi = udf_add_entry(inode, NULL, , , ); if (!fi) { inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } set_nlink(inode, 2); @@ -719,8 +717,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (!fi) { clear_nlink(inode); mark_inode_dirty(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); @@ -1047,8 +1044,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, out_no_entry: up_write(>i_data_sem); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } -- 2.11.0
[PATCH 07/16] ext2: make sure that partially set up inodes won't be returned by ext2_iget()
From: Al Viro Signed-off-by: Al Viro --- fs/ext2/ialloc.c | 3 +-- fs/ext2/namei.c | 9 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 6484199b35d1..5c3d7b7e4975 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -611,8 +611,7 @@ struct inode *ext2_new_inode(struct inode *dir, umode_t mode, dquot_drop(inode); inode->i_flags |= S_NOQUOTA; clear_nlink(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return ERR_PTR(err); fail: diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 152453a91877..0c26dcc5d850 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -45,8 +45,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) return 0; } inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -192,8 +191,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, out_fail: inode_dec_link_count(inode); - unlock_new_inode(inode); - iput (inode); + discard_new_inode(inode); goto out; } @@ -261,8 +259,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); out_dir: inode_dec_link_count(dir); goto out; -- 2.11.0
[PATCH 01/16] nfs_instantiate(): prevent multiple aliases for directory inode
From: Al Viro Since NFS allows open-by-fhandle, we have to cope with the possibility of mkdir vs. open-by-guessed-handle races. A local filesystem could decide what the inumber of the new object will be and insert a locked inode with that inumber into icache _before_ the on-disk data structures begin to look good and unlock it only once it has a dentry alias, so that open-by-handle coming first would quietly fail and mkdir coming first would have open-by-handle grab its dentry. For NFS it's a non-starter - the icache key is server-supplied fhandle and we do not get that until the object has been fully created on server. We really have to deal with the possibility that open-by-handle gets the in-core inode and attaches a dentry to it before mkdir does. Solution: let nfs_mkdir() use d_splice_alias() to catch those. We can * get an error. Just return it to our caller. * get NULL - no preexisting dentry aliases, we'd just done what d_add() would've done. Success. * get a reference to preexisting alias. In that case the alias had been moved in place of nfs_mkdir() argument (and hashed there), while nfs_mkdir() argument is left unhashed negative. Which is just fine for ->mkdir() callers, all we need is to release the reference we'd got from d_splice_alias() and report success. Cc: Trond Myklebust Signed-off-by: Al Viro --- fs/nfs/dir.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7a9c14426855..df6fd4e5b068 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1641,6 +1641,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, struct dentry *parent = dget_parent(dentry); struct inode *dir = d_inode(parent); struct inode *inode; + struct dentry *d; int error = -EACCES; d_drop(dentry); @@ -1662,10 +1663,12 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, goto out_error; } inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); - error = PTR_ERR(inode); - if (IS_ERR(inode)) + d = d_splice_alias(inode, dentry); + if (IS_ERR(d)) { + error = PTR_ERR(d); goto out_error; - d_add(dentry, inode); + } + dput(d); out: dput(parent); return 0; -- 2.11.0
[PATCH 06/16] udf: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/udf/namei.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index c586026508db..061d049c2620 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -608,8 +608,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode) fi = udf_add_entry(dir, dentry, , , ); if (unlikely(!fi)) { inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); @@ -700,8 +699,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) fi = udf_add_entry(inode, NULL, , , ); if (!fi) { inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } set_nlink(inode, 2); @@ -719,8 +717,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) if (!fi) { clear_nlink(inode); mark_inode_dirty(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); @@ -1047,8 +1044,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, out_no_entry: up_write(>i_data_sem); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); goto out; } -- 2.11.0
[PATCH 07/16] ext2: make sure that partially set up inodes won't be returned by ext2_iget()
From: Al Viro Signed-off-by: Al Viro --- fs/ext2/ialloc.c | 3 +-- fs/ext2/namei.c | 9 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 6484199b35d1..5c3d7b7e4975 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -611,8 +611,7 @@ struct inode *ext2_new_inode(struct inode *dir, umode_t mode, dquot_drop(inode); inode->i_flags |= S_NOQUOTA; clear_nlink(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return ERR_PTR(err); fail: diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 152453a91877..0c26dcc5d850 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -45,8 +45,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) return 0; } inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -192,8 +191,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, out_fail: inode_dec_link_count(inode); - unlock_new_inode(inode); - iput (inode); + discard_new_inode(inode); goto out; } @@ -261,8 +259,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); out_dir: inode_dec_link_count(dir); goto out; -- 2.11.0
[PATCH 01/16] nfs_instantiate(): prevent multiple aliases for directory inode
From: Al Viro Since NFS allows open-by-fhandle, we have to cope with the possibility of mkdir vs. open-by-guessed-handle races. A local filesystem could decide what the inumber of the new object will be and insert a locked inode with that inumber into icache _before_ the on-disk data structures begin to look good and unlock it only once it has a dentry alias, so that open-by-handle coming first would quietly fail and mkdir coming first would have open-by-handle grab its dentry. For NFS it's a non-starter - the icache key is server-supplied fhandle and we do not get that until the object has been fully created on server. We really have to deal with the possibility that open-by-handle gets the in-core inode and attaches a dentry to it before mkdir does. Solution: let nfs_mkdir() use d_splice_alias() to catch those. We can * get an error. Just return it to our caller. * get NULL - no preexisting dentry aliases, we'd just done what d_add() would've done. Success. * get a reference to preexisting alias. In that case the alias had been moved in place of nfs_mkdir() argument (and hashed there), while nfs_mkdir() argument is left unhashed negative. Which is just fine for ->mkdir() callers, all we need is to release the reference we'd got from d_splice_alias() and report success. Cc: Trond Myklebust Signed-off-by: Al Viro --- fs/nfs/dir.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7a9c14426855..df6fd4e5b068 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1641,6 +1641,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, struct dentry *parent = dget_parent(dentry); struct inode *dir = d_inode(parent); struct inode *inode; + struct dentry *d; int error = -EACCES; d_drop(dentry); @@ -1662,10 +1663,12 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, goto out_error; } inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label); - error = PTR_ERR(inode); - if (IS_ERR(inode)) + d = d_splice_alias(inode, dentry); + if (IS_ERR(d)) { + error = PTR_ERR(d); goto out_error; - d_add(dentry, inode); + } + dput(d); out: dput(parent); return 0; -- 2.11.0
[PATCH 04/16] btrfs: switch to discard_new_inode()
From: Al Viro Make sure that no partially set up inodes can be returned by open-by-handle. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 106 --- 1 file changed, 39 insertions(+), 67 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e9482f0db9d0..9382e0881900 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6335,8 +6335,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, location->type = BTRFS_INODE_ITEM_KEY; ret = btrfs_insert_inode_locked(inode); - if (ret < 0) + if (ret < 0) { + iput(inode); goto fail; + } path->leave_spinning = 1; ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems); @@ -6395,12 +6397,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, return inode; fail_unlock: - unlock_new_inode(inode); + discard_new_inode(inode); fail: if (dir && name) BTRFS_I(dir)->index_cnt--; btrfs_free_path(path); - iput(inode); return ERR_PTR(ret); } @@ -6505,7 +6506,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; int err; - int drop_inode = 0; u64 objectid; u64 index = 0; @@ -6527,6 +6527,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); + inode = NULL; goto out_unlock; } @@ -6541,31 +6542,24 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, err = btrfs_init_inode_security(trans, inode, dir, >d_name); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 0, index); - if (err) { - goto out_unlock_inode; - } else { - btrfs_update_inode(trans, root, inode); - d_instantiate_new(dentry, inode); - } + if (err) + goto out_unlock; + + btrfs_update_inode(trans, root, inode); + d_instantiate_new(dentry, inode); out_unlock: btrfs_end_transaction(trans); btrfs_btree_balance_dirty(fs_info); - if (drop_inode) { + if (err && inode) { inode_dec_link_count(inode); - iput(inode); + discard_new_inode(inode); } return err; - -out_unlock_inode: - drop_inode = 1; - unlock_new_inode(inode); - goto out_unlock; - } static int btrfs_create(struct inode *dir, struct dentry *dentry, @@ -6575,7 +6569,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; - int drop_inode_on_err = 0; int err; u64 objectid; u64 index = 0; @@ -6598,9 +6591,9 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); + inode = NULL; goto out_unlock; } - drop_inode_on_err = 1; /* * If the active LSM wants to access the inode during * d_instantiate it needs these. Smack checks to see @@ -6613,33 +6606,28 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, err = btrfs_init_inode_security(trans, inode, dir, >d_name); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_update_inode(trans, root, inode); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 0, index); if (err) - goto out_unlock_inode; + goto out_unlock; BTRFS_I(inode)->io_tree.ops = _extent_io_ops; d_instantiate_new(dentry, inode); out_unlock: btrfs_end_transaction(trans); - if (err && drop_inode_on_err) { + if (err && inode) { inode_dec_link_count(inode); - iput(inode); + discard_new_inode(inode); } btrfs_btree_balance_dirty(fs_info); return err; - -out_unlock_inode: - unlock_new_inode(inode); - goto out_unlock; - } static int btrfs_link(struct dentry *old_dentry, struct inode *dir, @@ -6748,6 +6736,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) S_IFDIR | mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); +
[PATCH 04/16] btrfs: switch to discard_new_inode()
From: Al Viro Make sure that no partially set up inodes can be returned by open-by-handle. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 106 --- 1 file changed, 39 insertions(+), 67 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e9482f0db9d0..9382e0881900 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6335,8 +6335,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, location->type = BTRFS_INODE_ITEM_KEY; ret = btrfs_insert_inode_locked(inode); - if (ret < 0) + if (ret < 0) { + iput(inode); goto fail; + } path->leave_spinning = 1; ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems); @@ -6395,12 +6397,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, return inode; fail_unlock: - unlock_new_inode(inode); + discard_new_inode(inode); fail: if (dir && name) BTRFS_I(dir)->index_cnt--; btrfs_free_path(path); - iput(inode); return ERR_PTR(ret); } @@ -6505,7 +6506,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; int err; - int drop_inode = 0; u64 objectid; u64 index = 0; @@ -6527,6 +6527,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); + inode = NULL; goto out_unlock; } @@ -6541,31 +6542,24 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, err = btrfs_init_inode_security(trans, inode, dir, >d_name); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 0, index); - if (err) { - goto out_unlock_inode; - } else { - btrfs_update_inode(trans, root, inode); - d_instantiate_new(dentry, inode); - } + if (err) + goto out_unlock; + + btrfs_update_inode(trans, root, inode); + d_instantiate_new(dentry, inode); out_unlock: btrfs_end_transaction(trans); btrfs_btree_balance_dirty(fs_info); - if (drop_inode) { + if (err && inode) { inode_dec_link_count(inode); - iput(inode); + discard_new_inode(inode); } return err; - -out_unlock_inode: - drop_inode = 1; - unlock_new_inode(inode); - goto out_unlock; - } static int btrfs_create(struct inode *dir, struct dentry *dentry, @@ -6575,7 +6569,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = NULL; - int drop_inode_on_err = 0; int err; u64 objectid; u64 index = 0; @@ -6598,9 +6591,9 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); + inode = NULL; goto out_unlock; } - drop_inode_on_err = 1; /* * If the active LSM wants to access the inode during * d_instantiate it needs these. Smack checks to see @@ -6613,33 +6606,28 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, err = btrfs_init_inode_security(trans, inode, dir, >d_name); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_update_inode(trans, root, inode); if (err) - goto out_unlock_inode; + goto out_unlock; err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 0, index); if (err) - goto out_unlock_inode; + goto out_unlock; BTRFS_I(inode)->io_tree.ops = _extent_io_ops; d_instantiate_new(dentry, inode); out_unlock: btrfs_end_transaction(trans); - if (err && drop_inode_on_err) { + if (err && inode) { inode_dec_link_count(inode); - iput(inode); + discard_new_inode(inode); } btrfs_btree_balance_dirty(fs_info); return err; - -out_unlock_inode: - unlock_new_inode(inode); - goto out_unlock; - } static int btrfs_link(struct dentry *old_dentry, struct inode *dir, @@ -6748,6 +6736,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) S_IFDIR | mode, ); if (IS_ERR(inode)) { err = PTR_ERR(inode); +
[PATCH 09/16] btrfs: IS_ERR(p) && PTR_ERR(p) == n is a weird way to spell p == ERR_PTR(n)
From: Al Viro Cc: Chris Mason Signed-off-by: Al Viro --- fs/btrfs/transaction.c | 2 +- fs/btrfs/tree-log.c| 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index ff5f6c719976..feb0348dbcbf 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -680,7 +680,7 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root) trans = start_transaction(root, 0, TRANS_ATTACH, BTRFS_RESERVE_NO_FLUSH, true); - if (IS_ERR(trans) && PTR_ERR(trans) == -ENOENT) + if (trans == ERR_PTR(-ENOENT)) btrfs_wait_for_commit(root->fs_info, 0); return trans; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index fcfbe1d8584a..2c13e8155ff1 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2116,7 +2116,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, dir_key->offset, name, name_len, 0); } - if (!log_di || (IS_ERR(log_di) && PTR_ERR(log_di) == -ENOENT)) { + if (!log_di || log_di == ERR_PTR(-ENOENT)) { btrfs_dir_item_key_to_cpu(eb, di, ); btrfs_release_path(path); btrfs_release_path(log_path); @@ -5090,8 +5090,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, * we don't need to do more work nor fallback to * a transaction commit. */ - if (IS_ERR(other_inode) && - PTR_ERR(other_inode) == -ENOENT) { + if (other_inode == ERR_PTR(-ENOENT)) { goto next_key; } else if (IS_ERR(other_inode)) { err = PTR_ERR(other_inode); -- 2.11.0
[PATCH 09/16] btrfs: IS_ERR(p) && PTR_ERR(p) == n is a weird way to spell p == ERR_PTR(n)
From: Al Viro Cc: Chris Mason Signed-off-by: Al Viro --- fs/btrfs/transaction.c | 2 +- fs/btrfs/tree-log.c| 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index ff5f6c719976..feb0348dbcbf 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -680,7 +680,7 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root) trans = start_transaction(root, 0, TRANS_ATTACH, BTRFS_RESERVE_NO_FLUSH, true); - if (IS_ERR(trans) && PTR_ERR(trans) == -ENOENT) + if (trans == ERR_PTR(-ENOENT)) btrfs_wait_for_commit(root->fs_info, 0); return trans; diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index fcfbe1d8584a..2c13e8155ff1 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2116,7 +2116,7 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, dir_key->offset, name, name_len, 0); } - if (!log_di || (IS_ERR(log_di) && PTR_ERR(log_di) == -ENOENT)) { + if (!log_di || log_di == ERR_PTR(-ENOENT)) { btrfs_dir_item_key_to_cpu(eb, di, ); btrfs_release_path(path); btrfs_release_path(log_path); @@ -5090,8 +5090,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, * we don't need to do more work nor fallback to * a transaction commit. */ - if (IS_ERR(other_inode) && - PTR_ERR(other_inode) == -ENOENT) { + if (other_inode == ERR_PTR(-ENOENT)) { goto next_key; } else if (IS_ERR(other_inode)) { err = PTR_ERR(other_inode); -- 2.11.0
[PATCH 03/16] vfs: don't evict uninitialized inode
From: Miklos Szeredi iput() ends up calling ->evict() on new inode, which is not yet initialized by owning fs. So use destroy_inode() instead. Add to sb->s_inodes list only if inode is not in I_CREATING state (meaning that it wasn't allocated with new_inode(), which already does the insertion). Reported-by: Al Viro Signed-off-by: Miklos Szeredi Fixes: 80ea09a002bf ("vfs: factor out inode_insert5()") Signed-off-by: Al Viro --- fs/inode.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 04dd7e0d5142..0aa5b29b6f87 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1050,6 +1050,7 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, { struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval); struct inode *old; + bool creating = inode->i_state & I_CREATING; again: spin_lock(_hash_lock); @@ -1083,6 +1084,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, inode->i_state |= I_NEW; hlist_add_head(>i_hash, head); spin_unlock(>i_lock); + if (!creating) + inode_sb_list_add(inode); unlock: spin_unlock(_hash_lock); @@ -1117,12 +1120,13 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, struct inode *inode = ilookup5(sb, hashval, test, data); if (!inode) { - struct inode *new = new_inode(sb); + struct inode *new = alloc_inode(sb); if (new) { + new->i_state = 0; inode = inode_insert5(new, hashval, test, set, data); if (unlikely(inode != new)) - iput(new); + destroy_inode(new); } } return inode; -- 2.11.0
[PATCH 03/16] vfs: don't evict uninitialized inode
From: Miklos Szeredi iput() ends up calling ->evict() on new inode, which is not yet initialized by owning fs. So use destroy_inode() instead. Add to sb->s_inodes list only if inode is not in I_CREATING state (meaning that it wasn't allocated with new_inode(), which already does the insertion). Reported-by: Al Viro Signed-off-by: Miklos Szeredi Fixes: 80ea09a002bf ("vfs: factor out inode_insert5()") Signed-off-by: Al Viro --- fs/inode.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 04dd7e0d5142..0aa5b29b6f87 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1050,6 +1050,7 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, { struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval); struct inode *old; + bool creating = inode->i_state & I_CREATING; again: spin_lock(_hash_lock); @@ -1083,6 +1084,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, inode->i_state |= I_NEW; hlist_add_head(>i_hash, head); spin_unlock(>i_lock); + if (!creating) + inode_sb_list_add(inode); unlock: spin_unlock(_hash_lock); @@ -1117,12 +1120,13 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, struct inode *inode = ilookup5(sb, hashval, test, data); if (!inode) { - struct inode *new = new_inode(sb); + struct inode *new = alloc_inode(sb); if (new) { + new->i_state = 0; inode = inode_insert5(new, hashval, test, set, data); if (unlikely(inode != new)) - iput(new); + destroy_inode(new); } } return inode; -- 2.11.0
[PATCH 14/16] btrfs: simplify btrfs_iget()
From: Al Viro don't open-code iget_failed(), don't bother with btrfs_free_path(NULL), move handling of positive return values of btrfs_lookup_inode() from btrfs_read_locked_inode() to btrfs_iget() and kill now obviously pointless ASSERT() in there. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 24 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8f0b2592feb0..388b2dba68a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3610,18 +3610,15 @@ static int btrfs_read_locked_inode(struct inode *inode) filled = true; path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto make_bad; - } + if (!path) + return -ENOMEM; memcpy(, _I(inode)->location, sizeof(location)); ret = btrfs_lookup_inode(NULL, root, path, , 0); if (ret) { - if (ret > 0) - ret = -ENOENT; - goto make_bad; + btrfs_free_path(path); + return ret; } leaf = path->nodes[0]; @@ -3774,10 +3771,6 @@ static int btrfs_read_locked_inode(struct inode *inode) btrfs_sync_inode_flags_to_i_flags(inode); return 0; - -make_bad: - btrfs_free_path(path); - return ret; } /* @@ -5713,11 +5706,10 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, if (new) *new = 1; } else { - make_bad_inode(inode); - unlock_new_inode(inode); - iput(inode); - ASSERT(ret < 0); - inode = ERR_PTR(ret < 0 ? ret : -ESTALE); + iget_failed(inode); + if (ret > 0) + ret = -ENOENT; + inode = ERR_PTR(ret); } } -- 2.11.0
[PATCH 14/16] btrfs: simplify btrfs_iget()
From: Al Viro don't open-code iget_failed(), don't bother with btrfs_free_path(NULL), move handling of positive return values of btrfs_lookup_inode() from btrfs_read_locked_inode() to btrfs_iget() and kill now obviously pointless ASSERT() in there. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 24 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8f0b2592feb0..388b2dba68a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3610,18 +3610,15 @@ static int btrfs_read_locked_inode(struct inode *inode) filled = true; path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto make_bad; - } + if (!path) + return -ENOMEM; memcpy(, _I(inode)->location, sizeof(location)); ret = btrfs_lookup_inode(NULL, root, path, , 0); if (ret) { - if (ret > 0) - ret = -ENOENT; - goto make_bad; + btrfs_free_path(path); + return ret; } leaf = path->nodes[0]; @@ -3774,10 +3771,6 @@ static int btrfs_read_locked_inode(struct inode *inode) btrfs_sync_inode_flags_to_i_flags(inode); return 0; - -make_bad: - btrfs_free_path(path); - return ret; } /* @@ -5713,11 +5706,10 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, if (new) *new = 1; } else { - make_bad_inode(inode); - unlock_new_inode(inode); - iput(inode); - ASSERT(ret < 0); - inode = ERR_PTR(ret < 0 ? ret : -ESTALE); + iget_failed(inode); + if (ret > 0) + ret = -ENOENT; + inode = ERR_PTR(ret); } } -- 2.11.0
[PATCH 02/16] new primitive: discard_new_inode()
From: Al Viro We don't want open-by-handle picking half-set-up in-core struct inode from e.g. mkdir() having failed halfway through. In other words, we don't want such inodes returned by iget_locked() on their way to extinction. However, we can't just have them unhashed - otherwise open-by-handle immediately *after* that would've ended up creating a new in-core inode over the on-disk one that is in process of being freed right under us. Solution: new flag (I_CREATING) set by insert_inode_locked() and removed by unlock_new_inode() and a new primitive (discard_new_inode()) to be used by such halfway-through-setup failure exits instead of unlock_new_inode() / iput() combinations. That primitive unlocks new inode, but leaves I_CREATING in place. iget_locked() treats finding an I_CREATING inode as failure (-ESTALE, once we sort out the error propagation). insert_inode_locked() treats the same as instant -EBUSY. ilookup() treats those as icache miss. Signed-off-by: Al Viro --- fs/inode.c | 44 include/linux/fs.h | 6 +- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2c300e981796..04dd7e0d5142 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -804,6 +804,10 @@ static struct inode *find_inode(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } + if (unlikely(inode->i_state & I_CREATING)) { + spin_unlock(>i_lock); + return ERR_PTR(-ESTALE); + } __iget(inode); spin_unlock(>i_lock); return inode; @@ -831,6 +835,10 @@ static struct inode *find_inode_fast(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } + if (unlikely(inode->i_state & I_CREATING)) { + spin_unlock(>i_lock); + return ERR_PTR(-ESTALE); + } __iget(inode); spin_unlock(>i_lock); return inode; @@ -961,13 +969,26 @@ void unlock_new_inode(struct inode *inode) lockdep_annotate_inode_mutex_key(inode); spin_lock(>i_lock); WARN_ON(!(inode->i_state & I_NEW)); - inode->i_state &= ~I_NEW; + inode->i_state &= ~I_NEW & ~I_CREATING; smp_mb(); wake_up_bit(>i_state, __I_NEW); spin_unlock(>i_lock); } EXPORT_SYMBOL(unlock_new_inode); +void discard_new_inode(struct inode *inode) +{ + lockdep_annotate_inode_mutex_key(inode); + spin_lock(>i_lock); + WARN_ON(!(inode->i_state & I_NEW)); + inode->i_state &= ~I_NEW; + smp_mb(); + wake_up_bit(>i_state, __I_NEW); + spin_unlock(>i_lock); + iput(inode); +} +EXPORT_SYMBOL(discard_new_inode); + /** * lock_two_nondirectories - take two i_mutexes on non-directory objects * @@ -1039,6 +1060,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, * Use the old inode instead of the preallocated one. */ spin_unlock(_hash_lock); + if (IS_ERR(old)) + return NULL; wait_on_inode(old); if (unlikely(inode_unhashed(old))) { iput(old); @@ -1128,6 +1151,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) inode = find_inode_fast(sb, head, ino); spin_unlock(_hash_lock); if (inode) { + if (IS_ERR(inode)) + return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1165,6 +1190,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) */ spin_unlock(_hash_lock); destroy_inode(inode); + if (IS_ERR(old)) + return NULL; inode = old; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { @@ -1282,7 +1309,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, inode = find_inode(sb, head, test, data); spin_unlock(_hash_lock); - return inode; + return IS_ERR(inode) ? NULL : inode; } EXPORT_SYMBOL(ilookup5_nowait); @@ -1338,6 +1365,8 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino) spin_unlock(_hash_lock); if (inode) { + if (IS_ERR(inode)) + return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1421,12 +1450,16 @@ int insert_inode_locked(struct inode *inode) } if
[PATCH 02/16] new primitive: discard_new_inode()
From: Al Viro We don't want open-by-handle picking half-set-up in-core struct inode from e.g. mkdir() having failed halfway through. In other words, we don't want such inodes returned by iget_locked() on their way to extinction. However, we can't just have them unhashed - otherwise open-by-handle immediately *after* that would've ended up creating a new in-core inode over the on-disk one that is in process of being freed right under us. Solution: new flag (I_CREATING) set by insert_inode_locked() and removed by unlock_new_inode() and a new primitive (discard_new_inode()) to be used by such halfway-through-setup failure exits instead of unlock_new_inode() / iput() combinations. That primitive unlocks new inode, but leaves I_CREATING in place. iget_locked() treats finding an I_CREATING inode as failure (-ESTALE, once we sort out the error propagation). insert_inode_locked() treats the same as instant -EBUSY. ilookup() treats those as icache miss. Signed-off-by: Al Viro --- fs/inode.c | 44 include/linux/fs.h | 6 +- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2c300e981796..04dd7e0d5142 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -804,6 +804,10 @@ static struct inode *find_inode(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } + if (unlikely(inode->i_state & I_CREATING)) { + spin_unlock(>i_lock); + return ERR_PTR(-ESTALE); + } __iget(inode); spin_unlock(>i_lock); return inode; @@ -831,6 +835,10 @@ static struct inode *find_inode_fast(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } + if (unlikely(inode->i_state & I_CREATING)) { + spin_unlock(>i_lock); + return ERR_PTR(-ESTALE); + } __iget(inode); spin_unlock(>i_lock); return inode; @@ -961,13 +969,26 @@ void unlock_new_inode(struct inode *inode) lockdep_annotate_inode_mutex_key(inode); spin_lock(>i_lock); WARN_ON(!(inode->i_state & I_NEW)); - inode->i_state &= ~I_NEW; + inode->i_state &= ~I_NEW & ~I_CREATING; smp_mb(); wake_up_bit(>i_state, __I_NEW); spin_unlock(>i_lock); } EXPORT_SYMBOL(unlock_new_inode); +void discard_new_inode(struct inode *inode) +{ + lockdep_annotate_inode_mutex_key(inode); + spin_lock(>i_lock); + WARN_ON(!(inode->i_state & I_NEW)); + inode->i_state &= ~I_NEW; + smp_mb(); + wake_up_bit(>i_state, __I_NEW); + spin_unlock(>i_lock); + iput(inode); +} +EXPORT_SYMBOL(discard_new_inode); + /** * lock_two_nondirectories - take two i_mutexes on non-directory objects * @@ -1039,6 +1060,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval, * Use the old inode instead of the preallocated one. */ spin_unlock(_hash_lock); + if (IS_ERR(old)) + return NULL; wait_on_inode(old); if (unlikely(inode_unhashed(old))) { iput(old); @@ -1128,6 +1151,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) inode = find_inode_fast(sb, head, ino); spin_unlock(_hash_lock); if (inode) { + if (IS_ERR(inode)) + return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1165,6 +1190,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) */ spin_unlock(_hash_lock); destroy_inode(inode); + if (IS_ERR(old)) + return NULL; inode = old; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { @@ -1282,7 +1309,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, inode = find_inode(sb, head, test, data); spin_unlock(_hash_lock); - return inode; + return IS_ERR(inode) ? NULL : inode; } EXPORT_SYMBOL(ilookup5_nowait); @@ -1338,6 +1365,8 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino) spin_unlock(_hash_lock); if (inode) { + if (IS_ERR(inode)) + return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1421,12 +1450,16 @@ int insert_inode_locked(struct inode *inode) } if
[PATCH 08/16] btrfs: btrfs_iget() never returns an is_bad_inode() inode.
From: Al Viro just get rid of pointless checks Cc: Chris Mason Signed-off-by: Al Viro --- fs/btrfs/free-space-cache.c | 4 fs/btrfs/relocation.c | 7 ++- fs/btrfs/tree-log.c | 6 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index d5f80cb300be..79f03b3bbbd4 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -71,10 +71,6 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, inode = btrfs_iget(fs_info->sb, , root, NULL); if (IS_ERR(inode)) return inode; - if (is_bad_inode(inode)) { - iput(inode); - return ERR_PTR(-ENOENT); - } mapping_set_gfp_mask(inode->i_mapping, mapping_gfp_constraint(inode->i_mapping, diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 879b76fa881a..f6e8dc134e44 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3563,11 +3563,8 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info, key.offset = 0; inode = btrfs_iget(fs_info->sb, , root, NULL); - if (IS_ERR(inode) || is_bad_inode(inode)) { - if (!IS_ERR(inode)) - iput(inode); + if (IS_ERR(inode)) return -ENOENT; - } truncate: ret = btrfs_check_trunc_cache_free_space(fs_info, @@ -4284,7 +4281,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; inode = btrfs_iget(fs_info->sb, , root, NULL); - BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); + BUG_ON(IS_ERR(inode)); BTRFS_I(inode)->index_cnt = group->key.objectid; err = btrfs_orphan_add(trans, BTRFS_I(inode)); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f8220ec02036..fcfbe1d8584a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -545,12 +545,8 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; inode = btrfs_iget(root->fs_info->sb, , root, NULL); - if (IS_ERR(inode)) { + if (IS_ERR(inode)) inode = NULL; - } else if (is_bad_inode(inode)) { - iput(inode); - inode = NULL; - } return inode; } -- 2.11.0
[PATCH 08/16] btrfs: btrfs_iget() never returns an is_bad_inode() inode.
From: Al Viro just get rid of pointless checks Cc: Chris Mason Signed-off-by: Al Viro --- fs/btrfs/free-space-cache.c | 4 fs/btrfs/relocation.c | 7 ++- fs/btrfs/tree-log.c | 6 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index d5f80cb300be..79f03b3bbbd4 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -71,10 +71,6 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, inode = btrfs_iget(fs_info->sb, , root, NULL); if (IS_ERR(inode)) return inode; - if (is_bad_inode(inode)) { - iput(inode); - return ERR_PTR(-ENOENT); - } mapping_set_gfp_mask(inode->i_mapping, mapping_gfp_constraint(inode->i_mapping, diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 879b76fa881a..f6e8dc134e44 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3563,11 +3563,8 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info, key.offset = 0; inode = btrfs_iget(fs_info->sb, , root, NULL); - if (IS_ERR(inode) || is_bad_inode(inode)) { - if (!IS_ERR(inode)) - iput(inode); + if (IS_ERR(inode)) return -ENOENT; - } truncate: ret = btrfs_check_trunc_cache_free_space(fs_info, @@ -4284,7 +4281,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; inode = btrfs_iget(fs_info->sb, , root, NULL); - BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); + BUG_ON(IS_ERR(inode)); BTRFS_I(inode)->index_cnt = group->key.objectid; err = btrfs_orphan_add(trans, BTRFS_I(inode)); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f8220ec02036..fcfbe1d8584a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -545,12 +545,8 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; inode = btrfs_iget(root->fs_info->sb, , root, NULL); - if (IS_ERR(inode)) { + if (IS_ERR(inode)) inode = NULL; - } else if (is_bad_inode(inode)) { - iput(inode); - inode = NULL; - } return inode; } -- 2.11.0
[PATCH 15/16] adfs: don't put inodes into icache
From: Al Viro We never look them up in there; inode_fake_hash() will make them appear hashed for mark_inode_dirty() purposes. And don't leave them around until memory pressure kicks them out - we never look them up again. Signed-off-by: Al Viro --- fs/adfs/inode.c | 2 +- fs/adfs/super.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index c836c425ca94..e91028d4340a 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -287,7 +287,7 @@ adfs_iget(struct super_block *sb, struct object_info *obj) ADFS_I(inode)->mmu_private = inode->i_size; } - insert_inode_hash(inode); + inode_fake_hash(inode); out: return inode; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 71fa525d63a0..7e099a7a4eb1 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -291,6 +291,7 @@ static void destroy_inodecache(void) static const struct super_operations adfs_sops = { .alloc_inode= adfs_alloc_inode, .destroy_inode = adfs_destroy_inode, + .drop_inode = generic_delete_inode, .write_inode= adfs_write_inode, .put_super = adfs_put_super, .statfs = adfs_statfs, -- 2.11.0
[PATCH 10/16] kill d_instantiate_no_diralias()
From: Al Viro The only user is fuse_create_new_entry(), and there it's used to mitigate the same mkdir/open-by-handle race as in nfs_mkdir(). The same solution applies - unhash the mkdir argument, then call d_splice_alias() and if that returns a reference to preexisting alias, dput() and report success. ->mkdir() argument left unhashed negative with the preexisting alias moved in the right place is just fine from the ->mkdir() callers point of view. Cc: Miklos Szeredi Signed-off-by: Al Viro --- fs/dcache.c| 27 --- fs/fuse/dir.c | 15 +++ include/linux/dcache.h | 1 - 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 0e8e5de3c48a..a7d9e7a4c283 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1899,33 +1899,6 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) } EXPORT_SYMBOL(d_instantiate_new); -/** - * d_instantiate_no_diralias - instantiate a non-aliased dentry - * @entry: dentry to complete - * @inode: inode to attach to this dentry - * - * Fill in inode information in the entry. If a directory alias is found, then - * return an error (and drop inode). Together with d_materialise_unique() this - * guarantees that a directory inode may never have more than one alias. - */ -int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) -{ - BUG_ON(!hlist_unhashed(>d_u.d_alias)); - - security_d_instantiate(entry, inode); - spin_lock(>i_lock); - if (S_ISDIR(inode->i_mode) && !hlist_empty(>i_dentry)) { - spin_unlock(>i_lock); - iput(inode); - return -EBUSY; - } - __d_instantiate(entry, inode); - spin_unlock(>i_lock); - - return 0; -} -EXPORT_SYMBOL(d_instantiate_no_diralias); - struct dentry *d_make_root(struct inode *root_inode) { struct dentry *res = NULL; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 56231b31f806..4bbae6ac75c3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -539,6 +539,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, { struct fuse_entry_out outarg; struct inode *inode; + struct dentry *d; int err; struct fuse_forget_link *forget; @@ -570,11 +571,17 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, } kfree(forget); - err = d_instantiate_no_diralias(entry, inode); - if (err) - return err; + d_drop(entry); + d = d_splice_alias(inode, entry); + if (IS_ERR(d)) + return PTR_ERR(d); - fuse_change_entry_timeout(entry, ); + if (d) { + fuse_change_entry_timeout(d, ); + dput(d); + } else { + fuse_change_entry_timeout(entry, ); + } fuse_invalidate_attr(dir); return 0; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 66c6e17e61e5..0b83629a3d8f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -227,7 +227,6 @@ extern void d_instantiate(struct dentry *, struct inode *); extern void d_instantiate_new(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *); -extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); extern void d_delete(struct dentry *); -- 2.11.0
[PATCH 12/16] new helper: inode_fake_hash()
From: Al Viro open-coded in a quite a few places... Signed-off-by: Al Viro --- fs/hfs/inode.c | 2 +- fs/jfs/jfs_imap.c | 8 +--- fs/jfs/super.c | 2 +- fs/xfs/xfs_iops.c | 2 +- include/linux/fs.h | 11 +++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 2a16111d312f..a2dfa1b2a89c 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -541,7 +541,7 @@ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, HFS_I(inode)->rsrc_inode = dir; HFS_I(dir)->rsrc_inode = inode; igrab(dir); - hlist_add_fake(>i_hash); + inode_fake_hash(inode); mark_inode_dirty(inode); dont_mount(dentry); out: diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index f36ef68905a7..93e8c590ff5c 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -491,13 +491,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) /* release the page */ release_metapage(mp); - /* -* __mark_inode_dirty expects inodes to be hashed. Since we don't -* want special inodes in the fileset inode space, we make them -* appear hashed, but do not put on any lists. hlist_del() -* will work fine and require no locking. -*/ - hlist_add_fake(>i_hash); + inode_fake_hash(ip); return (ip); } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 1b9264fd54b6..5403ece57dba 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -581,7 +581,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_ino = 0; inode->i_size = i_size_read(sb->s_bdev->bd_inode); inode->i_mapping->a_ops = _metapage_aops; - hlist_add_fake(>i_hash); + inode_fake_hash(inode); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); sbi->direct_inode = inode; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 0fa29f39d658..3a75de777843 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1253,7 +1253,7 @@ xfs_setup_inode( inode_sb_list_add(inode); /* make the inode look hashed for the writeback code */ - hlist_add_fake(>i_hash); + inode_fake_hash(inode); inode->i_uid= xfs_uid_to_kuid(ip->i_d.di_uid); inode->i_gid= xfs_gid_to_kgid(ip->i_d.di_gid); diff --git a/include/linux/fs.h b/include/linux/fs.h index a42600565925..43941e230e2b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -685,6 +685,17 @@ static inline int inode_unhashed(struct inode *inode) } /* + * __mark_inode_dirty expects inodes to be hashed. Since we don't + * want special inodes in the fileset inode space, we make them + * appear hashed, but do not put on any lists. hlist_del() + * will work fine and require no locking. + */ +static inline void inode_fake_hash(struct inode *inode) +{ + hlist_add_fake(>i_hash); +} + +/* * inode->i_mutex nesting subclasses for the lock validator: * * 0: the object of the current VFS operation -- 2.11.0
[PATCH 13/16] btrfs: lift make_bad_inode() into btrfs_iget()
From: Al Viro we don't need to check is_bad_inode() after the call of btrfs_read_locked_inode() - it's exactly the same as checking return value for being non-zero. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9382e0881900..8f0b2592feb0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3777,7 +3777,6 @@ static int btrfs_read_locked_inode(struct inode *inode) make_bad: btrfs_free_path(path); - make_bad_inode(inode); return ret; } @@ -5708,12 +5707,13 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, int ret; ret = btrfs_read_locked_inode(inode); - if (!is_bad_inode(inode)) { + if (!ret) { inode_tree_add(inode); unlock_new_inode(inode); if (new) *new = 1; } else { + make_bad_inode(inode); unlock_new_inode(inode); iput(inode); ASSERT(ret < 0); -- 2.11.0
[PATCH 16/16] jfs: don't bother with make_bad_inode() in ialloc()
From: Al Viro We hit that when inumber allocation has failed. In that case the in-core inode is not hashed and since its ->i_nlink is 1 the only place where jfs checks is_bad_inode() won't be reached. Signed-off-by: Al Viro --- fs/jfs/jfs_inode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 96732c24b054..4572b7cf183d 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -69,8 +69,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { jfs_warn("ialloc: diAlloc returned %d!", rc); - if (rc == -EIO) - make_bad_inode(inode); goto fail_put; } -- 2.11.0
[PATCH 15/16] adfs: don't put inodes into icache
From: Al Viro We never look them up in there; inode_fake_hash() will make them appear hashed for mark_inode_dirty() purposes. And don't leave them around until memory pressure kicks them out - we never look them up again. Signed-off-by: Al Viro --- fs/adfs/inode.c | 2 +- fs/adfs/super.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index c836c425ca94..e91028d4340a 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c @@ -287,7 +287,7 @@ adfs_iget(struct super_block *sb, struct object_info *obj) ADFS_I(inode)->mmu_private = inode->i_size; } - insert_inode_hash(inode); + inode_fake_hash(inode); out: return inode; diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 71fa525d63a0..7e099a7a4eb1 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -291,6 +291,7 @@ static void destroy_inodecache(void) static const struct super_operations adfs_sops = { .alloc_inode= adfs_alloc_inode, .destroy_inode = adfs_destroy_inode, + .drop_inode = generic_delete_inode, .write_inode= adfs_write_inode, .put_super = adfs_put_super, .statfs = adfs_statfs, -- 2.11.0
[PATCH 10/16] kill d_instantiate_no_diralias()
From: Al Viro The only user is fuse_create_new_entry(), and there it's used to mitigate the same mkdir/open-by-handle race as in nfs_mkdir(). The same solution applies - unhash the mkdir argument, then call d_splice_alias() and if that returns a reference to preexisting alias, dput() and report success. ->mkdir() argument left unhashed negative with the preexisting alias moved in the right place is just fine from the ->mkdir() callers point of view. Cc: Miklos Szeredi Signed-off-by: Al Viro --- fs/dcache.c| 27 --- fs/fuse/dir.c | 15 +++ include/linux/dcache.h | 1 - 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 0e8e5de3c48a..a7d9e7a4c283 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1899,33 +1899,6 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) } EXPORT_SYMBOL(d_instantiate_new); -/** - * d_instantiate_no_diralias - instantiate a non-aliased dentry - * @entry: dentry to complete - * @inode: inode to attach to this dentry - * - * Fill in inode information in the entry. If a directory alias is found, then - * return an error (and drop inode). Together with d_materialise_unique() this - * guarantees that a directory inode may never have more than one alias. - */ -int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) -{ - BUG_ON(!hlist_unhashed(>d_u.d_alias)); - - security_d_instantiate(entry, inode); - spin_lock(>i_lock); - if (S_ISDIR(inode->i_mode) && !hlist_empty(>i_dentry)) { - spin_unlock(>i_lock); - iput(inode); - return -EBUSY; - } - __d_instantiate(entry, inode); - spin_unlock(>i_lock); - - return 0; -} -EXPORT_SYMBOL(d_instantiate_no_diralias); - struct dentry *d_make_root(struct inode *root_inode) { struct dentry *res = NULL; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 56231b31f806..4bbae6ac75c3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -539,6 +539,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, { struct fuse_entry_out outarg; struct inode *inode; + struct dentry *d; int err; struct fuse_forget_link *forget; @@ -570,11 +571,17 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, } kfree(forget); - err = d_instantiate_no_diralias(entry, inode); - if (err) - return err; + d_drop(entry); + d = d_splice_alias(inode, entry); + if (IS_ERR(d)) + return PTR_ERR(d); - fuse_change_entry_timeout(entry, ); + if (d) { + fuse_change_entry_timeout(d, ); + dput(d); + } else { + fuse_change_entry_timeout(entry, ); + } fuse_invalidate_attr(dir); return 0; diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 66c6e17e61e5..0b83629a3d8f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -227,7 +227,6 @@ extern void d_instantiate(struct dentry *, struct inode *); extern void d_instantiate_new(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *); -extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); extern void d_delete(struct dentry *); -- 2.11.0
[PATCH 12/16] new helper: inode_fake_hash()
From: Al Viro open-coded in a quite a few places... Signed-off-by: Al Viro --- fs/hfs/inode.c | 2 +- fs/jfs/jfs_imap.c | 8 +--- fs/jfs/super.c | 2 +- fs/xfs/xfs_iops.c | 2 +- include/linux/fs.h | 11 +++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 2a16111d312f..a2dfa1b2a89c 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -541,7 +541,7 @@ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry, HFS_I(inode)->rsrc_inode = dir; HFS_I(dir)->rsrc_inode = inode; igrab(dir); - hlist_add_fake(>i_hash); + inode_fake_hash(inode); mark_inode_dirty(inode); dont_mount(dentry); out: diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index f36ef68905a7..93e8c590ff5c 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -491,13 +491,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) /* release the page */ release_metapage(mp); - /* -* __mark_inode_dirty expects inodes to be hashed. Since we don't -* want special inodes in the fileset inode space, we make them -* appear hashed, but do not put on any lists. hlist_del() -* will work fine and require no locking. -*/ - hlist_add_fake(>i_hash); + inode_fake_hash(ip); return (ip); } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 1b9264fd54b6..5403ece57dba 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -581,7 +581,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_ino = 0; inode->i_size = i_size_read(sb->s_bdev->bd_inode); inode->i_mapping->a_ops = _metapage_aops; - hlist_add_fake(>i_hash); + inode_fake_hash(inode); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); sbi->direct_inode = inode; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 0fa29f39d658..3a75de777843 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1253,7 +1253,7 @@ xfs_setup_inode( inode_sb_list_add(inode); /* make the inode look hashed for the writeback code */ - hlist_add_fake(>i_hash); + inode_fake_hash(inode); inode->i_uid= xfs_uid_to_kuid(ip->i_d.di_uid); inode->i_gid= xfs_gid_to_kgid(ip->i_d.di_gid); diff --git a/include/linux/fs.h b/include/linux/fs.h index a42600565925..43941e230e2b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -685,6 +685,17 @@ static inline int inode_unhashed(struct inode *inode) } /* + * __mark_inode_dirty expects inodes to be hashed. Since we don't + * want special inodes in the fileset inode space, we make them + * appear hashed, but do not put on any lists. hlist_del() + * will work fine and require no locking. + */ +static inline void inode_fake_hash(struct inode *inode) +{ + hlist_add_fake(>i_hash); +} + +/* * inode->i_mutex nesting subclasses for the lock validator: * * 0: the object of the current VFS operation -- 2.11.0
[PATCH 13/16] btrfs: lift make_bad_inode() into btrfs_iget()
From: Al Viro we don't need to check is_bad_inode() after the call of btrfs_read_locked_inode() - it's exactly the same as checking return value for being non-zero. Signed-off-by: Al Viro --- fs/btrfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9382e0881900..8f0b2592feb0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3777,7 +3777,6 @@ static int btrfs_read_locked_inode(struct inode *inode) make_bad: btrfs_free_path(path); - make_bad_inode(inode); return ret; } @@ -5708,12 +5707,13 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, int ret; ret = btrfs_read_locked_inode(inode); - if (!is_bad_inode(inode)) { + if (!ret) { inode_tree_add(inode); unlock_new_inode(inode); if (new) *new = 1; } else { + make_bad_inode(inode); unlock_new_inode(inode); iput(inode); ASSERT(ret < 0); -- 2.11.0
[PATCH 16/16] jfs: don't bother with make_bad_inode() in ialloc()
From: Al Viro We hit that when inumber allocation has failed. In that case the in-core inode is not hashed and since its ->i_nlink is 1 the only place where jfs checks is_bad_inode() won't be reached. Signed-off-by: Al Viro --- fs/jfs/jfs_inode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 96732c24b054..4572b7cf183d 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -69,8 +69,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { jfs_warn("ialloc: diAlloc returned %d!", rc); - if (rc == -EIO) - make_bad_inode(inode); goto fail_put; } -- 2.11.0
[PATCH 05/16] ufs: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/ufs/ialloc.c | 3 +-- fs/ufs/namei.c | 9 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index e1ef0f0a1353..02c0a4be4212 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -343,8 +343,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode) fail_remove_inode: mutex_unlock(>s_lock); clear_nlink(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); UFSD("EXIT (FAILED): err %d\n", err); return ERR_PTR(err); failed: diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d5f43ba76c59..9ef40f100415 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -43,8 +43,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) return 0; } inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -142,8 +141,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, out_fail: inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -198,8 +196,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput (inode); + discard_new_inode(inode); out_dir: inode_dec_link_count(dir); return err; -- 2.11.0
[PATCH 11/16] jfs: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/jfs/jfs_inode.c | 8 fs/jfs/namei.c | 12 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 5e9b7bb3aabf..96732c24b054 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -61,8 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) inode = new_inode(sb); if (!inode) { jfs_warn("ialloc: new_inode returned NULL!"); - rc = -ENOMEM; - goto fail; + return ERR_PTR(-ENOMEM); } jfs_inode = JFS_IP(inode); @@ -141,9 +140,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode) dquot_drop(inode); inode->i_flags |= S_NOQUOTA; clear_nlink(inode); - unlock_new_inode(inode); + discard_new_inode(inode); + return ERR_PTR(rc); + fail_put: iput(inode); -fail: return ERR_PTR(rc); } diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 56c3fcbfe80e..14528c0ffe63 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -175,8 +175,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -309,8 +308,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -1054,8 +1052,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -1441,8 +1438,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } -- 2.11.0
[PATCH 05/16] ufs: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/ufs/ialloc.c | 3 +-- fs/ufs/namei.c | 9 +++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index e1ef0f0a1353..02c0a4be4212 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -343,8 +343,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode) fail_remove_inode: mutex_unlock(>s_lock); clear_nlink(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); UFSD("EXIT (FAILED): err %d\n", err); return ERR_PTR(err); failed: diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d5f43ba76c59..9ef40f100415 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -43,8 +43,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode) return 0; } inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -142,8 +141,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, out_fail: inode_dec_link_count(inode); - unlock_new_inode(inode); - iput(inode); + discard_new_inode(inode); return err; } @@ -198,8 +196,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode) out_fail: inode_dec_link_count(inode); inode_dec_link_count(inode); - unlock_new_inode(inode); - iput (inode); + discard_new_inode(inode); out_dir: inode_dec_link_count(dir); return err; -- 2.11.0
[PATCH 11/16] jfs: switch to discard_new_inode()
From: Al Viro we don't want open-by-handle to pick an in-core inode that has failed setup halfway through. Signed-off-by: Al Viro --- fs/jfs/jfs_inode.c | 8 fs/jfs/namei.c | 12 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 5e9b7bb3aabf..96732c24b054 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -61,8 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) inode = new_inode(sb); if (!inode) { jfs_warn("ialloc: new_inode returned NULL!"); - rc = -ENOMEM; - goto fail; + return ERR_PTR(-ENOMEM); } jfs_inode = JFS_IP(inode); @@ -141,9 +140,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode) dquot_drop(inode); inode->i_flags |= S_NOQUOTA; clear_nlink(inode); - unlock_new_inode(inode); + discard_new_inode(inode); + return ERR_PTR(rc); + fail_put: iput(inode); -fail: return ERR_PTR(rc); } diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 56c3fcbfe80e..14528c0ffe63 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -175,8 +175,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -309,8 +308,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode) if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -1054,8 +1052,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } @@ -1441,8 +1438,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, if (rc) { free_ea_wmap(ip); clear_nlink(ip); - unlock_new_inode(ip); - iput(ip); + discard_new_inode(ip); } else { d_instantiate_new(dentry, ip); } -- 2.11.0