Re: [PATCH 2/5] zram: partial IO refactoring
Hi! On 04/03/2017 08:17 AM, Minchan Kim wrote: > For architecture(PAGE_SIZE > 4K), zram have supported partial IO. > However, the mixed code for handling normal/partial IO is too mess, > error-prone to modify IO handler functions with upcoming feature > so this patch aims for cleaning up zram's IO handling functions. > > Signed-off-by: Minchan Kim> --- > drivers/block/zram/zram_drv.c | 333 > +++--- > 1 file changed, 184 insertions(+), 149 deletions(-) > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > index 28c2836f8c96..7938f4b98b01 100644 > --- a/drivers/block/zram/zram_drv.c > +++ b/drivers/block/zram/zram_drv.c > @@ -45,6 +45,8 @@ static const char *default_compressor = "lzo"; > /* Module params (documentation at end) */ > static unsigned int num_devices = 1; > > +static void zram_free_page(struct zram *zram, size_t index); > + > static inline bool init_done(struct zram *zram) > { > return zram->disksize; > @@ -98,10 +100,17 @@ static void zram_set_obj_size(struct zram_meta *meta, > meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; > } > > +#if PAGE_SIZE != 4096 > static inline bool is_partial_io(struct bio_vec *bvec) > { > return bvec->bv_len != PAGE_SIZE; > } > +#else For page size of 4096 bv_len can still be < 4096 and partial pages should be supported (uncompress before write etc). ? > +static inline bool is_partial_io(struct bio_vec *bvec) > +{ > + return false; > +} > +#endif > > static void zram_revalidate_disk(struct zram *zram) > { > @@ -191,18 +200,6 @@ static bool page_same_filled(void *ptr, unsigned long > *element) > return true; > } > > -static void handle_same_page(struct bio_vec *bvec, unsigned long element) > -{ > - struct page *page = bvec->bv_page; > - void *user_mem; > - > - user_mem = kmap_atomic(page); > - zram_fill_page(user_mem + bvec->bv_offset, bvec->bv_len, element); > - kunmap_atomic(user_mem); > - > - flush_dcache_page(page); > -} > - > static ssize_t initstate_show(struct device *dev, > struct device_attribute *attr, char *buf) > { > @@ -418,6 +415,53 @@ static DEVICE_ATTR_RO(io_stat); > static DEVICE_ATTR_RO(mm_stat); > static DEVICE_ATTR_RO(debug_stat); > > +static bool zram_special_page_read(struct zram *zram, u32 index, > + struct page *page, > + unsigned int offset, unsigned int len) > +{ > + struct zram_meta *meta = zram->meta; > + > + bit_spin_lock(ZRAM_ACCESS, >table[index].value); > + if (unlikely(!meta->table[index].handle) || > + zram_test_flag(meta, index, ZRAM_SAME)) { > + void *mem; > + > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + mem = kmap_atomic(page); > + zram_fill_page(mem + offset, len, meta->table[index].element); > + kunmap_atomic(mem); > + return true; > + } > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + > + return false; > +} > + > +static bool zram_special_page_write(struct zram *zram, u32 index, > + struct page *page) > +{ > + unsigned long element; > + void *mem = kmap_atomic(page); > + > + if (page_same_filled(mem, )) { > + struct zram_meta *meta = zram->meta; > + > + kunmap_atomic(mem); > + /* Free memory associated with this sector now. */ > + bit_spin_lock(ZRAM_ACCESS, >table[index].value); > + zram_free_page(zram, index); > + zram_set_flag(meta, index, ZRAM_SAME); > + zram_set_element(meta, index, element); > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + > + atomic64_inc(>stats.same_pages); > + return true; > + } > + kunmap_atomic(mem); > + > + return false; > +} > + > static void zram_meta_free(struct zram_meta *meta, u64 disksize) > { > size_t num_pages = disksize >> PAGE_SHIFT; > @@ -504,169 +548,104 @@ static void zram_free_page(struct zram *zram, size_t > index) > zram_set_obj_size(meta, index, 0); > } > > -static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > +static int zram_decompress_page(struct zram *zram, struct page *page, u32 > index) > { > - int ret = 0; > - unsigned char *cmem; > - struct zram_meta *meta = zram->meta; > + int ret; > unsigned long handle; > unsigned int size; > + void *src, *dst; > + struct zram_meta *meta = zram->meta; > + > + if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) > + return 0; > > bit_spin_lock(ZRAM_ACCESS, >table[index].value); > handle = meta->table[index].handle; > size = zram_get_obj_size(meta, index); > > - if (!handle || zram_test_flag(meta, index, ZRAM_SAME)) { > -
Re: [PATCH 2/5] zram: partial IO refactoring
Hi! On 04/03/2017 08:17 AM, Minchan Kim wrote: > For architecture(PAGE_SIZE > 4K), zram have supported partial IO. > However, the mixed code for handling normal/partial IO is too mess, > error-prone to modify IO handler functions with upcoming feature > so this patch aims for cleaning up zram's IO handling functions. > > Signed-off-by: Minchan Kim > --- > drivers/block/zram/zram_drv.c | 333 > +++--- > 1 file changed, 184 insertions(+), 149 deletions(-) > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c > index 28c2836f8c96..7938f4b98b01 100644 > --- a/drivers/block/zram/zram_drv.c > +++ b/drivers/block/zram/zram_drv.c > @@ -45,6 +45,8 @@ static const char *default_compressor = "lzo"; > /* Module params (documentation at end) */ > static unsigned int num_devices = 1; > > +static void zram_free_page(struct zram *zram, size_t index); > + > static inline bool init_done(struct zram *zram) > { > return zram->disksize; > @@ -98,10 +100,17 @@ static void zram_set_obj_size(struct zram_meta *meta, > meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; > } > > +#if PAGE_SIZE != 4096 > static inline bool is_partial_io(struct bio_vec *bvec) > { > return bvec->bv_len != PAGE_SIZE; > } > +#else For page size of 4096 bv_len can still be < 4096 and partial pages should be supported (uncompress before write etc). ? > +static inline bool is_partial_io(struct bio_vec *bvec) > +{ > + return false; > +} > +#endif > > static void zram_revalidate_disk(struct zram *zram) > { > @@ -191,18 +200,6 @@ static bool page_same_filled(void *ptr, unsigned long > *element) > return true; > } > > -static void handle_same_page(struct bio_vec *bvec, unsigned long element) > -{ > - struct page *page = bvec->bv_page; > - void *user_mem; > - > - user_mem = kmap_atomic(page); > - zram_fill_page(user_mem + bvec->bv_offset, bvec->bv_len, element); > - kunmap_atomic(user_mem); > - > - flush_dcache_page(page); > -} > - > static ssize_t initstate_show(struct device *dev, > struct device_attribute *attr, char *buf) > { > @@ -418,6 +415,53 @@ static DEVICE_ATTR_RO(io_stat); > static DEVICE_ATTR_RO(mm_stat); > static DEVICE_ATTR_RO(debug_stat); > > +static bool zram_special_page_read(struct zram *zram, u32 index, > + struct page *page, > + unsigned int offset, unsigned int len) > +{ > + struct zram_meta *meta = zram->meta; > + > + bit_spin_lock(ZRAM_ACCESS, >table[index].value); > + if (unlikely(!meta->table[index].handle) || > + zram_test_flag(meta, index, ZRAM_SAME)) { > + void *mem; > + > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + mem = kmap_atomic(page); > + zram_fill_page(mem + offset, len, meta->table[index].element); > + kunmap_atomic(mem); > + return true; > + } > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + > + return false; > +} > + > +static bool zram_special_page_write(struct zram *zram, u32 index, > + struct page *page) > +{ > + unsigned long element; > + void *mem = kmap_atomic(page); > + > + if (page_same_filled(mem, )) { > + struct zram_meta *meta = zram->meta; > + > + kunmap_atomic(mem); > + /* Free memory associated with this sector now. */ > + bit_spin_lock(ZRAM_ACCESS, >table[index].value); > + zram_free_page(zram, index); > + zram_set_flag(meta, index, ZRAM_SAME); > + zram_set_element(meta, index, element); > + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > + > + atomic64_inc(>stats.same_pages); > + return true; > + } > + kunmap_atomic(mem); > + > + return false; > +} > + > static void zram_meta_free(struct zram_meta *meta, u64 disksize) > { > size_t num_pages = disksize >> PAGE_SHIFT; > @@ -504,169 +548,104 @@ static void zram_free_page(struct zram *zram, size_t > index) > zram_set_obj_size(meta, index, 0); > } > > -static int zram_decompress_page(struct zram *zram, char *mem, u32 index) > +static int zram_decompress_page(struct zram *zram, struct page *page, u32 > index) > { > - int ret = 0; > - unsigned char *cmem; > - struct zram_meta *meta = zram->meta; > + int ret; > unsigned long handle; > unsigned int size; > + void *src, *dst; > + struct zram_meta *meta = zram->meta; > + > + if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) > + return 0; > > bit_spin_lock(ZRAM_ACCESS, >table[index].value); > handle = meta->table[index].handle; > size = zram_get_obj_size(meta, index); > > - if (!handle || zram_test_flag(meta, index, ZRAM_SAME)) { > -
Re: [RFC] mm/crypto: add tunable compression algorithm for zswap
On Sat, Apr 01, 2017 at 11:18:13PM +0200, Vlastimil Babka wrote: > Zswap (and zram) save memory by compressing pages instead of swapping them > out. This is nice, but with traditional compression algorithms such as LZO, > one cannot know, how well the data will compress, so the overal savings are > unpredictable. This is further complicated by the choice of zpool > implementation for managing the compressed pages. Zbud and z3fold are > relatively simple, but cannot store more then 2 (zbud) or 3 (z3fold) > compressed pages in a page. The rest of the page is wasted. Zsmalloc is more > flexible, but also more complex. > > Clearly things would be much easier if the compression ratio was predictable. > But why stop at that - what if we could actually *choose* the compression > ratio? This patch introduces a new compression algorithm that can do just > that! It's called Tunable COmpression, or TCO for short. That was totally same I had an idea since long time ago but I don't have enough to dive into that. Thanks for raising an issue! > > In this prototype patch, it offers three predefined ratios, but nothing > prevents more fine-grained settings, except the current crypto API (or my > limited knowledge of it, but I'm guessing nobody really expected the > compression ratio to be tunable). So by doing > > echo tco50 > /sys/module/zswap/parameters/compressor > > you get 50% compression ratio, guaranteed! This setting and zbud are just the > perfect buddies, if you prefer the nice and simple allocator. Zero internal > fragmentation! > > Or, > > echo tco30 > /sys/module/zswap/parameters/compressor > > is a great match for z3fold, if you want to be smarter and save 50% memory > over zbud, again with no memory wasted! But why stop at that? If you do > > echo tco10 > /sys/module/zswap/parameters/compressor It's a great idea but a problem is we have very limited allocators. In short future, people might want z4fold, z8fold, z10fold and so on. So, I suggest to make zbud generic so it can cover every zXfold allocators. > > within the next hour, and choose zsmalloc, you will be able to neatly store > 10 compressed pages within a single page! Yes, 90% savings! > In the full version of this patch, you'll be able to set any ratio, so you > can decide exactly how much money to waste on extra RAM instead of compressing > the data. Let TCO cut down your system's TCO! > > This RFC was not yet tested, but it compiles fine and mostly passes checkpatch > so it must obviously work. I did test and found sometime crash happens but it's hard to reproduce. It seems it's easier to reprocue the problem with tco50. Even though I stare at the code in detail, I can't find any bugs. Hmm, If there is an update in your side, let me know it. Thanks.
Re: [RFC] mm/crypto: add tunable compression algorithm for zswap
On Sat, Apr 01, 2017 at 11:18:13PM +0200, Vlastimil Babka wrote: > Zswap (and zram) save memory by compressing pages instead of swapping them > out. This is nice, but with traditional compression algorithms such as LZO, > one cannot know, how well the data will compress, so the overal savings are > unpredictable. This is further complicated by the choice of zpool > implementation for managing the compressed pages. Zbud and z3fold are > relatively simple, but cannot store more then 2 (zbud) or 3 (z3fold) > compressed pages in a page. The rest of the page is wasted. Zsmalloc is more > flexible, but also more complex. > > Clearly things would be much easier if the compression ratio was predictable. > But why stop at that - what if we could actually *choose* the compression > ratio? This patch introduces a new compression algorithm that can do just > that! It's called Tunable COmpression, or TCO for short. That was totally same I had an idea since long time ago but I don't have enough to dive into that. Thanks for raising an issue! > > In this prototype patch, it offers three predefined ratios, but nothing > prevents more fine-grained settings, except the current crypto API (or my > limited knowledge of it, but I'm guessing nobody really expected the > compression ratio to be tunable). So by doing > > echo tco50 > /sys/module/zswap/parameters/compressor > > you get 50% compression ratio, guaranteed! This setting and zbud are just the > perfect buddies, if you prefer the nice and simple allocator. Zero internal > fragmentation! > > Or, > > echo tco30 > /sys/module/zswap/parameters/compressor > > is a great match for z3fold, if you want to be smarter and save 50% memory > over zbud, again with no memory wasted! But why stop at that? If you do > > echo tco10 > /sys/module/zswap/parameters/compressor It's a great idea but a problem is we have very limited allocators. In short future, people might want z4fold, z8fold, z10fold and so on. So, I suggest to make zbud generic so it can cover every zXfold allocators. > > within the next hour, and choose zsmalloc, you will be able to neatly store > 10 compressed pages within a single page! Yes, 90% savings! > In the full version of this patch, you'll be able to set any ratio, so you > can decide exactly how much money to waste on extra RAM instead of compressing > the data. Let TCO cut down your system's TCO! > > This RFC was not yet tested, but it compiles fine and mostly passes checkpatch > so it must obviously work. I did test and found sometime crash happens but it's hard to reproduce. It seems it's easier to reprocue the problem with tco50. Even though I stare at the code in detail, I can't find any bugs. Hmm, If there is an update in your side, let me know it. Thanks.
Re: [PATCH] dwc2: gadget: Fix in control write transfers
Hi, On 3/30/2017 2:42 PM, Felipe Balbi wrote: > > Hi, > > Minas Harutyunyanwrites: >> After data out stage gadget driver should not initate ZLP on control EP, >> because it is up to function driver. > > not true always, depends on return value from ->setup(). Which problem > did you have? Which gadget driver? How did you reproduce? Which other > tests did you run on this patch? > This required for delayed status support. Tested with Synopsys test gadget. As host used USB tracer traffic generator (different control transfers scenarios). Also performed smoke tests with mass storage function to detect any side effects. Thanks, Minas
Re: [PATCH] dwc2: gadget: Fix in control write transfers
Hi, On 3/30/2017 2:42 PM, Felipe Balbi wrote: > > Hi, > > Minas Harutyunyan writes: >> After data out stage gadget driver should not initate ZLP on control EP, >> because it is up to function driver. > > not true always, depends on return value from ->setup(). Which problem > did you have? Which gadget driver? How did you reproduce? Which other > tests did you run on this patch? > This required for delayed status support. Tested with Synopsys test gadget. As host used USB tracer traffic generator (different control transfers scenarios). Also performed smoke tests with mass storage function to detect any side effects. Thanks, Minas
Re: [PATCH v2 3/4] usb: dwc3: add dual-role support
On 03/30/2017 02:27 AM, Felipe Balbi wrote: > > Hi > > Roger Quadroswrites: > For something that simple, we wouldn't even need to use OTG FSM layer > because that brings no benefit for such a simple requirement. no no. I think you got it wrong. I'm not using the OTG FSM layer at all :). >>> >>> what are all the otg_fsm mentions then? Also you have: >>> >>> + struct usb_otg otg; >>> + struct otg_fsm otg_fsm; >>> >> >> I'll get rid of them. They aren't really needed. >> Now I see why you thought I was using the otg_fsm layer. :) > > fair enough > > Can you either confirm or refute the statement above? The real problem was that if host adapter was removed during a system suspend then while resuming XHCI was locking up like below. This is probably because we're trying to remove/Halt the HCD in the otg_irq_handler before XHCI driver has resumed? How can we ensure that we call dwc3_host_exit() only *after* XHCI driver has resumed? >>> >>> Well, xHCI is our child, so driver model should *already* be >>> guaranteeing that, no? Specially since you're calling this from >>> ->complete() which happens after ->resume() has been called for the >>> entire tree. It's true, however, that dwc3's ->complete() will be called >>> before xhci's ->complete(). Is this the problem you're pointing at? Or >>> do you mean xHCI is runtime suspended (or runtime resuming) while you >>> call dwc3_host_exit()? If that's the case, then there's a bug in xHCI >>> itself. >> >> Yes dwc3->complete() being called before xhci->complete(), and so HCD being >> removed before xhci->complete() causes the lockup. >> >> It could be a bug in xHCI driver as well. > > I see... > We need a way to mask the OTG events without loosing them while they are masked. Do you know how that could be achieved? >>> >>> masking doesn't clear events. It just masks them. Look at gadget.c for >>> how we do it. Basically, the code we have here is racy, really racy and >>> will cause hard-to-debug lockups. Your code can only work with >>> IRQF_ONESHOT, which we don't want to add back. >>> >>> In any case, to mask events, you set BIT 31 in GEVNTSIZ register. Just >>> copy it from gadget.c ;-) >> >> Isn't GEVNTSIZ specific to device side? We're talking about the OTG block >> here. > > that's true, sorry. > >> Are you sure that setting bit 31 of GEVNTSIZ will mask OTG_irq? I don't >> think so. >> >> Note that OTG_IRQ is a separate IRQ line than PERIPHERAL_IRQ. > > man, there's really no way to mask OTG events. This can be bad :-) > > John, can you confirm if there's really no way of masking OTG events > without loosing them? Not sure. I'll have to verify. If the IP version is 3.00a or higher you could experiment with using interrupt moderation as a global mask. John
Re: [PATCH v2 3/4] usb: dwc3: add dual-role support
On 03/30/2017 02:27 AM, Felipe Balbi wrote: > > Hi > > Roger Quadros writes: > For something that simple, we wouldn't even need to use OTG FSM layer > because that brings no benefit for such a simple requirement. no no. I think you got it wrong. I'm not using the OTG FSM layer at all :). >>> >>> what are all the otg_fsm mentions then? Also you have: >>> >>> + struct usb_otg otg; >>> + struct otg_fsm otg_fsm; >>> >> >> I'll get rid of them. They aren't really needed. >> Now I see why you thought I was using the otg_fsm layer. :) > > fair enough > > Can you either confirm or refute the statement above? The real problem was that if host adapter was removed during a system suspend then while resuming XHCI was locking up like below. This is probably because we're trying to remove/Halt the HCD in the otg_irq_handler before XHCI driver has resumed? How can we ensure that we call dwc3_host_exit() only *after* XHCI driver has resumed? >>> >>> Well, xHCI is our child, so driver model should *already* be >>> guaranteeing that, no? Specially since you're calling this from >>> ->complete() which happens after ->resume() has been called for the >>> entire tree. It's true, however, that dwc3's ->complete() will be called >>> before xhci's ->complete(). Is this the problem you're pointing at? Or >>> do you mean xHCI is runtime suspended (or runtime resuming) while you >>> call dwc3_host_exit()? If that's the case, then there's a bug in xHCI >>> itself. >> >> Yes dwc3->complete() being called before xhci->complete(), and so HCD being >> removed before xhci->complete() causes the lockup. >> >> It could be a bug in xHCI driver as well. > > I see... > We need a way to mask the OTG events without loosing them while they are masked. Do you know how that could be achieved? >>> >>> masking doesn't clear events. It just masks them. Look at gadget.c for >>> how we do it. Basically, the code we have here is racy, really racy and >>> will cause hard-to-debug lockups. Your code can only work with >>> IRQF_ONESHOT, which we don't want to add back. >>> >>> In any case, to mask events, you set BIT 31 in GEVNTSIZ register. Just >>> copy it from gadget.c ;-) >> >> Isn't GEVNTSIZ specific to device side? We're talking about the OTG block >> here. > > that's true, sorry. > >> Are you sure that setting bit 31 of GEVNTSIZ will mask OTG_irq? I don't >> think so. >> >> Note that OTG_IRQ is a separate IRQ line than PERIPHERAL_IRQ. > > man, there's really no way to mask OTG events. This can be bad :-) > > John, can you confirm if there's really no way of masking OTG events > without loosing them? Not sure. I'll have to verify. If the IP version is 3.00a or higher you could experiment with using interrupt moderation as a global mask. John
[PATCH v2 1/2] regulator: hi655x: Describe consumed platform device
The hi655x-regulator driver consumes a similarly named platform device. Adding that to the module device table, allows modprobe to locate this driver once the device is created. Signed-off-by: Jeremy Linton--- drivers/regulator/hi655x-regulator.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index 065c100..36ae54b 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -214,7 +214,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev) return 0; } +static const struct platform_device_id hi655x_regulator_table[] = { + { .name = "hi655x-regulator" }, + {}, +}; +MODULE_DEVICE_TABLE(platform, hi655x_regulator_table); + static struct platform_driver hi655x_regulator_driver = { + .id_table = hi655x_regulator_table, .driver = { .name = "hi655x-regulator", }, -- 2.10.2
[PATCH v2 1/2] regulator: hi655x: Describe consumed platform device
The hi655x-regulator driver consumes a similarly named platform device. Adding that to the module device table, allows modprobe to locate this driver once the device is created. Signed-off-by: Jeremy Linton --- drivers/regulator/hi655x-regulator.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index 065c100..36ae54b 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -214,7 +214,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev) return 0; } +static const struct platform_device_id hi655x_regulator_table[] = { + { .name = "hi655x-regulator" }, + {}, +}; +MODULE_DEVICE_TABLE(platform, hi655x_regulator_table); + static struct platform_driver hi655x_regulator_driver = { + .id_table = hi655x_regulator_table, .driver = { .name = "hi655x-regulator", }, -- 2.10.2
[PATCH v2 2/2] regulator: hi655x: Bump parent pmic module use count
The hi655x-regulator driver depends on the parent pmic/mfc device driver but doesn't increase its use count. This results in system crashes if the parent module is unloaded while the regulators are still in use. Add explicit module get/put calls to keep the parent from being unloaded. example crash: Unable to handle kernel paging request at virtual address 800078fc5c78 ... [] 0x800078fc5c78 [] regulator_set_voltage_sel_regmap+0x50/0x98 [] _regulator_do_set_voltage+0x4c8/0x7c0 [] regulator_set_voltage_unlocked+0xc4/0x258 [] regulator_set_voltage+0x3c/0x70 [] mmc_regulator_set_ocr+0x48/0x100 [mmc_core] [] dw_mci_set_ios+0x1e8/0x280 [dw_mmc] [] mmc_set_initial_state+0x84/0xf8 [mmc_core] [] mmc_power_up.part.13+0x5c/0x1f8 [mmc_core] [] mmc_rescan+0x270/0x3b0 [mmc_core] [] process_one_work+0x264/0x7c0 [] worker_thread+0x54/0x430 [] kthread+0x104/0x130 [] ret_from_fork+0x10/0x50 Signed-off-by: Jeremy Linton--- drivers/regulator/hi655x-regulator.c | 26 -- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index 36ae54b..336aaed 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -185,16 +185,29 @@ static int hi655x_regulator_probe(struct platform_device *pdev) struct hi655x_pmic *pmic; struct regulator_config config = { }; struct regulator_dev *rdev; + struct device *parent = pdev->dev.parent; - pmic = dev_get_drvdata(pdev->dev.parent); + if (!parent) { + dev_err(>dev, "no regulator parent node\n"); + return -ENODEV; + } + + pmic = dev_get_drvdata(parent); if (!pmic) { dev_err(>dev, "no pmic in the regulator parent node\n"); return -ENODEV; } + if (!try_module_get(parent->driver->owner)) { + dev_err(>dev, "unable to get parent module\n"); + return -ENODEV; + } + regulator = devm_kzalloc(>dev, sizeof(*regulator), GFP_KERNEL); - if (!regulator) + if (!regulator) { + module_put(parent->driver->owner); return -ENOMEM; + } platform_set_drvdata(pdev, regulator); @@ -214,6 +227,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev) return 0; } +static int hi655x_regulator_remove(struct platform_device *pdev) +{ + struct device *parent = pdev->dev.parent; + + module_put(parent->driver->owner); + return 0; +} + static const struct platform_device_id hi655x_regulator_table[] = { { .name = "hi655x-regulator" }, {}, @@ -226,6 +247,7 @@ static struct platform_driver hi655x_regulator_driver = { .name = "hi655x-regulator", }, .probe = hi655x_regulator_probe, + .remove = hi655x_regulator_remove }; module_platform_driver(hi655x_regulator_driver); -- 2.10.2
[PATCH v2 0/2] Hi655x: mfd/pmic: regulator: Correct dependencies
In an environment where the hi655x pmic is being built as a standalone module, it fails to automatically load resulting in boot failures, machine hangs, etc. First we correct this by setting an appropriate module dependency. Then we bump the module use count on the mfd/pmic driver so that it cannot be unloaded when in use. This avoids an unload warning and crashes like: Unable to handle kernel paging request at virtual address 800078fc5c78 pgd = 0a15 *pgd=7ffc0003, *pud=7ffc0003, *pmd=00e86711 Internal error: Oops: 860e [#1] SMP ... [] 0x800078fc5c78 [] regulator_set_voltage_sel_regmap+0x50/0x98 [] _regulator_do_set_voltage+0x4c8/0x7c0 [] regulator_set_voltage_unlocked+0xc4/0x258 [] regulator_set_voltage+0x3c/0x70 [] mmc_regulator_set_ocr+0x48/0x100 [mmc_core] [] dw_mci_set_ios+0x1e8/0x280 [dw_mmc] [] mmc_set_initial_state+0x84/0xf8 [mmc_core] [] mmc_power_up.part.13+0x5c/0x1f8 [mmc_core] [] mmc_rescan+0x270/0x3b0 [mmc_core] [] process_one_work+0x264/0x7c0 [] worker_thread+0x54/0x430 [] kthread+0x104/0x130 [] ret_from_fork+0x10/0x50 V1->V2: Change from a module post call to a module_device_table. Jeremy Linton (2): regulator: hi655x: Describe consumed platform device regulator: hi655x: Bump parent pmic module use count drivers/regulator/hi655x-regulator.c | 33 +++-- 1 file changed, 31 insertions(+), 2 deletions(-) -- 2.10.2
[PATCH v2 0/2] Hi655x: mfd/pmic: regulator: Correct dependencies
In an environment where the hi655x pmic is being built as a standalone module, it fails to automatically load resulting in boot failures, machine hangs, etc. First we correct this by setting an appropriate module dependency. Then we bump the module use count on the mfd/pmic driver so that it cannot be unloaded when in use. This avoids an unload warning and crashes like: Unable to handle kernel paging request at virtual address 800078fc5c78 pgd = 0a15 *pgd=7ffc0003, *pud=7ffc0003, *pmd=00e86711 Internal error: Oops: 860e [#1] SMP ... [] 0x800078fc5c78 [] regulator_set_voltage_sel_regmap+0x50/0x98 [] _regulator_do_set_voltage+0x4c8/0x7c0 [] regulator_set_voltage_unlocked+0xc4/0x258 [] regulator_set_voltage+0x3c/0x70 [] mmc_regulator_set_ocr+0x48/0x100 [mmc_core] [] dw_mci_set_ios+0x1e8/0x280 [dw_mmc] [] mmc_set_initial_state+0x84/0xf8 [mmc_core] [] mmc_power_up.part.13+0x5c/0x1f8 [mmc_core] [] mmc_rescan+0x270/0x3b0 [mmc_core] [] process_one_work+0x264/0x7c0 [] worker_thread+0x54/0x430 [] kthread+0x104/0x130 [] ret_from_fork+0x10/0x50 V1->V2: Change from a module post call to a module_device_table. Jeremy Linton (2): regulator: hi655x: Describe consumed platform device regulator: hi655x: Bump parent pmic module use count drivers/regulator/hi655x-regulator.c | 33 +++-- 1 file changed, 31 insertions(+), 2 deletions(-) -- 2.10.2
[PATCH v2 2/2] regulator: hi655x: Bump parent pmic module use count
The hi655x-regulator driver depends on the parent pmic/mfc device driver but doesn't increase its use count. This results in system crashes if the parent module is unloaded while the regulators are still in use. Add explicit module get/put calls to keep the parent from being unloaded. example crash: Unable to handle kernel paging request at virtual address 800078fc5c78 ... [] 0x800078fc5c78 [] regulator_set_voltage_sel_regmap+0x50/0x98 [] _regulator_do_set_voltage+0x4c8/0x7c0 [] regulator_set_voltage_unlocked+0xc4/0x258 [] regulator_set_voltage+0x3c/0x70 [] mmc_regulator_set_ocr+0x48/0x100 [mmc_core] [] dw_mci_set_ios+0x1e8/0x280 [dw_mmc] [] mmc_set_initial_state+0x84/0xf8 [mmc_core] [] mmc_power_up.part.13+0x5c/0x1f8 [mmc_core] [] mmc_rescan+0x270/0x3b0 [mmc_core] [] process_one_work+0x264/0x7c0 [] worker_thread+0x54/0x430 [] kthread+0x104/0x130 [] ret_from_fork+0x10/0x50 Signed-off-by: Jeremy Linton --- drivers/regulator/hi655x-regulator.c | 26 -- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index 36ae54b..336aaed 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -185,16 +185,29 @@ static int hi655x_regulator_probe(struct platform_device *pdev) struct hi655x_pmic *pmic; struct regulator_config config = { }; struct regulator_dev *rdev; + struct device *parent = pdev->dev.parent; - pmic = dev_get_drvdata(pdev->dev.parent); + if (!parent) { + dev_err(>dev, "no regulator parent node\n"); + return -ENODEV; + } + + pmic = dev_get_drvdata(parent); if (!pmic) { dev_err(>dev, "no pmic in the regulator parent node\n"); return -ENODEV; } + if (!try_module_get(parent->driver->owner)) { + dev_err(>dev, "unable to get parent module\n"); + return -ENODEV; + } + regulator = devm_kzalloc(>dev, sizeof(*regulator), GFP_KERNEL); - if (!regulator) + if (!regulator) { + module_put(parent->driver->owner); return -ENOMEM; + } platform_set_drvdata(pdev, regulator); @@ -214,6 +227,14 @@ static int hi655x_regulator_probe(struct platform_device *pdev) return 0; } +static int hi655x_regulator_remove(struct platform_device *pdev) +{ + struct device *parent = pdev->dev.parent; + + module_put(parent->driver->owner); + return 0; +} + static const struct platform_device_id hi655x_regulator_table[] = { { .name = "hi655x-regulator" }, {}, @@ -226,6 +247,7 @@ static struct platform_driver hi655x_regulator_driver = { .name = "hi655x-regulator", }, .probe = hi655x_regulator_probe, + .remove = hi655x_regulator_remove }; module_platform_driver(hi655x_regulator_driver); -- 2.10.2
Re: dwc2_hc_chhltd_intr_dma - ChHltd set errors?
On 03/31/2017 04:04 PM, John Stultz wrote: > On Thu, Mar 2, 2017 at 12:00 PM, John Stultzwrote: >> Hey John, >> We've noticed that when using usb ethernet adapters on HiKey, we >> occasionally see errors like: >> >> dwc2 f72c.usb: dwc2_hc_chhltd_intr_dma: Channel 0 - ChHltd set, >> but reason is unknown >> dwc2 f72c.usb: hcint 0x0002, intsts 0x06200029 >> >> dwc2 f72c.usb: dwc2_hc_chhltd_intr_dma: Channel 11 - ChHltd set, >> but reason is unknown >> dwc2 f72c.usb: hcint 0x0002, intsts 0x04200029 >> >> Sometimes followed up by a usb error in the driver, something like: >> asix 1-1.2:1.0 eth0: asix_rx_fixup() Bad Header Length 0x36000807, offset 68 >> >> Curious if you've seen any reports like this? > > Hey John, > Just wanted to check in again on this to see if you've seen anything > like it? I've not had too much time to debug it, but my attempts so > far haven't been productive. > I don't think I've seen that. We'll try to take a look this week. Thanks, John
Re: dwc2_hc_chhltd_intr_dma - ChHltd set errors?
On 03/31/2017 04:04 PM, John Stultz wrote: > On Thu, Mar 2, 2017 at 12:00 PM, John Stultz wrote: >> Hey John, >> We've noticed that when using usb ethernet adapters on HiKey, we >> occasionally see errors like: >> >> dwc2 f72c.usb: dwc2_hc_chhltd_intr_dma: Channel 0 - ChHltd set, >> but reason is unknown >> dwc2 f72c.usb: hcint 0x0002, intsts 0x06200029 >> >> dwc2 f72c.usb: dwc2_hc_chhltd_intr_dma: Channel 11 - ChHltd set, >> but reason is unknown >> dwc2 f72c.usb: hcint 0x0002, intsts 0x04200029 >> >> Sometimes followed up by a usb error in the driver, something like: >> asix 1-1.2:1.0 eth0: asix_rx_fixup() Bad Header Length 0x36000807, offset 68 >> >> Curious if you've seen any reports like this? > > Hey John, > Just wanted to check in again on this to see if you've seen anything > like it? I've not had too much time to debug it, but my attempts so > far haven't been productive. > I don't think I've seen that. We'll try to take a look this week. Thanks, John
Re: [PATCH RFC] remove custom Michael MIC implementation
+ linux-wireless "Tobin C. Harding"writes: > On Fri, Mar 31, 2017 at 09:58:51AM +0200, Wolfram Sang wrote: >> >> > The code is untested, I have hardware in the mail. >> >> Cool! > > The card I have is a Spectec FCC ID: S2Y-WLAN-11B-G which I believe is > a SDW-823 and should use the ks7010 driver. I am going to attempt to > get it running on a Raspberry Pi B+. I ordered the wrong size break > out board originally so waiting on the new one now. > >> >> > If any one is interested and has any comments I would really like to >> > hear them. I am open to all suggestions (even down to trivial coding >> > style issues). >> >> I'll just repeat that the key move to get this driver out of staging is >> to get away from the WEXT interface to CFG80211. Otherwise no chance >> that wireless maintainers will even look at it. This is a huge change >> but once it is done, features like Michael MIC come with it for free >> (from what I recall, I am not a wireless expert myself). > > That would explain why I could not find more than the Orinoco driver > using the Michael MIC module directly. I think cfg80211 and mac80211 got mixed up. mac80211 (the full IEEE 802.11 stack for "softmac" devices) provides Michael MIC implementation, but cfg80211 (for "hardmac" devices) does not. >> Without the CFG80211 conversion, replacing the Michael custom >> implementation with the in-kernel one makes the driver a tad better and >> is good exercise. However, it will sadly not help to get the driver out >> of staging. > > I'll drop it then. Could you please tell me, is there any thing else > more I need to do to let LKML know that this RFC is dropped? Or is > this reply enough. I don't want to use any ones time unnecessarily. > >> >> But if you want a clean WEXT driver first, this is a step in the right >> direction. > > Let's go for a CFG80211 driver and get out of staging :) So next step > is I guess study the ath6kl driver, learn how CFG80211 is done and > implement that interface in ks7010? Oh, and test that it works. Please keep linux-wireless list in loop so that people on that list can help. -- Kalle Valo
Re: [PATCH RFC] remove custom Michael MIC implementation
+ linux-wireless "Tobin C. Harding" writes: > On Fri, Mar 31, 2017 at 09:58:51AM +0200, Wolfram Sang wrote: >> >> > The code is untested, I have hardware in the mail. >> >> Cool! > > The card I have is a Spectec FCC ID: S2Y-WLAN-11B-G which I believe is > a SDW-823 and should use the ks7010 driver. I am going to attempt to > get it running on a Raspberry Pi B+. I ordered the wrong size break > out board originally so waiting on the new one now. > >> >> > If any one is interested and has any comments I would really like to >> > hear them. I am open to all suggestions (even down to trivial coding >> > style issues). >> >> I'll just repeat that the key move to get this driver out of staging is >> to get away from the WEXT interface to CFG80211. Otherwise no chance >> that wireless maintainers will even look at it. This is a huge change >> but once it is done, features like Michael MIC come with it for free >> (from what I recall, I am not a wireless expert myself). > > That would explain why I could not find more than the Orinoco driver > using the Michael MIC module directly. I think cfg80211 and mac80211 got mixed up. mac80211 (the full IEEE 802.11 stack for "softmac" devices) provides Michael MIC implementation, but cfg80211 (for "hardmac" devices) does not. >> Without the CFG80211 conversion, replacing the Michael custom >> implementation with the in-kernel one makes the driver a tad better and >> is good exercise. However, it will sadly not help to get the driver out >> of staging. > > I'll drop it then. Could you please tell me, is there any thing else > more I need to do to let LKML know that this RFC is dropped? Or is > this reply enough. I don't want to use any ones time unnecessarily. > >> >> But if you want a clean WEXT driver first, this is a step in the right >> direction. > > Let's go for a CFG80211 driver and get out of staging :) So next step > is I guess study the ath6kl driver, learn how CFG80211 is done and > implement that interface in ks7010? Oh, and test that it works. Please keep linux-wireless list in loop so that people on that list can help. -- Kalle Valo
[PATCH 0/5] zram clean up
This patchset aims zram clean-up. [1] clean up multiple pages's bvec handling. [2] clean up partial IO handling [3-5] clean up zram via using accessor and removing pointless structure. With [2-5] applied, we can get a few hundred bytes as well as huge readibility enhance. This patchset is based on v4.11-rc4-mmotm-2017-03-30-16-31 and *drop* zram-factor-out-partial-io-routine.patch. x86: 708 byte save add/remove: 1/1 grow/shrink: 0/11 up/down: 478/-1186 (-708) function old new delta zram_special_page_read - 478+478 zram_reset_device317 314 -3 mem_used_max_store 131 128 -3 compact_store 96 93 -3 mm_stat_show 203 197 -6 zram_add 719 712 -7 zram_slot_free_notify229 214 -15 zram_make_request819 803 -16 zram_meta_free 128 111 -17 zram_free_page 180 151 -29 disksize_store 432 361 -71 zram_decompress_page.isra504 --504 zram_bvec_rw25922080-512 Total: Before=25350773, After=25350065, chg -0.00% ppc64: 231 byte save add/remove: 2/0 grow/shrink: 1/9 up/down: 681/-912 (-231) function old new delta zram_special_page_read - 480+480 zram_slot_lock - 200+200 vermagic 39 40 +1 mm_stat_show 256 248 -8 zram_meta_free 200 184 -16 zram_add 944 912 -32 zram_free_page 348 308 -40 disksize_store 572 492 -80 zram_decompress_page 664 564-100 zram_slot_free_notify292 160-132 zram_make_request 11321000-132 zram_bvec_rw27682396-372 Total: Before=17565825, After=17565594, chg -0.00% Minchan Kim (5): [1] zram: handle multiple pages attached bio's bvec [2] zram: partial IO refactoring [3] zram: use zram_slot_lock instead of raw bit_spin_lock op [4] zram: remove zram_meta structure [5] zram: introduce zram data accessor drivers/block/zram/zram_drv.c | 532 +- drivers/block/zram/zram_drv.h | 6 +- 2 files changed, 270 insertions(+), 268 deletions(-) -- 2.7.4
Re: [PATCH] nios2: reserve boot memory for device tree
On Fri, 2017-03-31 at 11:40 +0200, Tobias Klauser wrote: > Make sure to reserve the boot memory for the flattened device tree. > Otherwise it might get overwritten, e.g. when initial_boot_params is > copied, leading to a corrupted FDT and a boot hang/crash: > > bootconsole [early0] enabled > Early console on uart16650 initialized at 0xf8001600 > OF: fdt: Error -11 processing FDT > Kernel panic - not syncing: setup_cpuinfo: No CPU found in > devicetree! > > ---[ end Kernel panic - not syncing: setup_cpuinfo: No CPU found in > devicetree! > > Guenter Roeck says: > > > > > I think I found the problem. In unflatten_and_copy_device_tree(), > > with added > > debug information: > > > > OF: fdt: initial_boot_params=c861e400, dt=c861f000 size=28874 > > (0x70ca) > > > > ... and then initial_boot_params is copied to dt, which results in > > corrupted > > fdt since the memory overlaps. Looks like the initial_boot_params > > memory > > is not reserved and (re-)allocated by > > early_init_dt_alloc_memory_arch(). > Cc: sta...@vger.kernel.org > Reported-by: Guenter Roeck> Reference: http://lkml.kernel.org/r/20170226210338.GA19476@roeck-us.n > et > Tested-by: Guenter Roeck > Signed-off-by: Tobias Klauser Acked-by: Ley Foon Tan Thanks for the fix. Will add this for 4.11. Regards Ley Foon > --- > arch/nios2/kernel/prom.c | 7 +++ > arch/nios2/kernel/setup.c | 3 +++ > 2 files changed, 10 insertions(+) > > diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c > index 367c5426157b..3901b80d4420 100644 > --- a/arch/nios2/kernel/prom.c > +++ b/arch/nios2/kernel/prom.c > @@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 > size, u64 align) > return alloc_bootmem_align(size, align); > } > > +int __init early_init_dt_reserve_memory_arch(phys_addr_t base, > phys_addr_t size, > +bool nomap) > +{ > + reserve_bootmem(base, size, BOOTMEM_DEFAULT); > + return 0; > +} > + > void __init early_init_devtree(void *params) > { > __be32 *dtb = (u32 *)__dtb_start; > diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c > index 6e57ffa5db27..6044d9be28b4 100644 > --- a/arch/nios2/kernel/setup.c > +++ b/arch/nios2/kernel/setup.c > @@ -201,6 +201,9 @@ void __init setup_arch(char **cmdline_p) > } > #endif /* CONFIG_BLK_DEV_INITRD */ > > + early_init_fdt_reserve_self(); > + early_init_fdt_scan_reserved_mem(); > + > unflatten_and_copy_device_tree(); > > setup_cpuinfo(); > -- > 2.12.2.399.g034667a45805 > > > > > > Confidentiality Notice. > This message may contain information that is confidential or > otherwise protected from disclosure. If you are not the intended > recipient, you are hereby notified that any use, disclosure, > dissemination, distribution, or copying of this message, or any > attachments, is strictly prohibited. If you have received this > message in error, please advise the sender by reply e-mail, and > delete the message and any attachments. Thank you.
[PATCH 0/5] zram clean up
This patchset aims zram clean-up. [1] clean up multiple pages's bvec handling. [2] clean up partial IO handling [3-5] clean up zram via using accessor and removing pointless structure. With [2-5] applied, we can get a few hundred bytes as well as huge readibility enhance. This patchset is based on v4.11-rc4-mmotm-2017-03-30-16-31 and *drop* zram-factor-out-partial-io-routine.patch. x86: 708 byte save add/remove: 1/1 grow/shrink: 0/11 up/down: 478/-1186 (-708) function old new delta zram_special_page_read - 478+478 zram_reset_device317 314 -3 mem_used_max_store 131 128 -3 compact_store 96 93 -3 mm_stat_show 203 197 -6 zram_add 719 712 -7 zram_slot_free_notify229 214 -15 zram_make_request819 803 -16 zram_meta_free 128 111 -17 zram_free_page 180 151 -29 disksize_store 432 361 -71 zram_decompress_page.isra504 --504 zram_bvec_rw25922080-512 Total: Before=25350773, After=25350065, chg -0.00% ppc64: 231 byte save add/remove: 2/0 grow/shrink: 1/9 up/down: 681/-912 (-231) function old new delta zram_special_page_read - 480+480 zram_slot_lock - 200+200 vermagic 39 40 +1 mm_stat_show 256 248 -8 zram_meta_free 200 184 -16 zram_add 944 912 -32 zram_free_page 348 308 -40 disksize_store 572 492 -80 zram_decompress_page 664 564-100 zram_slot_free_notify292 160-132 zram_make_request 11321000-132 zram_bvec_rw27682396-372 Total: Before=17565825, After=17565594, chg -0.00% Minchan Kim (5): [1] zram: handle multiple pages attached bio's bvec [2] zram: partial IO refactoring [3] zram: use zram_slot_lock instead of raw bit_spin_lock op [4] zram: remove zram_meta structure [5] zram: introduce zram data accessor drivers/block/zram/zram_drv.c | 532 +- drivers/block/zram/zram_drv.h | 6 +- 2 files changed, 270 insertions(+), 268 deletions(-) -- 2.7.4
Re: [PATCH] nios2: reserve boot memory for device tree
On Fri, 2017-03-31 at 11:40 +0200, Tobias Klauser wrote: > Make sure to reserve the boot memory for the flattened device tree. > Otherwise it might get overwritten, e.g. when initial_boot_params is > copied, leading to a corrupted FDT and a boot hang/crash: > > bootconsole [early0] enabled > Early console on uart16650 initialized at 0xf8001600 > OF: fdt: Error -11 processing FDT > Kernel panic - not syncing: setup_cpuinfo: No CPU found in > devicetree! > > ---[ end Kernel panic - not syncing: setup_cpuinfo: No CPU found in > devicetree! > > Guenter Roeck says: > > > > > I think I found the problem. In unflatten_and_copy_device_tree(), > > with added > > debug information: > > > > OF: fdt: initial_boot_params=c861e400, dt=c861f000 size=28874 > > (0x70ca) > > > > ... and then initial_boot_params is copied to dt, which results in > > corrupted > > fdt since the memory overlaps. Looks like the initial_boot_params > > memory > > is not reserved and (re-)allocated by > > early_init_dt_alloc_memory_arch(). > Cc: sta...@vger.kernel.org > Reported-by: Guenter Roeck > Reference: http://lkml.kernel.org/r/20170226210338.GA19476@roeck-us.n > et > Tested-by: Guenter Roeck > Signed-off-by: Tobias Klauser Acked-by: Ley Foon Tan Thanks for the fix. Will add this for 4.11. Regards Ley Foon > --- > arch/nios2/kernel/prom.c | 7 +++ > arch/nios2/kernel/setup.c | 3 +++ > 2 files changed, 10 insertions(+) > > diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c > index 367c5426157b..3901b80d4420 100644 > --- a/arch/nios2/kernel/prom.c > +++ b/arch/nios2/kernel/prom.c > @@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 > size, u64 align) > return alloc_bootmem_align(size, align); > } > > +int __init early_init_dt_reserve_memory_arch(phys_addr_t base, > phys_addr_t size, > +bool nomap) > +{ > + reserve_bootmem(base, size, BOOTMEM_DEFAULT); > + return 0; > +} > + > void __init early_init_devtree(void *params) > { > __be32 *dtb = (u32 *)__dtb_start; > diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c > index 6e57ffa5db27..6044d9be28b4 100644 > --- a/arch/nios2/kernel/setup.c > +++ b/arch/nios2/kernel/setup.c > @@ -201,6 +201,9 @@ void __init setup_arch(char **cmdline_p) > } > #endif /* CONFIG_BLK_DEV_INITRD */ > > + early_init_fdt_reserve_self(); > + early_init_fdt_scan_reserved_mem(); > + > unflatten_and_copy_device_tree(); > > setup_cpuinfo(); > -- > 2.12.2.399.g034667a45805 > > > > > > Confidentiality Notice. > This message may contain information that is confidential or > otherwise protected from disclosure. If you are not the intended > recipient, you are hereby notified that any use, disclosure, > dissemination, distribution, or copying of this message, or any > attachments, is strictly prohibited. If you have received this > message in error, please advise the sender by reply e-mail, and > delete the message and any attachments. Thank you.
[PATCH 3/5] zram: use zram_slot_lock instead of raw bit_spin_lock op
With this clean-up phase, I want to use zram's wrapper function to lock table access which is more consistent with other zram's functions. Signed-off-by: Minchan Kim--- drivers/block/zram/zram_drv.c | 42 -- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 7938f4b98b01..71b0a584bc85 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -415,24 +415,39 @@ static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(mm_stat); static DEVICE_ATTR_RO(debug_stat); + +static void zram_slot_lock(struct zram *zram, u32 index) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_lock(ZRAM_ACCESS, >table[index].value); +} + +static void zram_slot_unlock(struct zram *zram, u32 index) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); +} + static bool zram_special_page_read(struct zram *zram, u32 index, struct page *page, unsigned int offset, unsigned int len) { struct zram_meta *meta = zram->meta; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); if (unlikely(!meta->table[index].handle) || zram_test_flag(meta, index, ZRAM_SAME)) { void *mem; - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); mem = kmap_atomic(page); zram_fill_page(mem + offset, len, meta->table[index].element); kunmap_atomic(mem); return true; } - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); return false; } @@ -448,11 +463,11 @@ static bool zram_special_page_write(struct zram *zram, u32 index, kunmap_atomic(mem); /* Free memory associated with this sector now. */ - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); zram_set_flag(meta, index, ZRAM_SAME); zram_set_element(meta, index, element); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); atomic64_inc(>stats.same_pages); return true; @@ -559,7 +574,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) return 0; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); handle = meta->table[index].handle; size = zram_get_obj_size(meta, index); @@ -578,7 +593,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) zcomp_stream_put(zram->comp); } zs_unmap_object(meta->mem_pool, handle); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret)) @@ -731,11 +746,11 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, * Free memory associated with this sector * before overwriting unused sectors. */ - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); meta->table[index].handle = handle; zram_set_obj_size(meta, index, comp_len); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); /* Update stats */ atomic64_add(comp_len, >stats.compr_data_size); @@ -793,7 +808,6 @@ static void zram_bio_discard(struct zram *zram, u32 index, int offset, struct bio *bio) { size_t n = bio->bi_iter.bi_size; - struct zram_meta *meta = zram->meta; /* * zram manages data in physical block size units. Because logical block @@ -814,9 +828,9 @@ static void zram_bio_discard(struct zram *zram, u32 index, } while (n >= PAGE_SIZE) { - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); atomic64_inc(>stats.notify_free); index++; n -= PAGE_SIZE; @@ -925,9 +939,9 @@ static void zram_slot_free_notify(struct block_device *bdev, zram = bdev->bd_disk->private_data; meta = zram->meta; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); +
[PATCH 3/5] zram: use zram_slot_lock instead of raw bit_spin_lock op
With this clean-up phase, I want to use zram's wrapper function to lock table access which is more consistent with other zram's functions. Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 42 -- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 7938f4b98b01..71b0a584bc85 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -415,24 +415,39 @@ static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(mm_stat); static DEVICE_ATTR_RO(debug_stat); + +static void zram_slot_lock(struct zram *zram, u32 index) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_lock(ZRAM_ACCESS, >table[index].value); +} + +static void zram_slot_unlock(struct zram *zram, u32 index) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); +} + static bool zram_special_page_read(struct zram *zram, u32 index, struct page *page, unsigned int offset, unsigned int len) { struct zram_meta *meta = zram->meta; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); if (unlikely(!meta->table[index].handle) || zram_test_flag(meta, index, ZRAM_SAME)) { void *mem; - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); mem = kmap_atomic(page); zram_fill_page(mem + offset, len, meta->table[index].element); kunmap_atomic(mem); return true; } - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); return false; } @@ -448,11 +463,11 @@ static bool zram_special_page_write(struct zram *zram, u32 index, kunmap_atomic(mem); /* Free memory associated with this sector now. */ - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); zram_set_flag(meta, index, ZRAM_SAME); zram_set_element(meta, index, element); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); atomic64_inc(>stats.same_pages); return true; @@ -559,7 +574,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) return 0; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); handle = meta->table[index].handle; size = zram_get_obj_size(meta, index); @@ -578,7 +593,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) zcomp_stream_put(zram->comp); } zs_unmap_object(meta->mem_pool, handle); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret)) @@ -731,11 +746,11 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, * Free memory associated with this sector * before overwriting unused sectors. */ - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); meta->table[index].handle = handle; zram_set_obj_size(meta, index, comp_len); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); /* Update stats */ atomic64_add(comp_len, >stats.compr_data_size); @@ -793,7 +808,6 @@ static void zram_bio_discard(struct zram *zram, u32 index, int offset, struct bio *bio) { size_t n = bio->bi_iter.bi_size; - struct zram_meta *meta = zram->meta; /* * zram manages data in physical block size units. Because logical block @@ -814,9 +828,9 @@ static void zram_bio_discard(struct zram *zram, u32 index, } while (n >= PAGE_SIZE) { - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index); zram_free_page(zram, index); - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + zram_slot_unlock(zram, index); atomic64_inc(>stats.notify_free); index++; n -= PAGE_SIZE; @@ -925,9 +939,9 @@ static void zram_slot_free_notify(struct block_device *bdev, zram = bdev->bd_disk->private_data; meta = zram->meta; - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_slot_lock(zram, index);
[PATCH 1/5] zram: handle multiple pages attached bio's bvec
Johannes Thumshirn reported system goes the panic when using NVMe over Fabrics loopback target with zram. The reason is zram expects each bvec in bio contains a single page but nvme can attach a huge bulk of pages attached to the bio's bvec so that zram's index arithmetic could be wrong so that out-of-bound access makes panic. It can be solved by limiting max_sectors with SECTORS_PER_PAGE like [1] but it makes zram slow because bio should split with each pages so this patch makes zram aware of multiple pages in a bvec so it could solve without any regression. [1] 0bc315381fe9, zram: set physical queue limits to avoid array out of bounds accesses Cc: Jens AxboeCc: Hannes Reinecke Reported-by: Johannes Thumshirn Tested-by: Johannes Thumshirn Reviewed-by: Johannes Thumshirn Signed-off-by: Johannes Thumshirn Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 39 ++- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 01944419b1f3..28c2836f8c96 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -137,8 +137,7 @@ static inline bool valid_io_request(struct zram *zram, static void update_position(u32 *index, int *offset, struct bio_vec *bvec) { - if (*offset + bvec->bv_len >= PAGE_SIZE) - (*index)++; + *index += (*offset + bvec->bv_len) / PAGE_SIZE; *offset = (*offset + bvec->bv_len) % PAGE_SIZE; } @@ -838,34 +837,20 @@ static void __zram_make_request(struct zram *zram, struct bio *bio) } bio_for_each_segment(bvec, bio, iter) { - int max_transfer_size = PAGE_SIZE - offset; - - if (bvec.bv_len > max_transfer_size) { - /* -* zram_bvec_rw() can only make operation on a single -* zram page. Split the bio vector. -*/ - struct bio_vec bv; - - bv.bv_page = bvec.bv_page; - bv.bv_len = max_transfer_size; - bv.bv_offset = bvec.bv_offset; + struct bio_vec bv = bvec; + unsigned int remained = bvec.bv_len; + do { + bv.bv_len = min_t(unsigned int, PAGE_SIZE, remained); if (zram_bvec_rw(zram, , index, offset, -op_is_write(bio_op(bio))) < 0) + op_is_write(bio_op(bio))) < 0) goto out; - bv.bv_len = bvec.bv_len - max_transfer_size; - bv.bv_offset += max_transfer_size; - if (zram_bvec_rw(zram, , index + 1, 0, -op_is_write(bio_op(bio))) < 0) - goto out; - } else - if (zram_bvec_rw(zram, , index, offset, -op_is_write(bio_op(bio))) < 0) - goto out; + bv.bv_offset += bv.bv_len; + remained -= bv.bv_len; - update_position(, , ); + update_position(, , ); + } while (remained); } bio_endio(bio); @@ -882,8 +867,6 @@ static blk_qc_t zram_make_request(struct request_queue *queue, struct bio *bio) { struct zram *zram = queue->queuedata; - blk_queue_split(queue, , queue->bio_split); - if (!valid_io_request(zram, bio->bi_iter.bi_sector, bio->bi_iter.bi_size)) { atomic64_inc(>stats.invalid_io); @@ -1191,8 +1174,6 @@ static int zram_add(void) blk_queue_io_min(zram->disk->queue, PAGE_SIZE); blk_queue_io_opt(zram->disk->queue, PAGE_SIZE); zram->disk->queue->limits.discard_granularity = PAGE_SIZE; - zram->disk->queue->limits.max_sectors = SECTORS_PER_PAGE; - zram->disk->queue->limits.chunk_sectors = 0; blk_queue_max_discard_sectors(zram->disk->queue, UINT_MAX); /* * zram_bio_discard() will clear all logical blocks if logical block -- 2.7.4
[PATCH 4/5] zram: remove zram_meta structure
It's redundant now. Instead, remove it and use zram structure directly. Signed-off-by: Minchan Kim--- drivers/block/zram/zram_drv.c | 163 +- drivers/block/zram/zram_drv.h | 6 +- 2 files changed, 65 insertions(+), 104 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 71b0a584bc85..fdb73222841d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -58,46 +58,46 @@ static inline struct zram *dev_to_zram(struct device *dev) } /* flag operations require table entry bit_spin_lock() being held */ -static int zram_test_flag(struct zram_meta *meta, u32 index, +static int zram_test_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - return meta->table[index].value & BIT(flag); + return zram->table[index].value & BIT(flag); } -static void zram_set_flag(struct zram_meta *meta, u32 index, +static void zram_set_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - meta->table[index].value |= BIT(flag); + zram->table[index].value |= BIT(flag); } -static void zram_clear_flag(struct zram_meta *meta, u32 index, +static void zram_clear_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - meta->table[index].value &= ~BIT(flag); + zram->table[index].value &= ~BIT(flag); } -static inline void zram_set_element(struct zram_meta *meta, u32 index, +static inline void zram_set_element(struct zram *zram, u32 index, unsigned long element) { - meta->table[index].element = element; + zram->table[index].element = element; } -static inline void zram_clear_element(struct zram_meta *meta, u32 index) +static inline void zram_clear_element(struct zram *zram, u32 index) { - meta->table[index].element = 0; + zram->table[index].element = 0; } -static size_t zram_get_obj_size(struct zram_meta *meta, u32 index) +static size_t zram_get_obj_size(struct zram *zram, u32 index) { - return meta->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); + return zram->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); } -static void zram_set_obj_size(struct zram_meta *meta, +static void zram_set_obj_size(struct zram *zram, u32 index, size_t size) { - unsigned long flags = meta->table[index].value >> ZRAM_FLAG_SHIFT; + unsigned long flags = zram->table[index].value >> ZRAM_FLAG_SHIFT; - meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; + zram->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; } #if PAGE_SIZE != 4096 @@ -252,9 +252,8 @@ static ssize_t mem_used_max_store(struct device *dev, down_read(>init_lock); if (init_done(zram)) { - struct zram_meta *meta = zram->meta; atomic_long_set(>stats.max_used_pages, - zs_get_total_pages(meta->mem_pool)); + zs_get_total_pages(zram->mem_pool)); } up_read(>init_lock); @@ -327,7 +326,6 @@ static ssize_t compact_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); - struct zram_meta *meta; down_read(>init_lock); if (!init_done(zram)) { @@ -335,8 +333,7 @@ static ssize_t compact_store(struct device *dev, return -EINVAL; } - meta = zram->meta; - zs_compact(meta->mem_pool); + zs_compact(zram->mem_pool); up_read(>init_lock); return len; @@ -373,8 +370,8 @@ static ssize_t mm_stat_show(struct device *dev, down_read(>init_lock); if (init_done(zram)) { - mem_used = zs_get_total_pages(zram->meta->mem_pool); - zs_pool_stats(zram->meta->mem_pool, _stats); + mem_used = zs_get_total_pages(zram->mem_pool); + zs_pool_stats(zram->mem_pool, _stats); } orig_size = atomic64_read(>stats.pages_stored); @@ -418,32 +415,26 @@ static DEVICE_ATTR_RO(debug_stat); static void zram_slot_lock(struct zram *zram, u32 index) { - struct zram_meta *meta = zram->meta; - - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + bit_spin_lock(ZRAM_ACCESS, >table[index].value); } static void zram_slot_unlock(struct zram *zram, u32 index) { - struct zram_meta *meta = zram->meta; - - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); } static bool zram_special_page_read(struct zram *zram, u32 index, struct page *page, unsigned int offset, unsigned int len) { - struct zram_meta *meta = zram->meta; - zram_slot_lock(zram, index); - if
[PATCH 2/5] zram: partial IO refactoring
For architecture(PAGE_SIZE > 4K), zram have supported partial IO. However, the mixed code for handling normal/partial IO is too mess, error-prone to modify IO handler functions with upcoming feature so this patch aims for cleaning up zram's IO handling functions. Signed-off-by: Minchan Kim--- drivers/block/zram/zram_drv.c | 333 +++--- 1 file changed, 184 insertions(+), 149 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 28c2836f8c96..7938f4b98b01 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -45,6 +45,8 @@ static const char *default_compressor = "lzo"; /* Module params (documentation at end) */ static unsigned int num_devices = 1; +static void zram_free_page(struct zram *zram, size_t index); + static inline bool init_done(struct zram *zram) { return zram->disksize; @@ -98,10 +100,17 @@ static void zram_set_obj_size(struct zram_meta *meta, meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; } +#if PAGE_SIZE != 4096 static inline bool is_partial_io(struct bio_vec *bvec) { return bvec->bv_len != PAGE_SIZE; } +#else +static inline bool is_partial_io(struct bio_vec *bvec) +{ + return false; +} +#endif static void zram_revalidate_disk(struct zram *zram) { @@ -191,18 +200,6 @@ static bool page_same_filled(void *ptr, unsigned long *element) return true; } -static void handle_same_page(struct bio_vec *bvec, unsigned long element) -{ - struct page *page = bvec->bv_page; - void *user_mem; - - user_mem = kmap_atomic(page); - zram_fill_page(user_mem + bvec->bv_offset, bvec->bv_len, element); - kunmap_atomic(user_mem); - - flush_dcache_page(page); -} - static ssize_t initstate_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -418,6 +415,53 @@ static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(mm_stat); static DEVICE_ATTR_RO(debug_stat); +static bool zram_special_page_read(struct zram *zram, u32 index, + struct page *page, + unsigned int offset, unsigned int len) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_lock(ZRAM_ACCESS, >table[index].value); + if (unlikely(!meta->table[index].handle) || + zram_test_flag(meta, index, ZRAM_SAME)) { + void *mem; + + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + mem = kmap_atomic(page); + zram_fill_page(mem + offset, len, meta->table[index].element); + kunmap_atomic(mem); + return true; + } + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + + return false; +} + +static bool zram_special_page_write(struct zram *zram, u32 index, + struct page *page) +{ + unsigned long element; + void *mem = kmap_atomic(page); + + if (page_same_filled(mem, )) { + struct zram_meta *meta = zram->meta; + + kunmap_atomic(mem); + /* Free memory associated with this sector now. */ + bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_free_page(zram, index); + zram_set_flag(meta, index, ZRAM_SAME); + zram_set_element(meta, index, element); + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + + atomic64_inc(>stats.same_pages); + return true; + } + kunmap_atomic(mem); + + return false; +} + static void zram_meta_free(struct zram_meta *meta, u64 disksize) { size_t num_pages = disksize >> PAGE_SHIFT; @@ -504,169 +548,104 @@ static void zram_free_page(struct zram *zram, size_t index) zram_set_obj_size(meta, index, 0); } -static int zram_decompress_page(struct zram *zram, char *mem, u32 index) +static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) { - int ret = 0; - unsigned char *cmem; - struct zram_meta *meta = zram->meta; + int ret; unsigned long handle; unsigned int size; + void *src, *dst; + struct zram_meta *meta = zram->meta; + + if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) + return 0; bit_spin_lock(ZRAM_ACCESS, >table[index].value); handle = meta->table[index].handle; size = zram_get_obj_size(meta, index); - if (!handle || zram_test_flag(meta, index, ZRAM_SAME)) { - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); - zram_fill_page(mem, PAGE_SIZE, meta->table[index].element); - return 0; - } - - cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); + src = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { -
[PATCH 1/5] zram: handle multiple pages attached bio's bvec
Johannes Thumshirn reported system goes the panic when using NVMe over Fabrics loopback target with zram. The reason is zram expects each bvec in bio contains a single page but nvme can attach a huge bulk of pages attached to the bio's bvec so that zram's index arithmetic could be wrong so that out-of-bound access makes panic. It can be solved by limiting max_sectors with SECTORS_PER_PAGE like [1] but it makes zram slow because bio should split with each pages so this patch makes zram aware of multiple pages in a bvec so it could solve without any regression. [1] 0bc315381fe9, zram: set physical queue limits to avoid array out of bounds accesses Cc: Jens Axboe Cc: Hannes Reinecke Reported-by: Johannes Thumshirn Tested-by: Johannes Thumshirn Reviewed-by: Johannes Thumshirn Signed-off-by: Johannes Thumshirn Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 39 ++- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 01944419b1f3..28c2836f8c96 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -137,8 +137,7 @@ static inline bool valid_io_request(struct zram *zram, static void update_position(u32 *index, int *offset, struct bio_vec *bvec) { - if (*offset + bvec->bv_len >= PAGE_SIZE) - (*index)++; + *index += (*offset + bvec->bv_len) / PAGE_SIZE; *offset = (*offset + bvec->bv_len) % PAGE_SIZE; } @@ -838,34 +837,20 @@ static void __zram_make_request(struct zram *zram, struct bio *bio) } bio_for_each_segment(bvec, bio, iter) { - int max_transfer_size = PAGE_SIZE - offset; - - if (bvec.bv_len > max_transfer_size) { - /* -* zram_bvec_rw() can only make operation on a single -* zram page. Split the bio vector. -*/ - struct bio_vec bv; - - bv.bv_page = bvec.bv_page; - bv.bv_len = max_transfer_size; - bv.bv_offset = bvec.bv_offset; + struct bio_vec bv = bvec; + unsigned int remained = bvec.bv_len; + do { + bv.bv_len = min_t(unsigned int, PAGE_SIZE, remained); if (zram_bvec_rw(zram, , index, offset, -op_is_write(bio_op(bio))) < 0) + op_is_write(bio_op(bio))) < 0) goto out; - bv.bv_len = bvec.bv_len - max_transfer_size; - bv.bv_offset += max_transfer_size; - if (zram_bvec_rw(zram, , index + 1, 0, -op_is_write(bio_op(bio))) < 0) - goto out; - } else - if (zram_bvec_rw(zram, , index, offset, -op_is_write(bio_op(bio))) < 0) - goto out; + bv.bv_offset += bv.bv_len; + remained -= bv.bv_len; - update_position(, , ); + update_position(, , ); + } while (remained); } bio_endio(bio); @@ -882,8 +867,6 @@ static blk_qc_t zram_make_request(struct request_queue *queue, struct bio *bio) { struct zram *zram = queue->queuedata; - blk_queue_split(queue, , queue->bio_split); - if (!valid_io_request(zram, bio->bi_iter.bi_sector, bio->bi_iter.bi_size)) { atomic64_inc(>stats.invalid_io); @@ -1191,8 +1174,6 @@ static int zram_add(void) blk_queue_io_min(zram->disk->queue, PAGE_SIZE); blk_queue_io_opt(zram->disk->queue, PAGE_SIZE); zram->disk->queue->limits.discard_granularity = PAGE_SIZE; - zram->disk->queue->limits.max_sectors = SECTORS_PER_PAGE; - zram->disk->queue->limits.chunk_sectors = 0; blk_queue_max_discard_sectors(zram->disk->queue, UINT_MAX); /* * zram_bio_discard() will clear all logical blocks if logical block -- 2.7.4
[PATCH 4/5] zram: remove zram_meta structure
It's redundant now. Instead, remove it and use zram structure directly. Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 163 +- drivers/block/zram/zram_drv.h | 6 +- 2 files changed, 65 insertions(+), 104 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 71b0a584bc85..fdb73222841d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -58,46 +58,46 @@ static inline struct zram *dev_to_zram(struct device *dev) } /* flag operations require table entry bit_spin_lock() being held */ -static int zram_test_flag(struct zram_meta *meta, u32 index, +static int zram_test_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - return meta->table[index].value & BIT(flag); + return zram->table[index].value & BIT(flag); } -static void zram_set_flag(struct zram_meta *meta, u32 index, +static void zram_set_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - meta->table[index].value |= BIT(flag); + zram->table[index].value |= BIT(flag); } -static void zram_clear_flag(struct zram_meta *meta, u32 index, +static void zram_clear_flag(struct zram *zram, u32 index, enum zram_pageflags flag) { - meta->table[index].value &= ~BIT(flag); + zram->table[index].value &= ~BIT(flag); } -static inline void zram_set_element(struct zram_meta *meta, u32 index, +static inline void zram_set_element(struct zram *zram, u32 index, unsigned long element) { - meta->table[index].element = element; + zram->table[index].element = element; } -static inline void zram_clear_element(struct zram_meta *meta, u32 index) +static inline void zram_clear_element(struct zram *zram, u32 index) { - meta->table[index].element = 0; + zram->table[index].element = 0; } -static size_t zram_get_obj_size(struct zram_meta *meta, u32 index) +static size_t zram_get_obj_size(struct zram *zram, u32 index) { - return meta->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); + return zram->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); } -static void zram_set_obj_size(struct zram_meta *meta, +static void zram_set_obj_size(struct zram *zram, u32 index, size_t size) { - unsigned long flags = meta->table[index].value >> ZRAM_FLAG_SHIFT; + unsigned long flags = zram->table[index].value >> ZRAM_FLAG_SHIFT; - meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; + zram->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; } #if PAGE_SIZE != 4096 @@ -252,9 +252,8 @@ static ssize_t mem_used_max_store(struct device *dev, down_read(>init_lock); if (init_done(zram)) { - struct zram_meta *meta = zram->meta; atomic_long_set(>stats.max_used_pages, - zs_get_total_pages(meta->mem_pool)); + zs_get_total_pages(zram->mem_pool)); } up_read(>init_lock); @@ -327,7 +326,6 @@ static ssize_t compact_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); - struct zram_meta *meta; down_read(>init_lock); if (!init_done(zram)) { @@ -335,8 +333,7 @@ static ssize_t compact_store(struct device *dev, return -EINVAL; } - meta = zram->meta; - zs_compact(meta->mem_pool); + zs_compact(zram->mem_pool); up_read(>init_lock); return len; @@ -373,8 +370,8 @@ static ssize_t mm_stat_show(struct device *dev, down_read(>init_lock); if (init_done(zram)) { - mem_used = zs_get_total_pages(zram->meta->mem_pool); - zs_pool_stats(zram->meta->mem_pool, _stats); + mem_used = zs_get_total_pages(zram->mem_pool); + zs_pool_stats(zram->mem_pool, _stats); } orig_size = atomic64_read(>stats.pages_stored); @@ -418,32 +415,26 @@ static DEVICE_ATTR_RO(debug_stat); static void zram_slot_lock(struct zram *zram, u32 index) { - struct zram_meta *meta = zram->meta; - - bit_spin_lock(ZRAM_ACCESS, >table[index].value); + bit_spin_lock(ZRAM_ACCESS, >table[index].value); } static void zram_slot_unlock(struct zram *zram, u32 index) { - struct zram_meta *meta = zram->meta; - - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); } static bool zram_special_page_read(struct zram *zram, u32 index, struct page *page, unsigned int offset, unsigned int len) { - struct zram_meta *meta = zram->meta; - zram_slot_lock(zram, index); - if
[PATCH 2/5] zram: partial IO refactoring
For architecture(PAGE_SIZE > 4K), zram have supported partial IO. However, the mixed code for handling normal/partial IO is too mess, error-prone to modify IO handler functions with upcoming feature so this patch aims for cleaning up zram's IO handling functions. Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 333 +++--- 1 file changed, 184 insertions(+), 149 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 28c2836f8c96..7938f4b98b01 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -45,6 +45,8 @@ static const char *default_compressor = "lzo"; /* Module params (documentation at end) */ static unsigned int num_devices = 1; +static void zram_free_page(struct zram *zram, size_t index); + static inline bool init_done(struct zram *zram) { return zram->disksize; @@ -98,10 +100,17 @@ static void zram_set_obj_size(struct zram_meta *meta, meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; } +#if PAGE_SIZE != 4096 static inline bool is_partial_io(struct bio_vec *bvec) { return bvec->bv_len != PAGE_SIZE; } +#else +static inline bool is_partial_io(struct bio_vec *bvec) +{ + return false; +} +#endif static void zram_revalidate_disk(struct zram *zram) { @@ -191,18 +200,6 @@ static bool page_same_filled(void *ptr, unsigned long *element) return true; } -static void handle_same_page(struct bio_vec *bvec, unsigned long element) -{ - struct page *page = bvec->bv_page; - void *user_mem; - - user_mem = kmap_atomic(page); - zram_fill_page(user_mem + bvec->bv_offset, bvec->bv_len, element); - kunmap_atomic(user_mem); - - flush_dcache_page(page); -} - static ssize_t initstate_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -418,6 +415,53 @@ static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(mm_stat); static DEVICE_ATTR_RO(debug_stat); +static bool zram_special_page_read(struct zram *zram, u32 index, + struct page *page, + unsigned int offset, unsigned int len) +{ + struct zram_meta *meta = zram->meta; + + bit_spin_lock(ZRAM_ACCESS, >table[index].value); + if (unlikely(!meta->table[index].handle) || + zram_test_flag(meta, index, ZRAM_SAME)) { + void *mem; + + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + mem = kmap_atomic(page); + zram_fill_page(mem + offset, len, meta->table[index].element); + kunmap_atomic(mem); + return true; + } + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + + return false; +} + +static bool zram_special_page_write(struct zram *zram, u32 index, + struct page *page) +{ + unsigned long element; + void *mem = kmap_atomic(page); + + if (page_same_filled(mem, )) { + struct zram_meta *meta = zram->meta; + + kunmap_atomic(mem); + /* Free memory associated with this sector now. */ + bit_spin_lock(ZRAM_ACCESS, >table[index].value); + zram_free_page(zram, index); + zram_set_flag(meta, index, ZRAM_SAME); + zram_set_element(meta, index, element); + bit_spin_unlock(ZRAM_ACCESS, >table[index].value); + + atomic64_inc(>stats.same_pages); + return true; + } + kunmap_atomic(mem); + + return false; +} + static void zram_meta_free(struct zram_meta *meta, u64 disksize) { size_t num_pages = disksize >> PAGE_SHIFT; @@ -504,169 +548,104 @@ static void zram_free_page(struct zram *zram, size_t index) zram_set_obj_size(meta, index, 0); } -static int zram_decompress_page(struct zram *zram, char *mem, u32 index) +static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) { - int ret = 0; - unsigned char *cmem; - struct zram_meta *meta = zram->meta; + int ret; unsigned long handle; unsigned int size; + void *src, *dst; + struct zram_meta *meta = zram->meta; + + if (zram_special_page_read(zram, index, page, 0, PAGE_SIZE)) + return 0; bit_spin_lock(ZRAM_ACCESS, >table[index].value); handle = meta->table[index].handle; size = zram_get_obj_size(meta, index); - if (!handle || zram_test_flag(meta, index, ZRAM_SAME)) { - bit_spin_unlock(ZRAM_ACCESS, >table[index].value); - zram_fill_page(mem, PAGE_SIZE, meta->table[index].element); - return 0; - } - - cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); + src = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { - copy_page(mem, cmem);
[PATCH 5/5] zram: introduce zram data accessor
With element, sometime I got confused handle and element access. It might be my bad but I think it's time to introduce accessor to prevent future idiot like me. This patch is just clean-up patch so it shouldn't change any behavior. Signed-off-by: Minchan Kim--- drivers/block/zram/zram_drv.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index fdb73222841d..c3171e5aa582 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -57,6 +57,16 @@ static inline struct zram *dev_to_zram(struct device *dev) return (struct zram *)dev_to_disk(dev)->private_data; } +static unsigned long zram_get_handle(struct zram *zram, u32 index) +{ + return zram->table[index].handle; +} + +static void zram_set_handle(struct zram *zram, u32 index, unsigned long handle) +{ + zram->table[index].handle = handle; +} + /* flag operations require table entry bit_spin_lock() being held */ static int zram_test_flag(struct zram *zram, u32 index, enum zram_pageflags flag) @@ -82,9 +92,9 @@ static inline void zram_set_element(struct zram *zram, u32 index, zram->table[index].element = element; } -static inline void zram_clear_element(struct zram *zram, u32 index) +static unsigned long zram_get_element(struct zram *zram, u32 index) { - zram->table[index].element = 0; + return zram->table[index].element; } static size_t zram_get_obj_size(struct zram *zram, u32 index) @@ -428,13 +438,14 @@ static bool zram_special_page_read(struct zram *zram, u32 index, unsigned int offset, unsigned int len) { zram_slot_lock(zram, index); - if (unlikely(!zram->table[index].handle) || - zram_test_flag(zram, index, ZRAM_SAME)) { + if (unlikely(!zram_get_handle(zram, index) || + zram_test_flag(zram, index, ZRAM_SAME))) { void *mem; zram_slot_unlock(zram, index); mem = kmap_atomic(page); - zram_fill_page(mem + offset, len, zram->table[index].element); + zram_fill_page(mem + offset, len, + zram_get_element(zram, index)); kunmap_atomic(mem); return true; } @@ -473,7 +484,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize) /* Free all pages that are still in this zram device */ for (index = 0; index < num_pages; index++) { - unsigned long handle = zram->table[index].handle; + unsigned long handle = zram_get_handle(zram, index); /* * No memory is allocated for same element filled pages. * Simply clear same page flag. @@ -513,7 +524,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) */ static void zram_free_page(struct zram *zram, size_t index) { - unsigned long handle = zram->table[index].handle; + unsigned long handle = zram_get_handle(zram, index); /* * No memory is allocated for same element filled pages. @@ -521,7 +532,7 @@ static void zram_free_page(struct zram *zram, size_t index) */ if (zram_test_flag(zram, index, ZRAM_SAME)) { zram_clear_flag(zram, index, ZRAM_SAME); - zram_clear_element(zram, index); + zram_set_element(zram, index, 0); atomic64_dec(>stats.same_pages); return; } @@ -535,7 +546,7 @@ static void zram_free_page(struct zram *zram, size_t index) >stats.compr_data_size); atomic64_dec(>stats.pages_stored); - zram->table[index].handle = 0; + zram_set_handle(zram, index, 0); zram_set_obj_size(zram, index, 0); } @@ -550,7 +561,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) return 0; zram_slot_lock(zram, index); - handle = zram->table[index].handle; + handle = zram_get_handle(zram, index); size = zram_get_obj_size(zram, index); src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); @@ -721,7 +732,7 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, */ zram_slot_lock(zram, index); zram_free_page(zram, index); - zram->table[index].handle = handle; + zram_set_handle(zram, index, handle); zram_set_obj_size(zram, index, comp_len); zram_slot_unlock(zram, index); -- 2.7.4
[PATCH 5/5] zram: introduce zram data accessor
With element, sometime I got confused handle and element access. It might be my bad but I think it's time to introduce accessor to prevent future idiot like me. This patch is just clean-up patch so it shouldn't change any behavior. Signed-off-by: Minchan Kim --- drivers/block/zram/zram_drv.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index fdb73222841d..c3171e5aa582 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -57,6 +57,16 @@ static inline struct zram *dev_to_zram(struct device *dev) return (struct zram *)dev_to_disk(dev)->private_data; } +static unsigned long zram_get_handle(struct zram *zram, u32 index) +{ + return zram->table[index].handle; +} + +static void zram_set_handle(struct zram *zram, u32 index, unsigned long handle) +{ + zram->table[index].handle = handle; +} + /* flag operations require table entry bit_spin_lock() being held */ static int zram_test_flag(struct zram *zram, u32 index, enum zram_pageflags flag) @@ -82,9 +92,9 @@ static inline void zram_set_element(struct zram *zram, u32 index, zram->table[index].element = element; } -static inline void zram_clear_element(struct zram *zram, u32 index) +static unsigned long zram_get_element(struct zram *zram, u32 index) { - zram->table[index].element = 0; + return zram->table[index].element; } static size_t zram_get_obj_size(struct zram *zram, u32 index) @@ -428,13 +438,14 @@ static bool zram_special_page_read(struct zram *zram, u32 index, unsigned int offset, unsigned int len) { zram_slot_lock(zram, index); - if (unlikely(!zram->table[index].handle) || - zram_test_flag(zram, index, ZRAM_SAME)) { + if (unlikely(!zram_get_handle(zram, index) || + zram_test_flag(zram, index, ZRAM_SAME))) { void *mem; zram_slot_unlock(zram, index); mem = kmap_atomic(page); - zram_fill_page(mem + offset, len, zram->table[index].element); + zram_fill_page(mem + offset, len, + zram_get_element(zram, index)); kunmap_atomic(mem); return true; } @@ -473,7 +484,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize) /* Free all pages that are still in this zram device */ for (index = 0; index < num_pages; index++) { - unsigned long handle = zram->table[index].handle; + unsigned long handle = zram_get_handle(zram, index); /* * No memory is allocated for same element filled pages. * Simply clear same page flag. @@ -513,7 +524,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) */ static void zram_free_page(struct zram *zram, size_t index) { - unsigned long handle = zram->table[index].handle; + unsigned long handle = zram_get_handle(zram, index); /* * No memory is allocated for same element filled pages. @@ -521,7 +532,7 @@ static void zram_free_page(struct zram *zram, size_t index) */ if (zram_test_flag(zram, index, ZRAM_SAME)) { zram_clear_flag(zram, index, ZRAM_SAME); - zram_clear_element(zram, index); + zram_set_element(zram, index, 0); atomic64_dec(>stats.same_pages); return; } @@ -535,7 +546,7 @@ static void zram_free_page(struct zram *zram, size_t index) >stats.compr_data_size); atomic64_dec(>stats.pages_stored); - zram->table[index].handle = 0; + zram_set_handle(zram, index, 0); zram_set_obj_size(zram, index, 0); } @@ -550,7 +561,7 @@ static int zram_decompress_page(struct zram *zram, struct page *page, u32 index) return 0; zram_slot_lock(zram, index); - handle = zram->table[index].handle; + handle = zram_get_handle(zram, index); size = zram_get_obj_size(zram, index); src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); @@ -721,7 +732,7 @@ static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, */ zram_slot_lock(zram, index); zram_free_page(zram, index); - zram->table[index].handle = handle; + zram_set_handle(zram, index, handle); zram_set_obj_size(zram, index, comp_len); zram_slot_unlock(zram, index); -- 2.7.4
Re: + zram-factor-out-partial-io-routine.patch added to -mm tree
Hi Andrew, Could you drop this patchset because I will send new patchset to replace this. Thanks. On Wed, Mar 29, 2017 at 03:25:32PM -0700, a...@linux-foundation.org wrote: > > The patch titled > Subject: zram: factor out partial IO routine > has been added to the -mm tree. Its filename is > zram-factor-out-partial-io-routine.patch > > This patch should soon appear at > > http://ozlabs.org/~akpm/mmots/broken-out/zram-factor-out-partial-io-routine.patch > and later at > > http://ozlabs.org/~akpm/mmotm/broken-out/zram-factor-out-partial-io-routine.patch > > Before you just go and hit "reply", please: >a) Consider who else should be cc'ed >b) Prefer to cc a suitable mailing list as well >c) Ideally: find the original patch on the mailing list and do a > reply-to-all to that, adding suitable additional cc's > > *** Remember to use Documentation/SubmitChecklist when testing your code *** > > The -mm tree is included into linux-next and is updated > there every 3-4 working days > > -- > From: Minchan Kim> Subject: zram: factor out partial IO routine > > For architecture(PAGE_SIZE > 4K), zram have supported partial IO. > However, the mixed code for handling normal/partial IO is too messy, > error-prone to modify IO handler functions with upcoming feature so this > patch aims for cleaning up via factoring out partial IO routines to > zram_bvec_partial_[read|write] which will be disabled for most 4K page > architecures. > > x86(4K architecure) > add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-664 (-664) > function old new delta > zram_bvec_rw23012039-262 > zram_decompress_page.isra402 --402 > > So, we will save 662 bytes. > > However, as side effect, it will increase binary size in non-4K > architecure but it's not major for zram so I believe benefit(maintainance, > binary size for most architecture) is bigger. > > Link: > http://lkml.kernel.org/r/1490773683-10701-1-git-send-email-minc...@kernel.org > Signed-off-by: Minchan Kim > Cc: Sergey Senozhatsky > Signed-off-by: Andrew Morton > --- > > drivers/block/zram/zram_drv.c | 259 ++-- > 1 file changed, 186 insertions(+), 73 deletions(-) > > diff -puN drivers/block/zram/zram_drv.c~zram-factor-out-partial-io-routine > drivers/block/zram/zram_drv.c > --- a/drivers/block/zram/zram_drv.c~zram-factor-out-partial-io-routine > +++ a/drivers/block/zram/zram_drv.c > @@ -98,10 +98,17 @@ static void zram_set_obj_size(struct zra > meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; > } > > +#if PAGE_SIZE != 4096 > static inline bool is_partial_io(struct bio_vec *bvec) > { > return bvec->bv_len != PAGE_SIZE; > } > +#else > +static inline bool is_partial_io(struct bio_vec *bvec) > +{ > + return false; > +} > +#endif > > static void zram_revalidate_disk(struct zram *zram) > { > @@ -544,8 +551,8 @@ static int zram_decompress_page(struct z > return 0; > } > > -static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, > - u32 index, int offset) > +static int zram_bvec_partial_read(struct zram *zram, struct bio_vec *bvec, > + u32 index, int offset) > { > int ret; > struct page *page; > @@ -562,81 +569,87 @@ static int zram_bvec_read(struct zram *z > } > bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > > - if (is_partial_io(bvec)) > - /* Use a temporary buffer to decompress the page */ > - uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); > - > - user_mem = kmap_atomic(page); > - if (!is_partial_io(bvec)) > - uncmem = user_mem; > - > + /* Use a temporary buffer to decompress the page */ > + uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); > if (!uncmem) { > pr_err("Unable to allocate temp memory\n"); > - ret = -ENOMEM; > - goto out_cleanup; > + return -ENOMEM; > } > > + user_mem = kmap_atomic(page); > ret = zram_decompress_page(zram, uncmem, index); > - /* Should NEVER happen. Return bio error if it does. */ > if (unlikely(ret)) > goto out_cleanup; > > - if (is_partial_io(bvec)) > - memcpy(user_mem + bvec->bv_offset, uncmem + offset, > + memcpy(user_mem + bvec->bv_offset, uncmem + offset, > bvec->bv_len); > - > flush_dcache_page(page); > ret = 0; > out_cleanup: > kunmap_atomic(user_mem); > - if (is_partial_io(bvec)) > - kfree(uncmem); > + kfree(uncmem); > return ret; > } > > -static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 > index, > -
Re: + zram-factor-out-partial-io-routine.patch added to -mm tree
Hi Andrew, Could you drop this patchset because I will send new patchset to replace this. Thanks. On Wed, Mar 29, 2017 at 03:25:32PM -0700, a...@linux-foundation.org wrote: > > The patch titled > Subject: zram: factor out partial IO routine > has been added to the -mm tree. Its filename is > zram-factor-out-partial-io-routine.patch > > This patch should soon appear at > > http://ozlabs.org/~akpm/mmots/broken-out/zram-factor-out-partial-io-routine.patch > and later at > > http://ozlabs.org/~akpm/mmotm/broken-out/zram-factor-out-partial-io-routine.patch > > Before you just go and hit "reply", please: >a) Consider who else should be cc'ed >b) Prefer to cc a suitable mailing list as well >c) Ideally: find the original patch on the mailing list and do a > reply-to-all to that, adding suitable additional cc's > > *** Remember to use Documentation/SubmitChecklist when testing your code *** > > The -mm tree is included into linux-next and is updated > there every 3-4 working days > > -- > From: Minchan Kim > Subject: zram: factor out partial IO routine > > For architecture(PAGE_SIZE > 4K), zram have supported partial IO. > However, the mixed code for handling normal/partial IO is too messy, > error-prone to modify IO handler functions with upcoming feature so this > patch aims for cleaning up via factoring out partial IO routines to > zram_bvec_partial_[read|write] which will be disabled for most 4K page > architecures. > > x86(4K architecure) > add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-664 (-664) > function old new delta > zram_bvec_rw23012039-262 > zram_decompress_page.isra402 --402 > > So, we will save 662 bytes. > > However, as side effect, it will increase binary size in non-4K > architecure but it's not major for zram so I believe benefit(maintainance, > binary size for most architecture) is bigger. > > Link: > http://lkml.kernel.org/r/1490773683-10701-1-git-send-email-minc...@kernel.org > Signed-off-by: Minchan Kim > Cc: Sergey Senozhatsky > Signed-off-by: Andrew Morton > --- > > drivers/block/zram/zram_drv.c | 259 ++-- > 1 file changed, 186 insertions(+), 73 deletions(-) > > diff -puN drivers/block/zram/zram_drv.c~zram-factor-out-partial-io-routine > drivers/block/zram/zram_drv.c > --- a/drivers/block/zram/zram_drv.c~zram-factor-out-partial-io-routine > +++ a/drivers/block/zram/zram_drv.c > @@ -98,10 +98,17 @@ static void zram_set_obj_size(struct zra > meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; > } > > +#if PAGE_SIZE != 4096 > static inline bool is_partial_io(struct bio_vec *bvec) > { > return bvec->bv_len != PAGE_SIZE; > } > +#else > +static inline bool is_partial_io(struct bio_vec *bvec) > +{ > + return false; > +} > +#endif > > static void zram_revalidate_disk(struct zram *zram) > { > @@ -544,8 +551,8 @@ static int zram_decompress_page(struct z > return 0; > } > > -static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, > - u32 index, int offset) > +static int zram_bvec_partial_read(struct zram *zram, struct bio_vec *bvec, > + u32 index, int offset) > { > int ret; > struct page *page; > @@ -562,81 +569,87 @@ static int zram_bvec_read(struct zram *z > } > bit_spin_unlock(ZRAM_ACCESS, >table[index].value); > > - if (is_partial_io(bvec)) > - /* Use a temporary buffer to decompress the page */ > - uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); > - > - user_mem = kmap_atomic(page); > - if (!is_partial_io(bvec)) > - uncmem = user_mem; > - > + /* Use a temporary buffer to decompress the page */ > + uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); > if (!uncmem) { > pr_err("Unable to allocate temp memory\n"); > - ret = -ENOMEM; > - goto out_cleanup; > + return -ENOMEM; > } > > + user_mem = kmap_atomic(page); > ret = zram_decompress_page(zram, uncmem, index); > - /* Should NEVER happen. Return bio error if it does. */ > if (unlikely(ret)) > goto out_cleanup; > > - if (is_partial_io(bvec)) > - memcpy(user_mem + bvec->bv_offset, uncmem + offset, > + memcpy(user_mem + bvec->bv_offset, uncmem + offset, > bvec->bv_len); > - > flush_dcache_page(page); > ret = 0; > out_cleanup: > kunmap_atomic(user_mem); > - if (is_partial_io(bvec)) > - kfree(uncmem); > + kfree(uncmem); > return ret; > } > > -static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 > index, > -int offset) > +static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, > +
Re: [PATCH] zram: set physical queue limits to avoid array out of bounds accesses
Hi Jens, On Thu, Mar 30, 2017 at 07:38:26PM -0600, Jens Axboe wrote: > On 03/30/2017 05:45 PM, Minchan Kim wrote: > > On Thu, Mar 30, 2017 at 09:35:56AM -0600, Jens Axboe wrote: > >> On 03/30/2017 09:08 AM, Minchan Kim wrote: > >>> Hi Jens, > >>> > >>> It seems you miss this. > >>> Could you handle this? > >> > >> I can, but I'm a little confused. The comment talks about replacing > >> the one I merged with this one, I can't do that. I'm assuming you > >> are talking about this commit: > > > > Right. > > > >> > >> commit 0bc315381fe9ed9fb91db8b0e82171b645ac008f > >> Author: Johannes Thumshirn> >> Date: Mon Mar 6 11:23:35 2017 +0100 > >> > >> zram: set physical queue limits to avoid array out of bounds accesses > >> > >> which is in mainline. The patch still applies, though. > > > > You mean it's already in mainline so you cannot replace but can revert. > > Right? > > If so, please revert it and merge this one. > > Let's please fold it into the other patch. That's cleaner and it makes > logical sense. Understood. > > >> Do we really REALLY need this for 4.11, or can we queue for 4.12 and > >> mark it stable? > > > > Not urgent because one in mainline fixes the problem so I'm okay > > with 4.12 but I don't want mark it as -stable. > > OK good, please resend with the two-line revert in your current > patch, and I'll get it queued up for 4.12. Yeb. If so, now that I think about it, it would be better to handle it via Andrew's tree because Andrew have been handled zram's patches and I have several pending patches based on it. So, I will send new patchset with it to Andrew. Thanks!
Re: [PATCH] zram: set physical queue limits to avoid array out of bounds accesses
Hi Jens, On Thu, Mar 30, 2017 at 07:38:26PM -0600, Jens Axboe wrote: > On 03/30/2017 05:45 PM, Minchan Kim wrote: > > On Thu, Mar 30, 2017 at 09:35:56AM -0600, Jens Axboe wrote: > >> On 03/30/2017 09:08 AM, Minchan Kim wrote: > >>> Hi Jens, > >>> > >>> It seems you miss this. > >>> Could you handle this? > >> > >> I can, but I'm a little confused. The comment talks about replacing > >> the one I merged with this one, I can't do that. I'm assuming you > >> are talking about this commit: > > > > Right. > > > >> > >> commit 0bc315381fe9ed9fb91db8b0e82171b645ac008f > >> Author: Johannes Thumshirn > >> Date: Mon Mar 6 11:23:35 2017 +0100 > >> > >> zram: set physical queue limits to avoid array out of bounds accesses > >> > >> which is in mainline. The patch still applies, though. > > > > You mean it's already in mainline so you cannot replace but can revert. > > Right? > > If so, please revert it and merge this one. > > Let's please fold it into the other patch. That's cleaner and it makes > logical sense. Understood. > > >> Do we really REALLY need this for 4.11, or can we queue for 4.12 and > >> mark it stable? > > > > Not urgent because one in mainline fixes the problem so I'm okay > > with 4.12 but I don't want mark it as -stable. > > OK good, please resend with the two-line revert in your current > patch, and I'll get it queued up for 4.12. Yeb. If so, now that I think about it, it would be better to handle it via Andrew's tree because Andrew have been handled zram's patches and I have several pending patches based on it. So, I will send new patchset with it to Andrew. Thanks!
Re: [PATCH net-next v3 5/5] net-next: dsa: add dsa support for Mediatek MT7530 switch
Hi Sean, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/net-next-dsa-add-Mediatek-MT7530-support/20170330-135532 config: m68k-allmodconfig (attached as .config) compiler: m68k-linux-gcc (GCC) 4.9.0 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=m68k All errors (new ones prefixed by >>): In file included from net//dsa/tag_mtk.c:16:0: net//dsa/dsa_priv.h:51:16: warning: 'struct dsa_switch' declared inside parameter list struct dsa_port *dport, int port); ^ net//dsa/dsa_priv.h:51:16: warning: its scope is only this definition or declaration, which is probably not what you want net//dsa/dsa_priv.h:54:39: warning: 'struct dsa_switch' declared inside parameter list int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:55:42: warning: 'struct dsa_switch' declared inside parameter list void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:59:36: warning: 'struct dsa_switch' declared inside parameter list void dsa_slave_mii_bus_init(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:62:8: warning: 'struct dsa_switch' declared inside parameter list int port, const char *name); ^ net//dsa/dsa_priv.h:70:41: warning: 'struct dsa_switch' declared inside parameter list int dsa_switch_register_notifier(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:71:44: warning: 'struct dsa_switch' declared inside parameter list void dsa_switch_unregister_notifier(struct dsa_switch *ds); ^ net//dsa/tag_mtk.c: In function 'mtk_tag_xmit': >> net//dsa/tag_mtk.c:38:26: error: dereferencing pointer to incomplete type mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; ^ net//dsa/tag_mtk.c: In function 'mtk_tag_rcv': net//dsa/tag_mtk.c:85:10: error: dereferencing pointer to incomplete type ds = dst->ds[0]; ^ net//dsa/tag_mtk.c:91:9: error: dereferencing pointer to incomplete type if (!ds->ports[port].netdev) ^ net//dsa/tag_mtk.c:98:15: error: dereferencing pointer to incomplete type skb->dev = ds->ports[port].netdev; ^ vim +38 net//dsa/tag_mtk.c 2faad9d7 Sean Wang 2017-03-29 22 static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, 2faad9d7 Sean Wang 2017-03-29 23 struct net_device *dev) 2faad9d7 Sean Wang 2017-03-29 24 { 2faad9d7 Sean Wang 2017-03-29 25 struct dsa_slave_priv *p = netdev_priv(dev); 2faad9d7 Sean Wang 2017-03-29 26 u8 *mtk_tag; 2faad9d7 Sean Wang 2017-03-29 27 2faad9d7 Sean Wang 2017-03-29 28 if (skb_cow_head(skb, MTK_HDR_LEN) < 0) 2faad9d7 Sean Wang 2017-03-29 29 goto out_free; 2faad9d7 Sean Wang 2017-03-29 30 2faad9d7 Sean Wang 2017-03-29 31 skb_push(skb, MTK_HDR_LEN); 2faad9d7 Sean Wang 2017-03-29 32 2faad9d7 Sean Wang 2017-03-29 33 memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 2faad9d7 Sean Wang 2017-03-29 34 2faad9d7 Sean Wang 2017-03-29 35 /* Build the tag after the MAC Source Address */ 2faad9d7 Sean Wang 2017-03-29 36 mtk_tag = skb->data + 2 * ETH_ALEN; 2faad9d7 Sean Wang 2017-03-29 37 mtk_tag[0] = 0; 2faad9d7 Sean Wang 2017-03-29 @38 mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; 2faad9d7 Sean Wang 2017-03-29 39 mtk_tag[2] = 0; 2faad9d7 Sean Wang 2017-03-29 40 mtk_tag[3] = 0; 2faad9d7 Sean Wang 2017-03-29 41 2faad9d7 Sean Wang 2017-03-29 42 return skb; 2faad9d7 Sean Wang 2017-03-29 43 2faad9d7 Sean Wang 2017-03-29 44 out_free: 2faad9d7 Sean Wang 2017-03-29 45 kfree_skb(skb); 2faad9d7 Sean Wang 2017-03-29 46 return NULL; :: The code at line 38 was first introduced by commit :: 2faad9d71e4c0544e3cf43b24439517c95df301f net-next: dsa: add Mediatek tag RX/TX handler :: TO: Sean Wang:: CC: 0day robot --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH net-next v3 5/5] net-next: dsa: add dsa support for Mediatek MT7530 switch
Hi Sean, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/net-next-dsa-add-Mediatek-MT7530-support/20170330-135532 config: m68k-allmodconfig (attached as .config) compiler: m68k-linux-gcc (GCC) 4.9.0 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=m68k All errors (new ones prefixed by >>): In file included from net//dsa/tag_mtk.c:16:0: net//dsa/dsa_priv.h:51:16: warning: 'struct dsa_switch' declared inside parameter list struct dsa_port *dport, int port); ^ net//dsa/dsa_priv.h:51:16: warning: its scope is only this definition or declaration, which is probably not what you want net//dsa/dsa_priv.h:54:39: warning: 'struct dsa_switch' declared inside parameter list int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:55:42: warning: 'struct dsa_switch' declared inside parameter list void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:59:36: warning: 'struct dsa_switch' declared inside parameter list void dsa_slave_mii_bus_init(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:62:8: warning: 'struct dsa_switch' declared inside parameter list int port, const char *name); ^ net//dsa/dsa_priv.h:70:41: warning: 'struct dsa_switch' declared inside parameter list int dsa_switch_register_notifier(struct dsa_switch *ds); ^ net//dsa/dsa_priv.h:71:44: warning: 'struct dsa_switch' declared inside parameter list void dsa_switch_unregister_notifier(struct dsa_switch *ds); ^ net//dsa/tag_mtk.c: In function 'mtk_tag_xmit': >> net//dsa/tag_mtk.c:38:26: error: dereferencing pointer to incomplete type mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; ^ net//dsa/tag_mtk.c: In function 'mtk_tag_rcv': net//dsa/tag_mtk.c:85:10: error: dereferencing pointer to incomplete type ds = dst->ds[0]; ^ net//dsa/tag_mtk.c:91:9: error: dereferencing pointer to incomplete type if (!ds->ports[port].netdev) ^ net//dsa/tag_mtk.c:98:15: error: dereferencing pointer to incomplete type skb->dev = ds->ports[port].netdev; ^ vim +38 net//dsa/tag_mtk.c 2faad9d7 Sean Wang 2017-03-29 22 static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, 2faad9d7 Sean Wang 2017-03-29 23 struct net_device *dev) 2faad9d7 Sean Wang 2017-03-29 24 { 2faad9d7 Sean Wang 2017-03-29 25 struct dsa_slave_priv *p = netdev_priv(dev); 2faad9d7 Sean Wang 2017-03-29 26 u8 *mtk_tag; 2faad9d7 Sean Wang 2017-03-29 27 2faad9d7 Sean Wang 2017-03-29 28 if (skb_cow_head(skb, MTK_HDR_LEN) < 0) 2faad9d7 Sean Wang 2017-03-29 29 goto out_free; 2faad9d7 Sean Wang 2017-03-29 30 2faad9d7 Sean Wang 2017-03-29 31 skb_push(skb, MTK_HDR_LEN); 2faad9d7 Sean Wang 2017-03-29 32 2faad9d7 Sean Wang 2017-03-29 33 memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 2faad9d7 Sean Wang 2017-03-29 34 2faad9d7 Sean Wang 2017-03-29 35 /* Build the tag after the MAC Source Address */ 2faad9d7 Sean Wang 2017-03-29 36 mtk_tag = skb->data + 2 * ETH_ALEN; 2faad9d7 Sean Wang 2017-03-29 37 mtk_tag[0] = 0; 2faad9d7 Sean Wang 2017-03-29 @38 mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; 2faad9d7 Sean Wang 2017-03-29 39 mtk_tag[2] = 0; 2faad9d7 Sean Wang 2017-03-29 40 mtk_tag[3] = 0; 2faad9d7 Sean Wang 2017-03-29 41 2faad9d7 Sean Wang 2017-03-29 42 return skb; 2faad9d7 Sean Wang 2017-03-29 43 2faad9d7 Sean Wang 2017-03-29 44 out_free: 2faad9d7 Sean Wang 2017-03-29 45 kfree_skb(skb); 2faad9d7 Sean Wang 2017-03-29 46 return NULL; :: The code at line 38 was first introduced by commit :: 2faad9d71e4c0544e3cf43b24439517c95df301f net-next: dsa: add Mediatek tag RX/TX handler :: TO: Sean Wang :: CC: 0day robot --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] staging: rtl8712: fixed multiple line derefence issue
On Mon, 2017-04-03 at 09:43 +0530, Prasant Jalan wrote: > On Thu, Mar 30, 2017 at 12:03 AM, Prasant Jalan> wrote: > > Checkpatch emits WARNING: Avoid multiple line dereference. > > > > Trivial indentation improvement helps fix the checkpatch warning. [] > > diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c > > b/drivers/staging/rtl8712/rtl871x_xmit.c [] > > @@ -416,15 +417,14 @@ static sint xmitframe_addmic(struct _adapter > > *padapter, > >[10], 6); > > } > > if (pqospriv->qos_option == 1) > > - priority[0] = (u8)pxmitframe-> > > - attrib.priority; > > + priority[0] = > > (u8)pxmitframe->attrib.priority; > > r8712_secmicappend(, [0], 4); > > payload = pframe; > > for (curfragnum = 0; curfragnum < pattrib->nr_frags; > > curfragnum++) { > > payload = (u8 *)RND4((addr_t)(payload)); > > - payload = payload + pattrib-> > > - hdrlen + pattrib->iv_len; > > + payload = payload + pattrib->hdrlen + > > + pattrib->iv_len; += would be shorter
Re: [PATCH] staging: rtl8712: fixed multiple line derefence issue
On Mon, 2017-04-03 at 09:43 +0530, Prasant Jalan wrote: > On Thu, Mar 30, 2017 at 12:03 AM, Prasant Jalan > wrote: > > Checkpatch emits WARNING: Avoid multiple line dereference. > > > > Trivial indentation improvement helps fix the checkpatch warning. [] > > diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c > > b/drivers/staging/rtl8712/rtl871x_xmit.c [] > > @@ -416,15 +417,14 @@ static sint xmitframe_addmic(struct _adapter > > *padapter, > >[10], 6); > > } > > if (pqospriv->qos_option == 1) > > - priority[0] = (u8)pxmitframe-> > > - attrib.priority; > > + priority[0] = > > (u8)pxmitframe->attrib.priority; > > r8712_secmicappend(, [0], 4); > > payload = pframe; > > for (curfragnum = 0; curfragnum < pattrib->nr_frags; > > curfragnum++) { > > payload = (u8 *)RND4((addr_t)(payload)); > > - payload = payload + pattrib-> > > - hdrlen + pattrib->iv_len; > > + payload = payload + pattrib->hdrlen + > > + pattrib->iv_len; += would be shorter
Re: [RFC 1/8] Introduce Peer-to-Peer memory (p2pmem) device
On 02/04/17 03:03 PM, Sinan Kaya wrote: > Push the decision all the way to the user. Let them decide whether they > want this feature to work on a root port connected port or under the > switch. Yes, I prefer this too. If other folks agree with that I'd be very happy to go back to user chooses. I think Sagi was the most vocal proponent for kernel chooses at LSF so hopefully he will read this thread and offer some opinion. > I thought the issue was feature didn't work at all with some root ports > or there was some kind of memory corruption issue that you were trying to > avoid with the existing systems. I *think* there are some much older root ports where P2P TLPs don't even get through. But it doesn't really change the situation: in the nvmet case, the user would enable p2pmem and then be unable to connect and thus choose to disable it going forward. Not a big difference from the user seeing bad performance and not choosing to enable it. > I think you should get rid of all pci searching business in your code. Yes, my original proposal was when you configure the nvme target you chose the specific p2pmem device to use. That code had no tie ins to PCI code and could, in theory, work generically with any device and bus. Logan
Re: [RFC 1/8] Introduce Peer-to-Peer memory (p2pmem) device
On 02/04/17 03:03 PM, Sinan Kaya wrote: > Push the decision all the way to the user. Let them decide whether they > want this feature to work on a root port connected port or under the > switch. Yes, I prefer this too. If other folks agree with that I'd be very happy to go back to user chooses. I think Sagi was the most vocal proponent for kernel chooses at LSF so hopefully he will read this thread and offer some opinion. > I thought the issue was feature didn't work at all with some root ports > or there was some kind of memory corruption issue that you were trying to > avoid with the existing systems. I *think* there are some much older root ports where P2P TLPs don't even get through. But it doesn't really change the situation: in the nvmet case, the user would enable p2pmem and then be unable to connect and thus choose to disable it going forward. Not a big difference from the user seeing bad performance and not choosing to enable it. > I think you should get rid of all pci searching business in your code. Yes, my original proposal was when you configure the nvme target you chose the specific p2pmem device to use. That code had no tie ins to PCI code and could, in theory, work generically with any device and bus. Logan
Re: [RFC PATCH 0/4] fs: introduce new writeback error tracking infrastructure and convert ext4 to use it
On Fri, Mar 31 2017, Jeff Layton wrote: > During LSF/MM this year, we had a discussion about the current sorry > state of writeback error reporting, and what could be done to improve > the situation. This patchset represents a first pass at the proposal > I made there. > > It first adds a new set of writeback error tracking infrastructure to > ensure that errors are properly stored and reported at fsync time. It > also makes a small but significant change to ensure that writeback > errors are reported on all file descriptors, not just on the first one > where fsync is called. > > Note that this is a _very_ rough draft at this point. I did some by-hand > testing with dm-error to ensure that it does the right thing there. > Mostly I'm interested in early feedback at this point -- does this basic > approach make sense? I think that having ->wb_err_seq and returning errors to all file descriptors is a good idea. I don't like ->wb_err, particularly that you allow it to be set to zero: + /* + * This should be called with the error code that we want to return + * on fsync. Thus, it should always be <= 0. + */ + WARN_ON(err > 0); Why is that ?? Also I think that EIO should always over-ride ENOSPC as the possible responses are different. That probably means you need a separate seq number for each, which isn't ideal. I don't like that you need to add a 'flush' handler to every filesystem, most of which just call + return filemap_report_wb_error(file); Could we just have if (filp->f_op->flush) retval = filp->f_op->flush(filp, id); + else + retval = filemap_report_wb_error(filp); in flip_close() ?? ... or maybe it is wrong to return this error on close(). After all, the file actually does get closed, so no error occurred. If an application cares about EIO, it should always call fsync() before close(). Thanks, NeilBrown > > Jeff Layton (4): > fs: new infrastructure for writeback error handling and reporting > dax: set errors in mapping when writeback fails > buffer: set wb errors using both new and old infrastructure for now > ext4: wire it up to the new writeback error reporting infrastructure > > Documentation/filesystems/vfs.txt | 14 +++-- > fs/buffer.c | 6 +++- > fs/dax.c | 4 ++- > fs/ext4/dir.c | 1 + > fs/ext4/ext4.h| 1 + > fs/ext4/file.c| 1 + > fs/ext4/fsync.c | 15 +++--- > fs/ext4/inode.c | 2 +- > fs/ext4/page-io.c | 4 +-- > fs/open.c | 3 ++ > include/linux/fs.h| 5 > mm/filemap.c | 61 > +++ > 12 files changed, 106 insertions(+), 11 deletions(-) > > -- > 2.9.3 signature.asc Description: PGP signature
Re: [RFC PATCH 0/4] fs: introduce new writeback error tracking infrastructure and convert ext4 to use it
On Fri, Mar 31 2017, Jeff Layton wrote: > During LSF/MM this year, we had a discussion about the current sorry > state of writeback error reporting, and what could be done to improve > the situation. This patchset represents a first pass at the proposal > I made there. > > It first adds a new set of writeback error tracking infrastructure to > ensure that errors are properly stored and reported at fsync time. It > also makes a small but significant change to ensure that writeback > errors are reported on all file descriptors, not just on the first one > where fsync is called. > > Note that this is a _very_ rough draft at this point. I did some by-hand > testing with dm-error to ensure that it does the right thing there. > Mostly I'm interested in early feedback at this point -- does this basic > approach make sense? I think that having ->wb_err_seq and returning errors to all file descriptors is a good idea. I don't like ->wb_err, particularly that you allow it to be set to zero: + /* + * This should be called with the error code that we want to return + * on fsync. Thus, it should always be <= 0. + */ + WARN_ON(err > 0); Why is that ?? Also I think that EIO should always over-ride ENOSPC as the possible responses are different. That probably means you need a separate seq number for each, which isn't ideal. I don't like that you need to add a 'flush' handler to every filesystem, most of which just call + return filemap_report_wb_error(file); Could we just have if (filp->f_op->flush) retval = filp->f_op->flush(filp, id); + else + retval = filemap_report_wb_error(filp); in flip_close() ?? ... or maybe it is wrong to return this error on close(). After all, the file actually does get closed, so no error occurred. If an application cares about EIO, it should always call fsync() before close(). Thanks, NeilBrown > > Jeff Layton (4): > fs: new infrastructure for writeback error handling and reporting > dax: set errors in mapping when writeback fails > buffer: set wb errors using both new and old infrastructure for now > ext4: wire it up to the new writeback error reporting infrastructure > > Documentation/filesystems/vfs.txt | 14 +++-- > fs/buffer.c | 6 +++- > fs/dax.c | 4 ++- > fs/ext4/dir.c | 1 + > fs/ext4/ext4.h| 1 + > fs/ext4/file.c| 1 + > fs/ext4/fsync.c | 15 +++--- > fs/ext4/inode.c | 2 +- > fs/ext4/page-io.c | 4 +-- > fs/open.c | 3 ++ > include/linux/fs.h| 5 > mm/filemap.c | 61 > +++ > 12 files changed, 106 insertions(+), 11 deletions(-) > > -- > 2.9.3 signature.asc Description: PGP signature
Re: [RFCv2] arm64: support HAVE_ARCH_RARE_WRITE and HAVE_ARCH_RARE_WRITE_MEMCPY
> On 31 Mar 2017, at 6:25 PM, Ard Biesheuvelwrote: > > On 30 March 2017 at 15:39, Hoeun Ryu wrote: >> This patch might be a part of Kees Cook's rare_write infrastructure series >> for [1] for arm64 architecture. >> >> This implementation is based on Mark Rutland's suggestions [2], which is >> that a special userspace mm that maps only __start/end_rodata as RW permi- >> ssion is prepared during early boot time (paging_init) and __arch_rare_- >> write_begin() switches to the mm [2]. >> >> rare_write_mm address space is added for the special purpose and a page >> global directory is also prepared for it. The mm remaps __start_rodata ~ >> __end_rodata to rodata_rw_alias_start which starts from TASK_SIZE_64 / 4 >> + kaslr_offset(). >> >> It passes LKDTM's rare write test. >> >> [1] : http://www.openwall.com/lists/kernel-hardening/2017/02/27/5 >> [2] : https://lkml.org/lkml/2017/3/29/704 >> >> Signed-off-by: Hoeun Ryu >> --- >> arch/arm64/Kconfig | 2 + >> arch/arm64/include/asm/pgtable.h | 4 ++ >> arch/arm64/mm/mmu.c | 101 >> +++ >> 3 files changed, 107 insertions(+) >> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >> index f2b0b52..6e2c592 100644 >> --- a/arch/arm64/Kconfig >> +++ b/arch/arm64/Kconfig >> @@ -102,6 +102,8 @@ config ARM64 >>select HAVE_SYSCALL_TRACEPOINTS >>select HAVE_KPROBES >>select HAVE_KRETPROBES >> + select HAVE_ARCH_RARE_WRITE >> + select HAVE_ARCH_RARE_WRITE_MEMCPY >>select IOMMU_DMA if IOMMU_SUPPORT >>select IRQ_DOMAIN >>select IRQ_FORCED_THREADING >> diff --git a/arch/arm64/include/asm/pgtable.h >> b/arch/arm64/include/asm/pgtable.h >> index c213fdbd0..1514933 100644 >> --- a/arch/arm64/include/asm/pgtable.h >> +++ b/arch/arm64/include/asm/pgtable.h >> @@ -741,6 +741,10 @@ static inline void update_mmu_cache(struct >> vm_area_struct *vma, >> #define kc_vaddr_to_offset(v) ((v) & ~VA_START) >> #define kc_offset_to_vaddr(o) ((o) | VA_START) >> >> +unsigned long __arch_rare_write_begin(void); >> +unsigned long __arch_rare_write_end(void); >> +void __arch_rare_write_memcpy(void *dst, const void *src, __kernel_size_t >> len); >> + > > If these hook into a generic framework, shouldn't these already be > declared in a generic header file? the generic header file doesn't declare arch-specific version of api. > >> #endif /* !__ASSEMBLY__ */ >> >> #endif /* __ASM_PGTABLE_H */ >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c >> index 91502e3..86b25c9 100644 >> --- a/arch/arm64/mm/mmu.c >> +++ b/arch/arm64/mm/mmu.c >> @@ -570,6 +570,105 @@ static void __init map_kernel(pgd_t *pgd) >>kasan_copy_shadow(pgd); >> } >> >> +struct mm_struct rare_write_mm = { > > static please OK, add static. > >> + .mm_rb = RB_ROOT, >> + .mm_users = ATOMIC_INIT(2), >> + .mm_count = ATOMIC_INIT(1), >> + .mmap_sem = __RWSEM_INITIALIZER(rare_write_mm.mmap_sem), >> + .page_table_lock= >> __SPIN_LOCK_UNLOCKED(rare_write_mm.page_table_lock), >> + .mmlist = LIST_HEAD_INIT(rare_write_mm.mmlist), >> +}; >> + >> +#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS >> +#include >> + >> +static struct ptdump_info rare_write_ptdump_info = { >> + .mm = _write_mm, >> + .markers= (struct addr_marker[]){ >> + { 0,"rare-write start" }, >> + { TASK_SIZE_64, "rare-write end" } >> + }, >> + .base_addr = 0, >> +}; >> + >> +static int __init ptdump_init(void) >> +{ >> + return ptdump_debugfs_register(_write_ptdump_info, >> + "rare_write_page_tables"); >> +} >> +device_initcall(ptdump_init); >> + >> +#endif >> + >> +__always_inline unsigned long __arch_rare_write_begin(void) > > These functions are not called from the same compilation unit, so what > do you think __always_inline buys you here? The first patch of Kee's series ([PATCH 01/11] Introduce rare_write() infrastructure) [1] says some requirements and one of these is the arch-specific helpers should be inline to avoid making them ROP targets. So I'd make sure the helpers are inline. [1] : http://www.openwall.com/lists/kernel-hardening/2017/03/29/16 > >> +{ >> + struct mm_struct *mm = _write_mm; >> + >> + preempt_disable(); >> + >> + __switch_mm(mm); >> + >> + if (system_uses_ttbr0_pan()) { >> + update_saved_ttbr0(current, mm); >> + cpu_switch_mm(mm->pgd, mm); >> + } >> + >> + return 0; >> +} >> + >> +__always_inline unsigned long __arch_rare_write_end(void) >> +{ >> + struct mm_struct *mm = current->active_mm; >> + >> + __switch_mm(mm); >> + >> + if (system_uses_ttbr0_pan()) { >> + cpu_set_reserved_ttbr0(); >> + if (mm != _mm) >> +
Re: [RFCv2] arm64: support HAVE_ARCH_RARE_WRITE and HAVE_ARCH_RARE_WRITE_MEMCPY
> On 31 Mar 2017, at 6:25 PM, Ard Biesheuvel wrote: > > On 30 March 2017 at 15:39, Hoeun Ryu wrote: >> This patch might be a part of Kees Cook's rare_write infrastructure series >> for [1] for arm64 architecture. >> >> This implementation is based on Mark Rutland's suggestions [2], which is >> that a special userspace mm that maps only __start/end_rodata as RW permi- >> ssion is prepared during early boot time (paging_init) and __arch_rare_- >> write_begin() switches to the mm [2]. >> >> rare_write_mm address space is added for the special purpose and a page >> global directory is also prepared for it. The mm remaps __start_rodata ~ >> __end_rodata to rodata_rw_alias_start which starts from TASK_SIZE_64 / 4 >> + kaslr_offset(). >> >> It passes LKDTM's rare write test. >> >> [1] : http://www.openwall.com/lists/kernel-hardening/2017/02/27/5 >> [2] : https://lkml.org/lkml/2017/3/29/704 >> >> Signed-off-by: Hoeun Ryu >> --- >> arch/arm64/Kconfig | 2 + >> arch/arm64/include/asm/pgtable.h | 4 ++ >> arch/arm64/mm/mmu.c | 101 >> +++ >> 3 files changed, 107 insertions(+) >> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >> index f2b0b52..6e2c592 100644 >> --- a/arch/arm64/Kconfig >> +++ b/arch/arm64/Kconfig >> @@ -102,6 +102,8 @@ config ARM64 >>select HAVE_SYSCALL_TRACEPOINTS >>select HAVE_KPROBES >>select HAVE_KRETPROBES >> + select HAVE_ARCH_RARE_WRITE >> + select HAVE_ARCH_RARE_WRITE_MEMCPY >>select IOMMU_DMA if IOMMU_SUPPORT >>select IRQ_DOMAIN >>select IRQ_FORCED_THREADING >> diff --git a/arch/arm64/include/asm/pgtable.h >> b/arch/arm64/include/asm/pgtable.h >> index c213fdbd0..1514933 100644 >> --- a/arch/arm64/include/asm/pgtable.h >> +++ b/arch/arm64/include/asm/pgtable.h >> @@ -741,6 +741,10 @@ static inline void update_mmu_cache(struct >> vm_area_struct *vma, >> #define kc_vaddr_to_offset(v) ((v) & ~VA_START) >> #define kc_offset_to_vaddr(o) ((o) | VA_START) >> >> +unsigned long __arch_rare_write_begin(void); >> +unsigned long __arch_rare_write_end(void); >> +void __arch_rare_write_memcpy(void *dst, const void *src, __kernel_size_t >> len); >> + > > If these hook into a generic framework, shouldn't these already be > declared in a generic header file? the generic header file doesn't declare arch-specific version of api. > >> #endif /* !__ASSEMBLY__ */ >> >> #endif /* __ASM_PGTABLE_H */ >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c >> index 91502e3..86b25c9 100644 >> --- a/arch/arm64/mm/mmu.c >> +++ b/arch/arm64/mm/mmu.c >> @@ -570,6 +570,105 @@ static void __init map_kernel(pgd_t *pgd) >>kasan_copy_shadow(pgd); >> } >> >> +struct mm_struct rare_write_mm = { > > static please OK, add static. > >> + .mm_rb = RB_ROOT, >> + .mm_users = ATOMIC_INIT(2), >> + .mm_count = ATOMIC_INIT(1), >> + .mmap_sem = __RWSEM_INITIALIZER(rare_write_mm.mmap_sem), >> + .page_table_lock= >> __SPIN_LOCK_UNLOCKED(rare_write_mm.page_table_lock), >> + .mmlist = LIST_HEAD_INIT(rare_write_mm.mmlist), >> +}; >> + >> +#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS >> +#include >> + >> +static struct ptdump_info rare_write_ptdump_info = { >> + .mm = _write_mm, >> + .markers= (struct addr_marker[]){ >> + { 0,"rare-write start" }, >> + { TASK_SIZE_64, "rare-write end" } >> + }, >> + .base_addr = 0, >> +}; >> + >> +static int __init ptdump_init(void) >> +{ >> + return ptdump_debugfs_register(_write_ptdump_info, >> + "rare_write_page_tables"); >> +} >> +device_initcall(ptdump_init); >> + >> +#endif >> + >> +__always_inline unsigned long __arch_rare_write_begin(void) > > These functions are not called from the same compilation unit, so what > do you think __always_inline buys you here? The first patch of Kee's series ([PATCH 01/11] Introduce rare_write() infrastructure) [1] says some requirements and one of these is the arch-specific helpers should be inline to avoid making them ROP targets. So I'd make sure the helpers are inline. [1] : http://www.openwall.com/lists/kernel-hardening/2017/03/29/16 > >> +{ >> + struct mm_struct *mm = _write_mm; >> + >> + preempt_disable(); >> + >> + __switch_mm(mm); >> + >> + if (system_uses_ttbr0_pan()) { >> + update_saved_ttbr0(current, mm); >> + cpu_switch_mm(mm->pgd, mm); >> + } >> + >> + return 0; >> +} >> + >> +__always_inline unsigned long __arch_rare_write_end(void) >> +{ >> + struct mm_struct *mm = current->active_mm; >> + >> + __switch_mm(mm); >> + >> + if (system_uses_ttbr0_pan()) { >> + cpu_set_reserved_ttbr0(); >> + if (mm != _mm) >> + update_saved_ttbr0(current, mm); >> + } >> + >>
Re: [PATCH] staging: rtl8712: fixed multiple line derefence issue
On Thu, Mar 30, 2017 at 12:03 AM, Prasant Jalanwrote: > Checkpatch emits WARNING: Avoid multiple line dereference. > > Trivial indentation improvement helps fix the checkpatch warning. > > Signed-off-by: Prasant Jalan > --- > drivers/staging/rtl8712/rtl871x_xmit.c | 12 ++-- > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c > b/drivers/staging/rtl8712/rtl871x_xmit.c > index de88819..10edf00 100644 > --- a/drivers/staging/rtl8712/rtl871x_xmit.c > +++ b/drivers/staging/rtl8712/rtl871x_xmit.c > @@ -213,8 +213,9 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt > *pkt, > if (padapter->pwrctrlpriv.pwr_mode != > padapter->registrypriv.power_mgnt) { > del_timer_sync(>dhcp_timer); > - r8712_set_ps_mode(padapter, padapter->registrypriv. > - power_mgnt, padapter->registrypriv.smart_ps); > + r8712_set_ps_mode(padapter, > + padapter->registrypriv.power_mgnt, > + padapter->registrypriv.smart_ps); > } > } > } > @@ -416,15 +417,14 @@ static sint xmitframe_addmic(struct _adapter *padapter, >[10], 6); > } > if (pqospriv->qos_option == 1) > - priority[0] = (u8)pxmitframe-> > - attrib.priority; > + priority[0] = (u8)pxmitframe->attrib.priority; > r8712_secmicappend(, [0], 4); > payload = pframe; > for (curfragnum = 0; curfragnum < pattrib->nr_frags; > curfragnum++) { > payload = (u8 *)RND4((addr_t)(payload)); > - payload = payload + pattrib-> > - hdrlen + pattrib->iv_len; > + payload = payload + pattrib->hdrlen + > + pattrib->iv_len; > if ((curfragnum + 1) == pattrib->nr_frags) { > length = pattrib->last_txcmdsz - > pattrib->hdrlen - > -- > 2.7.4 > Hi all, A gentle reminder for my small patch. Some comments will be most helpful. Regards, Prasant Jalan
Re: [PATCH] staging: rtl8712: fixed multiple line derefence issue
On Thu, Mar 30, 2017 at 12:03 AM, Prasant Jalan wrote: > Checkpatch emits WARNING: Avoid multiple line dereference. > > Trivial indentation improvement helps fix the checkpatch warning. > > Signed-off-by: Prasant Jalan > --- > drivers/staging/rtl8712/rtl871x_xmit.c | 12 ++-- > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c > b/drivers/staging/rtl8712/rtl871x_xmit.c > index de88819..10edf00 100644 > --- a/drivers/staging/rtl8712/rtl871x_xmit.c > +++ b/drivers/staging/rtl8712/rtl871x_xmit.c > @@ -213,8 +213,9 @@ sint r8712_update_attrib(struct _adapter *padapter, _pkt > *pkt, > if (padapter->pwrctrlpriv.pwr_mode != > padapter->registrypriv.power_mgnt) { > del_timer_sync(>dhcp_timer); > - r8712_set_ps_mode(padapter, padapter->registrypriv. > - power_mgnt, padapter->registrypriv.smart_ps); > + r8712_set_ps_mode(padapter, > + padapter->registrypriv.power_mgnt, > + padapter->registrypriv.smart_ps); > } > } > } > @@ -416,15 +417,14 @@ static sint xmitframe_addmic(struct _adapter *padapter, >[10], 6); > } > if (pqospriv->qos_option == 1) > - priority[0] = (u8)pxmitframe-> > - attrib.priority; > + priority[0] = (u8)pxmitframe->attrib.priority; > r8712_secmicappend(, [0], 4); > payload = pframe; > for (curfragnum = 0; curfragnum < pattrib->nr_frags; > curfragnum++) { > payload = (u8 *)RND4((addr_t)(payload)); > - payload = payload + pattrib-> > - hdrlen + pattrib->iv_len; > + payload = payload + pattrib->hdrlen + > + pattrib->iv_len; > if ((curfragnum + 1) == pattrib->nr_frags) { > length = pattrib->last_txcmdsz - > pattrib->hdrlen - > -- > 2.7.4 > Hi all, A gentle reminder for my small patch. Some comments will be most helpful. Regards, Prasant Jalan
arch/x86/kernel/ftrace.c:35:3: error: #error The following combination is not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER &&
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: a71c9a1c779f2499fb2afc0553e543f18aff6edf commit: 3f135e57a4f76d24ae8d8a490314331f0ced40c5 x86/build: Mostly disable '-maccumulate-outgoing-args' date: 4 days ago config: x86_64-randconfig-a0-04031038 (attached as .config) compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 reproduce: git checkout 3f135e57a4f76d24ae8d8a490314331f0ced40c5 # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): >> arch/x86/kernel/ftrace.c:35:3: error: #error The following combination is >> not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and >> !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER && >> CONFIG_CC_OPTIMIZE_FOR_SIZE vim +35 arch/x86/kernel/ftrace.c 29 #include 30 #include 31 32 #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && \ 33 !defined(CC_USING_FENTRY) && \ 34 !defined(CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE) > 35 # error The following combination is not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER && CONFIG_CC_OPTIMIZE_FOR_SIZE 36 #endif 37 38 #ifdef CONFIG_DYNAMIC_FTRACE --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
arch/x86/kernel/ftrace.c:35:3: error: #error The following combination is not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER &&
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: a71c9a1c779f2499fb2afc0553e543f18aff6edf commit: 3f135e57a4f76d24ae8d8a490314331f0ced40c5 x86/build: Mostly disable '-maccumulate-outgoing-args' date: 4 days ago config: x86_64-randconfig-a0-04031038 (attached as .config) compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 reproduce: git checkout 3f135e57a4f76d24ae8d8a490314331f0ced40c5 # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): >> arch/x86/kernel/ftrace.c:35:3: error: #error The following combination is >> not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and >> !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER && >> CONFIG_CC_OPTIMIZE_FOR_SIZE vim +35 arch/x86/kernel/ftrace.c 29 #include 30 #include 31 32 #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && \ 33 !defined(CC_USING_FENTRY) && \ 34 !defined(CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE) > 35 # error The following combination is not supported: ((compiler missing -mfentry) || (CONFIG_X86_32 and !CONFIG_DYNAMIC_FTRACE)) && CONFIG_FUNCTION_GRAPH_TRACER && CONFIG_CC_OPTIMIZE_FOR_SIZE 36 #endif 37 38 #ifdef CONFIG_DYNAMIC_FTRACE --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] mm: Add additional consistency check
Kees Cookwrites: > On Fri, Mar 31, 2017 at 2:33 PM, Andrew Morton > wrote: >> On Fri, 31 Mar 2017 09:40:28 -0700 Kees Cook wrote: >> >>> As found in PaX, this adds a cheap check on heap consistency, just to >>> notice if things have gotten corrupted in the page lookup. >> >> "As found in PaX" isn't a very illuminating justification for such a >> change. Was there a real kernel bug which this would have exposed, or >> what? > > I don't know off the top of my head, but given the kinds of heap > attacks I've been seeing, I think this added consistency check is > worth it given how inexpensive it is. When heap metadata gets > corrupted, we can get into nasty side-effects that can be > attacker-controlled, so better to catch obviously bad states as early > as possible. There's your changelog :) >>> --- a/mm/slab.h >>> +++ b/mm/slab.h >>> @@ -384,6 +384,7 @@ static inline struct kmem_cache *cache_from_obj(struct >>> kmem_cache *s, void *x) >>> return s; >>> >>> page = virt_to_head_page(x); >>> + BUG_ON(!PageSlab(page)); >>> cachep = page->slab_cache; >>> if (slab_equal_or_root(cachep, s)) >>> return cachep; >> >> BUG_ON might be too severe. I expect the kindest VM_WARN_ON_ONCE() >> would suffice here, but without more details it is hard to say. > > So, WARN isn't enough to protect the kernel (execution continues and > the memory is still dereferenced for malicious purposes, etc). You could do: if (WARN_ON(!PageSlab(page))) return NULL. Though I see at least two callers that don't check for a NULL return. Looking at the context, the tail of the function already contains: pr_err("%s: Wrong slab cache. %s but object is from %s\n", __func__, s->name, cachep->name); WARN_ON_ONCE(1); return s; } At least in slab.c it seems that would allow you to "free" an object from one kmem_cache onto the array_cache of another kmem_cache, which seems fishy. But maybe there's a check somewhere I'm missing? cheers
Re: [PATCH] mm: Add additional consistency check
Kees Cook writes: > On Fri, Mar 31, 2017 at 2:33 PM, Andrew Morton > wrote: >> On Fri, 31 Mar 2017 09:40:28 -0700 Kees Cook wrote: >> >>> As found in PaX, this adds a cheap check on heap consistency, just to >>> notice if things have gotten corrupted in the page lookup. >> >> "As found in PaX" isn't a very illuminating justification for such a >> change. Was there a real kernel bug which this would have exposed, or >> what? > > I don't know off the top of my head, but given the kinds of heap > attacks I've been seeing, I think this added consistency check is > worth it given how inexpensive it is. When heap metadata gets > corrupted, we can get into nasty side-effects that can be > attacker-controlled, so better to catch obviously bad states as early > as possible. There's your changelog :) >>> --- a/mm/slab.h >>> +++ b/mm/slab.h >>> @@ -384,6 +384,7 @@ static inline struct kmem_cache *cache_from_obj(struct >>> kmem_cache *s, void *x) >>> return s; >>> >>> page = virt_to_head_page(x); >>> + BUG_ON(!PageSlab(page)); >>> cachep = page->slab_cache; >>> if (slab_equal_or_root(cachep, s)) >>> return cachep; >> >> BUG_ON might be too severe. I expect the kindest VM_WARN_ON_ONCE() >> would suffice here, but without more details it is hard to say. > > So, WARN isn't enough to protect the kernel (execution continues and > the memory is still dereferenced for malicious purposes, etc). You could do: if (WARN_ON(!PageSlab(page))) return NULL. Though I see at least two callers that don't check for a NULL return. Looking at the context, the tail of the function already contains: pr_err("%s: Wrong slab cache. %s but object is from %s\n", __func__, s->name, cachep->name); WARN_ON_ONCE(1); return s; } At least in slab.c it seems that would allow you to "free" an object from one kmem_cache onto the array_cache of another kmem_cache, which seems fishy. But maybe there's a check somewhere I'm missing? cheers
linux-next: build failure after merge of the drm-misc tree
Hi all, After merging the drm-misc tree, today's linux-next build (x86_64 allmodconfig) failed like this: drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c: In function 'vmw_sou_crtc_page_flip': drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c:327:8: error: too few arguments to function 'drm_atomic_helper_page_flip' ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); ^ In file included from drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c:31:0: include/drm/drm_atomic_helper.h:126:5: note: declared here int drm_atomic_helper_page_flip(struct drm_crtc *crtc, ^ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c: In function 'vmw_stdu_crtc_page_flip': drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:508:8: error: too few arguments to function 'drm_atomic_helper_page_flip' ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); ^ In file included from drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:32:0: include/drm/drm_atomic_helper.h:126:5: note: declared here int drm_atomic_helper_page_flip(struct drm_crtc *crtc, ^ Caused by commit 41292b1fa13a ("drm: Add acquire ctx parameter to ->page_flip(_target)") interacting with commits 904bb5e5817f ("drm/vmwgfx: Switch over to internal atomic API for STDU") b0119cb9229d ("drm/vmwgfx: Switch over to internal atomic API for SOU and LDU") from the drm tree. I added this merge fix patch for today: From: Stephen RothwellDate: Mon, 3 Apr 2017 13:25:55 +1000 Subject: [PATCH] drm/vmwgfx: merge fixup for page_flip API change Signed-off-by: Stephen Rothwell --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 02b8f2541dca..8d7dc9def7c2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -324,7 +324,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, return -EINVAL; flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; - ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); + ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx); if (ret) { DRM_ERROR("Page flip error %d.\n", ret); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index e59bbcd8b226..bad31bdf09b6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -505,7 +505,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, * don't hand it to the helper. */ flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; - ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); + ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx); if (ret) { DRM_ERROR("Page flip error %d.\n", ret); return ret; -- 2.11.0 -- Cheers, Stephen Rothwell
linux-next: build failure after merge of the drm-misc tree
Hi all, After merging the drm-misc tree, today's linux-next build (x86_64 allmodconfig) failed like this: drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c: In function 'vmw_sou_crtc_page_flip': drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c:327:8: error: too few arguments to function 'drm_atomic_helper_page_flip' ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); ^ In file included from drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c:31:0: include/drm/drm_atomic_helper.h:126:5: note: declared here int drm_atomic_helper_page_flip(struct drm_crtc *crtc, ^ drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c: In function 'vmw_stdu_crtc_page_flip': drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:508:8: error: too few arguments to function 'drm_atomic_helper_page_flip' ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); ^ In file included from drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c:32:0: include/drm/drm_atomic_helper.h:126:5: note: declared here int drm_atomic_helper_page_flip(struct drm_crtc *crtc, ^ Caused by commit 41292b1fa13a ("drm: Add acquire ctx parameter to ->page_flip(_target)") interacting with commits 904bb5e5817f ("drm/vmwgfx: Switch over to internal atomic API for STDU") b0119cb9229d ("drm/vmwgfx: Switch over to internal atomic API for SOU and LDU") from the drm tree. I added this merge fix patch for today: From: Stephen Rothwell Date: Mon, 3 Apr 2017 13:25:55 +1000 Subject: [PATCH] drm/vmwgfx: merge fixup for page_flip API change Signed-off-by: Stephen Rothwell --- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 02b8f2541dca..8d7dc9def7c2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -324,7 +324,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc, return -EINVAL; flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; - ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); + ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx); if (ret) { DRM_ERROR("Page flip error %d.\n", ret); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index e59bbcd8b226..bad31bdf09b6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -505,7 +505,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, * don't hand it to the helper. */ flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; - ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); + ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx); if (ret) { DRM_ERROR("Page flip error %d.\n", ret); return ret; -- 2.11.0 -- Cheers, Stephen Rothwell
Re: [PATCH v6 0/4] phy: USB and PCIe phy drivers for Qcom chipsets
On 03/20/2017 07:24 PM, Vivek Gautam wrote: This patch series adds couple of PHY drivers for Qualcomm chipsets. a) qcom-qusb2 phy driver: that provides High Speed USB functionality. b) qcom-qmp phy driver: that is a combo phy providing support for USB3, PCIe, UFS and few other controllers. The patches are based on next branch of linux-phy tree, and depends on phy driver grouping series[1]: [PATCH v4 0/3] phy: Group phy drivers based on vendor listing. These patches have been tested on Dragon board db820c hardware with required set of dt patches and the patches to get rpm up on msm8996. Couple of other patches [2, 3] fixing DMA config for XHCI are also pulled in for testing. The complete branch is available in github [4]. Changes since v5: - Addressed review comments from Bjorn: - Removed instances of readl/wirtel_relaxed calls from the drivers. Instead, using simple readl/writel. Inserting a readl after a writel to ensure the write is through to the device. - Replaced regulator handling with regulator_bulk_** apis. This helps in cutting down a lot of regulator handling code. - Fixed minor return statements. Changes since v4: - Addressed comment to add child nodes for qmp phy driver. Each phy lane now has a separate child node under the main qmp node. - Modified the clock and reset initialization and enable methods. Different phys - pcie, usb and later ufs, have varying number of clocks and resets that are mandatory. So adding provision for clocks and reset lists helps in requesting all mandatory resources for individual phys and handle their failure cases accordingly. Changes since v3: - Addressed review comments given by Rob and Stephen for qusb2 phy and qmp phy bindings respectively. - Addressed review comments given by Stephen and Bjorn for qmp phy driver. Changes since v2: - Addressed review comments given by Rob and Stephen for bindings. - Addressed the review comments given by Stephen for the qusb2 and qmp phy drivers. Changes since v1: - Moved device tree binding documentation to separate patches, as suggested by Rob. - Addressed review comment regarding qfprom accesses by qusb2 phy driver, given by Rob. - Addressed review comments from Kishon. - Addressed review comments from Srinivas for QMP phy driver. - Addressed kbuild warning. Please see individual patches for detailed changelogs. [1] https://www.spinics.net/lists/arm-kernel/msg569990.html [2] https://patchwork.kernel.org/patch/9567767/ [3] https://patchwork.kernel.org/patch/9567779/ [4] https://github.com/vivekgautam1/linux/tree/linux-phy-next-qcom-phy-db820c Vivek Gautam (4): dt-bindings: phy: Add support for QUSB2 phy phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips dt-bindings: phy: Add support for QMP phy phy: qcom-qmp: new qmp phy driver for qcom-chipsets Gentle ping! Any more comments on this series, or are we planning to get this in for 4.12 ? Regards Vivek .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++ .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 45 + drivers/phy/qualcomm/Kconfig | 18 + drivers/phy/qualcomm/Makefile |2 + drivers/phy/qualcomm/phy-qcom-qmp.c| 1153 drivers/phy/qualcomm/phy-qcom-qusb2.c | 491 + 6 files changed, 1815 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.c create mode 100644 drivers/phy/qualcomm/phy-qcom-qusb2.c -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v6 0/4] phy: USB and PCIe phy drivers for Qcom chipsets
On 03/20/2017 07:24 PM, Vivek Gautam wrote: This patch series adds couple of PHY drivers for Qualcomm chipsets. a) qcom-qusb2 phy driver: that provides High Speed USB functionality. b) qcom-qmp phy driver: that is a combo phy providing support for USB3, PCIe, UFS and few other controllers. The patches are based on next branch of linux-phy tree, and depends on phy driver grouping series[1]: [PATCH v4 0/3] phy: Group phy drivers based on vendor listing. These patches have been tested on Dragon board db820c hardware with required set of dt patches and the patches to get rpm up on msm8996. Couple of other patches [2, 3] fixing DMA config for XHCI are also pulled in for testing. The complete branch is available in github [4]. Changes since v5: - Addressed review comments from Bjorn: - Removed instances of readl/wirtel_relaxed calls from the drivers. Instead, using simple readl/writel. Inserting a readl after a writel to ensure the write is through to the device. - Replaced regulator handling with regulator_bulk_** apis. This helps in cutting down a lot of regulator handling code. - Fixed minor return statements. Changes since v4: - Addressed comment to add child nodes for qmp phy driver. Each phy lane now has a separate child node under the main qmp node. - Modified the clock and reset initialization and enable methods. Different phys - pcie, usb and later ufs, have varying number of clocks and resets that are mandatory. So adding provision for clocks and reset lists helps in requesting all mandatory resources for individual phys and handle their failure cases accordingly. Changes since v3: - Addressed review comments given by Rob and Stephen for qusb2 phy and qmp phy bindings respectively. - Addressed review comments given by Stephen and Bjorn for qmp phy driver. Changes since v2: - Addressed review comments given by Rob and Stephen for bindings. - Addressed the review comments given by Stephen for the qusb2 and qmp phy drivers. Changes since v1: - Moved device tree binding documentation to separate patches, as suggested by Rob. - Addressed review comment regarding qfprom accesses by qusb2 phy driver, given by Rob. - Addressed review comments from Kishon. - Addressed review comments from Srinivas for QMP phy driver. - Addressed kbuild warning. Please see individual patches for detailed changelogs. [1] https://www.spinics.net/lists/arm-kernel/msg569990.html [2] https://patchwork.kernel.org/patch/9567767/ [3] https://patchwork.kernel.org/patch/9567779/ [4] https://github.com/vivekgautam1/linux/tree/linux-phy-next-qcom-phy-db820c Vivek Gautam (4): dt-bindings: phy: Add support for QUSB2 phy phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips dt-bindings: phy: Add support for QMP phy phy: qcom-qmp: new qmp phy driver for qcom-chipsets Gentle ping! Any more comments on this series, or are we planning to get this in for 4.12 ? Regards Vivek .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++ .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 45 + drivers/phy/qualcomm/Kconfig | 18 + drivers/phy/qualcomm/Makefile |2 + drivers/phy/qualcomm/phy-qcom-qmp.c| 1153 drivers/phy/qualcomm/phy-qcom-qusb2.c | 491 + 6 files changed, 1815 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp.c create mode 100644 drivers/phy/qualcomm/phy-qcom-qusb2.c -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [RFCv2] arm64: support HAVE_ARCH_RARE_WRITE and HAVE_ARCH_RARE_WRITE_MEMCPY
> On Mar 31, 2017, at 4:38 AM, Kees Cookwrote: > >> On Thu, Mar 30, 2017 at 7:39 AM, Hoeun Ryu wrote: >> This patch might be a part of Kees Cook's rare_write infrastructure series >> for [1] for arm64 architecture. >> >> This implementation is based on Mark Rutland's suggestions [2], which is >> that a special userspace mm that maps only __start/end_rodata as RW permi- >> ssion is prepared during early boot time (paging_init) and __arch_rare_- >> write_begin() switches to the mm [2]. >> >> rare_write_mm address space is added for the special purpose and a page >> global directory is also prepared for it. The mm remaps __start_rodata ~ >> __end_rodata to rodata_rw_alias_start which starts from TASK_SIZE_64 / 4 >> + kaslr_offset(). >> >> It passes LKDTM's rare write test. > > Great work! I think this will need some further changes, though, since > it doesn't look to me like this would pass LKDTM's tests if it was > built as a module. (This is missing from my ARM attempt too... I > haven't figured out how to set the domain on the kernel modules...) > ah.. I understand.. so we need to additional rw mappings for modules, right ? >> >> [1] : http://www.openwall.com/lists/kernel-hardening/2017/02/27/5 >> [2] : https://lkml.org/lkml/2017/3/29/704 >> >> Signed-off-by: Hoeun Ryu >> --- >> arch/arm64/Kconfig | 2 + >> arch/arm64/include/asm/pgtable.h | 4 ++ >> arch/arm64/mm/mmu.c | 101 >> +++ >> 3 files changed, 107 insertions(+) >> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >> index f2b0b52..6e2c592 100644 >> --- a/arch/arm64/Kconfig >> +++ b/arch/arm64/Kconfig >> @@ -102,6 +102,8 @@ config ARM64 >>select HAVE_SYSCALL_TRACEPOINTS >>select HAVE_KPROBES >>select HAVE_KRETPROBES >> + select HAVE_ARCH_RARE_WRITE >> + select HAVE_ARCH_RARE_WRITE_MEMCPY >>select IOMMU_DMA if IOMMU_SUPPORT >>select IRQ_DOMAIN >>select IRQ_FORCED_THREADING >> diff --git a/arch/arm64/include/asm/pgtable.h >> b/arch/arm64/include/asm/pgtable.h >> index c213fdbd0..1514933 100644 >> --- a/arch/arm64/include/asm/pgtable.h >> +++ b/arch/arm64/include/asm/pgtable.h >> @@ -741,6 +741,10 @@ static inline void update_mmu_cache(struct >> vm_area_struct *vma, >> #define kc_vaddr_to_offset(v) ((v) & ~VA_START) >> #define kc_offset_to_vaddr(o) ((o) | VA_START) >> >> +unsigned long __arch_rare_write_begin(void); >> +unsigned long __arch_rare_write_end(void); >> +void __arch_rare_write_memcpy(void *dst, const void *src, __kernel_size_t >> len); >> + >> #endif /* !__ASSEMBLY__ */ >> >> #endif /* __ASM_PGTABLE_H */ >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c >> index 91502e3..86b25c9 100644 >> --- a/arch/arm64/mm/mmu.c >> +++ b/arch/arm64/mm/mmu.c >> @@ -570,6 +570,105 @@ static void __init map_kernel(pgd_t *pgd) >>kasan_copy_shadow(pgd); >> } >> >> +struct mm_struct rare_write_mm = { >> + .mm_rb = RB_ROOT, >> + .mm_users = ATOMIC_INIT(2), >> + .mm_count = ATOMIC_INIT(1), >> + .mmap_sem = __RWSEM_INITIALIZER(rare_write_mm.mmap_sem), >> + .page_table_lock= >> __SPIN_LOCK_UNLOCKED(rare_write_mm.page_table_lock), >> + .mmlist = LIST_HEAD_INIT(rare_write_mm.mmlist), >> +}; >> + >> +#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS >> +#include >> + >> +static struct ptdump_info rare_write_ptdump_info = { >> + .mm = _write_mm, >> + .markers= (struct addr_marker[]){ >> + { 0,"rare-write start" }, >> + { TASK_SIZE_64, "rare-write end" } >> + }, >> + .base_addr = 0, >> +}; >> + >> +static int __init ptdump_init(void) >> +{ >> + return ptdump_debugfs_register(_write_ptdump_info, >> + "rare_write_page_tables"); >> +} >> +device_initcall(ptdump_init); >> + >> +#endif >> + >> +__always_inline unsigned long __arch_rare_write_begin(void) >> +{ >> + struct mm_struct *mm = _write_mm; >> + >> + preempt_disable(); >> + >> + __switch_mm(mm); > > Can you include a BUG_ON check here that rare_write_mm is not already active? > OK, I will find the way to do so. >> + >> + if (system_uses_ttbr0_pan()) { >> + update_saved_ttbr0(current, mm); >> + cpu_switch_mm(mm->pgd, mm); >> + } >> + >> + return 0; >> +} >> + >> +__always_inline unsigned long __arch_rare_write_end(void) >> +{ >> + struct mm_struct *mm = current->active_mm; >> + >> + __switch_mm(mm); > > And same here (though the reverse test)? > >> + >> + if (system_uses_ttbr0_pan()) { >> + cpu_set_reserved_ttbr0(); >> + if (mm != _mm) >> + update_saved_ttbr0(current, mm); >> + } >> + >> + preempt_enable_no_resched(); >> + >> + return 0; >> +}
Re: [RFCv2] arm64: support HAVE_ARCH_RARE_WRITE and HAVE_ARCH_RARE_WRITE_MEMCPY
> On Mar 31, 2017, at 4:38 AM, Kees Cook wrote: > >> On Thu, Mar 30, 2017 at 7:39 AM, Hoeun Ryu wrote: >> This patch might be a part of Kees Cook's rare_write infrastructure series >> for [1] for arm64 architecture. >> >> This implementation is based on Mark Rutland's suggestions [2], which is >> that a special userspace mm that maps only __start/end_rodata as RW permi- >> ssion is prepared during early boot time (paging_init) and __arch_rare_- >> write_begin() switches to the mm [2]. >> >> rare_write_mm address space is added for the special purpose and a page >> global directory is also prepared for it. The mm remaps __start_rodata ~ >> __end_rodata to rodata_rw_alias_start which starts from TASK_SIZE_64 / 4 >> + kaslr_offset(). >> >> It passes LKDTM's rare write test. > > Great work! I think this will need some further changes, though, since > it doesn't look to me like this would pass LKDTM's tests if it was > built as a module. (This is missing from my ARM attempt too... I > haven't figured out how to set the domain on the kernel modules...) > ah.. I understand.. so we need to additional rw mappings for modules, right ? >> >> [1] : http://www.openwall.com/lists/kernel-hardening/2017/02/27/5 >> [2] : https://lkml.org/lkml/2017/3/29/704 >> >> Signed-off-by: Hoeun Ryu >> --- >> arch/arm64/Kconfig | 2 + >> arch/arm64/include/asm/pgtable.h | 4 ++ >> arch/arm64/mm/mmu.c | 101 >> +++ >> 3 files changed, 107 insertions(+) >> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig >> index f2b0b52..6e2c592 100644 >> --- a/arch/arm64/Kconfig >> +++ b/arch/arm64/Kconfig >> @@ -102,6 +102,8 @@ config ARM64 >>select HAVE_SYSCALL_TRACEPOINTS >>select HAVE_KPROBES >>select HAVE_KRETPROBES >> + select HAVE_ARCH_RARE_WRITE >> + select HAVE_ARCH_RARE_WRITE_MEMCPY >>select IOMMU_DMA if IOMMU_SUPPORT >>select IRQ_DOMAIN >>select IRQ_FORCED_THREADING >> diff --git a/arch/arm64/include/asm/pgtable.h >> b/arch/arm64/include/asm/pgtable.h >> index c213fdbd0..1514933 100644 >> --- a/arch/arm64/include/asm/pgtable.h >> +++ b/arch/arm64/include/asm/pgtable.h >> @@ -741,6 +741,10 @@ static inline void update_mmu_cache(struct >> vm_area_struct *vma, >> #define kc_vaddr_to_offset(v) ((v) & ~VA_START) >> #define kc_offset_to_vaddr(o) ((o) | VA_START) >> >> +unsigned long __arch_rare_write_begin(void); >> +unsigned long __arch_rare_write_end(void); >> +void __arch_rare_write_memcpy(void *dst, const void *src, __kernel_size_t >> len); >> + >> #endif /* !__ASSEMBLY__ */ >> >> #endif /* __ASM_PGTABLE_H */ >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c >> index 91502e3..86b25c9 100644 >> --- a/arch/arm64/mm/mmu.c >> +++ b/arch/arm64/mm/mmu.c >> @@ -570,6 +570,105 @@ static void __init map_kernel(pgd_t *pgd) >>kasan_copy_shadow(pgd); >> } >> >> +struct mm_struct rare_write_mm = { >> + .mm_rb = RB_ROOT, >> + .mm_users = ATOMIC_INIT(2), >> + .mm_count = ATOMIC_INIT(1), >> + .mmap_sem = __RWSEM_INITIALIZER(rare_write_mm.mmap_sem), >> + .page_table_lock= >> __SPIN_LOCK_UNLOCKED(rare_write_mm.page_table_lock), >> + .mmlist = LIST_HEAD_INIT(rare_write_mm.mmlist), >> +}; >> + >> +#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS >> +#include >> + >> +static struct ptdump_info rare_write_ptdump_info = { >> + .mm = _write_mm, >> + .markers= (struct addr_marker[]){ >> + { 0,"rare-write start" }, >> + { TASK_SIZE_64, "rare-write end" } >> + }, >> + .base_addr = 0, >> +}; >> + >> +static int __init ptdump_init(void) >> +{ >> + return ptdump_debugfs_register(_write_ptdump_info, >> + "rare_write_page_tables"); >> +} >> +device_initcall(ptdump_init); >> + >> +#endif >> + >> +__always_inline unsigned long __arch_rare_write_begin(void) >> +{ >> + struct mm_struct *mm = _write_mm; >> + >> + preempt_disable(); >> + >> + __switch_mm(mm); > > Can you include a BUG_ON check here that rare_write_mm is not already active? > OK, I will find the way to do so. >> + >> + if (system_uses_ttbr0_pan()) { >> + update_saved_ttbr0(current, mm); >> + cpu_switch_mm(mm->pgd, mm); >> + } >> + >> + return 0; >> +} >> + >> +__always_inline unsigned long __arch_rare_write_end(void) >> +{ >> + struct mm_struct *mm = current->active_mm; >> + >> + __switch_mm(mm); > > And same here (though the reverse test)? > >> + >> + if (system_uses_ttbr0_pan()) { >> + cpu_set_reserved_ttbr0(); >> + if (mm != _mm) >> + update_saved_ttbr0(current, mm); >> + } >> + >> + preempt_enable_no_resched(); >> + >> + return 0; >> +} >> + >> +static unsigned long rodata_rw_alias_start
linux-next: manual merge of the drm-misc tree with the drm tree
Hi all, Today's linux-next merge of the drm-misc tree got conflicts in: drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c between commits: 904bb5e5817f ("drm/vmwgfx: Switch over to internal atomic API for STDU") b0119cb9229d ("drm/vmwgfx: Switch over to internal atomic API for SOU and LDU") from the drm tree and commit: a4eff9aa6db8 ("drm: Add acquire ctx parameter to ->set_config") from the drm-misc tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. From: Stephen RothwellDate: Mon, 3 Apr 2017 13:04:36 +1000 Subject: [PATCH] drm/vmwgfx: merge fixup for set_config API change Signed-off-by: Stephen Rothwell --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 -- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 5 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c18c81f63ac3..2517debf214d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2940,6 +2940,7 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, * vmw_kms_set_config - Wrapper around drm_atomic_helper_set_config * * @set: The configuration to set. + * @ctx: lock acquisition context * * The vmwgfx Xorg driver doesn't assign the mode::type member, which * when drm_mode_set_crtcinfo is called as part of the configuration setting @@ -2947,10 +2948,11 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, * the vmwgfx modesetting. So explicitly clear that member before calling * into drm_atomic_helper_set_config. */ -int vmw_kms_set_config(struct drm_mode_set *set) +int vmw_kms_set_config(struct drm_mode_set *set, + struct drm_modeset_acquire_ctx *ctx) { if (set && set->mode) set->mode->type = 0; - return drm_atomic_helper_set_config(set); + return drm_atomic_helper_set_config(set, ctx); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 9c161d29aaeb..ecafa9a7648e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -453,6 +453,9 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, bool to_surface, bool interruptible); -int vmw_kms_set_config(struct drm_mode_set *set); +struct drm_modeset_acquire_ctx; + +int vmw_kms_set_config(struct drm_mode_set *set, + struct drm_modeset_acquire_ctx *ctx); #endif -- 2.11.0 -- Cheers, Stephen Rothwell
linux-next: manual merge of the drm-misc tree with the drm tree
Hi all, Today's linux-next merge of the drm-misc tree got conflicts in: drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c between commits: 904bb5e5817f ("drm/vmwgfx: Switch over to internal atomic API for STDU") b0119cb9229d ("drm/vmwgfx: Switch over to internal atomic API for SOU and LDU") from the drm tree and commit: a4eff9aa6db8 ("drm: Add acquire ctx parameter to ->set_config") from the drm-misc tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. From: Stephen Rothwell Date: Mon, 3 Apr 2017 13:04:36 +1000 Subject: [PATCH] drm/vmwgfx: merge fixup for set_config API change Signed-off-by: Stephen Rothwell --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 -- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 5 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c18c81f63ac3..2517debf214d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2940,6 +2940,7 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, * vmw_kms_set_config - Wrapper around drm_atomic_helper_set_config * * @set: The configuration to set. + * @ctx: lock acquisition context * * The vmwgfx Xorg driver doesn't assign the mode::type member, which * when drm_mode_set_crtcinfo is called as part of the configuration setting @@ -2947,10 +2948,11 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, * the vmwgfx modesetting. So explicitly clear that member before calling * into drm_atomic_helper_set_config. */ -int vmw_kms_set_config(struct drm_mode_set *set) +int vmw_kms_set_config(struct drm_mode_set *set, + struct drm_modeset_acquire_ctx *ctx) { if (set && set->mode) set->mode->type = 0; - return drm_atomic_helper_set_config(set); + return drm_atomic_helper_set_config(set, ctx); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 9c161d29aaeb..ecafa9a7648e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -453,6 +453,9 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, bool to_surface, bool interruptible); -int vmw_kms_set_config(struct drm_mode_set *set); +struct drm_modeset_acquire_ctx; + +int vmw_kms_set_config(struct drm_mode_set *set, + struct drm_modeset_acquire_ctx *ctx); #endif -- 2.11.0 -- Cheers, Stephen Rothwell
Re: [PATCH v3 14/37] mtd: nand: denali: support "nand-ecc-strength" DT property
Hi Boris, 2017-03-31 18:46 GMT+09:00 Boris Brezillon: > You can try something like that when no explicit ecc.strength and > ecc.size has been set in the DT and when ECC_MAXIMIZE was not passed. > > static int > denali_get_closest_ecc_strength(struct denali_nand_info *denali, > int strength) > { > /* > * Whatever you need to select a strength that is greater than > * or equal to strength. > */ > > return X; > } Is here anything specific to Denali? > static int denali_try_to_match_ecc_req(struct denali_nand_info *denali) > { > struct nand_chip *chip = >nand; > struct mtd_info *mtd = nand_to_mtd(chip); > int max_ecc_bytes = mtd->oobsize - denali->bbtskipbytes; > int ecc_steps, ecc_strength, ecc_bytes; > int ecc_size = chip->ecc_step_ds; > int ecc_strength = chip->ecc_strength_ds; > > /* > * No information provided by the NAND chip, let the core > * maximize the strength. > */ > if (!ecc_size || !ecc_strength) > return -ENOTSUPP; > > if (ecc_size > 512) > ecc_size = 1024; > else > ecc_size = 512; > > /* Adjust ECC step size based on hardware support. */ > if (ecc_size == 1024 && > !(denali->caps & DENALI_CAP_ECC_SIZE_1024)) > ecc_size = 512; > else if(ecc_size == 512 && > !(denali->caps & DENALI_CAP_ECC_SIZE_512)) > ecc_size = 1024; > > if (ecc_size < chip->ecc_size_ds) { > /* > * When the selected size if smaller than the expected > * one we try to use the same strength but on 512 blocks > * so that we can still fix the same number of errors > * even if they are concentrated in the first 512bytes > * of a 1024bytes portion. > */ > ecc_strength = chip->ecc_strength_ds; > ecc_strength = denali_get_closest_ecc_strength(denali, >ecc_strength); > } else { > /* Always prefer 1024bytes ECC blocks when possible. */ > if (ecc_size != 1024 && > (denali->caps & DENALI_CAP_ECC_SIZE_1024) && > mtd->writesize > 1024) > ecc_size = 1024; > > /* > * Adjust the strength based on the selected ECC step > * size. > */ > ecc_strength = DIV_ROUND_UP(ecc_size, > chip->ecc_step_ds) * >chip->ecc_strength_ds; > } > > ecc_bytes = denali_calc_ecc_bytes(ecc_size, > ecc_strength); > ecc_bytes *= mtd->writesize / ecc_size; > > /* > * If we don't have enough space, let the core maximize > * the strength. > */ > if (ecc_bytes > max_ecc_bytes) > return -ENOTSUPP; > > chip->ecc.strength = ecc_strength; > chip->ecc.size = ecc_size; > > return 0; > } As a whole, this does not seem to driver-specific. [1] A driver provides some pairs of (ecc_strength, ecc_size) it can support. [2] The core framework knows the chip's requirement (ecc_strength_ds, ecc_size_ds). Then, the core framework provides a function to return a most recommended (ecc_strength, ecc_size). struct nand_ecc_spec { int ecc_strength; int ecc_size; }; /* * This function choose the most recommented (ecc_str, ecc_size) * "recommended" means: minimum ecc stregth that meets * the chip's requirment. * * * @chip - nand_chip * @controller_ecc_spec - Array of (ecc_str, ecc_size) supported by the controller. (terminated by NULL as sentinel) */ struct nand_ecc_spec * nand_try_to_match_ecc_req(struct nand_chip *chip, struct nand_ecc_spec *controller_ecc_spec) { /* * Return the pointer to the most recommended * struct nand_ecc_spec. * If nothing suitable found, return NULL. */ } Then, Denali driver can call it: recommended_ecc_spec = nand_try_to_match_ecc_req(chip, denali->ecc_spec); if (recommended_ecc_spec) { chip->ecc.strength = recommended_ecc_spec.ecc_strength; chip->ecc.size = recommended_ecc_spec.ecc_size; } else { /* * Do something (for example, maximize the ECC) */ } It seems weird to force this to the Denali driver. -- Best Regards Masahiro Yamada
Re: [PATCH v3 14/37] mtd: nand: denali: support "nand-ecc-strength" DT property
Hi Boris, 2017-03-31 18:46 GMT+09:00 Boris Brezillon : > You can try something like that when no explicit ecc.strength and > ecc.size has been set in the DT and when ECC_MAXIMIZE was not passed. > > static int > denali_get_closest_ecc_strength(struct denali_nand_info *denali, > int strength) > { > /* > * Whatever you need to select a strength that is greater than > * or equal to strength. > */ > > return X; > } Is here anything specific to Denali? > static int denali_try_to_match_ecc_req(struct denali_nand_info *denali) > { > struct nand_chip *chip = >nand; > struct mtd_info *mtd = nand_to_mtd(chip); > int max_ecc_bytes = mtd->oobsize - denali->bbtskipbytes; > int ecc_steps, ecc_strength, ecc_bytes; > int ecc_size = chip->ecc_step_ds; > int ecc_strength = chip->ecc_strength_ds; > > /* > * No information provided by the NAND chip, let the core > * maximize the strength. > */ > if (!ecc_size || !ecc_strength) > return -ENOTSUPP; > > if (ecc_size > 512) > ecc_size = 1024; > else > ecc_size = 512; > > /* Adjust ECC step size based on hardware support. */ > if (ecc_size == 1024 && > !(denali->caps & DENALI_CAP_ECC_SIZE_1024)) > ecc_size = 512; > else if(ecc_size == 512 && > !(denali->caps & DENALI_CAP_ECC_SIZE_512)) > ecc_size = 1024; > > if (ecc_size < chip->ecc_size_ds) { > /* > * When the selected size if smaller than the expected > * one we try to use the same strength but on 512 blocks > * so that we can still fix the same number of errors > * even if they are concentrated in the first 512bytes > * of a 1024bytes portion. > */ > ecc_strength = chip->ecc_strength_ds; > ecc_strength = denali_get_closest_ecc_strength(denali, >ecc_strength); > } else { > /* Always prefer 1024bytes ECC blocks when possible. */ > if (ecc_size != 1024 && > (denali->caps & DENALI_CAP_ECC_SIZE_1024) && > mtd->writesize > 1024) > ecc_size = 1024; > > /* > * Adjust the strength based on the selected ECC step > * size. > */ > ecc_strength = DIV_ROUND_UP(ecc_size, > chip->ecc_step_ds) * >chip->ecc_strength_ds; > } > > ecc_bytes = denali_calc_ecc_bytes(ecc_size, > ecc_strength); > ecc_bytes *= mtd->writesize / ecc_size; > > /* > * If we don't have enough space, let the core maximize > * the strength. > */ > if (ecc_bytes > max_ecc_bytes) > return -ENOTSUPP; > > chip->ecc.strength = ecc_strength; > chip->ecc.size = ecc_size; > > return 0; > } As a whole, this does not seem to driver-specific. [1] A driver provides some pairs of (ecc_strength, ecc_size) it can support. [2] The core framework knows the chip's requirement (ecc_strength_ds, ecc_size_ds). Then, the core framework provides a function to return a most recommended (ecc_strength, ecc_size). struct nand_ecc_spec { int ecc_strength; int ecc_size; }; /* * This function choose the most recommented (ecc_str, ecc_size) * "recommended" means: minimum ecc stregth that meets * the chip's requirment. * * * @chip - nand_chip * @controller_ecc_spec - Array of (ecc_str, ecc_size) supported by the controller. (terminated by NULL as sentinel) */ struct nand_ecc_spec * nand_try_to_match_ecc_req(struct nand_chip *chip, struct nand_ecc_spec *controller_ecc_spec) { /* * Return the pointer to the most recommended * struct nand_ecc_spec. * If nothing suitable found, return NULL. */ } Then, Denali driver can call it: recommended_ecc_spec = nand_try_to_match_ecc_req(chip, denali->ecc_spec); if (recommended_ecc_spec) { chip->ecc.strength = recommended_ecc_spec.ecc_strength; chip->ecc.size = recommended_ecc_spec.ecc_size; } else { /* * Do something (for example, maximize the ECC) */ } It seems weird to force this to the Denali driver. -- Best Regards Masahiro Yamada
Re: [PATCH] phy: bcm-ns-usb3: split all writes into reg & val pairs
On Sun, Apr 2, 2017 at 12:55 PM, Rafał Miłeckiwrote: > From: Rafał Miłecki > > So far all the PHY initialization was implemented using some totally > magic values. There was some pattern there but it wasn't clear what is > it about. > > Thanks to the patch submitted by Broadcom: > [PATCH 5/6] phy: Add USB3 PHY support for Broadcom NSP SoC > and the upstream "iproc-mdio" driver we now know there is a MDIO bus > underneath with PHY(s) and their registers. > > It allows us to clean the driver a bit by making all these values less > magical. The next step is switching to using a proper MDIO layer. > > Signed-off-by: Rafał Miłecki Looks much better to me! Acked-by: Jon Mason > --- > drivers/phy/phy-bcm-ns-usb3.c | 69 > ++- > 1 file changed, 49 insertions(+), 20 deletions(-) > > diff --git a/drivers/phy/phy-bcm-ns-usb3.c b/drivers/phy/phy-bcm-ns-usb3.c > index f420fa4bebfc..22b5e7047fa6 100644 > --- a/drivers/phy/phy-bcm-ns-usb3.c > +++ b/drivers/phy/phy-bcm-ns-usb3.c > @@ -2,6 +2,7 @@ > * Broadcom Northstar USB 3.0 PHY Driver > * > * Copyright (C) 2016 Rafał Miłecki > + * Copyright (C) 2016 Broadcom > * > * All magic values used for initialization (and related comments) were > obtained > * from Broadcom's SDK: > @@ -23,6 +24,23 @@ > > #define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000/* usecs */ > > +#define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f > +#define BCM_NS_USB3_PHY_PLL30_BLOCK0x8000 > +#define BCM_NS_USB3_PHY_TX_PMD_BLOCK 0x8040 > +#define BCM_NS_USB3_PHY_PIPE_BLOCK 0x8060 > + > +/* Registers of PLL30 block */ > +#define BCM_NS_USB3_PLL_CONTROL0x01 > +#define BCM_NS_USB3_PLLA_CONTROL0 0x0a > +#define BCM_NS_USB3_PLLA_CONTROL1 0x0b > + > +/* Registers of TX PMD block */ > +#define BCM_NS_USB3_TX_PMD_CONTROL10x01 > + > +/* Registers of PIPE block */ > +#define BCM_NS_USB3_LFPS_CMP 0x02 > +#define BCM_NS_USB3_LFPS_DEGLITCH 0x03 > + > enum bcm_ns_family { > BCM_NS_UNKNOWN, > BCM_NS_AX, > @@ -76,8 +94,10 @@ static inline int bcm_ns_usb3_mii_mng_wait_idle(struct > bcm_ns_usb3 *usb3) > > usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US)); > } > > -static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value) > +static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, > + u16 value) > { > + u32 tmp = 0; > int err; > > err = bcm_ns_usb3_mii_mng_wait_idle(usb3); > @@ -86,7 +106,11 @@ static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 > *usb3, u32 value) > return err; > } > > - writel(value, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); > + /* TODO: Use a proper MDIO bus layer */ > + tmp |= 0x5802; /* Magic value for MDIO PHY write */ > + tmp |= reg << 18; > + tmp |= value; > + writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); > > return 0; > } > @@ -102,21 +126,22 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct > bcm_ns_usb3 *usb3) > udelay(2); > > /* USB3 PLL Block */ > - err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); > + err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, > +BCM_NS_USB3_PHY_PLL30_BLOCK); > if (err < 0) > return err; > > /* Assert Ana_Pllseq start */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x58061000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x1000); > > /* Assert CML Divider ratio to 26 */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL0, 0x6400); > > /* Asserting PLL Reset */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582ec000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0xc000); > > /* Deaaserting PLL Reset */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582e8000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000); > > /* Waiting MII Mgt interface idle */ > bcm_ns_usb3_mii_mng_wait_idle(usb3); > @@ -125,22 +150,24 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct > bcm_ns_usb3 *usb3) > writel(0, usb3->dmp + BCMA_RESET_CTL); > > /* PLL frequency monitor enable */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x58069000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x9000); > > /* PIPE Block */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8060); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, > + BCM_NS_USB3_PHY_PIPE_BLOCK); > > /* CMPMAX & CMPMINTH setting */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x580af30d); > +
Re: [PATCH] phy: bcm-ns-usb3: split all writes into reg & val pairs
On Sun, Apr 2, 2017 at 12:55 PM, Rafał Miłecki wrote: > From: Rafał Miłecki > > So far all the PHY initialization was implemented using some totally > magic values. There was some pattern there but it wasn't clear what is > it about. > > Thanks to the patch submitted by Broadcom: > [PATCH 5/6] phy: Add USB3 PHY support for Broadcom NSP SoC > and the upstream "iproc-mdio" driver we now know there is a MDIO bus > underneath with PHY(s) and their registers. > > It allows us to clean the driver a bit by making all these values less > magical. The next step is switching to using a proper MDIO layer. > > Signed-off-by: Rafał Miłecki Looks much better to me! Acked-by: Jon Mason > --- > drivers/phy/phy-bcm-ns-usb3.c | 69 > ++- > 1 file changed, 49 insertions(+), 20 deletions(-) > > diff --git a/drivers/phy/phy-bcm-ns-usb3.c b/drivers/phy/phy-bcm-ns-usb3.c > index f420fa4bebfc..22b5e7047fa6 100644 > --- a/drivers/phy/phy-bcm-ns-usb3.c > +++ b/drivers/phy/phy-bcm-ns-usb3.c > @@ -2,6 +2,7 @@ > * Broadcom Northstar USB 3.0 PHY Driver > * > * Copyright (C) 2016 Rafał Miłecki > + * Copyright (C) 2016 Broadcom > * > * All magic values used for initialization (and related comments) were > obtained > * from Broadcom's SDK: > @@ -23,6 +24,23 @@ > > #define BCM_NS_USB3_MII_MNG_TIMEOUT_US 1000/* usecs */ > > +#define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f > +#define BCM_NS_USB3_PHY_PLL30_BLOCK0x8000 > +#define BCM_NS_USB3_PHY_TX_PMD_BLOCK 0x8040 > +#define BCM_NS_USB3_PHY_PIPE_BLOCK 0x8060 > + > +/* Registers of PLL30 block */ > +#define BCM_NS_USB3_PLL_CONTROL0x01 > +#define BCM_NS_USB3_PLLA_CONTROL0 0x0a > +#define BCM_NS_USB3_PLLA_CONTROL1 0x0b > + > +/* Registers of TX PMD block */ > +#define BCM_NS_USB3_TX_PMD_CONTROL10x01 > + > +/* Registers of PIPE block */ > +#define BCM_NS_USB3_LFPS_CMP 0x02 > +#define BCM_NS_USB3_LFPS_DEGLITCH 0x03 > + > enum bcm_ns_family { > BCM_NS_UNKNOWN, > BCM_NS_AX, > @@ -76,8 +94,10 @@ static inline int bcm_ns_usb3_mii_mng_wait_idle(struct > bcm_ns_usb3 *usb3) > > usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US)); > } > > -static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 *usb3, u32 value) > +static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg, > + u16 value) > { > + u32 tmp = 0; > int err; > > err = bcm_ns_usb3_mii_mng_wait_idle(usb3); > @@ -86,7 +106,11 @@ static int bcm_ns_usb3_mii_mng_write32(struct bcm_ns_usb3 > *usb3, u32 value) > return err; > } > > - writel(value, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); > + /* TODO: Use a proper MDIO bus layer */ > + tmp |= 0x5802; /* Magic value for MDIO PHY write */ > + tmp |= reg << 18; > + tmp |= value; > + writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA); > > return 0; > } > @@ -102,21 +126,22 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct > bcm_ns_usb3 *usb3) > udelay(2); > > /* USB3 PLL Block */ > - err = bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8000); > + err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, > +BCM_NS_USB3_PHY_PLL30_BLOCK); > if (err < 0) > return err; > > /* Assert Ana_Pllseq start */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x58061000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x1000); > > /* Assert CML Divider ratio to 26 */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582a6400); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL0, 0x6400); > > /* Asserting PLL Reset */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582ec000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0xc000); > > /* Deaaserting PLL Reset */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x582e8000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000); > > /* Waiting MII Mgt interface idle */ > bcm_ns_usb3_mii_mng_wait_idle(usb3); > @@ -125,22 +150,24 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct > bcm_ns_usb3 *usb3) > writel(0, usb3->dmp + BCMA_RESET_CTL); > > /* PLL frequency monitor enable */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x58069000); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLL_CONTROL, 0x9000); > > /* PIPE Block */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x587e8060); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG, > + BCM_NS_USB3_PHY_PIPE_BLOCK); > > /* CMPMAX & CMPMINTH setting */ > - bcm_ns_usb3_mii_mng_write32(usb3, 0x580af30d); > + bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_LFPS_CMP, 0xf30d); > > /* DEGLITCH
Re: [kbuild-all] [PATCH] net: hns: fix boolreturn.cocci warnings
Hi David, On Sun, Apr 02, 2017 at 07:44:02PM -0700, David Miller wrote: From: kbuild test robotDate: Sat, 1 Apr 2017 07:50:55 +0800 drivers/net/ethernet/hisilicon/hns/hns_enet.c:1548:8-9: WARNING: return of 0/1 in function 'hns_enable_serdes_lb' with return type bool Return statements in functions returning bool should use true/false instead of 1/0. Generated by: scripts/coccinelle/misc/boolreturn.cocci CC: lipeng Signed-off-by: Fengguang Wu This doesn't apply to any of my trees. It's a reply to Salil's patch [PATCH net 08/19] net: hns: Fix to adjust buf_size of ring according to mtu and so is based on that patch. What can the robot improve to avoid you confusing it as a general patch for the net master trees? One possible way is to change title to [PATCH for Salil] net: hns: fix boolreturn.cocci warnings ^ Regards, Fengguang
Re: [kbuild-all] [PATCH] net: hns: fix boolreturn.cocci warnings
Hi David, On Sun, Apr 02, 2017 at 07:44:02PM -0700, David Miller wrote: From: kbuild test robot Date: Sat, 1 Apr 2017 07:50:55 +0800 drivers/net/ethernet/hisilicon/hns/hns_enet.c:1548:8-9: WARNING: return of 0/1 in function 'hns_enable_serdes_lb' with return type bool Return statements in functions returning bool should use true/false instead of 1/0. Generated by: scripts/coccinelle/misc/boolreturn.cocci CC: lipeng Signed-off-by: Fengguang Wu This doesn't apply to any of my trees. It's a reply to Salil's patch [PATCH net 08/19] net: hns: Fix to adjust buf_size of ring according to mtu and so is based on that patch. What can the robot improve to avoid you confusing it as a general patch for the net master trees? One possible way is to change title to [PATCH for Salil] net: hns: fix boolreturn.cocci warnings ^ Regards, Fengguang
Re: [PATCH] net: hns: fix boolreturn.cocci warnings
From: kbuild test robotDate: Sat, 1 Apr 2017 07:50:55 +0800 > drivers/net/ethernet/hisilicon/hns/hns_enet.c:1548:8-9: WARNING: return of > 0/1 in function 'hns_enable_serdes_lb' with return type bool > > Return statements in functions returning bool should use > true/false instead of 1/0. > Generated by: scripts/coccinelle/misc/boolreturn.cocci > > CC: lipeng > Signed-off-by: Fengguang Wu This doesn't apply to any of my trees.
Re: [PATCH] phy/ethtool: Add missing SPEED_ strings
On Sun, 2017-04-02 at 15:29 -0700, Florian Fainelli wrote: > Le 04/02/17 à 14:30, Joe Perches a écrit : > > Add all the currently available SPEED_ strings. > > > > Signed-off-by: Joe Perches> > Considering that PHYLIB does not support anything > 10Gbs at the moment, > I am not sure how useful that is except if we wanted to re-use > phy_speed_to_str() in other places of the kernel? phy_print_status() can be used several places already independent of phylib. Might as well make it more generic and so more usable.
Re: [PATCH] net: hns: fix boolreturn.cocci warnings
From: kbuild test robot Date: Sat, 1 Apr 2017 07:50:55 +0800 > drivers/net/ethernet/hisilicon/hns/hns_enet.c:1548:8-9: WARNING: return of > 0/1 in function 'hns_enable_serdes_lb' with return type bool > > Return statements in functions returning bool should use > true/false instead of 1/0. > Generated by: scripts/coccinelle/misc/boolreturn.cocci > > CC: lipeng > Signed-off-by: Fengguang Wu This doesn't apply to any of my trees.
Re: [PATCH] phy/ethtool: Add missing SPEED_ strings
On Sun, 2017-04-02 at 15:29 -0700, Florian Fainelli wrote: > Le 04/02/17 à 14:30, Joe Perches a écrit : > > Add all the currently available SPEED_ strings. > > > > Signed-off-by: Joe Perches > > Considering that PHYLIB does not support anything > 10Gbs at the moment, > I am not sure how useful that is except if we wanted to re-use > phy_speed_to_str() in other places of the kernel? phy_print_status() can be used several places already independent of phylib. Might as well make it more generic and so more usable.
Re: [PATCH] net: ethernet: ti: cpsw: wake tx queues on ndo_tx_timeout
From: Grygorii StrashkoDate: Fri, 31 Mar 2017 18:41:23 -0500 > In case, if TX watchdog is fired some or all netdev TX queues will be > stopped and as part of recovery it is required not only to drain and > reinitailize CPSW TX channeles, but also wake up stoppted TX queues what > doesn't happen now and netdevice will stop transmiting data until > reopenned. > > Hence, add netif_tx_wake_all_queues() call in .ndo_tx_timeout() to complete > recovery and restore TX path. > > Signed-off-by: Grygorii Strashko Applied, thank you.
Re: [PATCH] net: ethernet: ti: cpsw: wake tx queues on ndo_tx_timeout
From: Grygorii Strashko Date: Fri, 31 Mar 2017 18:41:23 -0500 > In case, if TX watchdog is fired some or all netdev TX queues will be > stopped and as part of recovery it is required not only to drain and > reinitailize CPSW TX channeles, but also wake up stoppted TX queues what > doesn't happen now and netdevice will stop transmiting data until > reopenned. > > Hence, add netif_tx_wake_all_queues() call in .ndo_tx_timeout() to complete > recovery and restore TX path. > > Signed-off-by: Grygorii Strashko Applied, thank you.
Re: linux-next: build warning after merge of the nfsd tree
On Mon, Apr 03, 2017 at 11:09:48AM +1000, Stephen Rothwell wrote: > Hi, > > After merging the nfsd tree, today's linux-next build (powerpc > ppc64_defconfig) produced this warning: > > fs/nfsd/nfs4state.c: In function 'copy_cred': > fs/nfsd/nfs4state.c:1917:6: warning: unused variable 'ret' [-Wunused-variable] > int ret; > ^ > > Introduced by commit > > d39662236bf8 ("nfsd4: remove pointless strdup_if_nonnull") > > Also, that commit has no Signed-off-by from its Author. Both fixed, thanks.--b.
Re: linux-next: build warning after merge of the nfsd tree
On Mon, Apr 03, 2017 at 11:09:48AM +1000, Stephen Rothwell wrote: > Hi, > > After merging the nfsd tree, today's linux-next build (powerpc > ppc64_defconfig) produced this warning: > > fs/nfsd/nfs4state.c: In function 'copy_cred': > fs/nfsd/nfs4state.c:1917:6: warning: unused variable 'ret' [-Wunused-variable] > int ret; > ^ > > Introduced by commit > > d39662236bf8 ("nfsd4: remove pointless strdup_if_nonnull") > > Also, that commit has no Signed-off-by from its Author. Both fixed, thanks.--b.
Re: [git pull] vfs fixes
On Sun, Apr 02, 2017 at 05:58:41PM -0700, Linus Torvalds wrote: > I had to go and double-check that "DCACHE_DIRECTORY_TYPE" is what > d_can_lookup() actually checks, so _that_ part is perhaps a bit > subtle, and might be worth noting in that comment that you edited. > > So the real "rule" ends up being that we only ever look up things from > dentries of type DCACHE_DIRECTORY_TYPE set, and those had better have > DCACHE_RCUACCESS bit set. > > And the only reason path_init() only checks it for that case is that > nd->root and nd->pwd both have to be of type d_can_lookup(). > > Do we check that when we set it? I hope/assume we do. For chdir()/chroot()/pivot_root() it's done by LOOKUP_DIRECTORY in lookup flags; fchdir() is slightly different - there we check S_ISDIR of inode of opened file. Which is almost the same thing, except for kinda-sorta directories that have no ->lookup() - we have them for NFS referral points. It should be impossible to end up with one of those opened - not even with O_PATH; follow_managed() will be called and we'll either fail or cross into whatever ends up overmounting them. Still, it might be cleaner to turn that check into d_can_lookup(f.file->f_path.dentry) simply for consistency sake. The thing I really don't like is mntns_install(). With sufficiently nasty nfsroot setup it might be possible to end up with referral point as one's root/pwd; getting out of such state would be interesting... Smells like that place should be a solitary follow_down(), not a loop of follow_down_one(), but I want Eric's opinion on that one; userns stuff is weird. diff --git a/fs/dcache.c b/fs/dcache.c index 95d71eda8142..05550139a8a6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1757,7 +1757,13 @@ static unsigned d_flags_for_inode(struct inode *inode) return DCACHE_MISS_TYPE; if (S_ISDIR(inode->i_mode)) { - add_flags = DCACHE_DIRECTORY_TYPE; + /* +* Any potential starting point of lookup should have +* DCACHE_RCUACCESS; currently directory dentries +* come from d_alloc() anyway, but it costs us nothing +* to enforce it here. +*/ + add_flags = DCACHE_DIRECTORY_TYPE | DCACHE_RCUACCESS; if (unlikely(!(inode->i_opflags & IOP_LOOKUP))) { if (unlikely(!inode->i_op->lookup)) add_flags = DCACHE_AUTODIR_TYPE; diff --git a/fs/namei.c b/fs/namei.c index d41fab78798b..19dcf62133cc 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2145,6 +2145,9 @@ static const char *path_init(struct nameidata *nd, unsigned flags) int retval = 0; const char *s = nd->name->name; + if (!*s) + flags &= ~LOOKUP_RCU; + nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; nd->depth = 0; diff --git a/fs/namespace.c b/fs/namespace.c index cc1375eff88c..31ec9a79d2d4 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3467,6 +3467,7 @@ static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) struct fs_struct *fs = current->fs; struct mnt_namespace *mnt_ns = to_mnt_ns(ns); struct path root; + int err; if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || !ns_capable(current_user_ns(), CAP_SYS_CHROOT) || @@ -3484,15 +3485,14 @@ static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) root.mnt= _ns->root->mnt; root.dentry = mnt_ns->root->mnt.mnt_root; path_get(); - while(d_mountpoint(root.dentry) && follow_down_one()) - ; - - /* Update the pwd and root */ - set_fs_pwd(fs, ); - set_fs_root(fs, ); - + err = follow_down(); + if (likely(!err)) { + /* Update the pwd and root */ + set_fs_pwd(fs, ); + set_fs_root(fs, ); + } path_put(); - return 0; + return err; } static struct user_namespace *mntns_owner(struct ns_common *ns) diff --git a/fs/open.c b/fs/open.c index 949cef29c3bb..217b5db588c8 100644 --- a/fs/open.c +++ b/fs/open.c @@ -459,20 +459,17 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename) SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); - struct inode *inode; int error = -EBADF; error = -EBADF; if (!f.file) goto out; - inode = file_inode(f.file); - error = -ENOTDIR; - if (!S_ISDIR(inode->i_mode)) + if (!d_can_lookup(f.file->f_path.dentry)) goto out_putf; - error = inode_permission(inode, MAY_EXEC | MAY_CHDIR); + error = inode_permission(file_inode(f.file), MAY_EXEC | MAY_CHDIR); if (!error) set_fs_pwd(current->fs, >f_path); out_putf:
Re: [git pull] vfs fixes
On Sun, Apr 02, 2017 at 05:58:41PM -0700, Linus Torvalds wrote: > I had to go and double-check that "DCACHE_DIRECTORY_TYPE" is what > d_can_lookup() actually checks, so _that_ part is perhaps a bit > subtle, and might be worth noting in that comment that you edited. > > So the real "rule" ends up being that we only ever look up things from > dentries of type DCACHE_DIRECTORY_TYPE set, and those had better have > DCACHE_RCUACCESS bit set. > > And the only reason path_init() only checks it for that case is that > nd->root and nd->pwd both have to be of type d_can_lookup(). > > Do we check that when we set it? I hope/assume we do. For chdir()/chroot()/pivot_root() it's done by LOOKUP_DIRECTORY in lookup flags; fchdir() is slightly different - there we check S_ISDIR of inode of opened file. Which is almost the same thing, except for kinda-sorta directories that have no ->lookup() - we have them for NFS referral points. It should be impossible to end up with one of those opened - not even with O_PATH; follow_managed() will be called and we'll either fail or cross into whatever ends up overmounting them. Still, it might be cleaner to turn that check into d_can_lookup(f.file->f_path.dentry) simply for consistency sake. The thing I really don't like is mntns_install(). With sufficiently nasty nfsroot setup it might be possible to end up with referral point as one's root/pwd; getting out of such state would be interesting... Smells like that place should be a solitary follow_down(), not a loop of follow_down_one(), but I want Eric's opinion on that one; userns stuff is weird. diff --git a/fs/dcache.c b/fs/dcache.c index 95d71eda8142..05550139a8a6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1757,7 +1757,13 @@ static unsigned d_flags_for_inode(struct inode *inode) return DCACHE_MISS_TYPE; if (S_ISDIR(inode->i_mode)) { - add_flags = DCACHE_DIRECTORY_TYPE; + /* +* Any potential starting point of lookup should have +* DCACHE_RCUACCESS; currently directory dentries +* come from d_alloc() anyway, but it costs us nothing +* to enforce it here. +*/ + add_flags = DCACHE_DIRECTORY_TYPE | DCACHE_RCUACCESS; if (unlikely(!(inode->i_opflags & IOP_LOOKUP))) { if (unlikely(!inode->i_op->lookup)) add_flags = DCACHE_AUTODIR_TYPE; diff --git a/fs/namei.c b/fs/namei.c index d41fab78798b..19dcf62133cc 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2145,6 +2145,9 @@ static const char *path_init(struct nameidata *nd, unsigned flags) int retval = 0; const char *s = nd->name->name; + if (!*s) + flags &= ~LOOKUP_RCU; + nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; nd->depth = 0; diff --git a/fs/namespace.c b/fs/namespace.c index cc1375eff88c..31ec9a79d2d4 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3467,6 +3467,7 @@ static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) struct fs_struct *fs = current->fs; struct mnt_namespace *mnt_ns = to_mnt_ns(ns); struct path root; + int err; if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || !ns_capable(current_user_ns(), CAP_SYS_CHROOT) || @@ -3484,15 +3485,14 @@ static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) root.mnt= _ns->root->mnt; root.dentry = mnt_ns->root->mnt.mnt_root; path_get(); - while(d_mountpoint(root.dentry) && follow_down_one()) - ; - - /* Update the pwd and root */ - set_fs_pwd(fs, ); - set_fs_root(fs, ); - + err = follow_down(); + if (likely(!err)) { + /* Update the pwd and root */ + set_fs_pwd(fs, ); + set_fs_root(fs, ); + } path_put(); - return 0; + return err; } static struct user_namespace *mntns_owner(struct ns_common *ns) diff --git a/fs/open.c b/fs/open.c index 949cef29c3bb..217b5db588c8 100644 --- a/fs/open.c +++ b/fs/open.c @@ -459,20 +459,17 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename) SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); - struct inode *inode; int error = -EBADF; error = -EBADF; if (!f.file) goto out; - inode = file_inode(f.file); - error = -ENOTDIR; - if (!S_ISDIR(inode->i_mode)) + if (!d_can_lookup(f.file->f_path.dentry)) goto out_putf; - error = inode_permission(inode, MAY_EXEC | MAY_CHDIR); + error = inode_permission(file_inode(f.file), MAY_EXEC | MAY_CHDIR); if (!error) set_fs_pwd(current->fs, >f_path); out_putf:
linux-next: manual merge of the net-next tree with the net tree
Hi all, Today's linux-next merge of the net-next tree got conflicts in: tools/testing/selftests/bpf/Makefile tools/testing/selftests/bpf/test_verifier.c between commit: 02ea80b1850e ("bpf: add various verifier test cases for self-tests") from the net tree and commits: 6882804c916b ("selftests/bpf: add a test for overlapping packet range checks") fb30d4b71214 ("bpf: Add tests for map-in-map") from the net-next tree. I fixed it up (see below - though there are probably more fixups needed) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc tools/testing/selftests/bpf/Makefile index 9af09e8099c0,32fb7a294f0f.. --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@@ -1,17 -1,12 +1,19 @@@ LIBDIR := ../../../lib BPFDIR := $(LIBDIR)/bpf +APIDIR := ../../../include/uapi +GENDIR := ../../../../include/generated +GENHDR := $(GENDIR)/autoconf.h -CFLAGS += -Wall -O2 -I../../../include/uapi -I$(LIBDIR) -I../../../include +ifneq ($(wildcard $(GENHDR)),) + GENFLAGS := -DHAVE_GENHDR +endif + - CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) - LDLIBS += -lcap ++CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) -I../../../include $(GENFLAGS) + LDLIBS += -lcap -lelf - TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map + TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs + + TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o TEST_PROGS := test_kmod.sh diff --cc tools/testing/selftests/bpf/test_verifier.c index c848e90b6421,f4f43c98cf7f.. --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@@ -46,9 -38,8 +46,10 @@@ #define MAX_INSNS 512 #define MAX_FIXUPS8 + #define MAX_NR_MAPS 4 +#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS(1 << 0) + struct bpf_test { const char *descr; struct bpf_insn insns[MAX_INSNS]; @@@ -4719,8 -4454,76 +4721,77 @@@ static struct bpf_test tests[] = .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", .result = REJECT, .result_unpriv = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, - } + }, + { + "map in map access", + .insns = { + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_MOV64_REG(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_in_map = { 3 }, + .result = ACCEPT, + }, + { + "invalid inner map pointer", + .insns = { + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_MOV64_REG(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_in_map = { 3 }, + .errstr = "R1 type=inv expected=map_ptr", + .errstr_unpriv = "R1 pointer arithmetic prohibited", +
linux-next: manual merge of the net-next tree with the net tree
Hi all, Today's linux-next merge of the net-next tree got conflicts in: tools/testing/selftests/bpf/Makefile tools/testing/selftests/bpf/test_verifier.c between commit: 02ea80b1850e ("bpf: add various verifier test cases for self-tests") from the net tree and commits: 6882804c916b ("selftests/bpf: add a test for overlapping packet range checks") fb30d4b71214 ("bpf: Add tests for map-in-map") from the net-next tree. I fixed it up (see below - though there are probably more fixups needed) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc tools/testing/selftests/bpf/Makefile index 9af09e8099c0,32fb7a294f0f.. --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@@ -1,17 -1,12 +1,19 @@@ LIBDIR := ../../../lib BPFDIR := $(LIBDIR)/bpf +APIDIR := ../../../include/uapi +GENDIR := ../../../../include/generated +GENHDR := $(GENDIR)/autoconf.h -CFLAGS += -Wall -O2 -I../../../include/uapi -I$(LIBDIR) -I../../../include +ifneq ($(wildcard $(GENHDR)),) + GENFLAGS := -DHAVE_GENHDR +endif + - CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) - LDLIBS += -lcap ++CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) -I../../../include $(GENFLAGS) + LDLIBS += -lcap -lelf - TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map + TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs + + TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o TEST_PROGS := test_kmod.sh diff --cc tools/testing/selftests/bpf/test_verifier.c index c848e90b6421,f4f43c98cf7f.. --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@@ -46,9 -38,8 +46,10 @@@ #define MAX_INSNS 512 #define MAX_FIXUPS8 + #define MAX_NR_MAPS 4 +#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS(1 << 0) + struct bpf_test { const char *descr; struct bpf_insn insns[MAX_INSNS]; @@@ -4719,8 -4454,76 +4721,77 @@@ static struct bpf_test tests[] = .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", .result = REJECT, .result_unpriv = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, - } + }, + { + "map in map access", + .insns = { + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_MOV64_REG(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_in_map = { 3 }, + .result = ACCEPT, + }, + { + "invalid inner map pointer", + .insns = { + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_LD_MAP_FD(BPF_REG_1, 0), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), + BPF_ST_MEM(0, BPF_REG_10, -4, 0), + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), + BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, +BPF_FUNC_map_lookup_elem), + BPF_MOV64_REG(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_in_map = { 3 }, + .errstr = "R1 type=inv expected=map_ptr", + .errstr_unpriv = "R1 pointer arithmetic prohibited", +
Re: [PATCH v2] usb: dwc2: Make sure we disconnect the gadget state
On 03/29/2017 08:23 PM, John Stultz wrote: > I had seen some odd behavior with HiKey's usb-gadget interface > that I finally seemed to have chased down. Basically every other > time I plugged in the OTG port, the gadget interface would > properly initialize. The other times, I'd get a big WARN_ON > in dwc2_hsotg_init_fifo() about the fifo_map not being clear. > > Ends up if we don't disconnect the gadget state, the fifo-map > doesn't get cleared properly, which causes WARN_ON messages and > also results in the device not properly being setup as a gadget > every other time the OTG port is connected. > > So this patch adds a call to dwc2_hsotg_disconnect() in the > reset path so the state is properly cleared. > > With it, the gadget interface initializes properly on every > plug in. > > Cc: Wei Xu> Cc: Guodong Xu > Cc: Amit Pundir > Cc: Rob Herring > Cc: John Youn > Cc: Douglas Anderson > Cc: Chen Yu > Cc: Felipe Balbi > Cc: Greg Kroah-Hartman > Cc: linux-...@vger.kernel.org > Acked-by: John Youn > Signed-off-by: John Stultz > --- > v2: Minor typo fix suggested by Sergei Shtylyov > --- > drivers/usb/dwc2/hcd.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c > index a73722e..91ed5b6 100644 > --- a/drivers/usb/dwc2/hcd.c > +++ b/drivers/usb/dwc2/hcd.c > @@ -3264,6 +3264,7 @@ static void dwc2_conn_id_status_change(struct > work_struct *work) > dwc2_core_init(hsotg, false); > dwc2_enable_global_interrupts(hsotg); > spin_lock_irqsave(>lock, flags); > + dwc2_hsotg_disconnect(hsotg); > dwc2_hsotg_core_init_disconnected(hsotg, false); > spin_unlock_irqrestore(>lock, flags); > dwc2_hsotg_core_connect(hsotg); > Hi Felipe, You may want to use this patch to replace the one in your testing/next as this has a cleaner commit message. Thanks, John
Re: [PATCH v2] usb: dwc2: Make sure we disconnect the gadget state
On 03/29/2017 08:23 PM, John Stultz wrote: > I had seen some odd behavior with HiKey's usb-gadget interface > that I finally seemed to have chased down. Basically every other > time I plugged in the OTG port, the gadget interface would > properly initialize. The other times, I'd get a big WARN_ON > in dwc2_hsotg_init_fifo() about the fifo_map not being clear. > > Ends up if we don't disconnect the gadget state, the fifo-map > doesn't get cleared properly, which causes WARN_ON messages and > also results in the device not properly being setup as a gadget > every other time the OTG port is connected. > > So this patch adds a call to dwc2_hsotg_disconnect() in the > reset path so the state is properly cleared. > > With it, the gadget interface initializes properly on every > plug in. > > Cc: Wei Xu > Cc: Guodong Xu > Cc: Amit Pundir > Cc: Rob Herring > Cc: John Youn > Cc: Douglas Anderson > Cc: Chen Yu > Cc: Felipe Balbi > Cc: Greg Kroah-Hartman > Cc: linux-...@vger.kernel.org > Acked-by: John Youn > Signed-off-by: John Stultz > --- > v2: Minor typo fix suggested by Sergei Shtylyov > --- > drivers/usb/dwc2/hcd.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c > index a73722e..91ed5b6 100644 > --- a/drivers/usb/dwc2/hcd.c > +++ b/drivers/usb/dwc2/hcd.c > @@ -3264,6 +3264,7 @@ static void dwc2_conn_id_status_change(struct > work_struct *work) > dwc2_core_init(hsotg, false); > dwc2_enable_global_interrupts(hsotg); > spin_lock_irqsave(>lock, flags); > + dwc2_hsotg_disconnect(hsotg); > dwc2_hsotg_core_init_disconnected(hsotg, false); > spin_unlock_irqrestore(>lock, flags); > dwc2_hsotg_core_connect(hsotg); > Hi Felipe, You may want to use this patch to replace the one in your testing/next as this has a cleaner commit message. Thanks, John
Re: [PATCH v4 3/5] watchdog: iTCO_wdt: Add PMC specific noreboot update api
Hi, On Sun, Apr 2, 2017 at 7:04 AM, Andy Shevchenkowrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> In some SOCs, setting noreboot bit needs modification to > > SoCs. > > Perhaps you can create a wikipage to share with your team what style > issues usually needs to be addressed. > One of them is a proper capitalization in abbreviations / code names. > >> PMC GC registers. But not all PMC drivers allow other drivers >> to memory map their GC region. This could create mem request >> conflict in watchdog driver. So this patch adds facility to allow >> PMC drivers to pass noreboot update function to watchdog >> drivers via platform data. > >> --- a/drivers/watchdog/iTCO_wdt.c >> +++ b/drivers/watchdog/iTCO_wdt.c >> @@ -100,6 +100,8 @@ struct iTCO_wdt_private { >> */ >> struct resource *gcs_pmc_res; >> unsigned long __iomem *gcs_pmc; > >> + /* pmc specific api to update noreboot flag */ > > PMC > API will fix in next version. > >> + int (*update_noreboot_flag)(bool status); >> /* the lock for io operations */ >> spinlock_t io_lock; >> /* the PCI-device */ >> @@ -176,9 +178,13 @@ static void iTCO_wdt_set_NO_REBOOT_bit(struct >> iTCO_wdt_private *p) >> >> /* Set the NO_REBOOT bit: this disables reboots */ >> if (p->iTCO_version >= 2) { >> - val32 = readl(p->gcs_pmc); >> - val32 |= no_reboot_bit(p); >> - writel(val32, p->gcs_pmc); >> + if (p->update_noreboot_flag) > >> + p->update_noreboot_flag(1); > > 1 -> true for sake of consistency. ditto > >> + else { >> + val32 = readl(p->gcs_pmc); >> + val32 |= no_reboot_bit(p); >> + writel(val32, p->gcs_pmc); >> + } >> } else if (p->iTCO_version == 1) { >> pci_read_config_dword(p->pci_dev, 0xd4, ); >> val32 |= no_reboot_bit(p); >> @@ -193,11 +199,14 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(struct >> iTCO_wdt_private *p) >> >> /* Unset the NO_REBOOT bit: this enables reboots */ >> if (p->iTCO_version >= 2) { >> - val32 = readl(p->gcs_pmc); >> - val32 &= ~enable_bit; >> - writel(val32, p->gcs_pmc); >> - >> - val32 = readl(p->gcs_pmc); >> + if (p->update_noreboot_flag) > >> + return p->update_noreboot_flag(0); > > 0 -> false. ditto > >> + else { > >> + val32 = readl(p->gcs_pmc); >> + val32 &= ~enable_bit; >> + writel(val32, p->gcs_pmc); >> + val32 = readl(p->gcs_pmc); > > This and similar above code might be split to a helper and you may > assign it once. In such case you will not need a special flag anymore. > > Helpers split might be done as a preparatory separate patch. Yes, will create a patch for fixing it. > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 3/5] watchdog: iTCO_wdt: Add PMC specific noreboot update api
Hi, On Sun, Apr 2, 2017 at 7:04 AM, Andy Shevchenko wrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> In some SOCs, setting noreboot bit needs modification to > > SoCs. > > Perhaps you can create a wikipage to share with your team what style > issues usually needs to be addressed. > One of them is a proper capitalization in abbreviations / code names. > >> PMC GC registers. But not all PMC drivers allow other drivers >> to memory map their GC region. This could create mem request >> conflict in watchdog driver. So this patch adds facility to allow >> PMC drivers to pass noreboot update function to watchdog >> drivers via platform data. > >> --- a/drivers/watchdog/iTCO_wdt.c >> +++ b/drivers/watchdog/iTCO_wdt.c >> @@ -100,6 +100,8 @@ struct iTCO_wdt_private { >> */ >> struct resource *gcs_pmc_res; >> unsigned long __iomem *gcs_pmc; > >> + /* pmc specific api to update noreboot flag */ > > PMC > API will fix in next version. > >> + int (*update_noreboot_flag)(bool status); >> /* the lock for io operations */ >> spinlock_t io_lock; >> /* the PCI-device */ >> @@ -176,9 +178,13 @@ static void iTCO_wdt_set_NO_REBOOT_bit(struct >> iTCO_wdt_private *p) >> >> /* Set the NO_REBOOT bit: this disables reboots */ >> if (p->iTCO_version >= 2) { >> - val32 = readl(p->gcs_pmc); >> - val32 |= no_reboot_bit(p); >> - writel(val32, p->gcs_pmc); >> + if (p->update_noreboot_flag) > >> + p->update_noreboot_flag(1); > > 1 -> true for sake of consistency. ditto > >> + else { >> + val32 = readl(p->gcs_pmc); >> + val32 |= no_reboot_bit(p); >> + writel(val32, p->gcs_pmc); >> + } >> } else if (p->iTCO_version == 1) { >> pci_read_config_dword(p->pci_dev, 0xd4, ); >> val32 |= no_reboot_bit(p); >> @@ -193,11 +199,14 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(struct >> iTCO_wdt_private *p) >> >> /* Unset the NO_REBOOT bit: this enables reboots */ >> if (p->iTCO_version >= 2) { >> - val32 = readl(p->gcs_pmc); >> - val32 &= ~enable_bit; >> - writel(val32, p->gcs_pmc); >> - >> - val32 = readl(p->gcs_pmc); >> + if (p->update_noreboot_flag) > >> + return p->update_noreboot_flag(0); > > 0 -> false. ditto > >> + else { > >> + val32 = readl(p->gcs_pmc); >> + val32 &= ~enable_bit; >> + writel(val32, p->gcs_pmc); >> + val32 = readl(p->gcs_pmc); > > This and similar above code might be split to a helper and you may > assign it once. In such case you will not need a special flag anymore. > > Helpers split might be done as a preparatory separate patch. Yes, will create a patch for fixing it. > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 4/5] platform/x86: intel_pmc_ipc: Fix iTCO GCS memory mapping failure
Hi Andy, On Sun, Apr 2, 2017 at 7:10 AM, Andy Shevchenkowrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> iTCO watchdog driver need access to PMC_CFG GCR register to modify > > iTCO_wdt or use above in the rest of the series. > > So, choose one and use it everywhere in your patch series. will go with iTCO_wdt. > >> the no reboot setting. Currently, this is done by passing PMC_CFG reg >> address as memory resource to watchdog driver and allowing it directly >> modify the PMC_CFG register. But currently PMC driver also has >> requirement to memory map the entire GCR register space in this driver. >> This causes mem request failure in watchdog driver. So this patch fixes >> this issue by adding api to update noreboot flag and passes them >> to watchdog driver via platform data. > > >> +static int update_noreboot_bit(bool status) >> +{ >> + if (status) > >> + return intel_pmc_gcr_update(PMC_GCR_PMC_CFG_REG, BIT(4), >> + BIT(4)); > > BIT(4) is a magic. Moreover, it's used as mask and value here, you > might introduce temporary variables for better understanding what is > what. > As an example you may look at drivers/acpi/acpi_lpss.c (code related > to IOSF MBI interaction). I will create macros with some meaningful name to explain what BIT(4) represents. > >> + else > > Redundant. > > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 4/5] platform/x86: intel_pmc_ipc: Fix iTCO GCS memory mapping failure
Hi Andy, On Sun, Apr 2, 2017 at 7:10 AM, Andy Shevchenko wrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> iTCO watchdog driver need access to PMC_CFG GCR register to modify > > iTCO_wdt or use above in the rest of the series. > > So, choose one and use it everywhere in your patch series. will go with iTCO_wdt. > >> the no reboot setting. Currently, this is done by passing PMC_CFG reg >> address as memory resource to watchdog driver and allowing it directly >> modify the PMC_CFG register. But currently PMC driver also has >> requirement to memory map the entire GCR register space in this driver. >> This causes mem request failure in watchdog driver. So this patch fixes >> this issue by adding api to update noreboot flag and passes them >> to watchdog driver via platform data. > > >> +static int update_noreboot_bit(bool status) >> +{ >> + if (status) > >> + return intel_pmc_gcr_update(PMC_GCR_PMC_CFG_REG, BIT(4), >> + BIT(4)); > > BIT(4) is a magic. Moreover, it's used as mask and value here, you > might introduce temporary variables for better understanding what is > what. > As an example you may look at drivers/acpi/acpi_lpss.c (code related > to IOSF MBI interaction). I will create macros with some meaningful name to explain what BIT(4) represents. > >> + else > > Redundant. > > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 1/5] platform/x86: intel_pmc_ipc: fix gcr offset
Yes, just applying this patch will fix the existing offset issue. On Sun, Apr 2, 2017 at 7:11 AM, Andy Shevchenkowrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> According to Broxton APL PMC spec, gcr mem region starts >> at offset 0x1000 from ipc mem base address. In this driver, >> PLAT_RESOURCE_GCR_OFFSET macro defines the offset of GCR >> memory region from IPC mem region. So we should use 0x1000(4K) >> as GCR offset. But currently this driver uses 0x1008 as GCT >> offset.This patch fixes this issue. > > > So, if I apply this one independently, would it fix an existin issue? > >> >> Signed-off-by: Kuppuswamy Sathyanarayanan >> >> --- >> drivers/platform/x86/intel_pmc_ipc.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> Changes since v3: >> * Updated the commit history >> >> diff --git a/drivers/platform/x86/intel_pmc_ipc.c >> b/drivers/platform/x86/intel_pmc_ipc.c >> index 0651d47..0a33592 100644 >> --- a/drivers/platform/x86/intel_pmc_ipc.c >> +++ b/drivers/platform/x86/intel_pmc_ipc.c >> @@ -82,7 +82,7 @@ >> /* exported resources from IFWI */ >> #define PLAT_RESOURCE_IPC_INDEX0 >> #define PLAT_RESOURCE_IPC_SIZE 0x1000 >> -#define PLAT_RESOURCE_GCR_OFFSET 0x1008 >> +#define PLAT_RESOURCE_GCR_OFFSET 0x1000 >> #define PLAT_RESOURCE_GCR_SIZE 0x1000 >> #define PLAT_RESOURCE_BIOS_DATA_INDEX 1 >> #define PLAT_RESOURCE_BIOS_IFACE_INDEX 2 >> -- >> 2.7.4 >> > > > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 1/5] platform/x86: intel_pmc_ipc: fix gcr offset
Yes, just applying this patch will fix the existing offset issue. On Sun, Apr 2, 2017 at 7:11 AM, Andy Shevchenko wrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> According to Broxton APL PMC spec, gcr mem region starts >> at offset 0x1000 from ipc mem base address. In this driver, >> PLAT_RESOURCE_GCR_OFFSET macro defines the offset of GCR >> memory region from IPC mem region. So we should use 0x1000(4K) >> as GCR offset. But currently this driver uses 0x1008 as GCT >> offset.This patch fixes this issue. > > > So, if I apply this one independently, would it fix an existin issue? > >> >> Signed-off-by: Kuppuswamy Sathyanarayanan >> >> --- >> drivers/platform/x86/intel_pmc_ipc.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> Changes since v3: >> * Updated the commit history >> >> diff --git a/drivers/platform/x86/intel_pmc_ipc.c >> b/drivers/platform/x86/intel_pmc_ipc.c >> index 0651d47..0a33592 100644 >> --- a/drivers/platform/x86/intel_pmc_ipc.c >> +++ b/drivers/platform/x86/intel_pmc_ipc.c >> @@ -82,7 +82,7 @@ >> /* exported resources from IFWI */ >> #define PLAT_RESOURCE_IPC_INDEX0 >> #define PLAT_RESOURCE_IPC_SIZE 0x1000 >> -#define PLAT_RESOURCE_GCR_OFFSET 0x1008 >> +#define PLAT_RESOURCE_GCR_OFFSET 0x1000 >> #define PLAT_RESOURCE_GCR_SIZE 0x1000 >> #define PLAT_RESOURCE_BIOS_DATA_INDEX 1 >> #define PLAT_RESOURCE_BIOS_IFACE_INDEX 2 >> -- >> 2.7.4 >> > > > > -- > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 2/5] platform/x86: intel_pmc_ipc: Add pmc gcr read/write/update api's
Hi Andy, Thanks for your comments. On Sun, Apr 2, 2017 at 6:58 AM, Andy Shevchenkowrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> This patch adds API's to read/write/update PMC GC registers. >> PMC dependent devices like iTCO_WDT, Telemetry has requirement > > iTCO_wdt will fix it in next version. > >> to acces GCR registers. These API's can be used for this >> purpose. > >> --- a/drivers/platform/x86/intel_pmc_ipc.c >> +++ b/drivers/platform/x86/intel_pmc_ipc.c > >> +static inline int is_gcr_valid(u32 offset) > > Pointer to ipcdev should be a parameter to this function. But ipcdev is a static variable, visible across this file. So there is no point in passing it as parameter. I just noticed that I am not holding the mutex lock in these functions. I will fix it in next version. > >> +{ >> + if (!ipcdev.has_gcr_regs) >> + return -EACCES; >> + >> + if (offset > PLAT_RESOURCE_GCR_SIZE) >> + return -EINVAL; >> + >> + return 0; >> +} > >> +/** >> + * intel_pmc_gcr_update() - Update PMC GCR register bits >> + * @offset:offset of GCR register from GCR address base >> + * @mask: bit mask for update operation >> + * @val: update value >> + * > >> + * Updates the bits of given GCR register as specified by >> + * mask and val > > -> * @mask and @val. > > You would need to refresh how to use kernel doc. -:) will fix it in next version. > >> + * >> + * Return: negative value on error or 0 on success. >> + */ > > With Best Regards, > Andy Shevchenko -- -- Sathya
Re: [PATCH v4 2/5] platform/x86: intel_pmc_ipc: Add pmc gcr read/write/update api's
Hi Andy, Thanks for your comments. On Sun, Apr 2, 2017 at 6:58 AM, Andy Shevchenko wrote: > On Sat, Apr 1, 2017 at 2:27 AM, Kuppuswamy Sathyanarayanan > wrote: >> This patch adds API's to read/write/update PMC GC registers. >> PMC dependent devices like iTCO_WDT, Telemetry has requirement > > iTCO_wdt will fix it in next version. > >> to acces GCR registers. These API's can be used for this >> purpose. > >> --- a/drivers/platform/x86/intel_pmc_ipc.c >> +++ b/drivers/platform/x86/intel_pmc_ipc.c > >> +static inline int is_gcr_valid(u32 offset) > > Pointer to ipcdev should be a parameter to this function. But ipcdev is a static variable, visible across this file. So there is no point in passing it as parameter. I just noticed that I am not holding the mutex lock in these functions. I will fix it in next version. > >> +{ >> + if (!ipcdev.has_gcr_regs) >> + return -EACCES; >> + >> + if (offset > PLAT_RESOURCE_GCR_SIZE) >> + return -EINVAL; >> + >> + return 0; >> +} > >> +/** >> + * intel_pmc_gcr_update() - Update PMC GCR register bits >> + * @offset:offset of GCR register from GCR address base >> + * @mask: bit mask for update operation >> + * @val: update value >> + * > >> + * Updates the bits of given GCR register as specified by >> + * mask and val > > -> * @mask and @val. > > You would need to refresh how to use kernel doc. -:) will fix it in next version. > >> + * >> + * Return: negative value on error or 0 on success. >> + */ > > With Best Regards, > Andy Shevchenko -- -- Sathya
Linux 4.11-rc5
Ok, things have definitely started to calm down, let's hope it stays this way and it wasn't just a fluke this week. Things look fairly normal, with just under 60% of the changes in drivers (edac, sound, block, pci, etc), and about 30% in arch updates (some misc ptrace fixes, random stuff). The only slightly unusual thing is how over half the arch updates are for parisc, but that's just a temporary oddity from the fix to the parisc user copy routines, which resulted in a fairly big patch (due to them just being written as regular assembler code rather than as a broken mess of inline assembly with some C mixed in). The rest is a random mix of some filesystem fixes (nfs[d], btrfs), with some misc core kernel and mm fixes thrown in. Shortlog appended for people who like just skimming the details. It's not big, just scroll down through it. Linus --- Aaron Armstrong Skomra (2): HID: wacom: Don't add ghost interface as shared data HID: wacom: call _query_tablet_data() for BAMBOO_TOUCH Adam Wallis (1): xhci: plat: Register shutdown for xhci_plat Alan Stern (1): USB: fix linked-list corruption in rh_call_control() Alex Williamson (1): drm/i915/kvmgt: Hold struct kvm reference Alexander Kochetkov (2): clockevents: Fix syntax error in clkevt-of macro vmlinux.lds: Add __clkevt_of_table to kernel Alexey Brodkin (2): ARC: vdk: Fix support of UIO ARCv2: SLC: Make sure busy bit is set properly on SLC flushing Andrzej Hajda (1): pinctrl: samsung: Fix memory mapping code Andy Adamson (3): NFS cleanup struct nfs4_filelayout_segment NFS store nfs4_deviceid in struct nfs4_filelayout_segment NFS filelayout:call GETDEVICEINFO after pnfs_layout_process completes Andy Shevchenko (1): Revert "i2c: mux: pca954x: Add ACPI support for pca954x" Andy Whitcroft (2): xfrm_user: validate XFRM_MSG_NEWAE XFRMA_REPLAY_ESN_VAL replay_window xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size harder Arnaud Pouliquen (1): ASoC: STI: Fix reader substream pointer set Arnd Bergmann (4): ASoC: mediatek: add I2C dependency for CS42XX8 irqchip/mvebu-odmi: Select GENERIC_MSI_IRQ_DOMAIN scsi: lpfc: fix building without debugfs support virtio_balloon: prevent uninitialized variable use Baoquan He (1): x86/mm/KASLR: Exclude EFI region from KASLR VA space randomization Bard Liao (6): ASoC: rt5665: fix getting wrong work handler container ASoC: rt5665: increase LDO level ASoC: rt5665: Vref3 is necessary for Mono Amp ASoC: rt5665: CLKDET is also a power of ASRC ASoC: rt5665: fix define of RT5665_HP_DRIVER_5X ASoC: rt5665: fix wrong shift rt5665_if2_1_adc_in_enum Bart Van Assche (3): scsi: scsi_dh_alua: Check scsi_device_get() return value scsi: scsi_dh_alua: Ensure that alua_activate() calls the completion function scsi: scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Benjamin Coddington (1): NFS: Fix old dentry rehash after move Bill Kuzeja (1): scsi: qla2xxx: Fix crash in qla2xxx_eh_abort on bad ptr Bjorn Andersson (1): pinctrl: qcom: Don't clear status bit on irq_unmask Bjorn Helgaas (1): PCI: iproc: Save host bridge window resource in struct iproc_pcie Borislav Petkov (2): EDAC: Select DEBUG_FS EDAC, pnd2_edac: Fix !EDAC_DEBUG build Brian Norris (1): ASoC: don't dereference NULL pcm_{new,free} Changbin Du (1): drm/i915/gvt: Use force single submit flag to distinguish gvt request from i915 request Charles Keepax (2): ASoC: wm_adsp: Return an error on write to a disabled volatile control ASoC: wm_adsp: Acknowledge controls should also check the DSP is running Chris Wilson (1): drm/i915: Restore marking context objects as dirty on pinning Christian Lamparter (1): pinctrl: qcom: ipq4019: add missing pingroups for pins > 70 Chuanxiao Dong (1): drm/i915/gvt: fix wrong offset when loading RCS mocs Chuck Lever (1): svcrdma: set XPT_CONG_CTRL flag for bc xprt Colin Ian King (1): EDAC, xgene: Fix wrongly spelled "procesing" Dan Carpenter (1): Btrfs: fix an integer overflow check Daniel Drake (1): efi/esrt: Cleanup bad memory map log messages Dave Martin (7): c6x/ptrace: Remove useless PTRACE_SETREGSET implementation h8300/ptrace: Fix incorrect register transfer count metag/ptrace: Preserve previous registers for short regset write metag/ptrace: Provide default TXSTATUS for short NT_PRSTATUS metag/ptrace: Reject partial NT_METAG_RPIPE writes mips/ptrace: Preserve previous registers for short regset write sparc/ptrace: Preserve previous registers for short regset write David Hildenbrand (1): KVM: kvm_io_bus_unregister_dev() should never fail Dick Kennedy (1): scsi: lpfc: Fix PT2PT PRLI reject Dmitry Vyukov (1): kvm: fix usage of uninit spinlock in
Linux 4.11-rc5
Ok, things have definitely started to calm down, let's hope it stays this way and it wasn't just a fluke this week. Things look fairly normal, with just under 60% of the changes in drivers (edac, sound, block, pci, etc), and about 30% in arch updates (some misc ptrace fixes, random stuff). The only slightly unusual thing is how over half the arch updates are for parisc, but that's just a temporary oddity from the fix to the parisc user copy routines, which resulted in a fairly big patch (due to them just being written as regular assembler code rather than as a broken mess of inline assembly with some C mixed in). The rest is a random mix of some filesystem fixes (nfs[d], btrfs), with some misc core kernel and mm fixes thrown in. Shortlog appended for people who like just skimming the details. It's not big, just scroll down through it. Linus --- Aaron Armstrong Skomra (2): HID: wacom: Don't add ghost interface as shared data HID: wacom: call _query_tablet_data() for BAMBOO_TOUCH Adam Wallis (1): xhci: plat: Register shutdown for xhci_plat Alan Stern (1): USB: fix linked-list corruption in rh_call_control() Alex Williamson (1): drm/i915/kvmgt: Hold struct kvm reference Alexander Kochetkov (2): clockevents: Fix syntax error in clkevt-of macro vmlinux.lds: Add __clkevt_of_table to kernel Alexey Brodkin (2): ARC: vdk: Fix support of UIO ARCv2: SLC: Make sure busy bit is set properly on SLC flushing Andrzej Hajda (1): pinctrl: samsung: Fix memory mapping code Andy Adamson (3): NFS cleanup struct nfs4_filelayout_segment NFS store nfs4_deviceid in struct nfs4_filelayout_segment NFS filelayout:call GETDEVICEINFO after pnfs_layout_process completes Andy Shevchenko (1): Revert "i2c: mux: pca954x: Add ACPI support for pca954x" Andy Whitcroft (2): xfrm_user: validate XFRM_MSG_NEWAE XFRMA_REPLAY_ESN_VAL replay_window xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size harder Arnaud Pouliquen (1): ASoC: STI: Fix reader substream pointer set Arnd Bergmann (4): ASoC: mediatek: add I2C dependency for CS42XX8 irqchip/mvebu-odmi: Select GENERIC_MSI_IRQ_DOMAIN scsi: lpfc: fix building without debugfs support virtio_balloon: prevent uninitialized variable use Baoquan He (1): x86/mm/KASLR: Exclude EFI region from KASLR VA space randomization Bard Liao (6): ASoC: rt5665: fix getting wrong work handler container ASoC: rt5665: increase LDO level ASoC: rt5665: Vref3 is necessary for Mono Amp ASoC: rt5665: CLKDET is also a power of ASRC ASoC: rt5665: fix define of RT5665_HP_DRIVER_5X ASoC: rt5665: fix wrong shift rt5665_if2_1_adc_in_enum Bart Van Assche (3): scsi: scsi_dh_alua: Check scsi_device_get() return value scsi: scsi_dh_alua: Ensure that alua_activate() calls the completion function scsi: scsi_dh_alua: Warn if the first argument of alua_rtpg_queue() is NULL Benjamin Coddington (1): NFS: Fix old dentry rehash after move Bill Kuzeja (1): scsi: qla2xxx: Fix crash in qla2xxx_eh_abort on bad ptr Bjorn Andersson (1): pinctrl: qcom: Don't clear status bit on irq_unmask Bjorn Helgaas (1): PCI: iproc: Save host bridge window resource in struct iproc_pcie Borislav Petkov (2): EDAC: Select DEBUG_FS EDAC, pnd2_edac: Fix !EDAC_DEBUG build Brian Norris (1): ASoC: don't dereference NULL pcm_{new,free} Changbin Du (1): drm/i915/gvt: Use force single submit flag to distinguish gvt request from i915 request Charles Keepax (2): ASoC: wm_adsp: Return an error on write to a disabled volatile control ASoC: wm_adsp: Acknowledge controls should also check the DSP is running Chris Wilson (1): drm/i915: Restore marking context objects as dirty on pinning Christian Lamparter (1): pinctrl: qcom: ipq4019: add missing pingroups for pins > 70 Chuanxiao Dong (1): drm/i915/gvt: fix wrong offset when loading RCS mocs Chuck Lever (1): svcrdma: set XPT_CONG_CTRL flag for bc xprt Colin Ian King (1): EDAC, xgene: Fix wrongly spelled "procesing" Dan Carpenter (1): Btrfs: fix an integer overflow check Daniel Drake (1): efi/esrt: Cleanup bad memory map log messages Dave Martin (7): c6x/ptrace: Remove useless PTRACE_SETREGSET implementation h8300/ptrace: Fix incorrect register transfer count metag/ptrace: Preserve previous registers for short regset write metag/ptrace: Provide default TXSTATUS for short NT_PRSTATUS metag/ptrace: Reject partial NT_METAG_RPIPE writes mips/ptrace: Preserve previous registers for short regset write sparc/ptrace: Preserve previous registers for short regset write David Hildenbrand (1): KVM: kvm_io_bus_unregister_dev() should never fail Dick Kennedy (1): scsi: lpfc: Fix PT2PT PRLI reject Dmitry Vyukov (1): kvm: fix usage of uninit spinlock in
Re: Updating sunxi tree in linux-next
Hi Stephen, On Mon, Apr 3, 2017 at 7:56 AM, Stephen Rothwellwrote: > Hi Maxime, > > On Fri, 31 Mar 2017 09:57:29 +0200 Maxime Ripard > wrote: >> >> We've switched from my personal git tree for the Allwinner sunxi >> development to a shared tree: >> git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git >> >> The branch to be included in linux-next will still be called >> sunxi/for-next as it used to be, and it will still go through the >> arm-soc tree to reach Linux. >> >> However, I'll still have the patches for our DRM drivers on my >> personal git repo: >> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git >> >> Could you add the branch sunxi-drm/for-next to the list of branches >> you merge? > > OK, just so we are on the same page: > > Currently I have: > > git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git branch > sunxi/for-next > > merged after the drm tree. > > You want: > > git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git branch > sunxi/for-next > > merged after the arm-soc tree and > > git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git branch > sunxi-drm/for-next > > merged after the drm tree? > > (I merge trees *after* the tree that is their upstream.) > > Do you want to be the only contact for both trees? Please add me as a contact for sunxi/for-next. Thanks ChenYu > -- > Cheers, > Stephen Rothwell
Re: Updating sunxi tree in linux-next
Hi Stephen, On Mon, Apr 3, 2017 at 7:56 AM, Stephen Rothwell wrote: > Hi Maxime, > > On Fri, 31 Mar 2017 09:57:29 +0200 Maxime Ripard > wrote: >> >> We've switched from my personal git tree for the Allwinner sunxi >> development to a shared tree: >> git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git >> >> The branch to be included in linux-next will still be called >> sunxi/for-next as it used to be, and it will still go through the >> arm-soc tree to reach Linux. >> >> However, I'll still have the patches for our DRM drivers on my >> personal git repo: >> git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git >> >> Could you add the branch sunxi-drm/for-next to the list of branches >> you merge? > > OK, just so we are on the same page: > > Currently I have: > > git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git branch > sunxi/for-next > > merged after the drm tree. > > You want: > > git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git branch > sunxi/for-next > > merged after the arm-soc tree and > > git://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git branch > sunxi-drm/for-next > > merged after the drm tree? > > (I merge trees *after* the tree that is their upstream.) > > Do you want to be the only contact for both trees? Please add me as a contact for sunxi/for-next. Thanks ChenYu > -- > Cheers, > Stephen Rothwell
[PATCH] loop: Add PF_LESS_THROTTLE to block/loop device thread.
When a filesystem is mounted from a loop device, writes are throttled by balance_dirty_pages() twice: once when writing to the filesystem and once when the loop_handle_cmd() writes to the backing file. This double-throttling can trigger positive feedback loops that create significant delays. The throttling at the lower level is seen by the upper level as a slow device, so it throttles extra hard. The PF_LESS_THROTTLE flag was created to handle exactly this circumstance, though with an NFS filesystem mounted from a local NFS server. It reduces the throttling on the lower layer so that it can proceed largely unthrottled. To demonstrate this, create a filesystem on a loop device and write (e.g. with dd) several large files which combine to consume significantly more than the limit set by /proc/sys/vm/dirty_ratio or dirty_bytes. Measure the total time taken. When I do this directly on a device (no loop device) the total time for several runs (mkfs, mount, write 200 files, umount) is fairly stable: 28-35 seconds. When I do this over a loop device the times are much worse and less stable. 52-460 seconds. Half below 100seconds, half above. When I apply this patch, the times become stable again, though not as fast as the no-loop-back case: 53-72 seconds. There may be room for further improvement as the total overhead still seems too high, but this is a big improvement. Signed-off-by: NeilBrown--- drivers/block/loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0ecb6461ed81..a7e1dd215fc2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1694,8 +1694,11 @@ static void loop_queue_work(struct kthread_work *work) { struct loop_cmd *cmd = container_of(work, struct loop_cmd, work); + int oldflags = current->flags & PF_LESS_THROTTLE; + current->flags |= PF_LESS_THROTTLE; loop_handle_cmd(cmd); + current->flags = (current->flags & ~PF_LESS_THROTTLE) | oldflags; } static int loop_init_request(void *data, struct request *rq, -- 2.12.0 signature.asc Description: PGP signature
[PATCH] loop: Add PF_LESS_THROTTLE to block/loop device thread.
When a filesystem is mounted from a loop device, writes are throttled by balance_dirty_pages() twice: once when writing to the filesystem and once when the loop_handle_cmd() writes to the backing file. This double-throttling can trigger positive feedback loops that create significant delays. The throttling at the lower level is seen by the upper level as a slow device, so it throttles extra hard. The PF_LESS_THROTTLE flag was created to handle exactly this circumstance, though with an NFS filesystem mounted from a local NFS server. It reduces the throttling on the lower layer so that it can proceed largely unthrottled. To demonstrate this, create a filesystem on a loop device and write (e.g. with dd) several large files which combine to consume significantly more than the limit set by /proc/sys/vm/dirty_ratio or dirty_bytes. Measure the total time taken. When I do this directly on a device (no loop device) the total time for several runs (mkfs, mount, write 200 files, umount) is fairly stable: 28-35 seconds. When I do this over a loop device the times are much worse and less stable. 52-460 seconds. Half below 100seconds, half above. When I apply this patch, the times become stable again, though not as fast as the no-loop-back case: 53-72 seconds. There may be room for further improvement as the total overhead still seems too high, but this is a big improvement. Signed-off-by: NeilBrown --- drivers/block/loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0ecb6461ed81..a7e1dd215fc2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1694,8 +1694,11 @@ static void loop_queue_work(struct kthread_work *work) { struct loop_cmd *cmd = container_of(work, struct loop_cmd, work); + int oldflags = current->flags & PF_LESS_THROTTLE; + current->flags |= PF_LESS_THROTTLE; loop_handle_cmd(cmd); + current->flags = (current->flags & ~PF_LESS_THROTTLE) | oldflags; } static int loop_init_request(void *data, struct request *rq, -- 2.12.0 signature.asc Description: PGP signature
Re: [PATCH net-next v3 5/5] net-next: dsa: add dsa support for Mediatek MT7530 switch
Hi Sean, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/net-next-dsa-add-Mediatek-MT7530-support/20170330-135532 config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): In file included from net/dsa/tag_mtk.c:16:0: net/dsa/dsa_priv.h:50:30: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, ^~ net/dsa/dsa_priv.h:54:39: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:55:42: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:59:36: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_slave_mii_bus_init(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:61:29: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_slave_create(struct dsa_switch *ds, struct device *parent, ^~ net/dsa/dsa_priv.h:70:41: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_switch_register_notifier(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:71:44: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_switch_unregister_notifier(struct dsa_switch *ds); ^~ net/dsa/tag_mtk.c: In function 'mtk_tag_xmit': >> net/dsa/tag_mtk.c:38:26: error: dereferencing pointer to incomplete type >> 'struct dsa_port' mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; ^~ net/dsa/tag_mtk.c: In function 'mtk_tag_rcv': >> net/dsa/tag_mtk.c:85:10: error: dereferencing pointer to incomplete type >> 'struct dsa_switch_tree' ds = dst->ds[0]; ^~ >> net/dsa/tag_mtk.c:91:9: error: dereferencing pointer to incomplete type >> 'struct dsa_switch' if (!ds->ports[port].netdev) ^~ vim +91 net/dsa/tag_mtk.c 2faad9d7 Sean Wang 2017-03-29 32 2faad9d7 Sean Wang 2017-03-29 33 memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 2faad9d7 Sean Wang 2017-03-29 34 2faad9d7 Sean Wang 2017-03-29 35 /* Build the tag after the MAC Source Address */ 2faad9d7 Sean Wang 2017-03-29 36 mtk_tag = skb->data + 2 * ETH_ALEN; 2faad9d7 Sean Wang 2017-03-29 37 mtk_tag[0] = 0; 2faad9d7 Sean Wang 2017-03-29 @38 mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; 2faad9d7 Sean Wang 2017-03-29 39 mtk_tag[2] = 0; 2faad9d7 Sean Wang 2017-03-29 40 mtk_tag[3] = 0; 2faad9d7 Sean Wang 2017-03-29 41 2faad9d7 Sean Wang 2017-03-29 42 return skb; 2faad9d7 Sean Wang 2017-03-29 43 2faad9d7 Sean Wang 2017-03-29 44 out_free: 2faad9d7 Sean Wang 2017-03-29 45 kfree_skb(skb); 2faad9d7 Sean Wang 2017-03-29 46 return NULL; 2faad9d7 Sean Wang 2017-03-29 47 } 2faad9d7 Sean Wang 2017-03-29 48 2faad9d7 Sean Wang 2017-03-29 49 static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, 2faad9d7 Sean Wang 2017-03-29 50 struct packet_type *pt, struct net_device *orig_dev) 2faad9d7 Sean Wang 2017-03-29 51 { 2faad9d7 Sean Wang 2017-03-29 52 struct dsa_switch_tree *dst = dev->dsa_ptr; 2faad9d7 Sean Wang 2017-03-29 53 struct dsa_switch *ds; 2faad9d7 Sean Wang 2017-03-29 54 int port; 2faad9d7 Sean Wang 2017-03-29 55 __be16 *phdr, hdr; 2faad9d7 Sean Wang 2017-03-29 56 2faad9d7 Sean Wang 2017-03-29 57 if (unlikely(!dst)) 2faad9d7 Sean Wang 2017-03-29 58 goto out_drop; 2faad9d7 Sean Wang 2017-03-29 59 2faad9d7 Sean Wang 2017-03-29 60 skb = skb_unshare(skb, GFP_ATOMIC); 2faad9d7 Sean Wang 2017-03-29 61 if (!skb) 2faad9d7 Sean Wang 2017-03-29 62 goto out; 2faad9d7 Sean Wang 2017-03-29 63 2faad9d7 Sean
Re: [PATCH net-next v3 5/5] net-next: dsa: add dsa support for Mediatek MT7530 switch
Hi Sean, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/sean-wang-mediatek-com/net-next-dsa-add-Mediatek-MT7530-support/20170330-135532 config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): In file included from net/dsa/tag_mtk.c:16:0: net/dsa/dsa_priv.h:50:30: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_cpu_dsa_setup(struct dsa_switch *ds, struct device *dev, ^~ net/dsa/dsa_priv.h:54:39: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_cpu_port_ethtool_setup(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:55:42: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_cpu_port_ethtool_restore(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:59:36: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_slave_mii_bus_init(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:61:29: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_slave_create(struct dsa_switch *ds, struct device *parent, ^~ net/dsa/dsa_priv.h:70:41: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration int dsa_switch_register_notifier(struct dsa_switch *ds); ^~ net/dsa/dsa_priv.h:71:44: warning: 'struct dsa_switch' declared inside parameter list will not be visible outside of this definition or declaration void dsa_switch_unregister_notifier(struct dsa_switch *ds); ^~ net/dsa/tag_mtk.c: In function 'mtk_tag_xmit': >> net/dsa/tag_mtk.c:38:26: error: dereferencing pointer to incomplete type >> 'struct dsa_port' mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; ^~ net/dsa/tag_mtk.c: In function 'mtk_tag_rcv': >> net/dsa/tag_mtk.c:85:10: error: dereferencing pointer to incomplete type >> 'struct dsa_switch_tree' ds = dst->ds[0]; ^~ >> net/dsa/tag_mtk.c:91:9: error: dereferencing pointer to incomplete type >> 'struct dsa_switch' if (!ds->ports[port].netdev) ^~ vim +91 net/dsa/tag_mtk.c 2faad9d7 Sean Wang 2017-03-29 32 2faad9d7 Sean Wang 2017-03-29 33 memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); 2faad9d7 Sean Wang 2017-03-29 34 2faad9d7 Sean Wang 2017-03-29 35 /* Build the tag after the MAC Source Address */ 2faad9d7 Sean Wang 2017-03-29 36 mtk_tag = skb->data + 2 * ETH_ALEN; 2faad9d7 Sean Wang 2017-03-29 37 mtk_tag[0] = 0; 2faad9d7 Sean Wang 2017-03-29 @38 mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; 2faad9d7 Sean Wang 2017-03-29 39 mtk_tag[2] = 0; 2faad9d7 Sean Wang 2017-03-29 40 mtk_tag[3] = 0; 2faad9d7 Sean Wang 2017-03-29 41 2faad9d7 Sean Wang 2017-03-29 42 return skb; 2faad9d7 Sean Wang 2017-03-29 43 2faad9d7 Sean Wang 2017-03-29 44 out_free: 2faad9d7 Sean Wang 2017-03-29 45 kfree_skb(skb); 2faad9d7 Sean Wang 2017-03-29 46 return NULL; 2faad9d7 Sean Wang 2017-03-29 47 } 2faad9d7 Sean Wang 2017-03-29 48 2faad9d7 Sean Wang 2017-03-29 49 static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, 2faad9d7 Sean Wang 2017-03-29 50 struct packet_type *pt, struct net_device *orig_dev) 2faad9d7 Sean Wang 2017-03-29 51 { 2faad9d7 Sean Wang 2017-03-29 52 struct dsa_switch_tree *dst = dev->dsa_ptr; 2faad9d7 Sean Wang 2017-03-29 53 struct dsa_switch *ds; 2faad9d7 Sean Wang 2017-03-29 54 int port; 2faad9d7 Sean Wang 2017-03-29 55 __be16 *phdr, hdr; 2faad9d7 Sean Wang 2017-03-29 56 2faad9d7 Sean Wang 2017-03-29 57 if (unlikely(!dst)) 2faad9d7 Sean Wang 2017-03-29 58 goto out_drop; 2faad9d7 Sean Wang 2017-03-29 59 2faad9d7 Sean Wang 2017-03-29 60 skb = skb_unshare(skb, GFP_ATOMIC); 2faad9d7 Sean Wang 2017-03-29 61 if (!skb) 2faad9d7 Sean Wang 2017-03-29 62 goto out; 2faad9d7 Sean Wang 2017-03-29 63 2faad9d7 Sean
Re: [PATCH] i2c: use void pointers for supplying data for reads and writes
Hi Dmitry, [auto build test ERROR on wsa/i2c/for-next] [also build test ERROR on v4.11-rc4 next-20170331] [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/Dmitry-Torokhov/i2c-use-void-pointers-for-supplying-data-for-reads-and-writes/20170403-074306 base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next config: i386-randconfig-a0-201714 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/iio/adc/max1363.c: In function 'max1363_probe': >> drivers/iio/adc/max1363.c:1633:12: error: assignment from incompatible >> pointer type [-Werror=incompatible-pointer-types] st->send = i2c_master_send; ^ drivers/iio/adc/max1363.c:1634:12: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types] st->recv = i2c_master_recv; ^ Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls Cyclomatic Complexity 1 arch/x86/include/asm/arch_hweight.h:__arch_hweight32 Cyclomatic Complexity 2 include/linux/bitops.h:hweight_long Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32 Cyclomatic Complexity 1 include/linux/kernel.h:kstrtoul Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_copy Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_subset Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_weight Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR Cyclomatic Complexity 1 include/linux/err.h:IS_ERR Cyclomatic Complexity 1 include/linux/device.h:devm_kzalloc Cyclomatic Complexity 1 include/linux/device.h:dev_get_drvdata Cyclomatic Complexity 1 include/linux/device.h:dev_set_drvdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_get_clientdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_set_clientdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_get_functionality Cyclomatic Complexity 1 include/linux/i2c.h:i2c_check_functionality Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large Cyclomatic Complexity 5 include/linux/slab.h:kmalloc Cyclomatic Complexity 1 include/linux/iio/iio.h:dev_to_iio_dev Cyclomatic Complexity 1 include/linux/iio/iio.h:iio_priv Cyclomatic Complexity 1 include/linux/iio/iio.h:iio_buffer_enabled Cyclomatic Complexity 2 include/linux/iio/buffer.h:iio_push_to_buffers_with_timestamp Cyclomatic Complexity 4 drivers/iio/adc/max1363.c:max1363_match_mode Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_write_basic_config Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_set_scan_mode Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_read_thresh Cyclomatic Complexity 7 drivers/iio/adc/max1363.c:max1363_write_thresh Cyclomatic Complexity 6 drivers/iio/adc/max1363.c:__max1363_check_event_mask Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_update_scan_mode Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_initial_setup Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_alloc_scan_masks Cyclomatic Complexity 8 drivers/iio/adc/max1363.c:max1363_read_single_chan Cyclomatic Complexity 4 drivers/iio/adc/max1363.c:max1363_read_raw Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_read_event_config Cyclomatic Complexity 5 drivers/iio/adc/max1363.c:max1363_monitor_store_freq Cyclomatic Complexity 16 drivers/iio/adc/max1363.c:max1363_monitor_mode_update Cyclomatic Complexity 6 drivers/iio/adc/max1363.c:max1363_write_event_config Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_monitor_show_freq Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_remove Cyclomatic Complexity 19 drivers/iio/adc/max1363.c:max1363_probe Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_event_handler Cyclomatic Complexity 8 drivers/iio/adc/max1363.c:max1363_trigger_handler Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_smbus_recv Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_smbus_send Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_driver_init Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_driver_exit cc1: some warnings being treated as errors vim +1633 drivers/iio/adc/max1363.c a405b00e Guenter Roeck 2013-02-03 1617if (!IS_ERR(vref)) { a405b00e Guenter Roeck 2013-02-03 1618int vref_uv; a405b00e Guenter Roeck 2013-02-03 1619 a405b00e Guenter Roeck 2013-02-03 1620ret
linux-next: build warning after merge of the nfsd tree
Hi, After merging the nfsd tree, today's linux-next build (powerpc ppc64_defconfig) produced this warning: fs/nfsd/nfs4state.c: In function 'copy_cred': fs/nfsd/nfs4state.c:1917:6: warning: unused variable 'ret' [-Wunused-variable] int ret; ^ Introduced by commit d39662236bf8 ("nfsd4: remove pointless strdup_if_nonnull") Also, that commit has no Signed-off-by from its Author. -- Cheers, Stephen Rothwell
Re: [PATCH] i2c: use void pointers for supplying data for reads and writes
Hi Dmitry, [auto build test ERROR on wsa/i2c/for-next] [also build test ERROR on v4.11-rc4 next-20170331] [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/Dmitry-Torokhov/i2c-use-void-pointers-for-supplying-data-for-reads-and-writes/20170403-074306 base: https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next config: i386-randconfig-a0-201714 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/iio/adc/max1363.c: In function 'max1363_probe': >> drivers/iio/adc/max1363.c:1633:12: error: assignment from incompatible >> pointer type [-Werror=incompatible-pointer-types] st->send = i2c_master_send; ^ drivers/iio/adc/max1363.c:1634:12: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types] st->recv = i2c_master_recv; ^ Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls Cyclomatic Complexity 1 arch/x86/include/asm/arch_hweight.h:__arch_hweight32 Cyclomatic Complexity 2 include/linux/bitops.h:hweight_long Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32 Cyclomatic Complexity 1 include/linux/kernel.h:kstrtoul Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_copy Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_subset Cyclomatic Complexity 3 include/linux/bitmap.h:bitmap_weight Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR Cyclomatic Complexity 1 include/linux/err.h:IS_ERR Cyclomatic Complexity 1 include/linux/device.h:devm_kzalloc Cyclomatic Complexity 1 include/linux/device.h:dev_get_drvdata Cyclomatic Complexity 1 include/linux/device.h:dev_set_drvdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_get_clientdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_set_clientdata Cyclomatic Complexity 1 include/linux/i2c.h:i2c_get_functionality Cyclomatic Complexity 1 include/linux/i2c.h:i2c_check_functionality Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large Cyclomatic Complexity 5 include/linux/slab.h:kmalloc Cyclomatic Complexity 1 include/linux/iio/iio.h:dev_to_iio_dev Cyclomatic Complexity 1 include/linux/iio/iio.h:iio_priv Cyclomatic Complexity 1 include/linux/iio/iio.h:iio_buffer_enabled Cyclomatic Complexity 2 include/linux/iio/buffer.h:iio_push_to_buffers_with_timestamp Cyclomatic Complexity 4 drivers/iio/adc/max1363.c:max1363_match_mode Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_write_basic_config Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_set_scan_mode Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_read_thresh Cyclomatic Complexity 7 drivers/iio/adc/max1363.c:max1363_write_thresh Cyclomatic Complexity 6 drivers/iio/adc/max1363.c:__max1363_check_event_mask Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_update_scan_mode Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_initial_setup Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_alloc_scan_masks Cyclomatic Complexity 8 drivers/iio/adc/max1363.c:max1363_read_single_chan Cyclomatic Complexity 4 drivers/iio/adc/max1363.c:max1363_read_raw Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_read_event_config Cyclomatic Complexity 5 drivers/iio/adc/max1363.c:max1363_monitor_store_freq Cyclomatic Complexity 16 drivers/iio/adc/max1363.c:max1363_monitor_mode_update Cyclomatic Complexity 6 drivers/iio/adc/max1363.c:max1363_write_event_config Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_monitor_show_freq Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_remove Cyclomatic Complexity 19 drivers/iio/adc/max1363.c:max1363_probe Cyclomatic Complexity 2 drivers/iio/adc/max1363.c:max1363_event_handler Cyclomatic Complexity 8 drivers/iio/adc/max1363.c:max1363_trigger_handler Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_smbus_recv Cyclomatic Complexity 3 drivers/iio/adc/max1363.c:max1363_smbus_send Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_driver_init Cyclomatic Complexity 1 drivers/iio/adc/max1363.c:max1363_driver_exit cc1: some warnings being treated as errors vim +1633 drivers/iio/adc/max1363.c a405b00e Guenter Roeck 2013-02-03 1617if (!IS_ERR(vref)) { a405b00e Guenter Roeck 2013-02-03 1618int vref_uv; a405b00e Guenter Roeck 2013-02-03 1619 a405b00e Guenter Roeck 2013-02-03 1620ret
linux-next: build warning after merge of the nfsd tree
Hi, After merging the nfsd tree, today's linux-next build (powerpc ppc64_defconfig) produced this warning: fs/nfsd/nfs4state.c: In function 'copy_cred': fs/nfsd/nfs4state.c:1917:6: warning: unused variable 'ret' [-Wunused-variable] int ret; ^ Introduced by commit d39662236bf8 ("nfsd4: remove pointless strdup_if_nonnull") Also, that commit has no Signed-off-by from its Author. -- Cheers, Stephen Rothwell