Re: [PATCH v2 1/3] resource: Use list_head to link sibling resource
Hi Baoquan, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16 next-20180406] [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/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180408-110108 config: sparc-defconfig (attached as .config) compiler: sparc-linux-gcc (GCC) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc All errors (new ones prefixed by >>): arch/sparc/kernel/ioport.c: In function 'sparc_io_proc_show': >> arch/sparc/kernel/ioport.c:672:9: error: incompatible types when assigning >> to type 'struct resource *' from type 'struct list_head' for (r = root->child; r != NULL; r = r->sibling) { ^ arch/sparc/kernel/ioport.c:672:37: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head' for (r = root->child; r != NULL; r = r->sibling) { ^ vim +672 arch/sparc/kernel/ioport.c ^1da177e4 Linus Torvalds 2005-04-16 666 e7a088f93 Alexey Dobriyan2009-09-01 667 static int sparc_io_proc_show(struct seq_file *m, void *v) ^1da177e4 Linus Torvalds 2005-04-16 668 { e7a088f93 Alexey Dobriyan2009-09-01 669struct resource *root = m->private, *r; ^1da177e4 Linus Torvalds 2005-04-16 670const char *nm; ^1da177e4 Linus Torvalds 2005-04-16 671 e7a088f93 Alexey Dobriyan2009-09-01 @672for (r = root->child; r != NULL; r = r->sibling) { c31f76518 Sam Ravnborg 2014-04-21 673if ((nm = r->name) == NULL) nm = "???"; e7a088f93 Alexey Dobriyan2009-09-01 674seq_printf(m, "%016llx-%016llx: %s\n", 685143ac1 Greg Kroah-Hartman 2006-06-12 675 (unsigned long long)r->start, 685143ac1 Greg Kroah-Hartman 2006-06-12 676 (unsigned long long)r->end, nm); ^1da177e4 Linus Torvalds 2005-04-16 677} ^1da177e4 Linus Torvalds 2005-04-16 678 e7a088f93 Alexey Dobriyan2009-09-01 679return 0; ^1da177e4 Linus Torvalds 2005-04-16 680 } ^1da177e4 Linus Torvalds 2005-04-16 681 :: The code at line 672 was first introduced by commit :: e7a088f935180b90cfe6ab0aaae8a556f46885fe sparc: convert /proc/io_map, /proc/dvma_map to seq_file :: TO: Alexey Dobriyan:: CC: David S. Miller --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 1/3] resource: Use list_head to link sibling resource
Hi Baoquan, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16 next-20180406] [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/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180408-110108 config: sparc-defconfig (attached as .config) compiler: sparc-linux-gcc (GCC) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sparc All errors (new ones prefixed by >>): arch/sparc/kernel/ioport.c: In function 'sparc_io_proc_show': >> arch/sparc/kernel/ioport.c:672:9: error: incompatible types when assigning >> to type 'struct resource *' from type 'struct list_head' for (r = root->child; r != NULL; r = r->sibling) { ^ arch/sparc/kernel/ioport.c:672:37: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head' for (r = root->child; r != NULL; r = r->sibling) { ^ vim +672 arch/sparc/kernel/ioport.c ^1da177e4 Linus Torvalds 2005-04-16 666 e7a088f93 Alexey Dobriyan2009-09-01 667 static int sparc_io_proc_show(struct seq_file *m, void *v) ^1da177e4 Linus Torvalds 2005-04-16 668 { e7a088f93 Alexey Dobriyan2009-09-01 669struct resource *root = m->private, *r; ^1da177e4 Linus Torvalds 2005-04-16 670const char *nm; ^1da177e4 Linus Torvalds 2005-04-16 671 e7a088f93 Alexey Dobriyan2009-09-01 @672for (r = root->child; r != NULL; r = r->sibling) { c31f76518 Sam Ravnborg 2014-04-21 673if ((nm = r->name) == NULL) nm = "???"; e7a088f93 Alexey Dobriyan2009-09-01 674seq_printf(m, "%016llx-%016llx: %s\n", 685143ac1 Greg Kroah-Hartman 2006-06-12 675 (unsigned long long)r->start, 685143ac1 Greg Kroah-Hartman 2006-06-12 676 (unsigned long long)r->end, nm); ^1da177e4 Linus Torvalds 2005-04-16 677} ^1da177e4 Linus Torvalds 2005-04-16 678 e7a088f93 Alexey Dobriyan2009-09-01 679return 0; ^1da177e4 Linus Torvalds 2005-04-16 680 } ^1da177e4 Linus Torvalds 2005-04-16 681 :: The code at line 672 was first introduced by commit :: e7a088f935180b90cfe6ab0aaae8a556f46885fe sparc: convert /proc/io_map, /proc/dvma_map to seq_file :: TO: Alexey Dobriyan :: CC: David S. Miller --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
On Sun, Apr 8, 2018 at 11:48 AM, Steven Rostedtwrote: > On Sun, 8 Apr 2018 10:16:23 +0800 > Zhaoyang Huang wrote: > >> Don't choose the process with adj == OOM_SCORE_ADJ_MIN which >> over-allocating pages for ring buffers. > > Why? > > -- Steve because in oom_evaluate_task, the process with adj == OOM_SCORE_ADJ_MIN will be suppressed by oom_badness, but with applying your latest patch, such process will be selected by oom_task_origin if (oom_task_origin(task)) { points = ULONG_MAX; goto select; } points = oom_badness(task, NULL, oc->nodemask, oc->totalpages); if (!points || points < oc->chosen_points) goto next;
Re: [PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
On Sun, Apr 8, 2018 at 11:48 AM, Steven Rostedt wrote: > On Sun, 8 Apr 2018 10:16:23 +0800 > Zhaoyang Huang wrote: > >> Don't choose the process with adj == OOM_SCORE_ADJ_MIN which >> over-allocating pages for ring buffers. > > Why? > > -- Steve because in oom_evaluate_task, the process with adj == OOM_SCORE_ADJ_MIN will be suppressed by oom_badness, but with applying your latest patch, such process will be selected by oom_task_origin if (oom_task_origin(task)) { points = ULONG_MAX; goto select; } points = oom_badness(task, NULL, oc->nodemask, oc->totalpages); if (!points || points < oc->chosen_points) goto next;
[no subject]
Benötigen Sie ein persönliches oder geschäftliches Darlehen mit 2% Zinssatz? Wir bieten Projektfinanzierung Business Loans Personal Loans. für weitere Informationen kontaktieren Sie uns bitte
[no subject]
Benötigen Sie ein persönliches oder geschäftliches Darlehen mit 2% Zinssatz? Wir bieten Projektfinanzierung Business Loans Personal Loans. für weitere Informationen kontaktieren Sie uns bitte
Re: Use struct page for filename
On Sat, Apr 07, 2018 at 08:16:46PM -0700, Matthew Wilcox wrote: > On Fri, Apr 06, 2018 at 03:33:36PM +0200, Dmitry Vyukov wrote: > > On Fri, Apr 6, 2018 at 3:24 PM, syzbot > >wrote: > > > cache_from_obj: Wrong slab cache. names_cache but object is from > > > kmalloc-96 > > > > Al, do you see how this can happen? > > I don't see how it happened, but when looking at this bug, I thought > "This is very complicated, I think there's a simpler way to handle this". > > Here's a proposal. It won't apply to any existing tree (depends on a > couple of local commits), but I think you'll get the general flavour > of it. It's mostly compile-tested (build still running, but fs/ and > kernel/ compiled without issue). > +struct audit_names; > + > +struct filename { > + const char *name; /* pointer to actual string */ > + const __user char *uptr; /* original userland pointer */ > + struct audit_names *aname; > +}; > > /* > * Each physical page in the system has a struct page associated with > @@ -188,6 +195,7 @@ struct page { > spinlock_t ptl; > #endif > }; > + struct filename filename; > }; Oh, lovely - extra 24 bytes into each struct page. Plus the delta to performance due to switching from kmem_cache_alloc to alloc_page. Negative one, that is...
Re: Use struct page for filename
On Sat, Apr 07, 2018 at 08:16:46PM -0700, Matthew Wilcox wrote: > On Fri, Apr 06, 2018 at 03:33:36PM +0200, Dmitry Vyukov wrote: > > On Fri, Apr 6, 2018 at 3:24 PM, syzbot > > wrote: > > > cache_from_obj: Wrong slab cache. names_cache but object is from > > > kmalloc-96 > > > > Al, do you see how this can happen? > > I don't see how it happened, but when looking at this bug, I thought > "This is very complicated, I think there's a simpler way to handle this". > > Here's a proposal. It won't apply to any existing tree (depends on a > couple of local commits), but I think you'll get the general flavour > of it. It's mostly compile-tested (build still running, but fs/ and > kernel/ compiled without issue). > +struct audit_names; > + > +struct filename { > + const char *name; /* pointer to actual string */ > + const __user char *uptr; /* original userland pointer */ > + struct audit_names *aname; > +}; > > /* > * Each physical page in the system has a struct page associated with > @@ -188,6 +195,7 @@ struct page { > spinlock_t ptl; > #endif > }; > + struct filename filename; > }; Oh, lovely - extra 24 bytes into each struct page. Plus the delta to performance due to switching from kmem_cache_alloc to alloc_page. Negative one, that is...
[PATCH] ASoC: fsl_ssi: Fix mode setting when changing channel number
This is a partial revert (in a cleaner way) of commit ebf08ae3bc90 ("ASoC: fsl_ssi: Keep ssi->i2s_net updated") to fix a regression at test cases when switching between mono and stereo audio. The problem is that ssi->i2s_net is initialized in set_dai_fmt() only, while this set_dai_fmt() is only called during the dai-link probe(). The original patch assumed set_dai_fmt() would be called during every playback instance, so it failed at the overriding use cases. This patch adds the local variable i2s_net back to let regular use cases still follow the mode settings from the set_dai_fmt(). Meanwhile, the original commit of keeping ssi->i2s_net updated was to make set_tdm_slot() clean by checking the ssi->i2s_net directly instead of reading SCR register. However, the change itself is not necessary (or even harmful) because the set_tdm_slot() might fail to check the slot number for Normal-Mode-None-Net settings while mono audio cases still need 2 slots. So this patch can also fix it. And it adds an extra line of comments to declare ssi->i2s_net does not reflect the register value but merely the initial setting from the set_dai_fmt(). Reported-by: Mika PenttiläSigned-off-by: Nicolin Chen Cc: Mika Penttilä --- sound/soc/fsl/fsl_ssi.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 0823b08..89df2d9 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -217,6 +217,7 @@ struct fsl_ssi_soc_data { * @dai_fmt: DAI configuration this device is currently used with * @streams: Mask of current active streams: BIT(TX) and BIT(RX) * @i2s_net: I2S and Network mode configurations of SCR register + * (this is the initial settings based on the DAI format) * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK * @use_dma: DMA is used or FIQ with stream filter * @use_dual_fifo: DMA with support for dual FIFO mode @@ -829,16 +830,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } if (!fsl_ssi_is_ac97(ssi)) { + /* +* Keep the ssi->i2s_net intact while having a local variable +* to override settings for special use cases. Otherwise, the +* ssi->i2s_net will lose the settings for regular use cases. +*/ + u8 i2s_net = ssi->i2s_net; + /* Normal + Network mode to send 16-bit data in 32-bit frames */ if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16) - ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; + i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; /* Use Normal mode to send mono data at 1st slot of 2 slots */ if (channels == 1) - ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL; + i2s_net = SSI_SCR_I2S_MODE_NORMAL; regmap_update_bits(regs, REG_SSI_SCR, - SSI_SCR_I2S_NET_MASK, ssi->i2s_net); + SSI_SCR_I2S_NET_MASK, i2s_net); } /* In synchronous mode, the SSI uses STCCR for capture */ -- 2.7.4
[PATCH] ASoC: fsl_ssi: Fix mode setting when changing channel number
This is a partial revert (in a cleaner way) of commit ebf08ae3bc90 ("ASoC: fsl_ssi: Keep ssi->i2s_net updated") to fix a regression at test cases when switching between mono and stereo audio. The problem is that ssi->i2s_net is initialized in set_dai_fmt() only, while this set_dai_fmt() is only called during the dai-link probe(). The original patch assumed set_dai_fmt() would be called during every playback instance, so it failed at the overriding use cases. This patch adds the local variable i2s_net back to let regular use cases still follow the mode settings from the set_dai_fmt(). Meanwhile, the original commit of keeping ssi->i2s_net updated was to make set_tdm_slot() clean by checking the ssi->i2s_net directly instead of reading SCR register. However, the change itself is not necessary (or even harmful) because the set_tdm_slot() might fail to check the slot number for Normal-Mode-None-Net settings while mono audio cases still need 2 slots. So this patch can also fix it. And it adds an extra line of comments to declare ssi->i2s_net does not reflect the register value but merely the initial setting from the set_dai_fmt(). Reported-by: Mika Penttilä Signed-off-by: Nicolin Chen Cc: Mika Penttilä --- sound/soc/fsl/fsl_ssi.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 0823b08..89df2d9 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -217,6 +217,7 @@ struct fsl_ssi_soc_data { * @dai_fmt: DAI configuration this device is currently used with * @streams: Mask of current active streams: BIT(TX) and BIT(RX) * @i2s_net: I2S and Network mode configurations of SCR register + * (this is the initial settings based on the DAI format) * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK * @use_dma: DMA is used or FIQ with stream filter * @use_dual_fifo: DMA with support for dual FIFO mode @@ -829,16 +830,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } if (!fsl_ssi_is_ac97(ssi)) { + /* +* Keep the ssi->i2s_net intact while having a local variable +* to override settings for special use cases. Otherwise, the +* ssi->i2s_net will lose the settings for regular use cases. +*/ + u8 i2s_net = ssi->i2s_net; + /* Normal + Network mode to send 16-bit data in 32-bit frames */ if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16) - ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; + i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; /* Use Normal mode to send mono data at 1st slot of 2 slots */ if (channels == 1) - ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL; + i2s_net = SSI_SCR_I2S_MODE_NORMAL; regmap_update_bits(regs, REG_SSI_SCR, - SSI_SCR_I2S_NET_MASK, ssi->i2s_net); + SSI_SCR_I2S_NET_MASK, i2s_net); } /* In synchronous mode, the SSI uses STCCR for capture */ -- 2.7.4
Re: __GFP_LOW
On Fri, Apr 06, 2018 at 08:09:53AM +0200, Michal Hocko wrote: > OK, we already split the documentation into these categories. So we got > at least the structure right ;) Yes, this part of the documentation makes sense to me :-) > > - What kind of memory to allocate (DMA, NORMAL, HIGHMEM) > > - Where to get the pages from > >- Local node only (THISNODE) > >- Only in compliance with cpuset policy (HARDWALL) > >- Spread the pages between zones (WRITE) > >- The movable zone (MOVABLE) > >- The reclaimable zone (RECLAIMABLE) > > - What you are willing to do if no free memory is available: > >- Nothing at all (NOWAIT) > >- Use my own time to free memory (DIRECT_RECLAIM) > > - But only try once (NORETRY) > > - Can call into filesystems (FS) > > - Can start I/O (IO) > > - Can sleep (!ATOMIC) > >- Steal time from other processes to free memory (KSWAPD_RECLAIM) > > What does that mean? If I drop the flag, do not steal? Well I do because > they will hit direct reclaim sooner... If they allocate memory, sure. A process which stays in its working set won't, unless it's preempted by kswapd. > >- Kill other processes to get their memory (!RETRY_MAYFAIL) > > Not really for costly orders. Yes, need to be more precise there. > >- All of the above, and wait forever (NOFAIL) > >- Take from emergency reserves (HIGH) > >- ... but not the last parts of the regular reserves (LOW) > > What does that mean and how it is different from NOWAIT? Is this about > the low watermark and if yes do we want to teach users about this and > make the whole thing even more complicated? Does it wake > kswapd? What is the eagerness ordering? LOW, NOWAIT, NORETRY, > RETRY_MAYFAIL, NOFAIL? LOW doesn't quite fit into the eagerness scale with the other flags; instead it's composable with them. So you can specify NOWAIT | LOW, NORETRY | LOW, NOFAIL | LOW, etc. All I have in mind is something like this: if (alloc_flags & ALLOC_HIGH) min -= min / 2; + if (alloc_flags & ALLOC_LOW) + min += min / 2; The idea is that a GFP_KERNEL | __GFP_LOW allocation cannot force a GFP_KERNEL allocation into an OOM situation because it cannot take the last pages of memory before the watermark. It can still make a GFP_KERNEL allocation *more likely* to hit OOM (just like any other kind of allocation can), but it can't do it by itself. --- I've been wondering about combining the DIRECT_RECLAIM, NORETRY, RETRY_MAYFAIL and NOFAIL flags together into a single field: 0 => RECLAIM_NEVER, /* !DIRECT_RECLAIM */ 1 => RECLAIM_ONCE, /* NORETRY */ 2 => RECLAIM_PROGRESS, /* RETRY_MAYFAIL */ 3 => RECLAIM_FOREVER, /* NOFAIL */ The existance of __GFP_RECLAIM makes this a bit tricky. I honestly don't know what this code is asking for: kernel/power/swap.c: __get_free_page(__GFP_RECLAIM | __GFP_HIGH); but I suspect I'll have to find out. There's about 60 places to look at. I also want to add __GFP_KILL (to be part of the GFP_KERNEL definition). That way, each bit that you set in the GFP mask increases the things the page allocator can do to get memory for you. At the moment, RETRY_MAYFAIL subtracts the ability to kill other tasks, which is unusual. For example, this test in kvmalloc_node: WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); doesn't catch RETRY_MAYFAIL being set.
Re: __GFP_LOW
On Fri, Apr 06, 2018 at 08:09:53AM +0200, Michal Hocko wrote: > OK, we already split the documentation into these categories. So we got > at least the structure right ;) Yes, this part of the documentation makes sense to me :-) > > - What kind of memory to allocate (DMA, NORMAL, HIGHMEM) > > - Where to get the pages from > >- Local node only (THISNODE) > >- Only in compliance with cpuset policy (HARDWALL) > >- Spread the pages between zones (WRITE) > >- The movable zone (MOVABLE) > >- The reclaimable zone (RECLAIMABLE) > > - What you are willing to do if no free memory is available: > >- Nothing at all (NOWAIT) > >- Use my own time to free memory (DIRECT_RECLAIM) > > - But only try once (NORETRY) > > - Can call into filesystems (FS) > > - Can start I/O (IO) > > - Can sleep (!ATOMIC) > >- Steal time from other processes to free memory (KSWAPD_RECLAIM) > > What does that mean? If I drop the flag, do not steal? Well I do because > they will hit direct reclaim sooner... If they allocate memory, sure. A process which stays in its working set won't, unless it's preempted by kswapd. > >- Kill other processes to get their memory (!RETRY_MAYFAIL) > > Not really for costly orders. Yes, need to be more precise there. > >- All of the above, and wait forever (NOFAIL) > >- Take from emergency reserves (HIGH) > >- ... but not the last parts of the regular reserves (LOW) > > What does that mean and how it is different from NOWAIT? Is this about > the low watermark and if yes do we want to teach users about this and > make the whole thing even more complicated? Does it wake > kswapd? What is the eagerness ordering? LOW, NOWAIT, NORETRY, > RETRY_MAYFAIL, NOFAIL? LOW doesn't quite fit into the eagerness scale with the other flags; instead it's composable with them. So you can specify NOWAIT | LOW, NORETRY | LOW, NOFAIL | LOW, etc. All I have in mind is something like this: if (alloc_flags & ALLOC_HIGH) min -= min / 2; + if (alloc_flags & ALLOC_LOW) + min += min / 2; The idea is that a GFP_KERNEL | __GFP_LOW allocation cannot force a GFP_KERNEL allocation into an OOM situation because it cannot take the last pages of memory before the watermark. It can still make a GFP_KERNEL allocation *more likely* to hit OOM (just like any other kind of allocation can), but it can't do it by itself. --- I've been wondering about combining the DIRECT_RECLAIM, NORETRY, RETRY_MAYFAIL and NOFAIL flags together into a single field: 0 => RECLAIM_NEVER, /* !DIRECT_RECLAIM */ 1 => RECLAIM_ONCE, /* NORETRY */ 2 => RECLAIM_PROGRESS, /* RETRY_MAYFAIL */ 3 => RECLAIM_FOREVER, /* NOFAIL */ The existance of __GFP_RECLAIM makes this a bit tricky. I honestly don't know what this code is asking for: kernel/power/swap.c: __get_free_page(__GFP_RECLAIM | __GFP_HIGH); but I suspect I'll have to find out. There's about 60 places to look at. I also want to add __GFP_KILL (to be part of the GFP_KERNEL definition). That way, each bit that you set in the GFP mask increases the things the page allocator can do to get memory for you. At the moment, RETRY_MAYFAIL subtracts the ability to kill other tasks, which is unusual. For example, this test in kvmalloc_node: WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL); doesn't catch RETRY_MAYFAIL being set.
Re: [PATCH v2 1/3] resource: Use list_head to link sibling resource
Hi Baoquan, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16 next-20180406] [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/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180408-110108 config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): drivers//parisc/lba_pci.c: In function 'lba_dump_res': >> drivers//parisc/lba_pci.c:173:15: error: incompatible type for argument 1 of >> 'lba_dump_res' lba_dump_res(r->child, d+2); ^ drivers//parisc/lba_pci.c:162:1: note: expected 'struct resource *' but argument is of type 'struct list_head' lba_dump_res(struct resource *r, int d) ^~~~ drivers//parisc/lba_pci.c:174:15: error: incompatible type for argument 1 of 'lba_dump_res' lba_dump_res(r->sibling, d); ^ drivers//parisc/lba_pci.c:162:1: note: expected 'struct resource *' but argument is of type 'struct list_head' lba_dump_res(struct resource *r, int d) ^~~~ vim +/lba_dump_res +173 drivers//parisc/lba_pci.c ^1da177e Linus Torvalds 2005-04-16 159 ^1da177e Linus Torvalds 2005-04-16 160 ^1da177e Linus Torvalds 2005-04-16 161 static void ^1da177e Linus Torvalds 2005-04-16 162 lba_dump_res(struct resource *r, int d) ^1da177e Linus Torvalds 2005-04-16 163 { ^1da177e Linus Torvalds 2005-04-16 164 int i; ^1da177e Linus Torvalds 2005-04-16 165 ^1da177e Linus Torvalds 2005-04-16 166 if (NULL == r) ^1da177e Linus Torvalds 2005-04-16 167 return; ^1da177e Linus Torvalds 2005-04-16 168 ^1da177e Linus Torvalds 2005-04-16 169 printk(KERN_DEBUG "(%p)", r->parent); ^1da177e Linus Torvalds 2005-04-16 170 for (i = d; i ; --i) printk(" "); 645d11d4 Matthew Wilcox 2006-12-24 171 printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r, 645d11d4 Matthew Wilcox 2006-12-24 172 (long)r->start, (long)r->end, r->flags); ^1da177e Linus Torvalds 2005-04-16 @173 lba_dump_res(r->child, d+2); ^1da177e Linus Torvalds 2005-04-16 174 lba_dump_res(r->sibling, d); ^1da177e Linus Torvalds 2005-04-16 175 } ^1da177e Linus Torvalds 2005-04-16 176 :: The code at line 173 was first introduced by commit :: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :: TO: Linus Torvalds:: CC: Linus Torvalds --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 1/3] resource: Use list_head to link sibling resource
Hi Baoquan, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16 next-20180406] [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/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180408-110108 config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): drivers//parisc/lba_pci.c: In function 'lba_dump_res': >> drivers//parisc/lba_pci.c:173:15: error: incompatible type for argument 1 of >> 'lba_dump_res' lba_dump_res(r->child, d+2); ^ drivers//parisc/lba_pci.c:162:1: note: expected 'struct resource *' but argument is of type 'struct list_head' lba_dump_res(struct resource *r, int d) ^~~~ drivers//parisc/lba_pci.c:174:15: error: incompatible type for argument 1 of 'lba_dump_res' lba_dump_res(r->sibling, d); ^ drivers//parisc/lba_pci.c:162:1: note: expected 'struct resource *' but argument is of type 'struct list_head' lba_dump_res(struct resource *r, int d) ^~~~ vim +/lba_dump_res +173 drivers//parisc/lba_pci.c ^1da177e Linus Torvalds 2005-04-16 159 ^1da177e Linus Torvalds 2005-04-16 160 ^1da177e Linus Torvalds 2005-04-16 161 static void ^1da177e Linus Torvalds 2005-04-16 162 lba_dump_res(struct resource *r, int d) ^1da177e Linus Torvalds 2005-04-16 163 { ^1da177e Linus Torvalds 2005-04-16 164 int i; ^1da177e Linus Torvalds 2005-04-16 165 ^1da177e Linus Torvalds 2005-04-16 166 if (NULL == r) ^1da177e Linus Torvalds 2005-04-16 167 return; ^1da177e Linus Torvalds 2005-04-16 168 ^1da177e Linus Torvalds 2005-04-16 169 printk(KERN_DEBUG "(%p)", r->parent); ^1da177e Linus Torvalds 2005-04-16 170 for (i = d; i ; --i) printk(" "); 645d11d4 Matthew Wilcox 2006-12-24 171 printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r, 645d11d4 Matthew Wilcox 2006-12-24 172 (long)r->start, (long)r->end, r->flags); ^1da177e Linus Torvalds 2005-04-16 @173 lba_dump_res(r->child, d+2); ^1da177e Linus Torvalds 2005-04-16 174 lba_dump_res(r->sibling, d); ^1da177e Linus Torvalds 2005-04-16 175 } ^1da177e Linus Torvalds 2005-04-16 176 :: The code at line 173 was first introduced by commit :: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :: TO: Linus Torvalds :: CC: Linus Torvalds --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
RE: [PATCH 1/1] target:separate tx/rx cmd_puds
> -Original Message- > From: David Disseldorp [mailto:dd...@suse.de] > Sent: Friday, April 6, 2018 8:10 PM > To: Zhang Zhuoyu> Cc: n...@linux-iscsi.org; linux-s...@vger.kernel.org; target- > de...@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH 1/1] target:separate tx/rx cmd_puds > > On Thu, 5 Apr 2018 13:12:12 +0200, David Disseldorp wrote: > > > > -CONFIGFS_ATTR_RO(target_stat_tgt_port_, in_cmds); > > > +CONFIGFS_ATTR_RO(target_stat_tgt_port_, tx_cmds); > > > +CONFIGFS_ATTR_RO(target_stat_tgt_port_, rx_cmds); > > > > I don't think the in_cmds metric should be deleted here. It could be > > calculated on the fly via tx_cmds + rx_cmds + nodata_cmds. > > @Zhang Zhuoyu: How about something like the following? > https://git.samba.org/?p=ddiss/linux.git;a=commitdiff;h=73723ccf433424721 > 830797d70cfb88d4596e0fc > Mmm... This patch is much better. Looks good to me. Zhuoyu > ...this keeps the in_cmds metric, and renames tx/rx_cmds read/write_cmds > respectively. read/write_cmds is still a bit ambiguous, as it refers to the > command data direction rather than SCSI READ/WRITE CDBs, but IMO it's > clearer, and more consistent with the read/write_mbytes metrics. > > Cheers, David
RE: [PATCH 1/1] target:separate tx/rx cmd_puds
> -Original Message- > From: David Disseldorp [mailto:dd...@suse.de] > Sent: Friday, April 6, 2018 8:10 PM > To: Zhang Zhuoyu > Cc: n...@linux-iscsi.org; linux-s...@vger.kernel.org; target- > de...@vger.kernel.org; linux-kernel@vger.kernel.org > Subject: Re: [PATCH 1/1] target:separate tx/rx cmd_puds > > On Thu, 5 Apr 2018 13:12:12 +0200, David Disseldorp wrote: > > > > -CONFIGFS_ATTR_RO(target_stat_tgt_port_, in_cmds); > > > +CONFIGFS_ATTR_RO(target_stat_tgt_port_, tx_cmds); > > > +CONFIGFS_ATTR_RO(target_stat_tgt_port_, rx_cmds); > > > > I don't think the in_cmds metric should be deleted here. It could be > > calculated on the fly via tx_cmds + rx_cmds + nodata_cmds. > > @Zhang Zhuoyu: How about something like the following? > https://git.samba.org/?p=ddiss/linux.git;a=commitdiff;h=73723ccf433424721 > 830797d70cfb88d4596e0fc > Mmm... This patch is much better. Looks good to me. Zhuoyu > ...this keeps the in_cmds metric, and renames tx/rx_cmds read/write_cmds > respectively. read/write_cmds is still a bit ambiguous, as it refers to the > command data direction rather than SCSI READ/WRITE CDBs, but IMO it's > clearer, and more consistent with the read/write_mbytes metrics. > > Cheers, David
Re: [PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
On Sun, 8 Apr 2018 10:16:23 +0800 Zhaoyang Huangwrote: > Don't choose the process with adj == OOM_SCORE_ADJ_MIN which > over-allocating pages for ring buffers. Why? -- Steve
Re: [PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
On Sun, 8 Apr 2018 10:16:23 +0800 Zhaoyang Huang wrote: > Don't choose the process with adj == OOM_SCORE_ADJ_MIN which > over-allocating pages for ring buffers. Why? -- Steve
[PATCH -mm] mm, pagemap: Fix swap offset value for PMD migration entry
From: Huang YingThe swap offset reported by /proc//pagemap may be not correct for PMD migration entry. If addr passed into pagemap_range() isn't aligned with PMD start address, the swap offset reported doesn't reflect this. And in the loop to report information of each sub-page, the swap offset isn't increased accordingly as that for PFN. BTW: migration swap entries have PFN information, do we need to restrict whether to show them? Signed-off-by: "Huang, Ying" Cc: Michal Hocko Cc: "Kirill A. Shutemov" Cc: Andrei Vagin Cc: Dan Williams Cc: "Jerome Glisse" Cc: Daniel Colascione Cc: Zi Yan Cc: Naoya Horiguchi --- fs/proc/task_mmu.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 65ae54659833..757e748da613 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1310,9 +1310,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION else if (is_swap_pmd(pmd)) { swp_entry_t entry = pmd_to_swp_entry(pmd); + unsigned long offset = swp_offset(entry); + offset += (addr & ~PMD_MASK) >> PAGE_SHIFT; frame = swp_type(entry) | - (swp_offset(entry) << MAX_SWAPFILES_SHIFT); + (offset << MAX_SWAPFILES_SHIFT); flags |= PM_SWAP; if (pmd_swp_soft_dirty(pmd)) flags |= PM_SOFT_DIRTY; @@ -1332,6 +1334,8 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, break; if (pm->show_pfn && (flags & PM_PRESENT)) frame++; + else if (flags | PM_SWAP) + frame += (1 << MAX_SWAPFILES_SHIFT); } spin_unlock(ptl); return err; -- 2.15.1
[PATCH -mm] mm, pagemap: Fix swap offset value for PMD migration entry
From: Huang Ying The swap offset reported by /proc//pagemap may be not correct for PMD migration entry. If addr passed into pagemap_range() isn't aligned with PMD start address, the swap offset reported doesn't reflect this. And in the loop to report information of each sub-page, the swap offset isn't increased accordingly as that for PFN. BTW: migration swap entries have PFN information, do we need to restrict whether to show them? Signed-off-by: "Huang, Ying" Cc: Michal Hocko Cc: "Kirill A. Shutemov" Cc: Andrei Vagin Cc: Dan Williams Cc: "Jerome Glisse" Cc: Daniel Colascione Cc: Zi Yan Cc: Naoya Horiguchi --- fs/proc/task_mmu.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 65ae54659833..757e748da613 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1310,9 +1310,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION else if (is_swap_pmd(pmd)) { swp_entry_t entry = pmd_to_swp_entry(pmd); + unsigned long offset = swp_offset(entry); + offset += (addr & ~PMD_MASK) >> PAGE_SHIFT; frame = swp_type(entry) | - (swp_offset(entry) << MAX_SWAPFILES_SHIFT); + (offset << MAX_SWAPFILES_SHIFT); flags |= PM_SWAP; if (pmd_swp_soft_dirty(pmd)) flags |= PM_SOFT_DIRTY; @@ -1332,6 +1334,8 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, break; if (pm->show_pfn && (flags & PM_PRESENT)) frame++; + else if (flags | PM_SWAP) + frame += (1 << MAX_SWAPFILES_SHIFT); } spin_unlock(ptl); return err; -- 2.15.1
[PATCH v2] ARM64: dts: meson-axg: enable the eMMC controller
From: Nan LiThe IP of eMMC controller in AXG is similiar to Meson-GX series. Here we add the initial support of the HS200 mode with clock running at 166MHz (to be safe), since we found some eMMC chip fail to run at 200MHz due to tunning phase error. Signed-off-by: Nan Li Signed-off-by: Yixun Lan --- Hi Kevin Please note this patch actually depend on the eMMC driver here [0]. Still a few problem to solve, to improve the tuning phase driver to make the clock running at 200MHz, and to further support the HS400 mode. Anyway, this patch itself is quite independent. changes since v1 at [1]: - fix missing gpio dt-bindings header [0] http://lkml.kernel.org/r/20180403100652.41056-1-yixun@amlogic.com [1] http://lkml.kernel.org/r/20180403102651.60340-1-yixun@amlogic.com --- arch/arm64/boot/dts/amlogic/meson-axg-s400.dts | 58 ++ arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 82 ++ 2 files changed, 140 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts index 57eedced5a51..f67d4e47e641 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts @@ -15,6 +15,44 @@ serial0 = _AO; serial1 = _A; }; + + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; + + vddio_ao18: regulator-vddio_ao18 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO18"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = < BOOT_9 GPIO_ACTIVE_LOW>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = < GPIOX_6 GPIO_ACTIVE_LOW>; + }; }; { @@ -47,3 +85,23 @@ pinctrl-0 = <_z_pins>; pinctrl-names = "default"; }; + +/* emmc storage */ +_emmc_c { + status = "okay"; + pinctrl-0 = <_pins>; + pinctrl-1 = <_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <18000>; + non-removable; + disable-wp; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + + vmmc-supply = <_3v3>; + vqmmc-supply = <_boot>; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index b58808eb3cc8..cb70778c323c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { compatible = "amlogic,meson-axg"; @@ -113,6 +114,36 @@ #size-cells = <2>; ranges; + apb: apb@ffe0 { + compatible = "simple-bus"; + reg = <0x0 0xffe0 0x0 0x20>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffe0 0x0 0x20>; + + sd_emmc_b: sd@5000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0x5000 0x0 0x2000>; + interrupts = ; + status = "disabled"; + clocks = < CLKID_SD_EMMC_B>, + < CLKID_SD_EMMC_B_CLK0>, + < CLKID_FCLK_DIV2>; + clock-names = "core", "clkin0", "clkin1"; + }; + + sd_emmc_c: mmc@7000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0x7000 0x0 0x2000>; + interrupts = ; + status = "disabled"; + clocks = < CLKID_SD_EMMC_C>, + < CLKID_SD_EMMC_C_CLK0>, +
[PATCH v2] ARM64: dts: meson-axg: enable the eMMC controller
From: Nan Li The IP of eMMC controller in AXG is similiar to Meson-GX series. Here we add the initial support of the HS200 mode with clock running at 166MHz (to be safe), since we found some eMMC chip fail to run at 200MHz due to tunning phase error. Signed-off-by: Nan Li Signed-off-by: Yixun Lan --- Hi Kevin Please note this patch actually depend on the eMMC driver here [0]. Still a few problem to solve, to improve the tuning phase driver to make the clock running at 200MHz, and to further support the HS400 mode. Anyway, this patch itself is quite independent. changes since v1 at [1]: - fix missing gpio dt-bindings header [0] http://lkml.kernel.org/r/20180403100652.41056-1-yixun@amlogic.com [1] http://lkml.kernel.org/r/20180403102651.60340-1-yixun@amlogic.com --- arch/arm64/boot/dts/amlogic/meson-axg-s400.dts | 58 ++ arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 82 ++ 2 files changed, 140 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts index 57eedced5a51..f67d4e47e641 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts @@ -15,6 +15,44 @@ serial0 = _AO; serial1 = _A; }; + + vddio_boot: regulator-vddio_boot { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_BOOT"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vddao_3v3: regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; + + vddio_ao18: regulator-vddio_ao18 { + compatible = "regulator-fixed"; + regulator-name = "VDDIO_AO18"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = < BOOT_9 GPIO_ACTIVE_LOW>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = < GPIOX_6 GPIO_ACTIVE_LOW>; + }; }; { @@ -47,3 +85,23 @@ pinctrl-0 = <_z_pins>; pinctrl-names = "default"; }; + +/* emmc storage */ +_emmc_c { + status = "okay"; + pinctrl-0 = <_pins>; + pinctrl-1 = <_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; + + bus-width = <8>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <18000>; + non-removable; + disable-wp; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + + vmmc-supply = <_3v3>; + vqmmc-supply = <_boot>; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi index b58808eb3cc8..cb70778c323c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { compatible = "amlogic,meson-axg"; @@ -113,6 +114,36 @@ #size-cells = <2>; ranges; + apb: apb@ffe0 { + compatible = "simple-bus"; + reg = <0x0 0xffe0 0x0 0x20>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffe0 0x0 0x20>; + + sd_emmc_b: sd@5000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0x5000 0x0 0x2000>; + interrupts = ; + status = "disabled"; + clocks = < CLKID_SD_EMMC_B>, + < CLKID_SD_EMMC_B_CLK0>, + < CLKID_FCLK_DIV2>; + clock-names = "core", "clkin0", "clkin1"; + }; + + sd_emmc_c: mmc@7000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x0 0x7000 0x0 0x2000>; + interrupts = ; + status = "disabled"; + clocks = < CLKID_SD_EMMC_C>, + < CLKID_SD_EMMC_C_CLK0>, + < CLKID_FCLK_DIV2>; +
[PATCH] f2fs: remove redundant block plug
For buffered IO, we don't need to use block plug to cache bio, for direct IO, generic f2fs_direct_IO has already added block plug, so let's remove redundant one in .write_iter. As Yunlei described in his patch: -f2fs_file_write_iter -blk_start_plug -__generic_file_write_iter ... -do_blockdev_direct_IO -blk_start_plug ... -blk_finish_plug ... -blk_finish_plug which may conduct performance decrease in our platform Signed-off-by: Yunlei HeSigned-off-by: Chao Yu --- fs/f2fs/file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7b8fb31086c3..cb315d23c56f 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2886,7 +2886,6 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct blk_plug plug; ssize_t ret; if (unlikely(f2fs_cp_error(F2FS_I_SB(inode @@ -2931,9 +2930,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) return err; } } - blk_start_plug(); ret = __generic_file_write_iter(iocb, from); - blk_finish_plug(); clear_inode_flag(inode, FI_NO_PREALLOC); /* if we couldn't write data, we should deallocate blocks. */ -- 2.15.0.55.gc2ece9dc4de6
[PATCH] f2fs: remove redundant block plug
For buffered IO, we don't need to use block plug to cache bio, for direct IO, generic f2fs_direct_IO has already added block plug, so let's remove redundant one in .write_iter. As Yunlei described in his patch: -f2fs_file_write_iter -blk_start_plug -__generic_file_write_iter ... -do_blockdev_direct_IO -blk_start_plug ... -blk_finish_plug ... -blk_finish_plug which may conduct performance decrease in our platform Signed-off-by: Yunlei He Signed-off-by: Chao Yu --- fs/f2fs/file.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 7b8fb31086c3..cb315d23c56f 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -2886,7 +2886,6 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct blk_plug plug; ssize_t ret; if (unlikely(f2fs_cp_error(F2FS_I_SB(inode @@ -2931,9 +2930,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) return err; } } - blk_start_plug(); ret = __generic_file_write_iter(iocb, from); - blk_finish_plug(); clear_inode_flag(inode, FI_NO_PREALLOC); /* if we couldn't write data, we should deallocate blocks. */ -- 2.15.0.55.gc2ece9dc4de6
[PATCH] f2fs: fix to show missing bits in FS_IOC_GETFLAGS
This patch fixes to show missing encrypt/inline_data flag in FS_IOC_GETFLAGS like ext4 does. Signed-off-by: Chao Yu--- fs/f2fs/file.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3fd485395f9d..79cfaad21705 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1584,8 +1584,15 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); - unsigned int flags = fi->i_flags & - (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL); + unsigned int flags = fi->i_flags; + + if (file_is_encrypt(inode)) + flags |= F2FS_ENCRYPT_FL; + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) + flags |= F2FS_INLINE_DATA_FL; + + flags &= F2FS_FL_USER_VISIBLE; + return put_user(flags, (int __user *)arg); } -- 2.15.0.55.gc2ece9dc4de6
[PATCH] f2fs: fix to show missing bits in FS_IOC_GETFLAGS
This patch fixes to show missing encrypt/inline_data flag in FS_IOC_GETFLAGS like ext4 does. Signed-off-by: Chao Yu --- fs/f2fs/file.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3fd485395f9d..79cfaad21705 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1584,8 +1584,15 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); - unsigned int flags = fi->i_flags & - (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL); + unsigned int flags = fi->i_flags; + + if (file_is_encrypt(inode)) + flags |= F2FS_ENCRYPT_FL; + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) + flags |= F2FS_INLINE_DATA_FL; + + flags &= F2FS_FL_USER_VISIBLE; + return put_user(flags, (int __user *)arg); } -- 2.15.0.55.gc2ece9dc4de6
[PATCH] f2fs: remove unneeded F2FS_PROJINHERIT_FL
Now F2FS_FL_USER_VISIBLE and F2FS_FL_USER_MODIFIABLE has included F2FS_PROJINHERIT_FL, so remove unneeded F2FS_PROJINHERIT_FL when using visible/modifiable flag macro. Signed-off-by: Chao Yu--- fs/f2fs/file.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 82a01f0aaa33..3fd485395f9d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -686,7 +686,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat, stat->btime.tv_nsec = fi->i_crtime.tv_nsec; } - flags = fi->i_flags & (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL); + flags = fi->i_flags & F2FS_FL_USER_VISIBLE; if (flags & F2FS_APPEND_FL) stat->attributes |= STATX_ATTR_APPEND; if (flags & F2FS_COMPR_FL) @@ -1606,8 +1606,8 @@ static int __f2fs_ioc_setflags(struct inode *inode, unsigned int flags) if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; - flags = flags & (F2FS_FL_USER_MODIFIABLE | F2FS_PROJINHERIT_FL); - flags |= oldflags & ~(F2FS_FL_USER_MODIFIABLE | F2FS_PROJINHERIT_FL); + flags = flags & F2FS_FL_USER_MODIFIABLE; + flags |= oldflags & ~F2FS_FL_USER_MODIFIABLE; fi->i_flags = flags; if (fi->i_flags & F2FS_PROJINHERIT_FL) @@ -2649,7 +2649,7 @@ static int f2fs_ioc_fsgetxattr(struct file *filp, unsigned long arg) memset(, 0, sizeof(struct fsxattr)); fa.fsx_xflags = f2fs_iflags_to_xflags(fi->i_flags & - (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL)); + F2FS_FL_USER_VISIBLE); if (f2fs_sb_has_project_quota(inode->i_sb)) fa.fsx_projid = (__u32)from_kprojid(_user_ns, -- 2.15.0.55.gc2ece9dc4de6
[PATCH] f2fs: remove unneeded F2FS_PROJINHERIT_FL
Now F2FS_FL_USER_VISIBLE and F2FS_FL_USER_MODIFIABLE has included F2FS_PROJINHERIT_FL, so remove unneeded F2FS_PROJINHERIT_FL when using visible/modifiable flag macro. Signed-off-by: Chao Yu --- fs/f2fs/file.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 82a01f0aaa33..3fd485395f9d 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -686,7 +686,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat, stat->btime.tv_nsec = fi->i_crtime.tv_nsec; } - flags = fi->i_flags & (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL); + flags = fi->i_flags & F2FS_FL_USER_VISIBLE; if (flags & F2FS_APPEND_FL) stat->attributes |= STATX_ATTR_APPEND; if (flags & F2FS_COMPR_FL) @@ -1606,8 +1606,8 @@ static int __f2fs_ioc_setflags(struct inode *inode, unsigned int flags) if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; - flags = flags & (F2FS_FL_USER_MODIFIABLE | F2FS_PROJINHERIT_FL); - flags |= oldflags & ~(F2FS_FL_USER_MODIFIABLE | F2FS_PROJINHERIT_FL); + flags = flags & F2FS_FL_USER_MODIFIABLE; + flags |= oldflags & ~F2FS_FL_USER_MODIFIABLE; fi->i_flags = flags; if (fi->i_flags & F2FS_PROJINHERIT_FL) @@ -2649,7 +2649,7 @@ static int f2fs_ioc_fsgetxattr(struct file *filp, unsigned long arg) memset(, 0, sizeof(struct fsxattr)); fa.fsx_xflags = f2fs_iflags_to_xflags(fi->i_flags & - (F2FS_FL_USER_VISIBLE | F2FS_PROJINHERIT_FL)); + F2FS_FL_USER_VISIBLE); if (f2fs_sb_has_project_quota(inode->i_sb)) fa.fsx_projid = (__u32)from_kprojid(_user_ns, -- 2.15.0.55.gc2ece9dc4de6
[PATCH v4 5/7] clk: meson-axg: Add AO Clock and Reset controller driver
From: Qiufang DaiAdds a Clock and Reset controller driver for the Always-On part of the Amlogic Meson-AXG SoC. Signed-off-by: Qiufang Dai Signed-off-by: Yixun Lan --- drivers/clk/meson/Makefile| 2 +- drivers/clk/meson/axg-aoclk.c | 164 ++ drivers/clk/meson/axg-aoclk.h | 31 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/meson/axg-aoclk.c create mode 100644 drivers/clk/meson/axg-aoclk.h diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 555ab9c6ab64..fa6d1e36cef6 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -5,5 +5,5 @@ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o meson-aoclk.o gxbb-aoclk.o gxbb-aoclk-32k.o -obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o +obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o meson-aoclk.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c new file mode 100644 index ..cb56d809d3df --- /dev/null +++ b/drivers/clk/meson/axg-aoclk.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson-AXG Clock Controller Driver + * + * Copyright (c) 2016 Baylibre SAS. + * Author: Michael Turquette + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ +#include +#include +#include +#include +#include +#include "clkc.h" +#include "axg-aoclk.h" + +#define AXG_AO_GATE(_name, _bit) \ +static struct clk_regmap _name##_ao = { \ + .data = &(struct clk_regmap_gate_data) {\ + .offset = (AO_RTI_GEN_CNTL_REG0), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) {\ + .name = #_name "_ao", \ + .ops = _regmap_gate_ops,\ + .parent_names = (const char *[]){ "clk81" },\ + .num_parents = 1, \ + .flags = CLK_IGNORE_UNUSED, \ + }, \ +} + +AXG_AO_GATE(remote, 0); +AXG_AO_GATE(i2c_master, 1); +AXG_AO_GATE(i2c_slave, 2); +AXG_AO_GATE(uart1, 3); +AXG_AO_GATE(uart2, 5); +AXG_AO_GATE(ir_blaster, 6); +AXG_AO_GATE(saradc, 7); + +static struct clk_regmap ao_clk81 = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_RTI_PWR_CNTL_REG0, + .mask = 0x1, + .shift = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_clk81", + .ops = _regmap_mux_ro_ops, + .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"}, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_saradc_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_SAR_CLK, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_mux", + .ops = _regmap_mux_ops, + .parent_names = (const char *[]){ "xtal", "ao_clk81" }, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_saradc_div = { + .data = &(struct clk_regmap_div_data) { + .offset = AO_SAR_CLK, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_div", + .ops = _regmap_divider_ops, + .parent_names = (const char *[]){ "axg_saradc_mux" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap axg_saradc_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = AO_SAR_CLK, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_gate", + .ops = _regmap_gate_ops, + .parent_names = (const char *[]){ "axg_saradc_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const unsigned int axg_aoclk_reset[] = { + [RESET_AO_REMOTE] = 16, + [RESET_AO_I2C_MASTER] = 18, + [RESET_AO_I2C_SLAVE] = 19, + [RESET_AO_UART1] = 17, + [RESET_AO_UART2] = 22, + [RESET_AO_IR_BLASTER] = 23, +}; + +static
[PATCH v4 6/7] clk: meson: drop CLK_SET_RATE_PARENT flag
The clk81 is not expected to be changed, so drop this flag. Signed-off-by: Yixun Lan--- drivers/clk/meson/gxbb-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 59db8e92f8cf..0a2641d6fd33 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -70,7 +70,7 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ + .flags = CLK_IGNORE_UNUSED, \ }, \ } -- 2.15.1
[PATCH v4 5/7] clk: meson-axg: Add AO Clock and Reset controller driver
From: Qiufang Dai Adds a Clock and Reset controller driver for the Always-On part of the Amlogic Meson-AXG SoC. Signed-off-by: Qiufang Dai Signed-off-by: Yixun Lan --- drivers/clk/meson/Makefile| 2 +- drivers/clk/meson/axg-aoclk.c | 164 ++ drivers/clk/meson/axg-aoclk.h | 31 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/meson/axg-aoclk.c create mode 100644 drivers/clk/meson/axg-aoclk.h diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 555ab9c6ab64..fa6d1e36cef6 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -5,5 +5,5 @@ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o meson-aoclk.o gxbb-aoclk.o gxbb-aoclk-32k.o -obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o +obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o meson-aoclk.o axg-aoclk.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c new file mode 100644 index ..cb56d809d3df --- /dev/null +++ b/drivers/clk/meson/axg-aoclk.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson-AXG Clock Controller Driver + * + * Copyright (c) 2016 Baylibre SAS. + * Author: Michael Turquette + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ +#include +#include +#include +#include +#include +#include "clkc.h" +#include "axg-aoclk.h" + +#define AXG_AO_GATE(_name, _bit) \ +static struct clk_regmap _name##_ao = { \ + .data = &(struct clk_regmap_gate_data) {\ + .offset = (AO_RTI_GEN_CNTL_REG0), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) {\ + .name = #_name "_ao", \ + .ops = _regmap_gate_ops,\ + .parent_names = (const char *[]){ "clk81" },\ + .num_parents = 1, \ + .flags = CLK_IGNORE_UNUSED, \ + }, \ +} + +AXG_AO_GATE(remote, 0); +AXG_AO_GATE(i2c_master, 1); +AXG_AO_GATE(i2c_slave, 2); +AXG_AO_GATE(uart1, 3); +AXG_AO_GATE(uart2, 5); +AXG_AO_GATE(ir_blaster, 6); +AXG_AO_GATE(saradc, 7); + +static struct clk_regmap ao_clk81 = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_RTI_PWR_CNTL_REG0, + .mask = 0x1, + .shift = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ao_clk81", + .ops = _regmap_mux_ro_ops, + .parent_names = (const char *[]){ "clk81", "ao_alt_xtal"}, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_saradc_mux = { + .data = &(struct clk_regmap_mux_data) { + .offset = AO_SAR_CLK, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_mux", + .ops = _regmap_mux_ops, + .parent_names = (const char *[]){ "xtal", "ao_clk81" }, + .num_parents = 2, + }, +}; + +static struct clk_regmap axg_saradc_div = { + .data = &(struct clk_regmap_div_data) { + .offset = AO_SAR_CLK, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_div", + .ops = _regmap_divider_ops, + .parent_names = (const char *[]){ "axg_saradc_mux" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap axg_saradc_gate = { + .data = &(struct clk_regmap_gate_data) { + .offset = AO_SAR_CLK, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_gate", + .ops = _regmap_gate_ops, + .parent_names = (const char *[]){ "axg_saradc_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const unsigned int axg_aoclk_reset[] = { + [RESET_AO_REMOTE] = 16, + [RESET_AO_I2C_MASTER] = 18, + [RESET_AO_I2C_SLAVE] = 19, + [RESET_AO_UART1] = 17, + [RESET_AO_UART2] = 22, + [RESET_AO_IR_BLASTER] = 23, +}; + +static struct clk_regmap *axg_aoclk_regmap[] = { + [CLKID_AO_REMOTE] = _ao, + [CLKID_AO_I2C_MASTER] =
[PATCH v4 6/7] clk: meson: drop CLK_SET_RATE_PARENT flag
The clk81 is not expected to be changed, so drop this flag. Signed-off-by: Yixun Lan --- drivers/clk/meson/gxbb-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 59db8e92f8cf..0a2641d6fd33 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -70,7 +70,7 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ + .flags = CLK_IGNORE_UNUSED, \ }, \ } -- 2.15.1
Re: [PATCH 01/15] mm/hmm: documentation editorial update to HMM documentation
On 03/22/2018 05:55 PM, jgli...@redhat.com wrote: > From: Ralph Campbell> > This patch updates the documentation for HMM to fix minor typos and > phrasing to be a bit more readable. > > Signed-off-by: Ralph Campbell > Signed-off-by: Jérôme Glisse > Cc: Stephen Bates > Cc: Jason Gunthorpe > Cc: Logan Gunthorpe > Cc: Evgeny Baskakov > Cc: Mark Hairgrove > Cc: John Hubbard > --- > Documentation/vm/hmm.txt | 360 > --- > MAINTAINERS | 1 + > 2 files changed, 187 insertions(+), 174 deletions(-) > > diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt > index 4d3aac9f4a5d..e99b97003982 100644 > --- a/Documentation/vm/hmm.txt > +++ b/Documentation/vm/hmm.txt > @@ -1,151 +1,159 @@ > Heterogeneous Memory Management (HMM) > > -Transparently allow any component of a program to use any memory region of > said > -program with a device without using device specific memory allocator. This is > -becoming a requirement to simplify the use of advance heterogeneous computing > -where GPU, DSP or FPGA are use to perform various computations. > - > -This document is divided as follow, in the first section i expose the > problems > -related to the use of a device specific allocator. The second section i > expose > -the hardware limitations that are inherent to many platforms. The third > section > -gives an overview of HMM designs. The fourth section explains how CPU page- > -table mirroring works and what is HMM purpose in this context. Fifth section > -deals with how device memory is represented inside the kernel. Finaly the > last > -section present the new migration helper that allow to leverage the device > DMA > -engine. > - > - > -1) Problems of using device specific memory allocator: > -2) System bus, device memory characteristics > -3) Share address space and migration > +Provide infrastructure and helpers to integrate non conventional memory > (device non-conventional > +memory like GPU on board memory) into regular kernel code path. Corner stone > of path, with the cornerstone of > +this being specialize struct page for such memory (see sections 5 to 7 of > this specialized > +document). > + > +HMM also provide optional helpers for SVM (Share Virtual Memory) ie allowing > a providesMemory), i.e., > +device to transparently access program address coherently with the CPU > meaning > +that any valid pointer on the CPU is also a valid pointer for the device. > This > +is becoming a mandatory to simplify the use of advance heterogeneous > computing becoming mandatory advanced > +where GPU, DSP, or FPGA are used to perform various computations on behalf of > +a process. > + > +This document is divided as follows: in the first section I expose the > problems > +related to using device specific memory allocators. In the second section, I > +expose the hardware limitations that are inherent to many platforms. The > third > +section gives an overview of the HMM design. The fourth section explains how > +CPU page-table mirroring works and what is HMM's purpose in this context. The and the purpose of HMM in this context. > +fifth section deals with how device memory is represented inside the kernel. > +Finally, the last section presents a new migration helper that allows lever- > +aging the device DMA engine. > + > + > +1) Problems of using a device specific memory allocator: > +2) I/O bus, device memory characteristics > +3) Shared address space and migration > 4) Address space mirroring implementation and API > 5) Represent and manage device memory from core kernel point of view > -6) Migrate to and from device memory > +6) Migration to and from device memory > 7) Memory cgroup (memcg) and rss accounting > > > > --- > > -1) Problems of using device specific memory allocator: > +1) Problems of using a device specific memory allocator: > > -Device with large amount of on board memory (several giga bytes) like GPU > have > -historically manage their memory through dedicated driver specific API. This > -creates a disconnect between memory allocated and managed by device driver > and > -regular application memory (private anonymous, share memory or regular file > -back memory). From here on i will refer to this aspect as split address > space. > -I use share address space to refer to the opposite situation ie one in which > -any memory region can be use by device transparently. > +Devices with a
Re: [PATCH 01/15] mm/hmm: documentation editorial update to HMM documentation
On 03/22/2018 05:55 PM, jgli...@redhat.com wrote: > From: Ralph Campbell > > This patch updates the documentation for HMM to fix minor typos and > phrasing to be a bit more readable. > > Signed-off-by: Ralph Campbell > Signed-off-by: Jérôme Glisse > Cc: Stephen Bates > Cc: Jason Gunthorpe > Cc: Logan Gunthorpe > Cc: Evgeny Baskakov > Cc: Mark Hairgrove > Cc: John Hubbard > --- > Documentation/vm/hmm.txt | 360 > --- > MAINTAINERS | 1 + > 2 files changed, 187 insertions(+), 174 deletions(-) > > diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt > index 4d3aac9f4a5d..e99b97003982 100644 > --- a/Documentation/vm/hmm.txt > +++ b/Documentation/vm/hmm.txt > @@ -1,151 +1,159 @@ > Heterogeneous Memory Management (HMM) > > -Transparently allow any component of a program to use any memory region of > said > -program with a device without using device specific memory allocator. This is > -becoming a requirement to simplify the use of advance heterogeneous computing > -where GPU, DSP or FPGA are use to perform various computations. > - > -This document is divided as follow, in the first section i expose the > problems > -related to the use of a device specific allocator. The second section i > expose > -the hardware limitations that are inherent to many platforms. The third > section > -gives an overview of HMM designs. The fourth section explains how CPU page- > -table mirroring works and what is HMM purpose in this context. Fifth section > -deals with how device memory is represented inside the kernel. Finaly the > last > -section present the new migration helper that allow to leverage the device > DMA > -engine. > - > - > -1) Problems of using device specific memory allocator: > -2) System bus, device memory characteristics > -3) Share address space and migration > +Provide infrastructure and helpers to integrate non conventional memory > (device non-conventional > +memory like GPU on board memory) into regular kernel code path. Corner stone > of path, with the cornerstone of > +this being specialize struct page for such memory (see sections 5 to 7 of > this specialized > +document). > + > +HMM also provide optional helpers for SVM (Share Virtual Memory) ie allowing > a providesMemory), i.e., > +device to transparently access program address coherently with the CPU > meaning > +that any valid pointer on the CPU is also a valid pointer for the device. > This > +is becoming a mandatory to simplify the use of advance heterogeneous > computing becoming mandatory advanced > +where GPU, DSP, or FPGA are used to perform various computations on behalf of > +a process. > + > +This document is divided as follows: in the first section I expose the > problems > +related to using device specific memory allocators. In the second section, I > +expose the hardware limitations that are inherent to many platforms. The > third > +section gives an overview of the HMM design. The fourth section explains how > +CPU page-table mirroring works and what is HMM's purpose in this context. The and the purpose of HMM in this context. > +fifth section deals with how device memory is represented inside the kernel. > +Finally, the last section presents a new migration helper that allows lever- > +aging the device DMA engine. > + > + > +1) Problems of using a device specific memory allocator: > +2) I/O bus, device memory characteristics > +3) Shared address space and migration > 4) Address space mirroring implementation and API > 5) Represent and manage device memory from core kernel point of view > -6) Migrate to and from device memory > +6) Migration to and from device memory > 7) Memory cgroup (memcg) and rss accounting > > > > --- > > -1) Problems of using device specific memory allocator: > +1) Problems of using a device specific memory allocator: > > -Device with large amount of on board memory (several giga bytes) like GPU > have > -historically manage their memory through dedicated driver specific API. This > -creates a disconnect between memory allocated and managed by device driver > and > -regular application memory (private anonymous, share memory or regular file > -back memory). From here on i will refer to this aspect as split address > space. > -I use share address space to refer to the opposite situation ie one in which > -any memory region can be use by device transparently. > +Devices with a large amount of on board memory (several giga bytes) like GPUs gigabytes) > +have historically managed their memory through dedicated
[PATCH v4 7/7] clk: meson: drop CLK_IGNORE_UNUSED flag
Rely on drivers to request the clock explicitly. Previous the kernel will leave the clock on while bootloader adready initilized the clock, this wasn't optimal way, so fix it here. Signed-off-by: Yixun Lan--- drivers/clk/meson/axg-aoclk.c | 1 - drivers/clk/meson/gxbb-aoclk.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index cb56d809d3df..8457b64b9b7c 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -27,7 +27,6 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ }, \ } diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 0a2641d6fd33..aa655044011a 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -70,7 +70,6 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ }, \ } -- 2.15.1
[PATCH v4 7/7] clk: meson: drop CLK_IGNORE_UNUSED flag
Rely on drivers to request the clock explicitly. Previous the kernel will leave the clock on while bootloader adready initilized the clock, this wasn't optimal way, so fix it here. Signed-off-by: Yixun Lan --- drivers/clk/meson/axg-aoclk.c | 1 - drivers/clk/meson/gxbb-aoclk.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index cb56d809d3df..8457b64b9b7c 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -27,7 +27,6 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ }, \ } diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 0a2641d6fd33..aa655044011a 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -70,7 +70,6 @@ static struct clk_regmap _name##_ao = { \ .ops = _regmap_gate_ops,\ .parent_names = (const char *[]){ "clk81" },\ .num_parents = 1, \ - .flags = CLK_IGNORE_UNUSED, \ }, \ } -- 2.15.1
[PATCH v4 0/7] clk: meson-axg: Add AO Cloclk and Reset driver
This patch try to add AO clock and Reset driver for Amlogic's Meson-AXG SoC. Please note that patch 7 need to wait for the DTS changes[3] merged into mainline first, otherwise it will break the serial console. patch 1: factor the common code into a dedicated file patch 3-5: add the aoclk driver for AXG SoC patch 6-7: drop unnecessary clock flags changes since v3 at [4]: - add 'const' contraint to the read-only data - switch to devm_of_clk_add_hw_provider API - check return value of devm_reset_controller_register changes since v2 at [2]: - rework meson_aoclkc_probe() which leverage the of_match_data - merge patch 5-6 into this series - seperate DTS patch, will send to Kevin Hilman independently changes since v1 at [0]: - rebase to clk-meson's branch 'next/drivers' [1] - fix license, update to BSD-3-Clause - drop un-used include header file [0] https://lkml.kernel.org/r/20180209070026.193879-1-yixun@amlogic.com [1] git://github.com/BayLibre/clk-meson.git branch: next-drivers [2] https://lkml.kernel.org/r/20180323143816.200573-1-yixun@amlogic.com [3] https://lkml.kernel.org/r/20180326081809.49493-4-yixun@amlogic.com [4] https://lkml.kernel.org/r/20180328025050.221585-1-yixun@amlogic.com Qiufang Dai (1): clk: meson-axg: Add AO Clock and Reset controller driver Yixun Lan (6): clk: meson: aoclk: refactor common code into dedicated file clk: meson: migrate to devm_of_clk_add_hw_provider API dt-bindings: clock: axg-aoclkc: New binding for Meson-AXG SoC dt-bindings: clock: reset: Add AXG AO Clock and Reset Bindings clk: meson: drop CLK_SET_RATE_PARENT flag clk: meson: drop CLK_IGNORE_UNUSED flag .../bindings/clock/amlogic,gxbb-aoclkc.txt | 1 + drivers/clk/meson/Makefile | 4 +- drivers/clk/meson/axg-aoclk.c | 163 + drivers/clk/meson/axg-aoclk.h | 31 drivers/clk/meson/gxbb-aoclk.c | 92 drivers/clk/meson/gxbb-aoclk.h | 7 + drivers/clk/meson/meson-aoclk.c| 83 +++ drivers/clk/meson/meson-aoclk.h| 35 + include/dt-bindings/clock/axg-aoclkc.h | 26 include/dt-bindings/reset/axg-aoclkc.h | 20 +++ 10 files changed, 399 insertions(+), 63 deletions(-) create mode 100644 drivers/clk/meson/axg-aoclk.c create mode 100644 drivers/clk/meson/axg-aoclk.h create mode 100644 drivers/clk/meson/meson-aoclk.c create mode 100644 drivers/clk/meson/meson-aoclk.h create mode 100644 include/dt-bindings/clock/axg-aoclkc.h create mode 100644 include/dt-bindings/reset/axg-aoclkc.h -- 2.15.1
[PATCH v4 0/7] clk: meson-axg: Add AO Cloclk and Reset driver
This patch try to add AO clock and Reset driver for Amlogic's Meson-AXG SoC. Please note that patch 7 need to wait for the DTS changes[3] merged into mainline first, otherwise it will break the serial console. patch 1: factor the common code into a dedicated file patch 3-5: add the aoclk driver for AXG SoC patch 6-7: drop unnecessary clock flags changes since v3 at [4]: - add 'const' contraint to the read-only data - switch to devm_of_clk_add_hw_provider API - check return value of devm_reset_controller_register changes since v2 at [2]: - rework meson_aoclkc_probe() which leverage the of_match_data - merge patch 5-6 into this series - seperate DTS patch, will send to Kevin Hilman independently changes since v1 at [0]: - rebase to clk-meson's branch 'next/drivers' [1] - fix license, update to BSD-3-Clause - drop un-used include header file [0] https://lkml.kernel.org/r/20180209070026.193879-1-yixun@amlogic.com [1] git://github.com/BayLibre/clk-meson.git branch: next-drivers [2] https://lkml.kernel.org/r/20180323143816.200573-1-yixun@amlogic.com [3] https://lkml.kernel.org/r/20180326081809.49493-4-yixun@amlogic.com [4] https://lkml.kernel.org/r/20180328025050.221585-1-yixun@amlogic.com Qiufang Dai (1): clk: meson-axg: Add AO Clock and Reset controller driver Yixun Lan (6): clk: meson: aoclk: refactor common code into dedicated file clk: meson: migrate to devm_of_clk_add_hw_provider API dt-bindings: clock: axg-aoclkc: New binding for Meson-AXG SoC dt-bindings: clock: reset: Add AXG AO Clock and Reset Bindings clk: meson: drop CLK_SET_RATE_PARENT flag clk: meson: drop CLK_IGNORE_UNUSED flag .../bindings/clock/amlogic,gxbb-aoclkc.txt | 1 + drivers/clk/meson/Makefile | 4 +- drivers/clk/meson/axg-aoclk.c | 163 + drivers/clk/meson/axg-aoclk.h | 31 drivers/clk/meson/gxbb-aoclk.c | 92 drivers/clk/meson/gxbb-aoclk.h | 7 + drivers/clk/meson/meson-aoclk.c| 83 +++ drivers/clk/meson/meson-aoclk.h| 35 + include/dt-bindings/clock/axg-aoclkc.h | 26 include/dt-bindings/reset/axg-aoclkc.h | 20 +++ 10 files changed, 399 insertions(+), 63 deletions(-) create mode 100644 drivers/clk/meson/axg-aoclk.c create mode 100644 drivers/clk/meson/axg-aoclk.h create mode 100644 drivers/clk/meson/meson-aoclk.c create mode 100644 drivers/clk/meson/meson-aoclk.h create mode 100644 include/dt-bindings/clock/axg-aoclkc.h create mode 100644 include/dt-bindings/reset/axg-aoclkc.h -- 2.15.1
[PATCH v4 2/7] clk: meson: migrate to devm_of_clk_add_hw_provider API
There is a protential memory leak, as of_clk_del_provider is never called if of_clk_add_hw_provider has been executed. Fix this by using devm variant API. Suggested-by: Stephen BoydSigned-off-by: Yixun Lan --- drivers/clk/meson/meson-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index 14862c22e20d..14a1e46a4de6 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -78,6 +78,6 @@ int meson_aoclkc_probe(struct platform_device *pdev) return ret; } - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, (void *) data->hw_data); } -- 2.15.1
[PATCH v4 2/7] clk: meson: migrate to devm_of_clk_add_hw_provider API
There is a protential memory leak, as of_clk_del_provider is never called if of_clk_add_hw_provider has been executed. Fix this by using devm variant API. Suggested-by: Stephen Boyd Signed-off-by: Yixun Lan --- drivers/clk/meson/meson-aoclk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index 14862c22e20d..14a1e46a4de6 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -78,6 +78,6 @@ int meson_aoclkc_probe(struct platform_device *pdev) return ret; } - return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, (void *) data->hw_data); } -- 2.15.1
[PATCH v4 3/7] dt-bindings: clock: axg-aoclkc: New binding for Meson-AXG SoC
Update the dt-binding documentation to support new compatible string for the Amlogic's Meson-AXG SoC. Reviewed-by: Rob HerringSigned-off-by: Yixun Lan --- Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt index 786dc39ca904..3a880528030e 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt @@ -9,6 +9,7 @@ Required Properties: - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" - GXM (S912) : "amlogic,meson-gxm-aoclkc" + - AXG (A113D, A113X) : "amlogic,meson-axg-aoclkc" followed by the common "amlogic,meson-gx-aoclkc" - #clock-cells: should be 1. -- 2.15.1
[PATCH v4 3/7] dt-bindings: clock: axg-aoclkc: New binding for Meson-AXG SoC
Update the dt-binding documentation to support new compatible string for the Amlogic's Meson-AXG SoC. Reviewed-by: Rob Herring Signed-off-by: Yixun Lan --- Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt index 786dc39ca904..3a880528030e 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt @@ -9,6 +9,7 @@ Required Properties: - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" - GXM (S912) : "amlogic,meson-gxm-aoclkc" + - AXG (A113D, A113X) : "amlogic,meson-axg-aoclkc" followed by the common "amlogic,meson-gx-aoclkc" - #clock-cells: should be 1. -- 2.15.1
Re: [PATCH 2/6] crypto: ctr - avoid VLA use
On Sat, Apr 07, 2018 at 08:38:19PM +0200, Salvatore Mesoraca wrote: > > @@ -206,6 +207,14 @@ static struct crypto_instance *crypto_ctr_alloc(struct > rtattr **tb) > if (alg->cra_blocksize < 4) > goto out_put_alg; > > + /* Block size must be <= MAX_BLOCKSIZE. */ > + if (alg->cra_blocksize > MAX_BLOCKSIZE) > + goto out_put_alg; > + > + /* Alignmask must be <= MAX_ALIGNMASK. */ > + if (alg->cra_alignmask > MAX_ALIGNMASK) > + goto out_put_alg; > + Since you're also adding a check to cipher algorithms in general, none of these individual checks are needed anymore. Cheers, -- Email: Herbert XuHome Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH v4 1/7] clk: meson: aoclk: refactor common code into dedicated file
We try to refactor the common code into one dedicated file, while preparing to add new Meson-AXG aoclk driver, this would help us to better share the code by all aoclk drivers. Suggested-by: Jerome BrunetSigned-off-by: Yixun Lan --- drivers/clk/meson/Makefile | 2 +- drivers/clk/meson/gxbb-aoclk.c | 91 ++--- drivers/clk/meson/gxbb-aoclk.h | 7 drivers/clk/meson/meson-aoclk.c | 83 + drivers/clk/meson/meson-aoclk.h | 35 5 files changed, 157 insertions(+), 61 deletions(-) create mode 100644 drivers/clk/meson/meson-aoclk.c create mode 100644 drivers/clk/meson/meson-aoclk.h diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index ffee82e60b7a..555ab9c6ab64 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -4,6 +4,6 @@ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o -obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o +obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o meson-aoclk.o gxbb-aoclk.o gxbb-aoclk-32k.o obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 9ec23ae9a219..59db8e92f8cf 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -52,39 +52,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include #include #include -#include #include -#include -#include -#include #include "clk-regmap.h" #include "gxbb-aoclk.h" -struct gxbb_aoclk_reset_controller { - struct reset_controller_dev reset; - unsigned int *data; - struct regmap *regmap; -}; - -static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct gxbb_aoclk_reset_controller *reset = - container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); - - return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, - BIT(reset->data[id])); -} - -static const struct reset_control_ops gxbb_aoclk_reset_ops = { - .reset = gxbb_aoclk_do_reset, -}; - #define GXBB_AO_GATE(_name, _bit) \ static struct clk_regmap _name##_ao = { \ .data = &(struct clk_regmap_gate_data) {\ @@ -117,7 +91,7 @@ static struct aoclk_cec_32k cec_32k_ao = { }, }; -static unsigned int gxbb_aoclk_reset[] = { +static const unsigned int gxbb_aoclk_reset[] = { [RESET_AO_REMOTE] = 16, [RESET_AO_I2C_MASTER] = 18, [RESET_AO_I2C_SLAVE] = 19, @@ -135,7 +109,7 @@ static struct clk_regmap *gxbb_aoclk_gate[] = { [CLKID_AO_IR_BLASTER] = _blaster_ao, }; -static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { +static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { .hws = { [CLKID_AO_REMOTE] = _ao.hw, [CLKID_AO_I2C_MASTER] = _master_ao.hw, @@ -145,19 +119,15 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { [CLKID_AO_IR_BLASTER] = _blaster_ao.hw, [CLKID_AO_CEC_32K] = _32k_ao.hw, }, - .num = 7, + .num = NR_CLKS, }; -static int gxbb_aoclkc_probe(struct platform_device *pdev) +static int gxbb_aoclkc_register_specific_clk( + struct platform_device *pdev) { - struct gxbb_aoclk_reset_controller *rstc; struct device *dev = >dev; struct regmap *regmap; - int ret, clkid; - - rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); - if (!rstc) - return -ENOMEM; + int ret; regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); if (IS_ERR(regmap)) { @@ -165,38 +135,39 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) return -ENODEV; } - /* Reset Controller */ - rstc->regmap = regmap; - rstc->data = gxbb_aoclk_reset; - rstc->reset.ops = _aoclk_reset_ops; - rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); - rstc->reset.of_node = dev->of_node; - ret = devm_reset_controller_register(dev, >reset); - - /* -* Populate regmap and register all clks -*/ - for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { - gxbb_aoclk_gate[clkid]->map = regmap; - - ret = devm_clk_hw_register(dev, - gxbb_aoclk_onecell_data.hws[clkid]); - if (ret) - return ret; - } - /* Specific clocks */
[PATCH v4 4/7] dt-bindings: clock: reset: Add AXG AO Clock and Reset Bindings
Add dt-bindings headers for the Meson-AXG's AO clock and reset controller. Reviewed-by: Rob HerringSigned-off-by: Yixun Lan --- include/dt-bindings/clock/axg-aoclkc.h | 26 ++ include/dt-bindings/reset/axg-aoclkc.h | 20 2 files changed, 46 insertions(+) create mode 100644 include/dt-bindings/clock/axg-aoclkc.h create mode 100644 include/dt-bindings/reset/axg-aoclkc.h diff --git a/include/dt-bindings/clock/axg-aoclkc.h b/include/dt-bindings/clock/axg-aoclkc.h new file mode 100644 index ..61955016a55b --- /dev/null +++ b/include/dt-bindings/clock/axg-aoclkc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* + * Copyright (c) 2016 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ + +#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK +#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK + +#define CLKID_AO_REMOTE0 +#define CLKID_AO_I2C_MASTER1 +#define CLKID_AO_I2C_SLAVE 2 +#define CLKID_AO_UART1 3 +#define CLKID_AO_UART2 4 +#define CLKID_AO_IR_BLASTER5 +#define CLKID_AO_SAR_ADC 6 +#define CLKID_AO_CLK81 7 +#define CLKID_AO_SAR_ADC_SEL 8 +#define CLKID_AO_SAR_ADC_DIV 9 +#define CLKID_AO_SAR_ADC_CLK 10 +#define CLKID_AO_ALT_XTAL 11 + +#endif diff --git a/include/dt-bindings/reset/axg-aoclkc.h b/include/dt-bindings/reset/axg-aoclkc.h new file mode 100644 index ..d342c0b6b2a7 --- /dev/null +++ b/include/dt-bindings/reset/axg-aoclkc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* + * Copyright (c) 2016 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ + +#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK +#define DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK + +#define RESET_AO_REMOTE0 +#define RESET_AO_I2C_MASTER1 +#define RESET_AO_I2C_SLAVE 2 +#define RESET_AO_UART1 3 +#define RESET_AO_UART2 4 +#define RESET_AO_IR_BLASTER5 + +#endif -- 2.15.1
Re: [PATCH 2/6] crypto: ctr - avoid VLA use
On Sat, Apr 07, 2018 at 08:38:19PM +0200, Salvatore Mesoraca wrote: > > @@ -206,6 +207,14 @@ static struct crypto_instance *crypto_ctr_alloc(struct > rtattr **tb) > if (alg->cra_blocksize < 4) > goto out_put_alg; > > + /* Block size must be <= MAX_BLOCKSIZE. */ > + if (alg->cra_blocksize > MAX_BLOCKSIZE) > + goto out_put_alg; > + > + /* Alignmask must be <= MAX_ALIGNMASK. */ > + if (alg->cra_alignmask > MAX_ALIGNMASK) > + goto out_put_alg; > + Since you're also adding a check to cipher algorithms in general, none of these individual checks are needed anymore. Cheers, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH v4 1/7] clk: meson: aoclk: refactor common code into dedicated file
We try to refactor the common code into one dedicated file, while preparing to add new Meson-AXG aoclk driver, this would help us to better share the code by all aoclk drivers. Suggested-by: Jerome Brunet Signed-off-by: Yixun Lan --- drivers/clk/meson/Makefile | 2 +- drivers/clk/meson/gxbb-aoclk.c | 91 ++--- drivers/clk/meson/gxbb-aoclk.h | 7 drivers/clk/meson/meson-aoclk.c | 83 + drivers/clk/meson/meson-aoclk.h | 35 5 files changed, 157 insertions(+), 61 deletions(-) create mode 100644 drivers/clk/meson/meson-aoclk.c create mode 100644 drivers/clk/meson/meson-aoclk.h diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index ffee82e60b7a..555ab9c6ab64 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -4,6 +4,6 @@ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o -obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o +obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o meson-aoclk.o gxbb-aoclk.o gxbb-aoclk-32k.o obj-$(CONFIG_COMMON_CLK_AXG)+= axg.o obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 9ec23ae9a219..59db8e92f8cf 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -52,39 +52,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include #include #include -#include #include -#include -#include -#include #include "clk-regmap.h" #include "gxbb-aoclk.h" -struct gxbb_aoclk_reset_controller { - struct reset_controller_dev reset; - unsigned int *data; - struct regmap *regmap; -}; - -static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct gxbb_aoclk_reset_controller *reset = - container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); - - return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, - BIT(reset->data[id])); -} - -static const struct reset_control_ops gxbb_aoclk_reset_ops = { - .reset = gxbb_aoclk_do_reset, -}; - #define GXBB_AO_GATE(_name, _bit) \ static struct clk_regmap _name##_ao = { \ .data = &(struct clk_regmap_gate_data) {\ @@ -117,7 +91,7 @@ static struct aoclk_cec_32k cec_32k_ao = { }, }; -static unsigned int gxbb_aoclk_reset[] = { +static const unsigned int gxbb_aoclk_reset[] = { [RESET_AO_REMOTE] = 16, [RESET_AO_I2C_MASTER] = 18, [RESET_AO_I2C_SLAVE] = 19, @@ -135,7 +109,7 @@ static struct clk_regmap *gxbb_aoclk_gate[] = { [CLKID_AO_IR_BLASTER] = _blaster_ao, }; -static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { +static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { .hws = { [CLKID_AO_REMOTE] = _ao.hw, [CLKID_AO_I2C_MASTER] = _master_ao.hw, @@ -145,19 +119,15 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { [CLKID_AO_IR_BLASTER] = _blaster_ao.hw, [CLKID_AO_CEC_32K] = _32k_ao.hw, }, - .num = 7, + .num = NR_CLKS, }; -static int gxbb_aoclkc_probe(struct platform_device *pdev) +static int gxbb_aoclkc_register_specific_clk( + struct platform_device *pdev) { - struct gxbb_aoclk_reset_controller *rstc; struct device *dev = >dev; struct regmap *regmap; - int ret, clkid; - - rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); - if (!rstc) - return -ENOMEM; + int ret; regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); if (IS_ERR(regmap)) { @@ -165,38 +135,39 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) return -ENODEV; } - /* Reset Controller */ - rstc->regmap = regmap; - rstc->data = gxbb_aoclk_reset; - rstc->reset.ops = _aoclk_reset_ops; - rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); - rstc->reset.of_node = dev->of_node; - ret = devm_reset_controller_register(dev, >reset); - - /* -* Populate regmap and register all clks -*/ - for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { - gxbb_aoclk_gate[clkid]->map = regmap; - - ret = devm_clk_hw_register(dev, - gxbb_aoclk_onecell_data.hws[clkid]); - if (ret) - return ret; - } - /* Specific clocks */ cec_32k_ao.regmap = regmap; ret =
[PATCH v4 4/7] dt-bindings: clock: reset: Add AXG AO Clock and Reset Bindings
Add dt-bindings headers for the Meson-AXG's AO clock and reset controller. Reviewed-by: Rob Herring Signed-off-by: Yixun Lan --- include/dt-bindings/clock/axg-aoclkc.h | 26 ++ include/dt-bindings/reset/axg-aoclkc.h | 20 2 files changed, 46 insertions(+) create mode 100644 include/dt-bindings/clock/axg-aoclkc.h create mode 100644 include/dt-bindings/reset/axg-aoclkc.h diff --git a/include/dt-bindings/clock/axg-aoclkc.h b/include/dt-bindings/clock/axg-aoclkc.h new file mode 100644 index ..61955016a55b --- /dev/null +++ b/include/dt-bindings/clock/axg-aoclkc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* + * Copyright (c) 2016 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ + +#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK +#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK + +#define CLKID_AO_REMOTE0 +#define CLKID_AO_I2C_MASTER1 +#define CLKID_AO_I2C_SLAVE 2 +#define CLKID_AO_UART1 3 +#define CLKID_AO_UART2 4 +#define CLKID_AO_IR_BLASTER5 +#define CLKID_AO_SAR_ADC 6 +#define CLKID_AO_CLK81 7 +#define CLKID_AO_SAR_ADC_SEL 8 +#define CLKID_AO_SAR_ADC_DIV 9 +#define CLKID_AO_SAR_ADC_CLK 10 +#define CLKID_AO_ALT_XTAL 11 + +#endif diff --git a/include/dt-bindings/reset/axg-aoclkc.h b/include/dt-bindings/reset/axg-aoclkc.h new file mode 100644 index ..d342c0b6b2a7 --- /dev/null +++ b/include/dt-bindings/reset/axg-aoclkc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* + * Copyright (c) 2016 BayLibre, SAS + * Author: Neil Armstrong + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + */ + +#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK +#define DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK + +#define RESET_AO_REMOTE0 +#define RESET_AO_I2C_MASTER1 +#define RESET_AO_I2C_SLAVE 2 +#define RESET_AO_UART1 3 +#define RESET_AO_UART2 4 +#define RESET_AO_IR_BLASTER5 + +#endif -- 2.15.1
Re: [PATCH V3 4/4] genirq/affinity: irq vector spread among online CPUs as far as possible
On Fri, Apr 06, 2018 at 11:49:47PM +0200, Thomas Gleixner wrote: > On Fri, 6 Apr 2018, Thomas Gleixner wrote: > > > On Fri, 6 Apr 2018, Ming Lei wrote: > > > > > > I will post V4 soon by using cpu_present_mask in the 1st stage irq spread. > > > And it should work fine for Kashyap's case in normal cases. > > > > No need to resend. I've changed it already and will push it out after > > lunch. > > No. Lunch did not last that long :) > > I pushed out the lot to > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core > > Please double check the modifications I did. The first related commit fixes > an existing error handling bug. I think your modification is better, especially about adding comment in irq_create_affinity_masks(). I also testes these patches again, and they just work fine. Thanks, Ming
Re: [PATCH V3 4/4] genirq/affinity: irq vector spread among online CPUs as far as possible
On Fri, Apr 06, 2018 at 11:49:47PM +0200, Thomas Gleixner wrote: > On Fri, 6 Apr 2018, Thomas Gleixner wrote: > > > On Fri, 6 Apr 2018, Ming Lei wrote: > > > > > > I will post V4 soon by using cpu_present_mask in the 1st stage irq spread. > > > And it should work fine for Kashyap's case in normal cases. > > > > No need to resend. I've changed it already and will push it out after > > lunch. > > No. Lunch did not last that long :) > > I pushed out the lot to > > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core > > Please double check the modifications I did. The first related commit fixes > an existing error handling bug. I think your modification is better, especially about adding comment in irq_create_affinity_masks(). I also testes these patches again, and they just work fine. Thanks, Ming
Re: [PATCH 3/6] crypto: api - avoid VLA use
On Sat, Apr 07, 2018 at 08:38:20PM +0200, Salvatore Mesoraca wrote: > > int crypto_init_cipher_ops(struct crypto_tfm *tfm) > { > + const unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); > + const unsigned int size = crypto_tfm_alg_blocksize(tfm); > struct cipher_tfm *ops = >crt_cipher; > struct cipher_alg *cipher = >__crt_alg->cra_cipher; > > + if (size > MAX_BLOCKSIZE || alignmask > MAX_ALIGNMASK) > + return -EINVAL; > + This check should be done when the algorithm is registered. Perhaps crypto_check_alg. Thanks, -- Email: Herbert XuHome Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Use struct page for filename
On Fri, Apr 06, 2018 at 03:33:36PM +0200, Dmitry Vyukov wrote: > On Fri, Apr 6, 2018 at 3:24 PM, syzbot >wrote: > > cache_from_obj: Wrong slab cache. names_cache but object is from kmalloc-96 > > Al, do you see how this can happen? I don't see how it happened, but when looking at this bug, I thought "This is very complicated, I think there's a simpler way to handle this". Here's a proposal. It won't apply to any existing tree (depends on a couple of local commits), but I think you'll get the general flavour of it. It's mostly compile-tested (build still running, but fs/ and kernel/ compiled without issue). fs/dcache.c | 7 fs/namei.c | 102 --- include/linux/fs.h | 26 ++-- include/linux/mm_types.h | 12 +- kernel/auditsc.c | 8 ++-- 5 files changed, 51 insertions(+), 104 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 593079176123..749b82b8fa1c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3172,10 +3172,6 @@ static void __init dcache_init(void) d_hash_shift = 32 - d_hash_shift; } -/* SLAB cache for __getname() consumers */ -struct kmem_cache *names_cachep __read_mostly; -EXPORT_SYMBOL(names_cachep); - void __init vfs_caches_init_early(void) { int i; @@ -3189,9 +3185,6 @@ void __init vfs_caches_init_early(void) void __init vfs_caches_init(void) { - names_cachep = kmem_cache_create_usercopy("names_cache", PATH_MAX, 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, 0, PATH_MAX, NULL); - dcache_init(); inode_init(); files_init(); diff --git a/fs/namei.c b/fs/namei.c index a09419379f5d..16fb4779d29f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -122,71 +122,46 @@ * PATH_MAX includes the nul terminator --RR. */ -#define EMBEDDED_NAME_MAX (PATH_MAX - offsetof(struct filename, iname)) +struct filename *alloc_filename(void) +{ + struct page *page = alloc_page(GFP_KERNEL); + + page->filename.name = page_to_virt(page); + return >filename; +} + +void putname(struct filename *name) +{ + __free_page(container_of(name, struct page, filename)); +} + +void filename_get(struct filename *name) +{ + page_ref_inc(container_of(name, struct page, filename)); +} struct filename * getname_flags(const char __user *filename, int flags, int *empty) { struct filename *result; - char *kname; int len; result = audit_reusename(filename); if (result) return result; - result = __getname(); + result = alloc_filename(); if (unlikely(!result)) return ERR_PTR(-ENOMEM); - /* -* First, try to embed the struct filename inside the names_cache -* allocation -*/ - kname = (char *)result->iname; - result->name = kname; - - len = strncpy_from_user(kname, filename, EMBEDDED_NAME_MAX); + len = strncpy_from_user((char *)result->name, filename, PATH_MAX); + if (unlikely(len == PATH_MAX)) + len = -ENAMETOOLONG; if (unlikely(len < 0)) { - __putname(result); + putname(result); return ERR_PTR(len); } - /* -* Uh-oh. We have a name that's approaching PATH_MAX. Allocate a -* separate struct filename so we can dedicate the entire -* names_cache allocation for the pathname, and re-do the copy from -* userland. -*/ - if (unlikely(len == EMBEDDED_NAME_MAX)) { - const size_t size = offsetof(struct filename, iname[1]); - kname = (char *)result; - - /* -* size is chosen that way we to guarantee that -* result->iname[0] is within the same object and that -* kname can't be equal to result->iname, no matter what. -*/ - result = kzalloc(size, GFP_KERNEL); - if (unlikely(!result)) { - __putname(kname); - return ERR_PTR(-ENOMEM); - } - result->name = kname; - len = strncpy_from_user(kname, filename, PATH_MAX); - if (unlikely(len < 0)) { - __putname(kname); - kfree(result); - return ERR_PTR(len); - } - if (unlikely(len == PATH_MAX)) { - __putname(kname); - kfree(result); - return ERR_PTR(-ENAMETOOLONG); - } - } - - result->refcnt = 1; /* The empty path is special. */ if (unlikely(!len)) { if (empty) @@ -215,49 +190,22 @@ getname_kernel(const char * filename) struct filename *result; int len = strlen(filename) + 1; - result = __getname(); +
Re: [PATCH 3/6] crypto: api - avoid VLA use
On Sat, Apr 07, 2018 at 08:38:20PM +0200, Salvatore Mesoraca wrote: > > int crypto_init_cipher_ops(struct crypto_tfm *tfm) > { > + const unsigned long alignmask = crypto_tfm_alg_alignmask(tfm); > + const unsigned int size = crypto_tfm_alg_blocksize(tfm); > struct cipher_tfm *ops = >crt_cipher; > struct cipher_alg *cipher = >__crt_alg->cra_cipher; > > + if (size > MAX_BLOCKSIZE || alignmask > MAX_ALIGNMASK) > + return -EINVAL; > + This check should be done when the algorithm is registered. Perhaps crypto_check_alg. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Use struct page for filename
On Fri, Apr 06, 2018 at 03:33:36PM +0200, Dmitry Vyukov wrote: > On Fri, Apr 6, 2018 at 3:24 PM, syzbot > wrote: > > cache_from_obj: Wrong slab cache. names_cache but object is from kmalloc-96 > > Al, do you see how this can happen? I don't see how it happened, but when looking at this bug, I thought "This is very complicated, I think there's a simpler way to handle this". Here's a proposal. It won't apply to any existing tree (depends on a couple of local commits), but I think you'll get the general flavour of it. It's mostly compile-tested (build still running, but fs/ and kernel/ compiled without issue). fs/dcache.c | 7 fs/namei.c | 102 --- include/linux/fs.h | 26 ++-- include/linux/mm_types.h | 12 +- kernel/auditsc.c | 8 ++-- 5 files changed, 51 insertions(+), 104 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 593079176123..749b82b8fa1c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -3172,10 +3172,6 @@ static void __init dcache_init(void) d_hash_shift = 32 - d_hash_shift; } -/* SLAB cache for __getname() consumers */ -struct kmem_cache *names_cachep __read_mostly; -EXPORT_SYMBOL(names_cachep); - void __init vfs_caches_init_early(void) { int i; @@ -3189,9 +3185,6 @@ void __init vfs_caches_init_early(void) void __init vfs_caches_init(void) { - names_cachep = kmem_cache_create_usercopy("names_cache", PATH_MAX, 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, 0, PATH_MAX, NULL); - dcache_init(); inode_init(); files_init(); diff --git a/fs/namei.c b/fs/namei.c index a09419379f5d..16fb4779d29f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -122,71 +122,46 @@ * PATH_MAX includes the nul terminator --RR. */ -#define EMBEDDED_NAME_MAX (PATH_MAX - offsetof(struct filename, iname)) +struct filename *alloc_filename(void) +{ + struct page *page = alloc_page(GFP_KERNEL); + + page->filename.name = page_to_virt(page); + return >filename; +} + +void putname(struct filename *name) +{ + __free_page(container_of(name, struct page, filename)); +} + +void filename_get(struct filename *name) +{ + page_ref_inc(container_of(name, struct page, filename)); +} struct filename * getname_flags(const char __user *filename, int flags, int *empty) { struct filename *result; - char *kname; int len; result = audit_reusename(filename); if (result) return result; - result = __getname(); + result = alloc_filename(); if (unlikely(!result)) return ERR_PTR(-ENOMEM); - /* -* First, try to embed the struct filename inside the names_cache -* allocation -*/ - kname = (char *)result->iname; - result->name = kname; - - len = strncpy_from_user(kname, filename, EMBEDDED_NAME_MAX); + len = strncpy_from_user((char *)result->name, filename, PATH_MAX); + if (unlikely(len == PATH_MAX)) + len = -ENAMETOOLONG; if (unlikely(len < 0)) { - __putname(result); + putname(result); return ERR_PTR(len); } - /* -* Uh-oh. We have a name that's approaching PATH_MAX. Allocate a -* separate struct filename so we can dedicate the entire -* names_cache allocation for the pathname, and re-do the copy from -* userland. -*/ - if (unlikely(len == EMBEDDED_NAME_MAX)) { - const size_t size = offsetof(struct filename, iname[1]); - kname = (char *)result; - - /* -* size is chosen that way we to guarantee that -* result->iname[0] is within the same object and that -* kname can't be equal to result->iname, no matter what. -*/ - result = kzalloc(size, GFP_KERNEL); - if (unlikely(!result)) { - __putname(kname); - return ERR_PTR(-ENOMEM); - } - result->name = kname; - len = strncpy_from_user(kname, filename, PATH_MAX); - if (unlikely(len < 0)) { - __putname(kname); - kfree(result); - return ERR_PTR(len); - } - if (unlikely(len == PATH_MAX)) { - __putname(kname); - kfree(result); - return ERR_PTR(-ENAMETOOLONG); - } - } - - result->refcnt = 1; /* The empty path is special. */ if (unlikely(!len)) { if (empty) @@ -215,49 +190,22 @@ getname_kernel(const char * filename) struct filename *result; int len = strlen(filename) + 1; - result = __getname(); + result = alloc_filename(); if
Re: [PATCH 1/6] crypto: api - laying macros for statically allocated buffers
On Sat, Apr 07, 2018 at 08:38:18PM +0200, Salvatore Mesoraca wrote: > Creating 2 new compile-time constants for internal use, > in preparation for the removal of VLAs[1] from crypto code. > All ciphers implemented in Linux have a block size less than or > equal to 16 bytes and the most demanding hw require 16 bytes > alignment for the block buffer. > > [1] > http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qpxydaacu1rq...@mail.gmail.com > > Signed-off-by: Salvatore Mesoraca> --- > crypto/internal.h | 8 > 1 file changed, 8 insertions(+) > > diff --git a/crypto/internal.h b/crypto/internal.h > index 9a3f399..89ae41e 100644 > --- a/crypto/internal.h > +++ b/crypto/internal.h > @@ -26,6 +26,14 @@ > #include > #include > > +/* > + * Maximum values for blocksize and alignmask, used to allocate > + * static buffers that are big enough for any combination of > + * ciphers and architectures. > + */ > +#define MAX_BLOCKSIZE16 > +#define MAX_ALIGNMASK15 No please don't put this here if you intend on using it everywhere. This file is reserved for truly internal bits. Perhaps include/crypto/algapi.h would be a better place. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 1/6] crypto: api - laying macros for statically allocated buffers
On Sat, Apr 07, 2018 at 08:38:18PM +0200, Salvatore Mesoraca wrote: > Creating 2 new compile-time constants for internal use, > in preparation for the removal of VLAs[1] from crypto code. > All ciphers implemented in Linux have a block size less than or > equal to 16 bytes and the most demanding hw require 16 bytes > alignment for the block buffer. > > [1] > http://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qpxydaacu1rq...@mail.gmail.com > > Signed-off-by: Salvatore Mesoraca > --- > crypto/internal.h | 8 > 1 file changed, 8 insertions(+) > > diff --git a/crypto/internal.h b/crypto/internal.h > index 9a3f399..89ae41e 100644 > --- a/crypto/internal.h > +++ b/crypto/internal.h > @@ -26,6 +26,14 @@ > #include > #include > > +/* > + * Maximum values for blocksize and alignmask, used to allocate > + * static buffers that are big enough for any combination of > + * ciphers and architectures. > + */ > +#define MAX_BLOCKSIZE16 > +#define MAX_ALIGNMASK15 No please don't put this here if you intend on using it everywhere. This file is reserved for truly internal bits. Perhaps include/crypto/algapi.h would be a better place. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH v2 1/3] mm/gup_benchmark: handle gup failures
On Sat, Apr 07, 2018 at 01:08:43PM -0700, Linus Torvalds wrote: > On Thu, Apr 5, 2018 at 2:03 PM, Michael S. Tsirkinwrote: > > > > nr = get_user_pages_fast(addr, nr, gup->flags & 1, pages + > > i); > > - i += nr; > > + if (nr > 0) > > + i += nr; > > Can we just make this robust while at it, and just make it > > if (nr <= 0) > break; > > instead? Then it doesn't care about zero vs negative error, and > wouldn't get stuck in an endless loop if it got zero. > > Linus I don't mind though it alredy breaks out on the next cycle: if (nr != gup->nr_pages_per_call) break; the only issue is i getting corrupted when nr < 0;
Re: [PATCH v2 1/3] mm/gup_benchmark: handle gup failures
On Sat, Apr 07, 2018 at 01:08:43PM -0700, Linus Torvalds wrote: > On Thu, Apr 5, 2018 at 2:03 PM, Michael S. Tsirkin wrote: > > > > nr = get_user_pages_fast(addr, nr, gup->flags & 1, pages + > > i); > > - i += nr; > > + if (nr > 0) > > + i += nr; > > Can we just make this robust while at it, and just make it > > if (nr <= 0) > break; > > instead? Then it doesn't care about zero vs negative error, and > wouldn't get stuck in an endless loop if it got zero. > > Linus I don't mind though it alredy breaks out on the next cycle: if (nr != gup->nr_pages_per_call) break; the only issue is i getting corrupted when nr < 0;
Re: [PATCH v8 15/18] mm, fs, dax: handle layout changes to pinned dax mappings
On Sat, Apr 07, 2018 at 12:38:24PM -0700, Dan Williams wrote: > [ adding Paul and Josh ] > > On Wed, Apr 4, 2018 at 2:46 AM, Jan Karawrote: > > On Fri 30-03-18 21:03:30, Dan Williams wrote: > >> Background: > >> > >> get_user_pages() in the filesystem pins file backed memory pages for > >> access by devices performing dma. However, it only pins the memory pages > >> not the page-to-file offset association. If a file is truncated the > >> pages are mapped out of the file and dma may continue indefinitely into > >> a page that is owned by a device driver. This breaks coherency of the > >> file vs dma, but the assumption is that if userspace wants the > >> file-space truncated it does not matter what data is inbound from the > >> device, it is not relevant anymore. The only expectation is that dma can > >> safely continue while the filesystem reallocates the block(s). > >> > >> Problem: > >> > >> This expectation that dma can safely continue while the filesystem > >> changes the block map is broken by dax. With dax the target dma page > >> *is* the filesystem block. The model of leaving the page pinned for dma, > >> but truncating the file block out of the file, means that the filesytem > >> is free to reallocate a block under active dma to another file and now > >> the expected data-incoherency situation has turned into active > >> data-corruption. > >> > >> Solution: > >> > >> Defer all filesystem operations (fallocate(), truncate()) on a dax mode > >> file while any page/block in the file is under active dma. This solution > >> assumes that dma is transient. Cases where dma operations are known to > >> not be transient, like RDMA, have been explicitly disabled via > >> commits like 5f1d43de5416 "IB/core: disable memory registration of > >> filesystem-dax vmas". > >> > >> The dax_layout_busy_page() routine is called by filesystems with a lock > >> held against mm faults (i_mmap_lock) to find pinned / busy dax pages. > >> The process of looking up a busy page invalidates all mappings > >> to trigger any subsequent get_user_pages() to block on i_mmap_lock. > >> The filesystem continues to call dax_layout_busy_page() until it finally > >> returns no more active pages. This approach assumes that the page > >> pinning is transient, if that assumption is violated the system would > >> have likely hung from the uncompleted I/O. > >> > >> Cc: Jan Kara > >> Cc: Jeff Moyer > >> Cc: Dave Chinner > >> Cc: Matthew Wilcox > >> Cc: Alexander Viro > >> Cc: "Darrick J. Wong" > >> Cc: Ross Zwisler > >> Cc: Dave Hansen > >> Cc: Andrew Morton > >> Reported-by: Christoph Hellwig > >> Reviewed-by: Christoph Hellwig > >> Signed-off-by: Dan Williams > >> --- > >> drivers/dax/super.c |2 + > >> fs/dax.c| 92 > >> +++ > >> include/linux/dax.h | 25 ++ > >> mm/gup.c|5 +++ > >> 4 files changed, 123 insertions(+), 1 deletion(-) > > > > ... > > > >> +/** > >> + * dax_layout_busy_page - find first pinned page in @mapping > >> + * @mapping: address space to scan for a page with ref count > 1 > >> + * > >> + * DAX requires ZONE_DEVICE mapped pages. These pages are never > >> + * 'onlined' to the page allocator so they are considered idle when > >> + * page->count == 1. A filesystem uses this interface to determine if > >> + * any page in the mapping is busy, i.e. for DMA, or other > >> + * get_user_pages() usages. > >> + * > >> + * It is expected that the filesystem is holding locks to block the > >> + * establishment of new mappings in this address_space. I.e. it expects > >> + * to be able to run unmap_mapping_range() and subsequently not race > >> + * mapping_mapped() becoming true. It expects that get_user_pages() pte > >> + * walks are performed under rcu_read_lock(). > >> + */ > >> +struct page *dax_layout_busy_page(struct address_space *mapping) > >> +{ > >> + pgoff_t indices[PAGEVEC_SIZE]; > >> + struct page *page = NULL; > >> + struct pagevec pvec; > >> + pgoff_t index, end; > >> + unsigned i; > >> + > >> + /* > >> + * In the 'limited' case get_user_pages() for dax is disabled. > >> + */ > >> + if (IS_ENABLED(CONFIG_FS_DAX_LIMITED)) > >> + return NULL; > >> + > >> + if (!dax_mapping(mapping) || !mapping_mapped(mapping)) > >> + return NULL; > >> + > >> + pagevec_init(); > >> + index = 0; > >> + end = -1; > >> + /* > >> + * Flush dax_layout_lock() sections to ensure all possible page > >> + * references have been taken, or otherwise arrange for faults > >> + * to block on the filesystem lock that is taken for > >> + * establishing new mappings.
Re: [PATCH v8 15/18] mm, fs, dax: handle layout changes to pinned dax mappings
On Sat, Apr 07, 2018 at 12:38:24PM -0700, Dan Williams wrote: > [ adding Paul and Josh ] > > On Wed, Apr 4, 2018 at 2:46 AM, Jan Kara wrote: > > On Fri 30-03-18 21:03:30, Dan Williams wrote: > >> Background: > >> > >> get_user_pages() in the filesystem pins file backed memory pages for > >> access by devices performing dma. However, it only pins the memory pages > >> not the page-to-file offset association. If a file is truncated the > >> pages are mapped out of the file and dma may continue indefinitely into > >> a page that is owned by a device driver. This breaks coherency of the > >> file vs dma, but the assumption is that if userspace wants the > >> file-space truncated it does not matter what data is inbound from the > >> device, it is not relevant anymore. The only expectation is that dma can > >> safely continue while the filesystem reallocates the block(s). > >> > >> Problem: > >> > >> This expectation that dma can safely continue while the filesystem > >> changes the block map is broken by dax. With dax the target dma page > >> *is* the filesystem block. The model of leaving the page pinned for dma, > >> but truncating the file block out of the file, means that the filesytem > >> is free to reallocate a block under active dma to another file and now > >> the expected data-incoherency situation has turned into active > >> data-corruption. > >> > >> Solution: > >> > >> Defer all filesystem operations (fallocate(), truncate()) on a dax mode > >> file while any page/block in the file is under active dma. This solution > >> assumes that dma is transient. Cases where dma operations are known to > >> not be transient, like RDMA, have been explicitly disabled via > >> commits like 5f1d43de5416 "IB/core: disable memory registration of > >> filesystem-dax vmas". > >> > >> The dax_layout_busy_page() routine is called by filesystems with a lock > >> held against mm faults (i_mmap_lock) to find pinned / busy dax pages. > >> The process of looking up a busy page invalidates all mappings > >> to trigger any subsequent get_user_pages() to block on i_mmap_lock. > >> The filesystem continues to call dax_layout_busy_page() until it finally > >> returns no more active pages. This approach assumes that the page > >> pinning is transient, if that assumption is violated the system would > >> have likely hung from the uncompleted I/O. > >> > >> Cc: Jan Kara > >> Cc: Jeff Moyer > >> Cc: Dave Chinner > >> Cc: Matthew Wilcox > >> Cc: Alexander Viro > >> Cc: "Darrick J. Wong" > >> Cc: Ross Zwisler > >> Cc: Dave Hansen > >> Cc: Andrew Morton > >> Reported-by: Christoph Hellwig > >> Reviewed-by: Christoph Hellwig > >> Signed-off-by: Dan Williams > >> --- > >> drivers/dax/super.c |2 + > >> fs/dax.c| 92 > >> +++ > >> include/linux/dax.h | 25 ++ > >> mm/gup.c|5 +++ > >> 4 files changed, 123 insertions(+), 1 deletion(-) > > > > ... > > > >> +/** > >> + * dax_layout_busy_page - find first pinned page in @mapping > >> + * @mapping: address space to scan for a page with ref count > 1 > >> + * > >> + * DAX requires ZONE_DEVICE mapped pages. These pages are never > >> + * 'onlined' to the page allocator so they are considered idle when > >> + * page->count == 1. A filesystem uses this interface to determine if > >> + * any page in the mapping is busy, i.e. for DMA, or other > >> + * get_user_pages() usages. > >> + * > >> + * It is expected that the filesystem is holding locks to block the > >> + * establishment of new mappings in this address_space. I.e. it expects > >> + * to be able to run unmap_mapping_range() and subsequently not race > >> + * mapping_mapped() becoming true. It expects that get_user_pages() pte > >> + * walks are performed under rcu_read_lock(). > >> + */ > >> +struct page *dax_layout_busy_page(struct address_space *mapping) > >> +{ > >> + pgoff_t indices[PAGEVEC_SIZE]; > >> + struct page *page = NULL; > >> + struct pagevec pvec; > >> + pgoff_t index, end; > >> + unsigned i; > >> + > >> + /* > >> + * In the 'limited' case get_user_pages() for dax is disabled. > >> + */ > >> + if (IS_ENABLED(CONFIG_FS_DAX_LIMITED)) > >> + return NULL; > >> + > >> + if (!dax_mapping(mapping) || !mapping_mapped(mapping)) > >> + return NULL; > >> + > >> + pagevec_init(); > >> + index = 0; > >> + end = -1; > >> + /* > >> + * Flush dax_layout_lock() sections to ensure all possible page > >> + * references have been taken, or otherwise arrange for faults > >> + * to block on the filesystem lock that is taken for > >> + * establishing new mappings. > >> + */ > >> + unmap_mapping_range(mapping, 0, 0, 1); > >> + synchronize_rcu(); > > > > So I still don't like the use of RCU for this. It just seems as an abuse to > > use RCU like that. Furthermore it has a hefty latency cost for the truncate > > path. A trivial
Re: [PATCH v2 0/3] mm/get_user_pages_fast fixes, cleanups
On Fri, Apr 06, 2018 at 01:08:02PM -0700, Andrew Morton wrote: > On Fri, 6 Apr 2018 00:03:48 +0300 "Michael S. Tsirkin"> wrote: > > > Turns out get_user_pages_fast and __get_user_pages_fast return different > > values on error when given a single page: __get_user_pages_fast returns > > 0. get_user_pages_fast returns either 0 or an error. > > > > Callers of get_user_pages_fast expect an error so fix it up to return an > > error consistently. > > > > Stress the difference between get_user_pages_fast and __get_user_pages_fast > > to make sure callers aren't confused. > > > > A term which is missing from all these changelogs is "vhost" :( vhost has a BUG_ON for unexpected handling so it catches the bug, but it's not the only site affected. > This patchset fixes a user-affecting bug, does it not? If so, please > fully describe that bug so that we can decide which kernel version(s) > need the patchset. OK, I'll try to write up something. > And yes, this return value asymmetry is sad. Did you scope out what > would be needed to fix up the callers so we can avoid this? Yes - there is a very small number of callers for __get_user_pages_fast so it's easy to teach them all to treat any value <=0 as 0. There seems to be some opposition to changing the API, I'd like to look into this after the bugfix patchset is merged. -- MST
Re: [PATCH v2 0/3] mm/get_user_pages_fast fixes, cleanups
On Fri, Apr 06, 2018 at 01:08:02PM -0700, Andrew Morton wrote: > On Fri, 6 Apr 2018 00:03:48 +0300 "Michael S. Tsirkin" > wrote: > > > Turns out get_user_pages_fast and __get_user_pages_fast return different > > values on error when given a single page: __get_user_pages_fast returns > > 0. get_user_pages_fast returns either 0 or an error. > > > > Callers of get_user_pages_fast expect an error so fix it up to return an > > error consistently. > > > > Stress the difference between get_user_pages_fast and __get_user_pages_fast > > to make sure callers aren't confused. > > > > A term which is missing from all these changelogs is "vhost" :( vhost has a BUG_ON for unexpected handling so it catches the bug, but it's not the only site affected. > This patchset fixes a user-affecting bug, does it not? If so, please > fully describe that bug so that we can decide which kernel version(s) > need the patchset. OK, I'll try to write up something. > And yes, this return value asymmetry is sad. Did you scope out what > would be needed to fix up the callers so we can avoid this? Yes - there is a very small number of callers for __get_user_pages_fast so it's easy to teach them all to treat any value <=0 as 0. There seems to be some opposition to changing the API, I'd like to look into this after the bugfix patchset is merged. -- MST
[PATCH 2/2] hwspinlock: Introduce one new mode for hwspinlock
In some scenarios, user need do some time-consuming or sleepable operations under the hardware spinlock protection for synchronization between the multiple subsystems. For example, there is one PMIC efuse on Spreadtrum platform, which need to be accessed under one hardware lock. But during the hardware lock protection, the efuse operation is time-consuming to almost 5 ms, so we can not disable the interrupts or preemption so long in this case. Thus we can introduce one new mode to indicate that we just acquire the hardware lock and do not disable interrupts or preemption, meanwhile we should force user to protect the hardware lock with mutex or spinlock to avoid dead-lock. Signed-off-by: Baolin Wang--- drivers/hwspinlock/hwspinlock_core.c | 34 include/linux/hwspinlock.h | 58 ++ 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index f4a59f5..5278d05 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -71,10 +71,16 @@ * This function attempts to lock an hwspinlock, and will immediately * fail if the hwspinlock is already taken. * - * Upon a successful return from this function, preemption (and possibly - * interrupts) is disabled, so the caller must not sleep, and is advised to - * release the hwspinlock as soon as possible. This is required in order to - * minimize remote cores polling on the hardware interconnect. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption (and possibly interrupts) is disabled, so the caller must not + * sleep, and is advised to release the hwspinlock as soon as possible. This is + * required in order to minimize remote cores polling on the hardware + * interconnect. * * The user decides whether local interrupts are disabled or not, and if yes, * whether he wants their previous state to be saved. It is up to the user @@ -113,6 +119,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: ret = spin_trylock_irq(>lock); break; + case HWLOCK_RAW: + ret = 1; + break; default: ret = spin_trylock(>lock); break; @@ -134,6 +143,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(>lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(>lock); break; @@ -170,9 +182,14 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) * is already taken, the function will busy loop waiting for it to * be released, but give up after @timeout msecs have elapsed. * - * Upon a successful return from this function, preemption is disabled - * (and possibly local interrupts, too), so the caller must not sleep, - * and is advised to release the hwspinlock as soon as possible. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption is disabled (and possibly local interrupts, too), so the caller + * must not sleep, and is advised to release the hwspinlock as soon as possible. * This is required in order to minimize remote cores polling on the * hardware interconnect. * @@ -266,6 +283,9 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(>lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(>lock); break; diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index 859d673..fe450ee 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -24,6 +24,7 @@ /* hwspinlock mode argument */ #define HWLOCK_IRQSTATE0x01/* Disable interrupts, save state */ #define HWLOCK_IRQ 0x02/* Disable interrupts, don't save state */ +#define
[PATCH 2/2] hwspinlock: Introduce one new mode for hwspinlock
In some scenarios, user need do some time-consuming or sleepable operations under the hardware spinlock protection for synchronization between the multiple subsystems. For example, there is one PMIC efuse on Spreadtrum platform, which need to be accessed under one hardware lock. But during the hardware lock protection, the efuse operation is time-consuming to almost 5 ms, so we can not disable the interrupts or preemption so long in this case. Thus we can introduce one new mode to indicate that we just acquire the hardware lock and do not disable interrupts or preemption, meanwhile we should force user to protect the hardware lock with mutex or spinlock to avoid dead-lock. Signed-off-by: Baolin Wang --- drivers/hwspinlock/hwspinlock_core.c | 34 include/linux/hwspinlock.h | 58 ++ 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index f4a59f5..5278d05 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -71,10 +71,16 @@ * This function attempts to lock an hwspinlock, and will immediately * fail if the hwspinlock is already taken. * - * Upon a successful return from this function, preemption (and possibly - * interrupts) is disabled, so the caller must not sleep, and is advised to - * release the hwspinlock as soon as possible. This is required in order to - * minimize remote cores polling on the hardware interconnect. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption (and possibly interrupts) is disabled, so the caller must not + * sleep, and is advised to release the hwspinlock as soon as possible. This is + * required in order to minimize remote cores polling on the hardware + * interconnect. * * The user decides whether local interrupts are disabled or not, and if yes, * whether he wants their previous state to be saved. It is up to the user @@ -113,6 +119,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: ret = spin_trylock_irq(>lock); break; + case HWLOCK_RAW: + ret = 1; + break; default: ret = spin_trylock(>lock); break; @@ -134,6 +143,9 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(>lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(>lock); break; @@ -170,9 +182,14 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) * is already taken, the function will busy loop waiting for it to * be released, but give up after @timeout msecs have elapsed. * - * Upon a successful return from this function, preemption is disabled - * (and possibly local interrupts, too), so the caller must not sleep, - * and is advised to release the hwspinlock as soon as possible. + * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine + * of getting hardware lock with mutex or spinlock. Since in some scenarios, + * user need some time-consuming or sleepable operations under the hardware + * lock, they need one sleepable lock (like mutex) to protect the operations. + * + * If the mode is not HWLOCK_RAW, upon a successful return from this function, + * preemption is disabled (and possibly local interrupts, too), so the caller + * must not sleep, and is advised to release the hwspinlock as soon as possible. * This is required in order to minimize remote cores polling on the * hardware interconnect. * @@ -266,6 +283,9 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) case HWLOCK_IRQ: spin_unlock_irq(>lock); break; + case HWLOCK_RAW: + /* Nothing to do */ + break; default: spin_unlock(>lock); break; diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index 859d673..fe450ee 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -24,6 +24,7 @@ /* hwspinlock mode argument */ #define HWLOCK_IRQSTATE0x01/* Disable interrupts, save state */ #define HWLOCK_IRQ 0x02/* Disable interrupts, don't save state */ +#define HWLOCK_RAW 0x03 struct
[PATCH 1/2] hwspinlock: Convert to use 'switch' statement
We have different hwspinlock modes to select, thus it will be more readable to handle different modes with using 'switch' statement instead of 'if' statement. Signed-off-by: Baolin Wang--- drivers/hwspinlock/hwspinlock_core.c | 33 - 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 4074441..f4a59f5 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -106,12 +106,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) *problems with hwspinlock usage (e.g. scheduler checks like *'scheduling while atomic' etc.) */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: ret = spin_trylock_irqsave(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: ret = spin_trylock_irq(>lock); - else + break; + default: ret = spin_trylock(>lock); + break; + } /* is lock already taken by another context on the local cpu ? */ if (!ret) @@ -122,12 +127,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) /* if hwlock is already taken, undo spin_trylock_* and exit */ if (!ret) { - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(>lock); - else + break; + default: spin_unlock(>lock); + break; + } return -EBUSY; } @@ -249,12 +259,17 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) hwlock->bank->ops->unlock(hwlock); /* Undo the spin_trylock{_irq, _irqsave} called while locking */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(>lock); - else + break; + default: spin_unlock(>lock); + break; + } } EXPORT_SYMBOL_GPL(__hwspin_unlock); -- 1.7.9.5
[PATCH 1/2] hwspinlock: Convert to use 'switch' statement
We have different hwspinlock modes to select, thus it will be more readable to handle different modes with using 'switch' statement instead of 'if' statement. Signed-off-by: Baolin Wang --- drivers/hwspinlock/hwspinlock_core.c | 33 - 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 4074441..f4a59f5 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -106,12 +106,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) *problems with hwspinlock usage (e.g. scheduler checks like *'scheduling while atomic' etc.) */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: ret = spin_trylock_irqsave(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: ret = spin_trylock_irq(>lock); - else + break; + default: ret = spin_trylock(>lock); + break; + } /* is lock already taken by another context on the local cpu ? */ if (!ret) @@ -122,12 +127,17 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) /* if hwlock is already taken, undo spin_trylock_* and exit */ if (!ret) { - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(>lock); - else + break; + default: spin_unlock(>lock); + break; + } return -EBUSY; } @@ -249,12 +259,17 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) hwlock->bank->ops->unlock(hwlock); /* Undo the spin_trylock{_irq, _irqsave} called while locking */ - if (mode == HWLOCK_IRQSTATE) + switch (mode) { + case HWLOCK_IRQSTATE: spin_unlock_irqrestore(>lock, *flags); - else if (mode == HWLOCK_IRQ) + break; + case HWLOCK_IRQ: spin_unlock_irq(>lock); - else + break; + default: spin_unlock(>lock); + break; + } } EXPORT_SYMBOL_GPL(__hwspin_unlock); -- 1.7.9.5
Re: [PATCH v3 1/6] clk: meson: aoclk: refactor common code into dedicated file
HI Stephen thanks for the review On 04/07/18 02:39, Stephen Boyd wrote: > Quoting Yixun Lan (2018-03-27 19:50:45) >> diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c >> index 9ec23ae9a219..5a922639a264 100644 >> --- a/drivers/clk/meson/gxbb-aoclk.c >> +++ b/drivers/clk/meson/gxbb-aoclk.c >> @@ -165,38 +135,39 @@ static int gxbb_aoclkc_probe(struct platform_device >> *pdev) >> return -ENODEV; >> } >> >> - /* Reset Controller */ >> - rstc->regmap = regmap; >> - rstc->data = gxbb_aoclk_reset; >> - rstc->reset.ops = _aoclk_reset_ops; >> - rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); >> - rstc->reset.of_node = dev->of_node; >> - ret = devm_reset_controller_register(dev, >reset); >> - >> - /* >> -* Populate regmap and register all clks >> -*/ >> - for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { >> - gxbb_aoclk_gate[clkid]->map = regmap; >> - >> - ret = devm_clk_hw_register(dev, >> - >> gxbb_aoclk_onecell_data.hws[clkid]); >> - if (ret) >> - return ret; >> - } >> - >> /* Specific clocks */ >> cec_32k_ao.regmap = regmap; >> ret = devm_clk_hw_register(dev, _32k_ao.hw); >> - if (ret) >> + if (ret) { >> + dev_err(>dev, "clk cec_32k_ao register failed.\n"); >> return ret; >> + } >> + >> + return 0; >> +} >> + >> +static struct meson_aoclk_data gxbb_aoclkc_data = { > > Can this be const? > sure, I'll update at v4 >> + .reset_reg = AO_RTI_GEN_CNTL_REG0, >> + .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), >> + .reset = gxbb_aoclk_reset, >> + .num_clks = ARRAY_SIZE(gxbb_aoclk_gate), >> + .clks = gxbb_aoclk_gate, >> + .hw_data= _aoclk_onecell_data, >> +}; >> + >> diff --git a/drivers/clk/meson/meson-aoclk.c >> b/drivers/clk/meson/meson-aoclk.c >> new file mode 100644 >> index ..36067c801f7b >> --- /dev/null >> +++ b/drivers/clk/meson/meson-aoclk.c >> @@ -0,0 +1,79 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Amlogic Meson-AXG Clock Controller Driver >> + * >> + * Copyright (c) 2016 BayLibre, SAS. >> + * Author: Neil Armstrong>> + * >> + * Copyright (c) 2018 Amlogic, inc. >> + * Author: Qiufang Dai >> + * Author: Yixun Lan >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include "clk-regmap.h" >> +#include "meson-aoclk.h" >> + >> +static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, >> + unsigned long id) >> +{ >> + struct meson_aoclk_reset_controller *rstc = >> + container_of(rcdev, struct meson_aoclk_reset_controller, >> reset); >> + >> + return regmap_write(rstc->regmap, rstc->data->reset_reg, >> + BIT(rstc->data->reset[id])); >> +} >> + >> +static const struct reset_control_ops meson_aoclk_reset_ops = { >> + .reset = meson_aoclk_do_reset, >> +}; >> + >> +int meson_aoclkc_probe(struct platform_device *pdev) >> +{ >> + struct meson_aoclk_reset_controller *rstc; >> + struct meson_aoclk_data *data; >> + struct device *dev = >dev; >> + struct regmap *regmap; >> + int ret, clkid; >> + >> + data = (struct meson_aoclk_data *) >> + of_device_get_match_data(dev); >> + if (!data) >> + return -ENODEV; >> + >> + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); >> + if (!rstc) >> + return -ENOMEM; >> + >> + regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); >> + if (IS_ERR(regmap)) { >> + dev_err(dev, "failed to get regmap\n"); >> + return -ENODEV; >> + } >> + >> + /* Reset Controller */ >> + rstc->data = data; >> + rstc->regmap = regmap; >> + rstc->reset.ops = _aoclk_reset_ops; >> + rstc->reset.nr_resets = data->num_reset, >> + rstc->reset.of_node = dev->of_node; >> + ret = devm_reset_controller_register(dev, >reset); > > Please check the return value here. > will do, thanks for pointing out this >> + >> + /* >> +* Populate regmap and register all clks >> +*/ >> + for (clkid = 0; clkid < data->num_clks; clkid++) { >> + data->clks[clkid]->map = regmap; >> + >> + ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]); >> + if (ret) >> + return ret; >> + } >> + >> + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, >> + data->hw_data); > > Use devm_ variant? > sure > I suppose because code is moving in this patch that it would be better > to make
Re: [PATCH v3 1/6] clk: meson: aoclk: refactor common code into dedicated file
HI Stephen thanks for the review On 04/07/18 02:39, Stephen Boyd wrote: > Quoting Yixun Lan (2018-03-27 19:50:45) >> diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c >> index 9ec23ae9a219..5a922639a264 100644 >> --- a/drivers/clk/meson/gxbb-aoclk.c >> +++ b/drivers/clk/meson/gxbb-aoclk.c >> @@ -165,38 +135,39 @@ static int gxbb_aoclkc_probe(struct platform_device >> *pdev) >> return -ENODEV; >> } >> >> - /* Reset Controller */ >> - rstc->regmap = regmap; >> - rstc->data = gxbb_aoclk_reset; >> - rstc->reset.ops = _aoclk_reset_ops; >> - rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); >> - rstc->reset.of_node = dev->of_node; >> - ret = devm_reset_controller_register(dev, >reset); >> - >> - /* >> -* Populate regmap and register all clks >> -*/ >> - for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { >> - gxbb_aoclk_gate[clkid]->map = regmap; >> - >> - ret = devm_clk_hw_register(dev, >> - >> gxbb_aoclk_onecell_data.hws[clkid]); >> - if (ret) >> - return ret; >> - } >> - >> /* Specific clocks */ >> cec_32k_ao.regmap = regmap; >> ret = devm_clk_hw_register(dev, _32k_ao.hw); >> - if (ret) >> + if (ret) { >> + dev_err(>dev, "clk cec_32k_ao register failed.\n"); >> return ret; >> + } >> + >> + return 0; >> +} >> + >> +static struct meson_aoclk_data gxbb_aoclkc_data = { > > Can this be const? > sure, I'll update at v4 >> + .reset_reg = AO_RTI_GEN_CNTL_REG0, >> + .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), >> + .reset = gxbb_aoclk_reset, >> + .num_clks = ARRAY_SIZE(gxbb_aoclk_gate), >> + .clks = gxbb_aoclk_gate, >> + .hw_data= _aoclk_onecell_data, >> +}; >> + >> diff --git a/drivers/clk/meson/meson-aoclk.c >> b/drivers/clk/meson/meson-aoclk.c >> new file mode 100644 >> index ..36067c801f7b >> --- /dev/null >> +++ b/drivers/clk/meson/meson-aoclk.c >> @@ -0,0 +1,79 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Amlogic Meson-AXG Clock Controller Driver >> + * >> + * Copyright (c) 2016 BayLibre, SAS. >> + * Author: Neil Armstrong >> + * >> + * Copyright (c) 2018 Amlogic, inc. >> + * Author: Qiufang Dai >> + * Author: Yixun Lan >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include "clk-regmap.h" >> +#include "meson-aoclk.h" >> + >> +static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, >> + unsigned long id) >> +{ >> + struct meson_aoclk_reset_controller *rstc = >> + container_of(rcdev, struct meson_aoclk_reset_controller, >> reset); >> + >> + return regmap_write(rstc->regmap, rstc->data->reset_reg, >> + BIT(rstc->data->reset[id])); >> +} >> + >> +static const struct reset_control_ops meson_aoclk_reset_ops = { >> + .reset = meson_aoclk_do_reset, >> +}; >> + >> +int meson_aoclkc_probe(struct platform_device *pdev) >> +{ >> + struct meson_aoclk_reset_controller *rstc; >> + struct meson_aoclk_data *data; >> + struct device *dev = >dev; >> + struct regmap *regmap; >> + int ret, clkid; >> + >> + data = (struct meson_aoclk_data *) >> + of_device_get_match_data(dev); >> + if (!data) >> + return -ENODEV; >> + >> + rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); >> + if (!rstc) >> + return -ENOMEM; >> + >> + regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); >> + if (IS_ERR(regmap)) { >> + dev_err(dev, "failed to get regmap\n"); >> + return -ENODEV; >> + } >> + >> + /* Reset Controller */ >> + rstc->data = data; >> + rstc->regmap = regmap; >> + rstc->reset.ops = _aoclk_reset_ops; >> + rstc->reset.nr_resets = data->num_reset, >> + rstc->reset.of_node = dev->of_node; >> + ret = devm_reset_controller_register(dev, >reset); > > Please check the return value here. > will do, thanks for pointing out this >> + >> + /* >> +* Populate regmap and register all clks >> +*/ >> + for (clkid = 0; clkid < data->num_clks; clkid++) { >> + data->clks[clkid]->map = regmap; >> + >> + ret = devm_clk_hw_register(dev, data->hw_data->hws[clkid]); >> + if (ret) >> + return ret; >> + } >> + >> + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, >> + data->hw_data); > > Use devm_ variant? > sure > I suppose because code is moving in this patch that it would be better > to make improvements in another patch so that this patch is a pure code > movement
[PATCH] Documentation: fix reST markup error in driver-api/usb/typec.rst
From: Changbin DuThere is an format error in driver-api/usb/typec.rst that breaks sphinx docs building. reST markup error: /home/changbin/work/linux/Documentation/driver-api/usb/typec.rst:215: (SEVERE/4) Unexpected section title or transition. Documentation/Makefile:68: recipe for target 'htmldocs' failed make[1]: *** [htmldocs] Error 1 Makefile:1527: recipe for target 'htmldocs' failed make: *** [htmldocs] Error 2 Signed-off-by: Changbin Du --- Documentation/driver-api/usb/typec.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/usb/typec.rst b/Documentation/driver-api/usb/typec.rst index feb3194..48ff580 100644 --- a/Documentation/driver-api/usb/typec.rst +++ b/Documentation/driver-api/usb/typec.rst @@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data role. USB Type-C Connector Class does not supply separate API for them. The port drivers can use USB Role Class API with those. -Illustration of the muxes behind a connector that supports an alternate mode: +Illustration of the muxes behind a connector that supports an alternate mode:: | Connector | -- 2.7.4
Re: linux-next: build failure after merge of the vfs tree
Hi Al, On Sun, 8 Apr 2018 03:19:56 +0100 Al Virowrote: > > > > Caused by commit > > > > > > 92afc556e622 ("buffer.c: call thaw_super during emergency thaw") > > > > > > I have reverted that commit for today. > > > > I am still doing that revert ... > > That's interesting, seeing that this commit is *not* in #for-next and > 08fdc8a0138a should not have that problem... I do the revert by applying a reverse patch (initially generated by a "git revert"). That reverse patch still applies cleanly, so I have no easy way to tell that this problem has been fixed (except by trying without the reverse patch each day - which would add a significant cost to my work as that patch touches linux/fs.h). Anyway, thanks for letting me know, I will remove the reverse patch from tomorrow. -- Cheers, Stephen Rothwell pgpPDpY08iQ_Y.pgp Description: OpenPGP digital signature
[PATCH] Documentation: fix reST markup error in driver-api/usb/typec.rst
From: Changbin Du There is an format error in driver-api/usb/typec.rst that breaks sphinx docs building. reST markup error: /home/changbin/work/linux/Documentation/driver-api/usb/typec.rst:215: (SEVERE/4) Unexpected section title or transition. Documentation/Makefile:68: recipe for target 'htmldocs' failed make[1]: *** [htmldocs] Error 1 Makefile:1527: recipe for target 'htmldocs' failed make: *** [htmldocs] Error 2 Signed-off-by: Changbin Du --- Documentation/driver-api/usb/typec.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/driver-api/usb/typec.rst b/Documentation/driver-api/usb/typec.rst index feb3194..48ff580 100644 --- a/Documentation/driver-api/usb/typec.rst +++ b/Documentation/driver-api/usb/typec.rst @@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data role. USB Type-C Connector Class does not supply separate API for them. The port drivers can use USB Role Class API with those. -Illustration of the muxes behind a connector that supports an alternate mode: +Illustration of the muxes behind a connector that supports an alternate mode:: | Connector | -- 2.7.4
Re: linux-next: build failure after merge of the vfs tree
Hi Al, On Sun, 8 Apr 2018 03:19:56 +0100 Al Viro wrote: > > > > Caused by commit > > > > > > 92afc556e622 ("buffer.c: call thaw_super during emergency thaw") > > > > > > I have reverted that commit for today. > > > > I am still doing that revert ... > > That's interesting, seeing that this commit is *not* in #for-next and > 08fdc8a0138a should not have that problem... I do the revert by applying a reverse patch (initially generated by a "git revert"). That reverse patch still applies cleanly, so I have no easy way to tell that this problem has been fixed (except by trying without the reverse patch each day - which would add a significant cost to my work as that patch touches linux/fs.h). Anyway, thanks for letting me know, I will remove the reverse patch from tomorrow. -- Cheers, Stephen Rothwell pgpPDpY08iQ_Y.pgp Description: OpenPGP digital signature
[PATCH v2 2/3] resource: add walk_system_ram_res_rev()
This function, being a variant of walk_system_ram_res() introduced in commit 8c86e70acead ("resource: provide new functions to walk through resources"), walks through a list of all the resources of System RAM in reversed order, i.e., from higher to lower. It will be used in kexec_file code. Signed-off-by: Baoquan HeCc: Andrew Morton Cc: Thomas Gleixner Cc: Brijesh Singh Cc: "Jérôme Glisse" Cc: Borislav Petkov Cc: Tom Lendacky Cc: Wei Yang --- include/linux/ioport.h | 3 +++ kernel/resource.c | 40 2 files changed, 43 insertions(+) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 745f2acc3674..ae2c409a0634 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -277,6 +277,9 @@ extern int walk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); extern int +walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)); +extern int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); diff --git a/kernel/resource.c b/kernel/resource.c index 05b1efa595c2..332a27403c33 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -487,6 +489,44 @@ int walk_system_ram_res(u64 start, u64 end, void *arg, } /* + * This function, being a variant of walk_system_ram_res(), calls the @func + * callback against all memory ranges of type System RAM which are marked as + * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from + * higher to lower. + */ +int walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)) +{ + unsigned long flags; + struct resource *res; + int ret = -1; + + flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + read_lock(_lock); + list_for_each_entry_reverse(res, _resource.child, sibling) { + if (start >= end) + break; + if ((res->flags & flags) != flags) + continue; + if (res->desc != IORES_DESC_NONE) + continue; + if (res->end < start) + break; + + if ((res->end >= start) && (res->start < end)) { + ret = (*func)(res, arg); + if (ret) + break; + } + end = res->start - 1; + + } + read_unlock(_lock); + return ret; +} + +/* * This function calls the @func callback against all memory ranges, which * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY. */ -- 2.13.6
[PATCH v2 3/3] kexec_file: Load kernel at top of system RAM if required
For kexec_file loading, if kexec_buf.top_down is 'true', the memory which is used to load kernel/initrd/purgatory is supposed to be allocated from top to down. This is what we have been doing all along in the old kexec loading interface and the kexec loading is still default setting in some distributions. However, the current kexec_file loading interface doesn't do likt this. The function arch_kexec_walk_mem() it calls ignores checking kexec_buf.top_down, but calls walk_system_ram_res() directly to go through all resources of System RAM from bottom to up, to try to find memory region which can contain the specific kexec buffer, then call locate_mem_hole_callback() to allocate memory in that found memory region from top to down. This brings confusion. These two interfaces need be unified on behaviour. Here add checking if kexec_buf.top_down is 'true' in arch_kexec_walk_mem(), if yes, call the newly added walk_system_ram_res_rev() to find memory region from top to down to load kernel. Signed-off-by: Baoquan HeCc: Eric Biederman Cc: Vivek Goyal Cc: Dave Young Cc: Andrew Morton Cc: Yinghai Lu Cc: ke...@lists.infradead.org --- kernel/kexec_file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 57ec39995b23..76e6307f8971 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -445,6 +445,8 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY, crashk_res.start, crashk_res.end, kbuf, func); + else if (kbuf->top_down) + return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func); else return walk_system_ram_res(0, ULONG_MAX, kbuf, func); } -- 2.13.6
[PATCH v2 2/3] resource: add walk_system_ram_res_rev()
This function, being a variant of walk_system_ram_res() introduced in commit 8c86e70acead ("resource: provide new functions to walk through resources"), walks through a list of all the resources of System RAM in reversed order, i.e., from higher to lower. It will be used in kexec_file code. Signed-off-by: Baoquan He Cc: Andrew Morton Cc: Thomas Gleixner Cc: Brijesh Singh Cc: "Jérôme Glisse" Cc: Borislav Petkov Cc: Tom Lendacky Cc: Wei Yang --- include/linux/ioport.h | 3 +++ kernel/resource.c | 40 2 files changed, 43 insertions(+) diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 745f2acc3674..ae2c409a0634 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -277,6 +277,9 @@ extern int walk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); extern int +walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)); +extern int walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(struct resource *, void *)); diff --git a/kernel/resource.c b/kernel/resource.c index 05b1efa595c2..332a27403c33 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include @@ -487,6 +489,44 @@ int walk_system_ram_res(u64 start, u64 end, void *arg, } /* + * This function, being a variant of walk_system_ram_res(), calls the @func + * callback against all memory ranges of type System RAM which are marked as + * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from + * higher to lower. + */ +int walk_system_ram_res_rev(u64 start, u64 end, void *arg, + int (*func)(struct resource *, void *)) +{ + unsigned long flags; + struct resource *res; + int ret = -1; + + flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; + + read_lock(_lock); + list_for_each_entry_reverse(res, _resource.child, sibling) { + if (start >= end) + break; + if ((res->flags & flags) != flags) + continue; + if (res->desc != IORES_DESC_NONE) + continue; + if (res->end < start) + break; + + if ((res->end >= start) && (res->start < end)) { + ret = (*func)(res, arg); + if (ret) + break; + } + end = res->start - 1; + + } + read_unlock(_lock); + return ret; +} + +/* * This function calls the @func callback against all memory ranges, which * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY. */ -- 2.13.6
[PATCH v2 3/3] kexec_file: Load kernel at top of system RAM if required
For kexec_file loading, if kexec_buf.top_down is 'true', the memory which is used to load kernel/initrd/purgatory is supposed to be allocated from top to down. This is what we have been doing all along in the old kexec loading interface and the kexec loading is still default setting in some distributions. However, the current kexec_file loading interface doesn't do likt this. The function arch_kexec_walk_mem() it calls ignores checking kexec_buf.top_down, but calls walk_system_ram_res() directly to go through all resources of System RAM from bottom to up, to try to find memory region which can contain the specific kexec buffer, then call locate_mem_hole_callback() to allocate memory in that found memory region from top to down. This brings confusion. These two interfaces need be unified on behaviour. Here add checking if kexec_buf.top_down is 'true' in arch_kexec_walk_mem(), if yes, call the newly added walk_system_ram_res_rev() to find memory region from top to down to load kernel. Signed-off-by: Baoquan He Cc: Eric Biederman Cc: Vivek Goyal Cc: Dave Young Cc: Andrew Morton Cc: Yinghai Lu Cc: ke...@lists.infradead.org --- kernel/kexec_file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 57ec39995b23..76e6307f8971 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -445,6 +445,8 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY, crashk_res.start, crashk_res.end, kbuf, func); + else if (kbuf->top_down) + return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func); else return walk_system_ram_res(0, ULONG_MAX, kbuf, func); } -- 2.13.6
[PATCH v2 1/3] resource: Use list_head to link sibling resource
The struct resource uses singly linked list to link siblings. It's not easy to do reverse iteration on sibling list. So replace it with list_head. And this makes codes in kernel/resource.c more readable after refactoring than pointer operation. Suggested-by: Andrew MortonSigned-off-by: Baoquan He Cc: Patrik Jakobsson Cc: David Airlie Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Dmitry Torokhov Cc: Dan Williams Cc: Rob Herring Cc: Frank Rowand Cc: Keith Busch Cc: Jonathan Derrick Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Cc: Thomas Gleixner Cc: Brijesh Singh Cc: "Jérôme Glisse" Cc: Borislav Petkov Cc: Tom Lendacky Cc: Greg Kroah-Hartman Cc: Yaowei Bai Cc: Wei Yang Cc: de...@linuxdriverproject.org Cc: linux-in...@vger.kernel.org Cc: linux-nvd...@lists.01.org Cc: devicet...@vger.kernel.org Cc: linux-...@vger.kernel.org --- drivers/gpu/drm/gma500/gtt.c| 5 +- drivers/hv/vmbus_drv.c | 52 drivers/input/joystick/iforce/iforce-main.c | 4 +- drivers/nvdimm/e820.c | 2 +- drivers/nvdimm/namespace_devs.c | 14 +- drivers/nvdimm/nd.h | 5 +- drivers/of/address.c| 4 +- drivers/pci/host/vmd.c | 8 +- drivers/pci/probe.c | 2 + drivers/pci/setup-bus.c | 2 +- include/linux/ioport.h | 4 +- kernel/resource.c | 193 ++-- 12 files changed, 151 insertions(+), 144 deletions(-) diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 3949b0990916..addd3bc009af 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -565,7 +565,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) int psb_gtt_restore(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct resource *r = dev_priv->gtt_mem->child; + struct resource *r; struct gtt_range *range; unsigned int restored = 0, total = 0, size = 0; @@ -573,14 +573,13 @@ int psb_gtt_restore(struct drm_device *dev) mutex_lock(_priv->gtt_mutex); psb_gtt_init(dev, 1); - while (r != NULL) { + list_for_each_entry(r, _priv->gtt_mem->child, sibling) { range = container_of(r, struct gtt_range, resource); if (range->pages) { psb_gtt_insert(dev, range, 1); size += range->resource.end - range->resource.start; restored++; } - r = r->sibling; total++; } mutex_unlock(_priv->gtt_mutex); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index bc65c4d79c1f..7ba8a25520d9 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1413,9 +1413,8 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) { resource_size_t start = 0; resource_size_t end = 0; - struct resource *new_res; + struct resource *new_res, *tmp; struct resource **old_res = _mmio; - struct resource **prev_res = NULL; switch (res->type) { @@ -1462,44 +1461,36 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) /* * If two ranges are adjacent, merge them. */ - do { - if (!*old_res) { - *old_res = new_res; - break; - } - - if (((*old_res)->end + 1) == new_res->start) { - (*old_res)->end = new_res->end; + if (!*old_res) { + *old_res = new_res; + return AE_OK; + } + tmp = *old_res; + list_for_each_entry_from(tmp, >parent->child, sibling) { + if ((tmp->end + 1) == new_res->start) { + tmp->end = new_res->end; kfree(new_res); break; } - if ((*old_res)->start == new_res->end + 1) { - (*old_res)->start = new_res->start; + if (tmp->start == new_res->end + 1) { + tmp->start = new_res->start; kfree(new_res); break; } -
[PATCH v2 1/3] resource: Use list_head to link sibling resource
The struct resource uses singly linked list to link siblings. It's not easy to do reverse iteration on sibling list. So replace it with list_head. And this makes codes in kernel/resource.c more readable after refactoring than pointer operation. Suggested-by: Andrew Morton Signed-off-by: Baoquan He Cc: Patrik Jakobsson Cc: David Airlie Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Stephen Hemminger Cc: Dmitry Torokhov Cc: Dan Williams Cc: Rob Herring Cc: Frank Rowand Cc: Keith Busch Cc: Jonathan Derrick Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Cc: Thomas Gleixner Cc: Brijesh Singh Cc: "Jérôme Glisse" Cc: Borislav Petkov Cc: Tom Lendacky Cc: Greg Kroah-Hartman Cc: Yaowei Bai Cc: Wei Yang Cc: de...@linuxdriverproject.org Cc: linux-in...@vger.kernel.org Cc: linux-nvd...@lists.01.org Cc: devicet...@vger.kernel.org Cc: linux-...@vger.kernel.org --- drivers/gpu/drm/gma500/gtt.c| 5 +- drivers/hv/vmbus_drv.c | 52 drivers/input/joystick/iforce/iforce-main.c | 4 +- drivers/nvdimm/e820.c | 2 +- drivers/nvdimm/namespace_devs.c | 14 +- drivers/nvdimm/nd.h | 5 +- drivers/of/address.c| 4 +- drivers/pci/host/vmd.c | 8 +- drivers/pci/probe.c | 2 + drivers/pci/setup-bus.c | 2 +- include/linux/ioport.h | 4 +- kernel/resource.c | 193 ++-- 12 files changed, 151 insertions(+), 144 deletions(-) diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 3949b0990916..addd3bc009af 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -565,7 +565,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) int psb_gtt_restore(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - struct resource *r = dev_priv->gtt_mem->child; + struct resource *r; struct gtt_range *range; unsigned int restored = 0, total = 0, size = 0; @@ -573,14 +573,13 @@ int psb_gtt_restore(struct drm_device *dev) mutex_lock(_priv->gtt_mutex); psb_gtt_init(dev, 1); - while (r != NULL) { + list_for_each_entry(r, _priv->gtt_mem->child, sibling) { range = container_of(r, struct gtt_range, resource); if (range->pages) { psb_gtt_insert(dev, range, 1); size += range->resource.end - range->resource.start; restored++; } - r = r->sibling; total++; } mutex_unlock(_priv->gtt_mutex); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index bc65c4d79c1f..7ba8a25520d9 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1413,9 +1413,8 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) { resource_size_t start = 0; resource_size_t end = 0; - struct resource *new_res; + struct resource *new_res, *tmp; struct resource **old_res = _mmio; - struct resource **prev_res = NULL; switch (res->type) { @@ -1462,44 +1461,36 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) /* * If two ranges are adjacent, merge them. */ - do { - if (!*old_res) { - *old_res = new_res; - break; - } - - if (((*old_res)->end + 1) == new_res->start) { - (*old_res)->end = new_res->end; + if (!*old_res) { + *old_res = new_res; + return AE_OK; + } + tmp = *old_res; + list_for_each_entry_from(tmp, >parent->child, sibling) { + if ((tmp->end + 1) == new_res->start) { + tmp->end = new_res->end; kfree(new_res); break; } - if ((*old_res)->start == new_res->end + 1) { - (*old_res)->start = new_res->start; + if (tmp->start == new_res->end + 1) { + tmp->start = new_res->start; kfree(new_res); break; } - if ((*old_res)->start > new_res->end) { - new_res->sibling = *old_res; - if (prev_res) - (*prev_res)->sibling = new_res; - *old_res = new_res; + if (tmp->start > new_res->end) { + list_add(_res->sibling, tmp->sibling.prev); break; } - - prev_res = old_res; - old_res = &(*old_res)->sibling; - - } while (1); + }
[PATCH v2 0/3] resource: Use list_head to link sibling resource
This post mainly converts strut resource's sibling list from singly linked list to doubly linked list, list_head. This is suggested by Andrew. Since I need a reversed searching on iomem_resource's IORESOURCE_SYSTEM_RAM children, the old singly linked list way makes the code in v1 post really ugly. With this change, we only need one simple list_for_each_entry_reverse() to do reversed iteration on sibling list. The relevant codes in kernel/resource.c are more readable since those dazzling pointer operation codes for singly linked list are replaced. With the help of list_head, in patch 0002 we can have a very simple walk_system_ram_res_rev(). And in patch 0003, will use it to search available system RAM region for kexec_buffer of kexec_file from top to down, just like we have been doing all along in kexec loading which is done in kexec-tools utility. Note: This patchset passed testing on my kvm guest, x86_64 arch with network enabling. The thing we need pay attetion to is that a root resource's child member need be initialized specifically with LIST_HEAD_INIT() if sttically defined or INIT_LIST_HEAD() for dynamically definition. Here Just like we do for iomem_resource/ioport_resource, or the change in get_pci_domain_busn_res(). And there are two places of change I am not very sure. One is in drivers/hv/vmbus_drv.c, the other is in drivers/pci/host/vmd.c. So will invite experts on these areas to help review. v1->v2: Use list_head instead to link resource siblings. This is suggested by Andrew. Rewrite walk_system_ram_res_rev() after list_head is taken to link resouce siblings. Baoquan He (3): resource: Use list_head to link sibling resource resource: add walk_system_ram_res_rev() kexec_file: Load kernel at top of system RAM if required drivers/gpu/drm/gma500/gtt.c| 5 +- drivers/hv/vmbus_drv.c | 52 +++ drivers/input/joystick/iforce/iforce-main.c | 4 +- drivers/nvdimm/e820.c | 2 +- drivers/nvdimm/namespace_devs.c | 14 +- drivers/nvdimm/nd.h | 5 +- drivers/of/address.c| 4 +- drivers/pci/host/vmd.c | 8 +- drivers/pci/probe.c | 2 + drivers/pci/setup-bus.c | 2 +- include/linux/ioport.h | 7 +- kernel/kexec_file.c | 2 + kernel/resource.c | 233 +--- 13 files changed, 196 insertions(+), 144 deletions(-) -- 2.13.6
[PATCH v2 0/3] resource: Use list_head to link sibling resource
This post mainly converts strut resource's sibling list from singly linked list to doubly linked list, list_head. This is suggested by Andrew. Since I need a reversed searching on iomem_resource's IORESOURCE_SYSTEM_RAM children, the old singly linked list way makes the code in v1 post really ugly. With this change, we only need one simple list_for_each_entry_reverse() to do reversed iteration on sibling list. The relevant codes in kernel/resource.c are more readable since those dazzling pointer operation codes for singly linked list are replaced. With the help of list_head, in patch 0002 we can have a very simple walk_system_ram_res_rev(). And in patch 0003, will use it to search available system RAM region for kexec_buffer of kexec_file from top to down, just like we have been doing all along in kexec loading which is done in kexec-tools utility. Note: This patchset passed testing on my kvm guest, x86_64 arch with network enabling. The thing we need pay attetion to is that a root resource's child member need be initialized specifically with LIST_HEAD_INIT() if sttically defined or INIT_LIST_HEAD() for dynamically definition. Here Just like we do for iomem_resource/ioport_resource, or the change in get_pci_domain_busn_res(). And there are two places of change I am not very sure. One is in drivers/hv/vmbus_drv.c, the other is in drivers/pci/host/vmd.c. So will invite experts on these areas to help review. v1->v2: Use list_head instead to link resource siblings. This is suggested by Andrew. Rewrite walk_system_ram_res_rev() after list_head is taken to link resouce siblings. Baoquan He (3): resource: Use list_head to link sibling resource resource: add walk_system_ram_res_rev() kexec_file: Load kernel at top of system RAM if required drivers/gpu/drm/gma500/gtt.c| 5 +- drivers/hv/vmbus_drv.c | 52 +++ drivers/input/joystick/iforce/iforce-main.c | 4 +- drivers/nvdimm/e820.c | 2 +- drivers/nvdimm/namespace_devs.c | 14 +- drivers/nvdimm/nd.h | 5 +- drivers/of/address.c| 4 +- drivers/pci/host/vmd.c | 8 +- drivers/pci/probe.c | 2 + drivers/pci/setup-bus.c | 2 +- include/linux/ioport.h | 7 +- kernel/kexec_file.c | 2 + kernel/resource.c | 233 +--- 13 files changed, 196 insertions(+), 144 deletions(-) -- 2.13.6
Re: simultaneous voice/data works (was Re: call/normal switch was Re: omap4-droid4: voice call support was)
On Sat, 2018-04-07 at 14:22 +0200, Pavel Machek wrote: > On Sat 2018-04-07 10:10:00, Pavel Machek wrote: > > Hi! > > > > It seems qmicli can be used while unicsy_demo/ofone talks to the > > modem > > using the AT commands. > > > > So I could do: > > > > qmicli -d /dev/cdc-wdm0 --wds-follow-network --wds-start- > > network=apn=internet.t-mobile.cz > > route del default > > sudo ifconfig wwan0 up > > dhclient wwan0 > > > > to get GPRS/UMTS connection. AT commands still work. > > > > Does anyone have any idea what to do to get the GPS to work? > > Got that to work. > > I installed modemmanager -- unfortunately that claims ttyUSB4 so it > breaks voice/sms -- but then It shouldn't break SMS since MM will do SMS via QMI, but yeah for now it'll break voice because that would happen via QMI too, and we haven't implemented voice for QMI yet. --help-messaging --help-sms Also available via D-Bus of course. > mmcli -m 0 --enable > mmcli -m 0 --location-enable-gps-nmea > watch -n .3 sudo mmcli -m 0 --location-get-gps-nmea > > ...can be used to get GPS data. Droid4 seems to have rather bad GPS, > so you should probably put it near window for testing. > > Is there way to grab data from modemmanager and feed it to gpsd, so > that normal applications can access gps? I don't see easy way. > > I tried --location-enable-gps-unmanaged , but that did not work for > me. That requires a TTY that would spit out the GPS data; in this mode MM only sends the start/stop commands, and what comes out the GPS TTY is undefined (at least by MM). So unless you know that one of the 6600's TTYs does GPS and in what format it does GPS, then no. Doesn't --location-get-gps-nmea work for you? That will spit out the latest NMEA traces MM gets from the modem, if it supports NMEA. I believe --location-status will tell you what methods MM supports with the modem. Also available via D-Bus of course. > Is modemmanager enabling GPS, or is it talking to libqmi to do that? > The code is quite confusing to me... Yes. When the modem is driven with QMI, then all the data comes from QMI. For other modems (like Huawei HiLink and Gobi 1000) the enabling commands are done via AT on the main command port and then one of the TTYs starts spewing out NMEA. Dan
Re: simultaneous voice/data works (was Re: call/normal switch was Re: omap4-droid4: voice call support was)
On Sat, 2018-04-07 at 14:22 +0200, Pavel Machek wrote: > On Sat 2018-04-07 10:10:00, Pavel Machek wrote: > > Hi! > > > > It seems qmicli can be used while unicsy_demo/ofone talks to the > > modem > > using the AT commands. > > > > So I could do: > > > > qmicli -d /dev/cdc-wdm0 --wds-follow-network --wds-start- > > network=apn=internet.t-mobile.cz > > route del default > > sudo ifconfig wwan0 up > > dhclient wwan0 > > > > to get GPRS/UMTS connection. AT commands still work. > > > > Does anyone have any idea what to do to get the GPS to work? > > Got that to work. > > I installed modemmanager -- unfortunately that claims ttyUSB4 so it > breaks voice/sms -- but then It shouldn't break SMS since MM will do SMS via QMI, but yeah for now it'll break voice because that would happen via QMI too, and we haven't implemented voice for QMI yet. --help-messaging --help-sms Also available via D-Bus of course. > mmcli -m 0 --enable > mmcli -m 0 --location-enable-gps-nmea > watch -n .3 sudo mmcli -m 0 --location-get-gps-nmea > > ...can be used to get GPS data. Droid4 seems to have rather bad GPS, > so you should probably put it near window for testing. > > Is there way to grab data from modemmanager and feed it to gpsd, so > that normal applications can access gps? I don't see easy way. > > I tried --location-enable-gps-unmanaged , but that did not work for > me. That requires a TTY that would spit out the GPS data; in this mode MM only sends the start/stop commands, and what comes out the GPS TTY is undefined (at least by MM). So unless you know that one of the 6600's TTYs does GPS and in what format it does GPS, then no. Doesn't --location-get-gps-nmea work for you? That will spit out the latest NMEA traces MM gets from the modem, if it supports NMEA. I believe --location-status will tell you what methods MM supports with the modem. Also available via D-Bus of course. > Is modemmanager enabling GPS, or is it talking to libqmi to do that? > The code is quite confusing to me... Yes. When the modem is driven with QMI, then all the data comes from QMI. For other modems (like Huawei HiLink and Gobi 1000) the enabling commands are done via AT on the main command port and then one of the TTYs starts spewing out NMEA. Dan
Re: WARNING in ext4_superblock_csum_set
#syz fix: ext4: always initialize the crc32c checksum driver
Re: WARNING in ext4_superblock_csum_set
#syz fix: ext4: always initialize the crc32c checksum driver
Re: [PATCH] drm: Add crtc_queue_syncobj and crtc_get_syncobj ioctls
Jason Ekstrandwrites: > Yeah, I suppose an application could ask for 10k frames in the future or > something ridiculous like that. For sync_file, people strongly want a > finite time guarantee for security/deadlock reasons. I don't know how > happy they would be with a finite time of 10 minutes... Sure, we've put arbitrary finite limits on vblank counters in other places, so adding some kind of arbitrary limit like a couple of seconds would be entirely reasonable here. The Vulkan API doesn't need any of this complexity at all; the one I'm doing only lets you create a fence for the next vblank. > Ok, that's not expected... Part of the point of sync objects is that > they're re-usable. The client is free to not re-use them or to be very > careful about the recycling process. Heh. I thought the opposite -- lightweight objects that you'd use once and delete. I can certainly change the API to pass in an existing syncobj rather than creating a new one. That would be easier in some ways as it reduces the failure paths a bit. > Is the event the important part or the moderately accurate timestamp? I need the timestamp and sequence number, getting them in an event would mean not having to make another syscall. > We could probably modify drm_syncobj to have a "last signaled" > timestamp that's queryable through an IOCTL. That's exactly what I did, but it only works for these new syncobjs. The fields are global and could be filled in by other bits of the code. > Is the sequence number returned necessary? Will it ever be different from > the one requested? Yes, when the application queues it just slightly too late. The application doesn't actually need either of these values directly, but the system needs them to respond to requests to queue presentation at a specific time, so the vulkan driver wants 'recent' vblank time/sequence data to estimate when a vblank will occur. -- -keith signature.asc Description: PGP signature
Re: [PATCH] drm: Add crtc_queue_syncobj and crtc_get_syncobj ioctls
Jason Ekstrand writes: > Yeah, I suppose an application could ask for 10k frames in the future or > something ridiculous like that. For sync_file, people strongly want a > finite time guarantee for security/deadlock reasons. I don't know how > happy they would be with a finite time of 10 minutes... Sure, we've put arbitrary finite limits on vblank counters in other places, so adding some kind of arbitrary limit like a couple of seconds would be entirely reasonable here. The Vulkan API doesn't need any of this complexity at all; the one I'm doing only lets you create a fence for the next vblank. > Ok, that's not expected... Part of the point of sync objects is that > they're re-usable. The client is free to not re-use them or to be very > careful about the recycling process. Heh. I thought the opposite -- lightweight objects that you'd use once and delete. I can certainly change the API to pass in an existing syncobj rather than creating a new one. That would be easier in some ways as it reduces the failure paths a bit. > Is the event the important part or the moderately accurate timestamp? I need the timestamp and sequence number, getting them in an event would mean not having to make another syscall. > We could probably modify drm_syncobj to have a "last signaled" > timestamp that's queryable through an IOCTL. That's exactly what I did, but it only works for these new syncobjs. The fields are global and could be filled in by other bits of the code. > Is the sequence number returned necessary? Will it ever be different from > the one requested? Yes, when the application queues it just slightly too late. The application doesn't actually need either of these values directly, but the system needs them to respond to requests to queue presentation at a specific time, so the vulkan driver wants 'recent' vblank time/sequence data to estimate when a vblank will occur. -- -keith signature.asc Description: PGP signature
Re: linux-next: build failure after merge of the vfs tree
On Tue, Apr 03, 2018 at 12:26:29PM +1000, Stephen Rothwell wrote: > Hi Al, > > On Mon, 19 Mar 2018 17:06:27 +1100 Stephen Rothwell> wrote: > > > > After merging the vfs tree, today's linux-next build (x86_64 allnoconfig) > > failed like this: > > > > fs/super.c: In function 'do_thaw_all_callback': > > fs/super.c:942:3: error: implicit declaration of function > > 'emergency_thaw_bdev'; did you mean 'emergency_remount'? > > [-Werror=implicit-function-declaration] > >emergency_thaw_bdev(sb); > >^~~ > >emergency_remount > > > > Caused by commit > > > > 92afc556e622 ("buffer.c: call thaw_super during emergency thaw") > > > > I have reverted that commit for today. > > I am still doing that revert ... That's interesting, seeing that this commit is *not* in #for-next and 08fdc8a0138a should not have that problem...
Re: linux-next: build failure after merge of the vfs tree
On Tue, Apr 03, 2018 at 12:26:29PM +1000, Stephen Rothwell wrote: > Hi Al, > > On Mon, 19 Mar 2018 17:06:27 +1100 Stephen Rothwell > wrote: > > > > After merging the vfs tree, today's linux-next build (x86_64 allnoconfig) > > failed like this: > > > > fs/super.c: In function 'do_thaw_all_callback': > > fs/super.c:942:3: error: implicit declaration of function > > 'emergency_thaw_bdev'; did you mean 'emergency_remount'? > > [-Werror=implicit-function-declaration] > >emergency_thaw_bdev(sb); > >^~~ > >emergency_remount > > > > Caused by commit > > > > 92afc556e622 ("buffer.c: call thaw_super during emergency thaw") > > > > I have reverted that commit for today. > > I am still doing that revert ... That's interesting, seeing that this commit is *not* in #for-next and 08fdc8a0138a should not have that problem...
答复: 答复: [PATCH 1/2] x86/mce: new centaur CPUs support MCE broadcasting
> -邮件原件- > 发件人: Borislav Petkov [mailto:b...@alien8.de] > 发送时间: 2018年4月4日 19:18 > 收件人: David Wang> 抄送: tony.l...@intel.com; t...@linutronix.de; mi...@redhat.com; > h...@zytor.com; x...@kernel.org; linux-e...@vger.kernel.org; > linux-kernel@vger.kernel.org; Bruce Chang (VAS) > ; Cooper Yan(BJ-RD) > ; Qiyuan Wang(BJ-RD) > ; Benjamin Pan ; > Luke Lin ; Tim Guo(BJ-RD) > 主题: Re: 答复: [PATCH 1/2] x86/mce: new centaur CPUs support MCE > broadcasting > > On Wed, Apr 04, 2018 at 02:34:52AM +, David Wang wrote: > > Those are new processors and main usage of CentaurHauls CPUs in recent > > years is for limited and/or embedded instead of distribution markets. > > So there is no plan or resource to create such document for public > > access. Is public spec mandatory for code check-in? We can provide > > platforms for verification instead. > > Nah, not needed. As long as the code paths don't break anything else and as > long as we can CC you to fix bugs people report, we're good. :-) > > Btw, please do not top-post on a public ML. I got it. Thanks. --- David > > Thx. > > -- > Regards/Gruss, > Boris. > > Good mailing practices for 400: avoid top-posting and trim the reply.
答复: 答复: [PATCH 1/2] x86/mce: new centaur CPUs support MCE broadcasting
> -邮件原件- > 发件人: Borislav Petkov [mailto:b...@alien8.de] > 发送时间: 2018年4月4日 19:18 > 收件人: David Wang > 抄送: tony.l...@intel.com; t...@linutronix.de; mi...@redhat.com; > h...@zytor.com; x...@kernel.org; linux-e...@vger.kernel.org; > linux-kernel@vger.kernel.org; Bruce Chang (VAS) > ; Cooper Yan(BJ-RD) > ; Qiyuan Wang(BJ-RD) > ; Benjamin Pan ; > Luke Lin ; Tim Guo(BJ-RD) > 主题: Re: 答复: [PATCH 1/2] x86/mce: new centaur CPUs support MCE > broadcasting > > On Wed, Apr 04, 2018 at 02:34:52AM +, David Wang wrote: > > Those are new processors and main usage of CentaurHauls CPUs in recent > > years is for limited and/or embedded instead of distribution markets. > > So there is no plan or resource to create such document for public > > access. Is public spec mandatory for code check-in? We can provide > > platforms for verification instead. > > Nah, not needed. As long as the code paths don't break anything else and as > long as we can CC you to fix bugs people report, we're good. :-) > > Btw, please do not top-post on a public ML. I got it. Thanks. --- David > > Thx. > > -- > Regards/Gruss, > Boris. > > Good mailing practices for 400: avoid top-posting and trim the reply.
[PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
Don't choose the process with adj == OOM_SCORE_ADJ_MIN which over-allocating pages for ring buffers. Signed-off-by: Zhaoyang Huang--- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5f38398..1005d73 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1135,7 +1135,7 @@ static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu) { struct buffer_page *bpage, *tmp; - bool user_thread = current->mm != NULL; + bool user_thread = (current->mm != NULL && current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN); gfp_t mflags; long i; -- 1.9.1
[PATCH v1] ringbuffer: Don't choose the process with adj equal OOM_SCORE_ADJ_MIN
Don't choose the process with adj == OOM_SCORE_ADJ_MIN which over-allocating pages for ring buffers. Signed-off-by: Zhaoyang Huang --- kernel/trace/ring_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 5f38398..1005d73 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1135,7 +1135,7 @@ static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu) { struct buffer_page *bpage, *tmp; - bool user_thread = current->mm != NULL; + bool user_thread = (current->mm != NULL && current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN); gfp_t mflags; long i; -- 1.9.1
Re: [PATCH] checkpatch: relax check for revert commit
Hi Andy & Joe Although it is minor, it is a real bug, I thought. Is there any comment? Thank you --- Cheers, Jia On 4/2/2018 10:28 PM, Jia He Wrote: For revert commit, it might has two double quotation marks in its commit log. Relax the check condition for revert commit to avoid checkpatch errors. Signed-off-by: Jia He--- scripts/checkpatch.pl | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3d40403..96138d6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2643,20 +2643,20 @@ sub process { $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); - if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { + if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("(.*)"\)/i) { $orig_desc = $1; $hasparens = 1; } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && defined $rawlines[$linenr] && -$rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { +$rawlines[$linenr] =~ /^\s*\("(.*)"\)/) { $orig_desc = $1; $hasparens = 1; - } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && -defined $rawlines[$linenr] && -$rawlines[$linenr] =~ /^\s*[^"]+"\)/) { - $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; + } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\(".*$/i && + defined $rawlines[$linenr] && + $rawlines[$linenr] =~ /^\s*.*"\)/) { + $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("(.*)$/i; $orig_desc = $1; - $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; + $rawlines[$linenr] =~ /^\s*(.*)"\)/; $orig_desc .= " " . $1; $hasparens = 1; }
Re: [PATCH] checkpatch: relax check for revert commit
Hi Andy & Joe Although it is minor, it is a real bug, I thought. Is there any comment? Thank you --- Cheers, Jia On 4/2/2018 10:28 PM, Jia He Wrote: For revert commit, it might has two double quotation marks in its commit log. Relax the check condition for revert commit to avoid checkpatch errors. Signed-off-by: Jia He --- scripts/checkpatch.pl | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3d40403..96138d6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2643,20 +2643,20 @@ sub process { $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); - if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { + if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("(.*)"\)/i) { $orig_desc = $1; $hasparens = 1; } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && defined $rawlines[$linenr] && -$rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { +$rawlines[$linenr] =~ /^\s*\("(.*)"\)/) { $orig_desc = $1; $hasparens = 1; - } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && -defined $rawlines[$linenr] && -$rawlines[$linenr] =~ /^\s*[^"]+"\)/) { - $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; + } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\(".*$/i && + defined $rawlines[$linenr] && + $rawlines[$linenr] =~ /^\s*.*"\)/) { + $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("(.*)$/i; $orig_desc = $1; - $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; + $rawlines[$linenr] =~ /^\s*(.*)"\)/; $orig_desc .= " " . $1; $hasparens = 1; }
Re: [PATCH v7 2/5] arm: arm64: page_alloc: reduce unnecessary binary search in memblock_next_valid_pfn()
Thanks for your comments, Russell On 4/6/2018 5:09 PM, Russell King - ARM Linux Wrote: On Thu, Apr 05, 2018 at 05:50:54AM -0700, Matthew Wilcox wrote: On Thu, Apr 05, 2018 at 08:44:12PM +0800, Jia He wrote: On 4/5/2018 7:34 PM, Matthew Wilcox Wrote: On Thu, Apr 05, 2018 at 01:04:35AM -0700, Jia He wrote: Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns where possible") optimized the loop in memmap_init_zone(). But there is still some room for improvement. E.g. if pfn and pfn+1 are in the same memblock region, we can simply pfn++ instead of doing the binary search in memblock_next_valid_pfn. Sure, but I bet if we are >end_pfn, we're almost certainly going to the start_pfn of the next block, so why not test that as well? + /* fast path, return pfn+1 if next pfn is in the same region */ + if (early_region_idx != -1) { + start_pfn = PFN_DOWN(regions[early_region_idx].base); + end_pfn = PFN_DOWN(regions[early_region_idx].base + + regions[early_region_idx].size); + + if (pfn >= start_pfn && pfn < end_pfn) + return pfn; early_region_idx++; start_pfn = PFN_DOWN(regions[early_region_idx].base); if (pfn >= end_pfn && pfn <= start_pfn) return start_pfn; Thanks, thus the binary search in next step can be discarded? I don't know all the circumstances in which this is called. Maybe a linear search with memo is more appropriate than a binary search. That's been brought up before, and the reasoning appears to be something along the lines of... Academics and published wisdom is that on cached architectures, binary searches are bad because it doesn't operate efficiently due to the overhead from having to load cache lines. Consequently, there seems to be a knee-jerk reaction that "all binary searches are bad, we must eliminate them." IIUC, are you opposed to entirely removing the binary search instead of my previous patch set? What is failed to be grasped here, though, is that it is typical that the number of entries in this array tend to be small, so the entire array takes up one or two cache lines, maybe a maximum of four lines depending on your cache line length and number of entries. This means that the binary search expense is reduced, and is lower than a linear search for the majority of cases. What is key here as far as performance is concerned is whether the general usage of pfn_valid() by the kernel is optimal. We should not optimise only for the boot case, which means evaluating the effect of these changes with _real_ workloads, not just "does my machine boot a milliseconds faster". hmm.. But pfn is linearly increased during the booting time. This assumption is not correct in real workload for pfn_valid out of booting time. So in my patchset, I defined another pfn_valid_region for booting time only. I didn't have many arm/arm64 boxes to verifed. What I can do is guaranteeing the improvemnet in my armv8a (qualcom centriq 2400). Sorry about it. -- Cheers, Jia
Re: [PATCH v7 2/5] arm: arm64: page_alloc: reduce unnecessary binary search in memblock_next_valid_pfn()
Thanks for your comments, Russell On 4/6/2018 5:09 PM, Russell King - ARM Linux Wrote: On Thu, Apr 05, 2018 at 05:50:54AM -0700, Matthew Wilcox wrote: On Thu, Apr 05, 2018 at 08:44:12PM +0800, Jia He wrote: On 4/5/2018 7:34 PM, Matthew Wilcox Wrote: On Thu, Apr 05, 2018 at 01:04:35AM -0700, Jia He wrote: Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns where possible") optimized the loop in memmap_init_zone(). But there is still some room for improvement. E.g. if pfn and pfn+1 are in the same memblock region, we can simply pfn++ instead of doing the binary search in memblock_next_valid_pfn. Sure, but I bet if we are >end_pfn, we're almost certainly going to the start_pfn of the next block, so why not test that as well? + /* fast path, return pfn+1 if next pfn is in the same region */ + if (early_region_idx != -1) { + start_pfn = PFN_DOWN(regions[early_region_idx].base); + end_pfn = PFN_DOWN(regions[early_region_idx].base + + regions[early_region_idx].size); + + if (pfn >= start_pfn && pfn < end_pfn) + return pfn; early_region_idx++; start_pfn = PFN_DOWN(regions[early_region_idx].base); if (pfn >= end_pfn && pfn <= start_pfn) return start_pfn; Thanks, thus the binary search in next step can be discarded? I don't know all the circumstances in which this is called. Maybe a linear search with memo is more appropriate than a binary search. That's been brought up before, and the reasoning appears to be something along the lines of... Academics and published wisdom is that on cached architectures, binary searches are bad because it doesn't operate efficiently due to the overhead from having to load cache lines. Consequently, there seems to be a knee-jerk reaction that "all binary searches are bad, we must eliminate them." IIUC, are you opposed to entirely removing the binary search instead of my previous patch set? What is failed to be grasped here, though, is that it is typical that the number of entries in this array tend to be small, so the entire array takes up one or two cache lines, maybe a maximum of four lines depending on your cache line length and number of entries. This means that the binary search expense is reduced, and is lower than a linear search for the majority of cases. What is key here as far as performance is concerned is whether the general usage of pfn_valid() by the kernel is optimal. We should not optimise only for the boot case, which means evaluating the effect of these changes with _real_ workloads, not just "does my machine boot a milliseconds faster". hmm.. But pfn is linearly increased during the booting time. This assumption is not correct in real workload for pfn_valid out of booting time. So in my patchset, I defined another pfn_valid_region for booting time only. I didn't have many arm/arm64 boxes to verifed. What I can do is guaranteeing the improvemnet in my armv8a (qualcom centriq 2400). Sorry about it. -- Cheers, Jia
Re: [PATCH] mmc: dw_mmc-k3: Fix DDR52 mode by setting required clock divisor
On 2018/4/6 21:41, Ryan Grachek wrote: On Wed, Apr 4, 2018 at 7:51 PM, Shawn Linwrote: [+ Zhangfei Gao who added support for hi6220] On 2018/4/4 23:31, Ryan Grachek wrote: On Tue, Apr 3, 2018 at 6:31 AM, Shawn Lin > wrote: On 2018/3/30 2:24, oscardagrach wrote: Need at least one line commit body. Signed-off-by: oscardagrach > --- drivers/mmc/host/dw_mmc-k3.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 89cdb3d533bb..efc546cb4db8 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -194,8 +194,14 @@ static void dw_mci_hi6220_set_ios(struct dw_mci *host, struct mmc_ios *ios) int ret; unsigned int clock; - clock = (ios->clock <= 2500) ? 2500 : ios->clock; - + /* CLKDIV must be 1 for DDR52/8-bit mode */ + if (ios->bus_width == MMC_BUS_WIDTH_8 && + ios->timing == MMC_TIMING_MMC_DDR52) { + mci_writel(host, CLKDIV, 0x1); + clock = ios->clock; + } else { + clock = (ios->clock <= 2500) ? 2500 : ios->clock; + } I undertand DDR52/8-bit need CLKDIV fixed 1, but shouldn't the following change is more sensible? if (ios->bus_width == MMC_BUS_WIDTH_8 && ios->timing == MMC_TIMING_MMC_DDR52) clock = ios->clock * 2; else clock = (ios->clock <= 2500) ? 2500 : ios->clock; The reason is ios->clock is 52MHz and you could claim 104MHz from the clock provider and let dw_mmc core take care of the divder to be 1. Otherwise, you just force it to be DDR52/8-bit with a clk rate of 26MHz. ret = clk_set_rate(host->biu_clk, clock); if (ret) dev_warn(host->dev, "failed to set rate %uHz\n", clock); For future wise, please use plain mode mail, but not HTML format. Your feedback is correct. I see the Rockchip dwmmc driver has a similar implementation. After applying your suggested changes, however, my board reports "dwmmc_k3 f723d000.dwmmc0: failed to set rate 10400Hz" during intialization of eMMC. In addition, I do not see CLKDIV being set to 1. clk_set_rate fails and I wonder if this is out-of-scope of the driver. If I set CLKDIV where I did prior, with your changes, the device fails to set the clock and falls back to 52 MHz (26 MHz) and works fine, but again, CLKDIV is reported as 0 (even though it is 1.) One thing of interest to note is when I manually set the clock by doing: (echo 10400 > /sys/kernel/debug/mmc0/clock) the device reports back 'mmc_host mmc0: Bus speed (slot 0) = 19840Hz (slot req 10400Hz, actual 9920HZ div = 1)' which works reliably and clk_set_rate does not report any error. When looking closely into the code, at least dw_mci_hi6220_set_ios goes wrong with the bus_hz, since it should be ciu_clk but not biu_clk. "b" stands for bus, and "c" stands for card IMHO, however bus_hz describs the clock to the card, provided by controller. Does the following patch help? diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 89cdb3d..9e78cf2 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -194,13 +194,21 @@ static void dw_mci_hi6220_set_ios(struct dw_mci *host, struct mmc_ios *ios) int ret; unsigned int clock; - clock = (ios->clock <= 2500) ? 2500 : ios->clock; + if (ios->bus_width == MMC_BUS_WIDTH_8 && + ios->timing == MMC_TIMING_MMC_DDR52) + clock = ios->clock * 2; + else + clock = (ios->clock <= 2500) ? 2500 : ios->clock; - ret = clk_set_rate(host->biu_clk, clock); + ret = clk_set_rate(host->ciu_clk, clock); if (ret) dev_warn(host->dev, "failed to set rate %uHz\n", clock); - host->bus_hz = clk_get_rate(host->biu_clk); + clock = clk_get_rate(host->ciu_clk); + if (clock != host->bus_hz) { + host->bus_hz = clock; + host->current_speed = 0; + } } I am not sure where to begin debugging these clock issues and welcome any feedback. The change results in the following: 'dwmmc_k3 f723e000.dwmmc1: failed to set rate 2500Hz' 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 2500Hz' 'dwmmc_k3 f723f000.dwmmc2: failed to set rate 2500Hz' and later on: 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 5200Hz' 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 10400Hz' Eventually mmc1 (UHS-1 MicroSD)
Re: [PATCH] mmc: dw_mmc-k3: Fix DDR52 mode by setting required clock divisor
On 2018/4/6 21:41, Ryan Grachek wrote: On Wed, Apr 4, 2018 at 7:51 PM, Shawn Lin wrote: [+ Zhangfei Gao who added support for hi6220] On 2018/4/4 23:31, Ryan Grachek wrote: On Tue, Apr 3, 2018 at 6:31 AM, Shawn Lin mailto:shawn@rock-chips.com>> wrote: On 2018/3/30 2:24, oscardagrach wrote: Need at least one line commit body. Signed-off-by: oscardagrach mailto:r...@edited.us>> --- drivers/mmc/host/dw_mmc-k3.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 89cdb3d533bb..efc546cb4db8 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -194,8 +194,14 @@ static void dw_mci_hi6220_set_ios(struct dw_mci *host, struct mmc_ios *ios) int ret; unsigned int clock; - clock = (ios->clock <= 2500) ? 2500 : ios->clock; - + /* CLKDIV must be 1 for DDR52/8-bit mode */ + if (ios->bus_width == MMC_BUS_WIDTH_8 && + ios->timing == MMC_TIMING_MMC_DDR52) { + mci_writel(host, CLKDIV, 0x1); + clock = ios->clock; + } else { + clock = (ios->clock <= 2500) ? 2500 : ios->clock; + } I undertand DDR52/8-bit need CLKDIV fixed 1, but shouldn't the following change is more sensible? if (ios->bus_width == MMC_BUS_WIDTH_8 && ios->timing == MMC_TIMING_MMC_DDR52) clock = ios->clock * 2; else clock = (ios->clock <= 2500) ? 2500 : ios->clock; The reason is ios->clock is 52MHz and you could claim 104MHz from the clock provider and let dw_mmc core take care of the divder to be 1. Otherwise, you just force it to be DDR52/8-bit with a clk rate of 26MHz. ret = clk_set_rate(host->biu_clk, clock); if (ret) dev_warn(host->dev, "failed to set rate %uHz\n", clock); For future wise, please use plain mode mail, but not HTML format. Your feedback is correct. I see the Rockchip dwmmc driver has a similar implementation. After applying your suggested changes, however, my board reports "dwmmc_k3 f723d000.dwmmc0: failed to set rate 10400Hz" during intialization of eMMC. In addition, I do not see CLKDIV being set to 1. clk_set_rate fails and I wonder if this is out-of-scope of the driver. If I set CLKDIV where I did prior, with your changes, the device fails to set the clock and falls back to 52 MHz (26 MHz) and works fine, but again, CLKDIV is reported as 0 (even though it is 1.) One thing of interest to note is when I manually set the clock by doing: (echo 10400 > /sys/kernel/debug/mmc0/clock) the device reports back 'mmc_host mmc0: Bus speed (slot 0) = 19840Hz (slot req 10400Hz, actual 9920HZ div = 1)' which works reliably and clk_set_rate does not report any error. When looking closely into the code, at least dw_mci_hi6220_set_ios goes wrong with the bus_hz, since it should be ciu_clk but not biu_clk. "b" stands for bus, and "c" stands for card IMHO, however bus_hz describs the clock to the card, provided by controller. Does the following patch help? diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 89cdb3d..9e78cf2 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -194,13 +194,21 @@ static void dw_mci_hi6220_set_ios(struct dw_mci *host, struct mmc_ios *ios) int ret; unsigned int clock; - clock = (ios->clock <= 2500) ? 2500 : ios->clock; + if (ios->bus_width == MMC_BUS_WIDTH_8 && + ios->timing == MMC_TIMING_MMC_DDR52) + clock = ios->clock * 2; + else + clock = (ios->clock <= 2500) ? 2500 : ios->clock; - ret = clk_set_rate(host->biu_clk, clock); + ret = clk_set_rate(host->ciu_clk, clock); if (ret) dev_warn(host->dev, "failed to set rate %uHz\n", clock); - host->bus_hz = clk_get_rate(host->biu_clk); + clock = clk_get_rate(host->ciu_clk); + if (clock != host->bus_hz) { + host->bus_hz = clock; + host->current_speed = 0; + } } I am not sure where to begin debugging these clock issues and welcome any feedback. The change results in the following: 'dwmmc_k3 f723e000.dwmmc1: failed to set rate 2500Hz' 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 2500Hz' 'dwmmc_k3 f723f000.dwmmc2: failed to set rate 2500Hz' and later on: 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 5200Hz' 'dwmmc_k3 f723d000.dwmmc0: failed to set rate 10400Hz' Eventually mmc1 (UHS-1 MicroSD) will settle down after repeated attempts at setting 25 MHz: 'mmc_host
Re: [PATCH 1/3] hexagon: fix ffz/fls/ffs return type
On Fri, Apr 06, 2018 at 04:28:21PM +0200, Arnd Bergmann wrote: > Let's use the same return type as the major architectures to > avoid warnings like > > drivers/ata/libahci_platform.c: In function 'ahci_platform_init_host': > drivers/ata/libahci_platform.c:561:12: warning: comparison of distinct > pointer types lacks a cast [enabled by default] > > Signed-off-by: Arnd Bergmann> --- > arch/hexagon/include/asm/bitops.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/hexagon/include/asm/bitops.h > b/arch/hexagon/include/asm/bitops.h > index 5e4a59b3ec1b..8790a50b1f5e 100644 > --- a/arch/hexagon/include/asm/bitops.h > +++ b/arch/hexagon/include/asm/bitops.h > @@ -194,7 +194,7 @@ static inline int __test_bit(int nr, const volatile > unsigned long *addr) > * > * Undefined if no zero exists, so code should check against ~0UL first. > */ > -static inline long ffz(int x) > +static inline int ffz(int x) > { > int r; > > @@ -211,7 +211,7 @@ static inline long ffz(int x) > * This is defined the same way as ffs. > * Note fls(0) = 0, fls(1) = 1, fls(0x8000) = 32. > */ > -static inline long fls(int x) > +static inline int fls(int x) > { > int r; > > @@ -232,7 +232,7 @@ static inline long fls(int x) > * the libc and compiler builtin ffs routines, therefore > * differs in spirit from the above ffz (man ffs). > */ > -static inline long ffs(int x) > +static inline int ffs(int x) > { > int r; > Isn't ffz usually long/unsigned long on other architectures? -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 1/3] hexagon: fix ffz/fls/ffs return type
On Fri, Apr 06, 2018 at 04:28:21PM +0200, Arnd Bergmann wrote: > Let's use the same return type as the major architectures to > avoid warnings like > > drivers/ata/libahci_platform.c: In function 'ahci_platform_init_host': > drivers/ata/libahci_platform.c:561:12: warning: comparison of distinct > pointer types lacks a cast [enabled by default] > > Signed-off-by: Arnd Bergmann > --- > arch/hexagon/include/asm/bitops.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/hexagon/include/asm/bitops.h > b/arch/hexagon/include/asm/bitops.h > index 5e4a59b3ec1b..8790a50b1f5e 100644 > --- a/arch/hexagon/include/asm/bitops.h > +++ b/arch/hexagon/include/asm/bitops.h > @@ -194,7 +194,7 @@ static inline int __test_bit(int nr, const volatile > unsigned long *addr) > * > * Undefined if no zero exists, so code should check against ~0UL first. > */ > -static inline long ffz(int x) > +static inline int ffz(int x) > { > int r; > > @@ -211,7 +211,7 @@ static inline long ffz(int x) > * This is defined the same way as ffs. > * Note fls(0) = 0, fls(1) = 1, fls(0x8000) = 32. > */ > -static inline long fls(int x) > +static inline int fls(int x) > { > int r; > > @@ -232,7 +232,7 @@ static inline long fls(int x) > * the libc and compiler builtin ffs routines, therefore > * differs in spirit from the above ffz (man ffs). > */ > -static inline long ffs(int x) > +static inline int ffs(int x) > { > int r; > Isn't ffz usually long/unsigned long on other architectures? -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project