mm/slub.o:undefined reference to `_GLOBAL_OFFSET_TABLE_'
Hi Jesper, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 7d1e042314619115153a0f6f06e4552c09a50e13 commit: d0ecd894e3d5f768a84403b34019c4a7daa05882 slub: optimize bulk slowpath free by detached freelist date: 10 months ago config: microblaze-allnoconfig (attached as .config) compiler: microblaze-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout d0ecd894e3d5f768a84403b34019c4a7daa05882 # save the attached .config to linux build tree make.cross ARCH=microblaze All errors (new ones prefixed by >>): mm/built-in.o: In function `__slab_free.isra.14': >> mm/slub.o:(.text+0x28d1c): undefined reference to `_GLOBAL_OFFSET_TABLE_' scripts/link-vmlinux.sh: line 52: 18051 Segmentation fault ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds} ${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
mm/slub.o:undefined reference to `_GLOBAL_OFFSET_TABLE_'
Hi Jesper, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 7d1e042314619115153a0f6f06e4552c09a50e13 commit: d0ecd894e3d5f768a84403b34019c4a7daa05882 slub: optimize bulk slowpath free by detached freelist date: 10 months ago config: microblaze-allnoconfig (attached as .config) compiler: microblaze-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout d0ecd894e3d5f768a84403b34019c4a7daa05882 # save the attached .config to linux build tree make.cross ARCH=microblaze All errors (new ones prefixed by >>): mm/built-in.o: In function `__slab_free.isra.14': >> mm/slub.o:(.text+0x28d1c): undefined reference to `_GLOBAL_OFFSET_TABLE_' scripts/link-vmlinux.sh: line 52: 18051 Segmentation fault ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds} ${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v7 6/6] powerpc: pSeries: Add pv-qspinlock build config/make
hi, all ok, this patch set depends on https://patchwork.kernel.org/patch/8953981/ [V4] powerpc: Implement {cmp}xchg for u8 and u16 sorry. On 2016年09月19日 16:58, kbuild test robot wrote: Hi Pan, [auto build test ERROR on powerpc/next] [also build test ERROR on v4.8-rc7 next-20160916] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] [Suggest to use git(>=2.9.0) format-patch --base= (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on] [Check https://git-scm.com/docs/git-format-patch for more information] url: https://github.com/0day-ci/linux/commits/Pan-Xinhui/Implement-qspinlock-pv-qspinlock-on-ppc/20160919-133130 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__cmpxchg', inlined from 'pv_wait_node' at kernel/locking/qspinlock_paravirt.h:328:3, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:538:3: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_326' declared with attribute error: Unsupported size for __cmpxchg _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__cmpxchg', inlined from 'pv_wait_head_or_lock' at kernel/locking/qspinlock_paravirt.h:109:10, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:573:5: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_326' declared with attribute error: Unsupported size for __cmpxchg _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__xchg_relaxed', inlined from 'pv_wait_head_or_lock' at kernel/locking/qspinlock_paravirt.h:442:8, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:573:5: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_113' declared with attribute error: Unsupported size for __xchg_local _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~
Re: [PATCH v7 6/6] powerpc: pSeries: Add pv-qspinlock build config/make
hi, all ok, this patch set depends on https://patchwork.kernel.org/patch/8953981/ [V4] powerpc: Implement {cmp}xchg for u8 and u16 sorry. On 2016年09月19日 16:58, kbuild test robot wrote: Hi Pan, [auto build test ERROR on powerpc/next] [also build test ERROR on v4.8-rc7 next-20160916] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] [Suggest to use git(>=2.9.0) format-patch --base= (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on] [Check https://git-scm.com/docs/git-format-patch for more information] url: https://github.com/0day-ci/linux/commits/Pan-Xinhui/Implement-qspinlock-pv-qspinlock-on-ppc/20160919-133130 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__cmpxchg', inlined from 'pv_wait_node' at kernel/locking/qspinlock_paravirt.h:328:3, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:538:3: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_326' declared with attribute error: Unsupported size for __cmpxchg _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__cmpxchg', inlined from 'pv_wait_head_or_lock' at kernel/locking/qspinlock_paravirt.h:109:10, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:573:5: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_326' declared with attribute error: Unsupported size for __cmpxchg _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~ include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert' #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) ^~ arch/powerpc/include/asm/cmpxchg.h:326:2: note: in expansion of macro 'BUILD_BUG_ON_MSG' BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); ^~~~ In function '__xchg_relaxed', inlined from 'pv_wait_head_or_lock' at kernel/locking/qspinlock_paravirt.h:442:8, inlined from '__pv_queued_spin_lock_slowpath' at kernel/locking/qspinlock.c:573:5: include/linux/compiler.h:491:38: error: call to '__compiletime_assert_113' declared with attribute error: Unsupported size for __xchg_local _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^ include/linux/compiler.h:474:4: note: in definition of macro '__compiletime_assert' prefix ## suffix();\ ^~ include/linux/compiler.h:491:2: note: in expansion of macro '_compiletime_assert' _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__) ^~~
Re: [PATCH] cxgb4: fix signed wrap around when decrementing index idx
From: Colin KingDate: Tue, 20 Sep 2016 15:48:45 +0100 > From: Colin Ian King > > Change predecrement compare to post decrement compare to avoid an > unsigned integer wrap-around comparison when decrementing idx in > the while loop. > > For example, when idx is zero, the current situation will > predecrement idx in the while loop, wrapping idx to the maximum > signed integer and cause out of bounds reads on rxq_info->msix_tbl[idx]. > > Signed-off-by: Colin Ian King This doesn't apply cleanly to the 'net' tree, please respin.
Re: [PATCH] cxgb4: fix signed wrap around when decrementing index idx
From: Colin King Date: Tue, 20 Sep 2016 15:48:45 +0100 > From: Colin Ian King > > Change predecrement compare to post decrement compare to avoid an > unsigned integer wrap-around comparison when decrementing idx in > the while loop. > > For example, when idx is zero, the current situation will > predecrement idx in the while loop, wrapping idx to the maximum > signed integer and cause out of bounds reads on rxq_info->msix_tbl[idx]. > > Signed-off-by: Colin Ian King This doesn't apply cleanly to the 'net' tree, please respin.
Re: [PATCH v5 3/6] mm/cma: populate ZONE_CMA
On Wed, Sep 21, 2016 at 11:20:11AM +0200, Vlastimil Babka wrote: > On 08/29/2016 07:07 AM, js1...@gmail.com wrote: > >From: Joonsoo Kim> > > >Until now, reserved pages for CMA are managed in the ordinary zones > >where page's pfn are belong to. This approach has numorous problems > >and fixing them isn't easy. (It is mentioned on previous patch.) > >To fix this situation, ZONE_CMA is introduced in previous patch, but, > >not yet populated. This patch implement population of ZONE_CMA > >by stealing reserved pages from the ordinary zones. > > > >Unlike previous implementation that kernel allocation request with > >__GFP_MOVABLE could be serviced from CMA region, allocation request only > >with GFP_HIGHUSER_MOVABLE can be serviced from CMA region in the new > >approach. This is an inevitable design decision to use the zone > >implementation because ZONE_CMA could contain highmem. Due to this > >decision, ZONE_CMA will work like as ZONE_HIGHMEM or ZONE_MOVABLE. > > > >I don't think it would be a problem because most of file cache pages > >and anonymous pages are requested with GFP_HIGHUSER_MOVABLE. It could > >be proved by the fact that there are many systems with ZONE_HIGHMEM and > >they work fine. Notable disadvantage is that we cannot use these pages > >for blockdev file cache page, because it usually has __GFP_MOVABLE but > >not __GFP_HIGHMEM and __GFP_USER. But, in this case, there is pros and > >cons. In my experience, blockdev file cache pages are one of the top > >reason that causes cma_alloc() to fail temporarily. So, we can get more > >guarantee of cma_alloc() success by discarding that case. > > > >Implementation itself is very easy to understand. Steal when cma area is > >initialized and recalculate various per zone stat/threshold. > > > >Signed-off-by: Joonsoo Kim > > ... > > >@@ -145,6 +145,28 @@ err: > > static int __init cma_init_reserved_areas(void) > > { > > int i; > >+struct zone *zone; > >+unsigned long start_pfn = UINT_MAX, end_pfn = 0; > >+ > >+if (!cma_area_count) > >+return 0; > >+ > >+for (i = 0; i < cma_area_count; i++) { > >+if (start_pfn > cma_areas[i].base_pfn) > >+start_pfn = cma_areas[i].base_pfn; > >+if (end_pfn < cma_areas[i].base_pfn + cma_areas[i].count) > >+end_pfn = cma_areas[i].base_pfn + cma_areas[i].count; > >+} > >+ > >+for_each_zone(zone) { > >+if (!is_zone_cma(zone)) > >+continue; > >+ > >+/* ZONE_CMA doesn't need to exceed CMA region */ > >+zone->zone_start_pfn = max(zone->zone_start_pfn, start_pfn); > >+zone->spanned_pages = min(zone_end_pfn(zone), end_pfn) - > >+zone->zone_start_pfn; > >+} > > Hmm, so what happens on a system with multiple nodes? Each will have > its own ZONE_CMA, and all will have the same start pfn and spanned > pages? Each of zone_start_pfn and spanned_pages are initialized in calculate_node_totalpages() which considers node boundary. So, they will have not the same start pfn and spanned pages. However, each would contain unnecessary holes. > > > /* Free whole pageblock and set its migration type to MIGRATE_CMA. */ > > void __init init_cma_reserved_pageblock(struct page *page) > > { > > unsigned i = pageblock_nr_pages; > >+unsigned long pfn = page_to_pfn(page); > > struct page *p = page; > >+int nid = page_to_nid(page); > >+ > >+/* > >+ * ZONE_CMA will steal present pages from other zones by changing > >+ * page links so page_zone() is changed. Before that, > >+ * we need to adjust previous zone's page count first. > >+ */ > >+adjust_present_page_count(page, -pageblock_nr_pages); > > > > do { > > __ClearPageReserved(p); > > set_page_count(p, 0); > >-} while (++p, --i); > >+ > >+/* Steal pages from other zones */ > >+set_page_links(p, ZONE_CMA, nid, pfn); > >+} while (++p, ++pfn, --i); > >+ > >+adjust_present_page_count(page, pageblock_nr_pages); > > This seems to assign pages to ZONE_CMA on the proper node, which is > good. But then ZONE_CMA on multiple nodes will have unnecessary > holes in the spanned pages, as each will contain only a subset. True, I will fix it and respin the series. Thanks.
Re: [PATCH v5 3/6] mm/cma: populate ZONE_CMA
On Wed, Sep 21, 2016 at 11:20:11AM +0200, Vlastimil Babka wrote: > On 08/29/2016 07:07 AM, js1...@gmail.com wrote: > >From: Joonsoo Kim > > > >Until now, reserved pages for CMA are managed in the ordinary zones > >where page's pfn are belong to. This approach has numorous problems > >and fixing them isn't easy. (It is mentioned on previous patch.) > >To fix this situation, ZONE_CMA is introduced in previous patch, but, > >not yet populated. This patch implement population of ZONE_CMA > >by stealing reserved pages from the ordinary zones. > > > >Unlike previous implementation that kernel allocation request with > >__GFP_MOVABLE could be serviced from CMA region, allocation request only > >with GFP_HIGHUSER_MOVABLE can be serviced from CMA region in the new > >approach. This is an inevitable design decision to use the zone > >implementation because ZONE_CMA could contain highmem. Due to this > >decision, ZONE_CMA will work like as ZONE_HIGHMEM or ZONE_MOVABLE. > > > >I don't think it would be a problem because most of file cache pages > >and anonymous pages are requested with GFP_HIGHUSER_MOVABLE. It could > >be proved by the fact that there are many systems with ZONE_HIGHMEM and > >they work fine. Notable disadvantage is that we cannot use these pages > >for blockdev file cache page, because it usually has __GFP_MOVABLE but > >not __GFP_HIGHMEM and __GFP_USER. But, in this case, there is pros and > >cons. In my experience, blockdev file cache pages are one of the top > >reason that causes cma_alloc() to fail temporarily. So, we can get more > >guarantee of cma_alloc() success by discarding that case. > > > >Implementation itself is very easy to understand. Steal when cma area is > >initialized and recalculate various per zone stat/threshold. > > > >Signed-off-by: Joonsoo Kim > > ... > > >@@ -145,6 +145,28 @@ err: > > static int __init cma_init_reserved_areas(void) > > { > > int i; > >+struct zone *zone; > >+unsigned long start_pfn = UINT_MAX, end_pfn = 0; > >+ > >+if (!cma_area_count) > >+return 0; > >+ > >+for (i = 0; i < cma_area_count; i++) { > >+if (start_pfn > cma_areas[i].base_pfn) > >+start_pfn = cma_areas[i].base_pfn; > >+if (end_pfn < cma_areas[i].base_pfn + cma_areas[i].count) > >+end_pfn = cma_areas[i].base_pfn + cma_areas[i].count; > >+} > >+ > >+for_each_zone(zone) { > >+if (!is_zone_cma(zone)) > >+continue; > >+ > >+/* ZONE_CMA doesn't need to exceed CMA region */ > >+zone->zone_start_pfn = max(zone->zone_start_pfn, start_pfn); > >+zone->spanned_pages = min(zone_end_pfn(zone), end_pfn) - > >+zone->zone_start_pfn; > >+} > > Hmm, so what happens on a system with multiple nodes? Each will have > its own ZONE_CMA, and all will have the same start pfn and spanned > pages? Each of zone_start_pfn and spanned_pages are initialized in calculate_node_totalpages() which considers node boundary. So, they will have not the same start pfn and spanned pages. However, each would contain unnecessary holes. > > > /* Free whole pageblock and set its migration type to MIGRATE_CMA. */ > > void __init init_cma_reserved_pageblock(struct page *page) > > { > > unsigned i = pageblock_nr_pages; > >+unsigned long pfn = page_to_pfn(page); > > struct page *p = page; > >+int nid = page_to_nid(page); > >+ > >+/* > >+ * ZONE_CMA will steal present pages from other zones by changing > >+ * page links so page_zone() is changed. Before that, > >+ * we need to adjust previous zone's page count first. > >+ */ > >+adjust_present_page_count(page, -pageblock_nr_pages); > > > > do { > > __ClearPageReserved(p); > > set_page_count(p, 0); > >-} while (++p, --i); > >+ > >+/* Steal pages from other zones */ > >+set_page_links(p, ZONE_CMA, nid, pfn); > >+} while (++p, ++pfn, --i); > >+ > >+adjust_present_page_count(page, pageblock_nr_pages); > > This seems to assign pages to ZONE_CMA on the proper node, which is > good. But then ZONE_CMA on multiple nodes will have unnecessary > holes in the spanned pages, as each will contain only a subset. True, I will fix it and respin the series. Thanks.
Re: [RFC PATCH v3 2/7] proc: Reduce cache miss in {snmp,netstat}_seq_show
On 9/22/16 2:24 AM, Marcelo wrote: On Thu, Sep 22, 2016 at 12:18:46AM +0800, hejianet wrote: Hi Marcelo sorry for the late, just came back from a vacation. Hi, no problem. Hope your batteries are recharged now :-) On 9/14/16 7:55 PM, Marcelo wrote: Hi Jia, On Wed, Sep 14, 2016 at 01:58:42PM +0800, hejianet wrote: Hi Marcelo On 9/13/16 2:57 AM, Marcelo wrote: On Fri, Sep 09, 2016 at 02:33:57PM +0800, Jia He wrote: This is to use the generic interface snmp_get_cpu_field{,64}_batch to aggregate the data by going through all the items of each cpu sequentially. Then snmp_seq_show and netstat_seq_show are split into 2 parts to avoid build warning "the frame size" larger than 1024 on s390. Yeah about that, did you test it with stack overflow detection? These arrays can be quite large. One more below.. Do you think it is acceptable if the stack usage is a little larger than 1024? e.g. 1120 I can't find any other way to reduce the stack usage except use "static" before unsigned long buff[TCP_MIB_MAX] PS. sizeof buff is about TCP_MIB_MAX(116)*8=928 B.R. That's pretty much the question. Linux has the option on some archs to run with 4Kb (4KSTACKS option), so this function alone would be using 25% of it in this last case. While on x86_64, it uses 16Kb (6538b8ea886e ("x86_64: expand kernel stack to 16K")). Adding static to it is not an option as it actually makes the variable shared amongst the CPUs (and then you have concurrency issues), plus the fact that it's always allocated, even while not in use. Others here certainly know better than me if it's okay to make such usage of the stach. What about this patch instead? It is a trade-off. I split the aggregation process into 2 parts, it will increase the cache miss a little bit, but it can reduce the stack usage. After this, stack usage is 672bytes objdump -d vmlinux | ./scripts/checkstack.pl ppc64 | grep seq_show 0xc07f7cc0 netstat_seq_show_tcpext.isra.3 [vmlinux]:672 diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index c6ee8a2..cc41590 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -486,22 +486,37 @@ static const struct file_operations snmp_seq_fops = { */ static int netstat_seq_show_tcpext(struct seq_file *seq, void *v) { - int i; - unsigned long buff[LINUX_MIB_MAX]; + int i, c; + unsigned long buff[LINUX_MIB_MAX/2 + 1]; struct net *net = seq->private; - memset(buff, 0, sizeof(unsigned long) * LINUX_MIB_MAX); + memset(buff, 0, sizeof(unsigned long) * (LINUX_MIB_MAX/2 + 1)); seq_puts(seq, "TcpExt:"); for (i = 0; snmp4_net_list[i].name; i++) seq_printf(seq, " %s", snmp4_net_list[i].name); seq_puts(seq, "\nTcpExt:"); - snmp_get_cpu_field_batch(buff, snmp4_net_list, -net->mib.net_statistics); - for (i = 0; snmp4_net_list[i].name; i++) + for_each_possible_cpu(c) { + for (i = 0; i < LINUX_MIB_MAX/2; i++) + buff[i] += snmp_get_cpu_field( + net->mib.net_statistics, + c, snmp4_net_list[i].entry); + } + for (i = 0; i < LINUX_MIB_MAX/2; i++) seq_printf(seq, " %lu", buff[i]); + memset(buff, 0, sizeof(unsigned long) * (LINUX_MIB_MAX/2 + 1)); + for_each_possible_cpu(c) { + for (i = LINUX_MIB_MAX/2; snmp4_net_list[i].name; i++) + buff[i - LINUX_MIB_MAX/2] += snmp_get_cpu_field( + net->mib.net_statistics, + c, + snmp4_net_list[i].entry); + } +for (i = LINUX_MIB_MAX/2; snmp4_net_list[i].name; i++) +seq_printf(seq, " %lu", buff[i - LINUX_MIB_MAX/2]); + return 0; } Yep, it halves the stack usage, but it doesn't look good heh But well, you may try to post the patchset (with or without this last change, you pick) officially and see how it goes. As you're posting as RFC, it's not being evaluated as seriously. Thanks for the suggestion, I will remove it in future patch version FWIW, I tested your patches, using your test and /proc/net/snmp file on a x86_64 box, Intel(R) Xeon(R) CPU E5-2643 v3. Before the patches: Performance counter stats for './test /proc/net/snmp': 5.225 cache-misses 12.708.673.785 L1-dcache-loads 1.288.450.174 L1-dcache-load-misses # 10,14% of all L1-dcache hits 1.271.857.028 LLC-loads 4.122 LLC-load-misses #0,00% of all LL-cache hits 9,174936524 seconds time elapsed After: Performance counter stats for './test /proc/net/snmp': 2.865 cache-misses 30.203.883.807 L1-dcache-loads 1.215.774.643 L1-dcache-load-misses #4,03% of all L1-dcache hits 1.181.662.831 LLC-loads 2.685 LLC-load-misses #0,00%
Re: [RFC PATCH v3 2/7] proc: Reduce cache miss in {snmp,netstat}_seq_show
On 9/22/16 2:24 AM, Marcelo wrote: On Thu, Sep 22, 2016 at 12:18:46AM +0800, hejianet wrote: Hi Marcelo sorry for the late, just came back from a vacation. Hi, no problem. Hope your batteries are recharged now :-) On 9/14/16 7:55 PM, Marcelo wrote: Hi Jia, On Wed, Sep 14, 2016 at 01:58:42PM +0800, hejianet wrote: Hi Marcelo On 9/13/16 2:57 AM, Marcelo wrote: On Fri, Sep 09, 2016 at 02:33:57PM +0800, Jia He wrote: This is to use the generic interface snmp_get_cpu_field{,64}_batch to aggregate the data by going through all the items of each cpu sequentially. Then snmp_seq_show and netstat_seq_show are split into 2 parts to avoid build warning "the frame size" larger than 1024 on s390. Yeah about that, did you test it with stack overflow detection? These arrays can be quite large. One more below.. Do you think it is acceptable if the stack usage is a little larger than 1024? e.g. 1120 I can't find any other way to reduce the stack usage except use "static" before unsigned long buff[TCP_MIB_MAX] PS. sizeof buff is about TCP_MIB_MAX(116)*8=928 B.R. That's pretty much the question. Linux has the option on some archs to run with 4Kb (4KSTACKS option), so this function alone would be using 25% of it in this last case. While on x86_64, it uses 16Kb (6538b8ea886e ("x86_64: expand kernel stack to 16K")). Adding static to it is not an option as it actually makes the variable shared amongst the CPUs (and then you have concurrency issues), plus the fact that it's always allocated, even while not in use. Others here certainly know better than me if it's okay to make such usage of the stach. What about this patch instead? It is a trade-off. I split the aggregation process into 2 parts, it will increase the cache miss a little bit, but it can reduce the stack usage. After this, stack usage is 672bytes objdump -d vmlinux | ./scripts/checkstack.pl ppc64 | grep seq_show 0xc07f7cc0 netstat_seq_show_tcpext.isra.3 [vmlinux]:672 diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index c6ee8a2..cc41590 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -486,22 +486,37 @@ static const struct file_operations snmp_seq_fops = { */ static int netstat_seq_show_tcpext(struct seq_file *seq, void *v) { - int i; - unsigned long buff[LINUX_MIB_MAX]; + int i, c; + unsigned long buff[LINUX_MIB_MAX/2 + 1]; struct net *net = seq->private; - memset(buff, 0, sizeof(unsigned long) * LINUX_MIB_MAX); + memset(buff, 0, sizeof(unsigned long) * (LINUX_MIB_MAX/2 + 1)); seq_puts(seq, "TcpExt:"); for (i = 0; snmp4_net_list[i].name; i++) seq_printf(seq, " %s", snmp4_net_list[i].name); seq_puts(seq, "\nTcpExt:"); - snmp_get_cpu_field_batch(buff, snmp4_net_list, -net->mib.net_statistics); - for (i = 0; snmp4_net_list[i].name; i++) + for_each_possible_cpu(c) { + for (i = 0; i < LINUX_MIB_MAX/2; i++) + buff[i] += snmp_get_cpu_field( + net->mib.net_statistics, + c, snmp4_net_list[i].entry); + } + for (i = 0; i < LINUX_MIB_MAX/2; i++) seq_printf(seq, " %lu", buff[i]); + memset(buff, 0, sizeof(unsigned long) * (LINUX_MIB_MAX/2 + 1)); + for_each_possible_cpu(c) { + for (i = LINUX_MIB_MAX/2; snmp4_net_list[i].name; i++) + buff[i - LINUX_MIB_MAX/2] += snmp_get_cpu_field( + net->mib.net_statistics, + c, + snmp4_net_list[i].entry); + } +for (i = LINUX_MIB_MAX/2; snmp4_net_list[i].name; i++) +seq_printf(seq, " %lu", buff[i - LINUX_MIB_MAX/2]); + return 0; } Yep, it halves the stack usage, but it doesn't look good heh But well, you may try to post the patchset (with or without this last change, you pick) officially and see how it goes. As you're posting as RFC, it's not being evaluated as seriously. Thanks for the suggestion, I will remove it in future patch version FWIW, I tested your patches, using your test and /proc/net/snmp file on a x86_64 box, Intel(R) Xeon(R) CPU E5-2643 v3. Before the patches: Performance counter stats for './test /proc/net/snmp': 5.225 cache-misses 12.708.673.785 L1-dcache-loads 1.288.450.174 L1-dcache-load-misses # 10,14% of all L1-dcache hits 1.271.857.028 LLC-loads 4.122 LLC-load-misses #0,00% of all LL-cache hits 9,174936524 seconds time elapsed After: Performance counter stats for './test /proc/net/snmp': 2.865 cache-misses 30.203.883.807 L1-dcache-loads 1.215.774.643 L1-dcache-load-misses #4,03% of all L1-dcache hits 1.181.662.831 LLC-loads 2.685 LLC-load-misses #0,00%
[PATCH 11/11] staging: dgnc: introduce find_board_by_major()
It was used to get a board structure with dgnc_BoardsByMajor array. But this driver already has the array for managing initialized board as dgap_board[]. It can be used for searching the board structure by major number. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_tty.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index ba724ab..a486a86 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -45,7 +45,6 @@ /* * internal variables */ -static struct dgnc_board *dgnc_BoardsByMajor[256]; static unsigned char *dgnc_TmpWriteBuf; /* @@ -251,8 +250,6 @@ int dgnc_tty_register(struct dgnc_board *brd) goto free_print_driver; } - dgnc_BoardsByMajor[brd->serial_driver->major] = brd; - return 0; free_print_driver: @@ -388,7 +385,6 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; - dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -397,7 +393,6 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) } tty_unregister_driver(brd->serial_driver); - dgnc_BoardsByMajor[brd->print_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -935,6 +930,24 @@ void dgnc_wakeup_writes(struct channel_t *ch) spin_unlock_irqrestore(>ch_lock, flags); } +struct dgnc_board *find_board_by_major(unsigned int major) +{ + int i; + + for (i = 0; i < MAXBOARDS; i++) { + struct dgnc_board *brd = dgnc_board[i]; + + if (!brd) + return NULL; + + if (major == brd->serial_driver->major || + major == brd->print_driver->major) + return brd; + } + + return NULL; +} + / * * TTY Entry points and helper functions @@ -964,7 +977,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) return -ENXIO; /* Get board pointer from our array of majors we have allocated */ - brd = dgnc_BoardsByMajor[major]; + brd = find_board_by_major(major); if (!brd) return -ENXIO; -- 1.9.1
[PATCH 11/11] staging: dgnc: introduce find_board_by_major()
It was used to get a board structure with dgnc_BoardsByMajor array. But this driver already has the array for managing initialized board as dgap_board[]. It can be used for searching the board structure by major number. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_tty.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index ba724ab..a486a86 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -45,7 +45,6 @@ /* * internal variables */ -static struct dgnc_board *dgnc_BoardsByMajor[256]; static unsigned char *dgnc_TmpWriteBuf; /* @@ -251,8 +250,6 @@ int dgnc_tty_register(struct dgnc_board *brd) goto free_print_driver; } - dgnc_BoardsByMajor[brd->serial_driver->major] = brd; - return 0; free_print_driver: @@ -388,7 +385,6 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; - dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -397,7 +393,6 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) } tty_unregister_driver(brd->serial_driver); - dgnc_BoardsByMajor[brd->print_driver->major] = NULL; for (i = 0; i < brd->nasync; i++) { if (brd->channels[i]) dgnc_remove_tty_sysfs(brd->channels[i]-> @@ -935,6 +930,24 @@ void dgnc_wakeup_writes(struct channel_t *ch) spin_unlock_irqrestore(>ch_lock, flags); } +struct dgnc_board *find_board_by_major(unsigned int major) +{ + int i; + + for (i = 0; i < MAXBOARDS; i++) { + struct dgnc_board *brd = dgnc_board[i]; + + if (!brd) + return NULL; + + if (major == brd->serial_driver->major || + major == brd->print_driver->major) + return brd; + } + + return NULL; +} + / * * TTY Entry points and helper functions @@ -964,7 +977,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file) return -ENXIO; /* Get board pointer from our array of majors we have allocated */ - brd = dgnc_BoardsByMajor[major]; + brd = find_board_by_major(major); if (!brd) return -ENXIO; -- 1.9.1
[PATCH 08/11] staging: dgnc: introduce the dgnc_free_irq()
The dgnc_free_irq() will free the requested IRQ from the dgnc_request_irq(). Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 70e68b5..81ce5c4 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -38,6 +38,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ static int dgnc_start(void); static int dgnc_request_irq(struct dgnc_board *brd); +static void dgnc_free_irq(struct dgnc_board *brd); static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); @@ -305,7 +306,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = dgnc_tty_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto unregister_tty; + goto free_irq; } brd->state = BOARD_READY; @@ -317,6 +318,8 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; +free_irq: + dgnc_free_irq(brd); unregister_tty: dgnc_tty_unregister(brd); @@ -577,6 +580,12 @@ static int dgnc_request_irq(struct dgnc_board *brd) return rc; } +static void dgnc_free_irq(struct dgnc_board *brd) +{ + if (brd->irq) + free_irq(brd->irq, brd); +} + /* * Remap PCI memory. */ -- 1.9.1
[PATCH 06/11] staging: dgnc: introduce the dgnc_tty_unregister()
The dgnc_tty_unregister() will be called when the dgnc_tty_register() is failed. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 7 +-- drivers/staging/dgnc/dgnc_tty.c| 8 drivers/staging/dgnc/dgnc_tty.h| 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index a95d13c..ffe55a2 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -299,13 +299,13 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = dgnc_finalize_board_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); - goto failed; + goto unregister_tty; } rc = dgnc_tty_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto failed; + goto unregister_tty; } brd->state = BOARD_READY; @@ -317,6 +317,9 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; +unregister_tty: + dgnc_tty_unregister(brd); + failed: kfree(brd); diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index fd46ef0..893f473 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -273,6 +273,14 @@ free_serial_driver: return rc; } +void dgnc_tty_unregister(struct dgnc_board *brd) +{ + tty_unregister_driver(brd->print_driver); + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->print_driver); + put_tty_driver(brd->serial_driver); +} + /* * dgnc_tty_init() * diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 21d3369..f065c8f 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -19,6 +19,7 @@ #include "dgnc_driver.h" intdgnc_tty_register(struct dgnc_board *brd); +void dgnc_tty_unregister(struct dgnc_board *brd); intdgnc_tty_preinit(void); int dgnc_tty_init(struct dgnc_board *); -- 1.9.1
[PATCH 08/11] staging: dgnc: introduce the dgnc_free_irq()
The dgnc_free_irq() will free the requested IRQ from the dgnc_request_irq(). Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 70e68b5..81ce5c4 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -38,6 +38,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ static int dgnc_start(void); static int dgnc_request_irq(struct dgnc_board *brd); +static void dgnc_free_irq(struct dgnc_board *brd); static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); @@ -305,7 +306,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = dgnc_tty_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto unregister_tty; + goto free_irq; } brd->state = BOARD_READY; @@ -317,6 +318,8 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; +free_irq: + dgnc_free_irq(brd); unregister_tty: dgnc_tty_unregister(brd); @@ -577,6 +580,12 @@ static int dgnc_request_irq(struct dgnc_board *brd) return rc; } +static void dgnc_free_irq(struct dgnc_board *brd) +{ + if (brd->irq) + free_irq(brd->irq, brd); +} + /* * Remap PCI memory. */ -- 1.9.1
[PATCH 06/11] staging: dgnc: introduce the dgnc_tty_unregister()
The dgnc_tty_unregister() will be called when the dgnc_tty_register() is failed. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 7 +-- drivers/staging/dgnc/dgnc_tty.c| 8 drivers/staging/dgnc/dgnc_tty.h| 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index a95d13c..ffe55a2 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -299,13 +299,13 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rc = dgnc_finalize_board_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); - goto failed; + goto unregister_tty; } rc = dgnc_tty_init(brd); if (rc < 0) { pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto failed; + goto unregister_tty; } brd->state = BOARD_READY; @@ -317,6 +317,9 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; +unregister_tty: + dgnc_tty_unregister(brd); + failed: kfree(brd); diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index fd46ef0..893f473 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -273,6 +273,14 @@ free_serial_driver: return rc; } +void dgnc_tty_unregister(struct dgnc_board *brd) +{ + tty_unregister_driver(brd->print_driver); + tty_unregister_driver(brd->serial_driver); + put_tty_driver(brd->print_driver); + put_tty_driver(brd->serial_driver); +} + /* * dgnc_tty_init() * diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 21d3369..f065c8f 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -19,6 +19,7 @@ #include "dgnc_driver.h" intdgnc_tty_register(struct dgnc_board *brd); +void dgnc_tty_unregister(struct dgnc_board *brd); intdgnc_tty_preinit(void); int dgnc_tty_init(struct dgnc_board *); -- 1.9.1
[PATCH 07/11] staging: dgnc: rename dgnc_finalize_board_init() to
The dgnc_finalize_board_init() function has only job for requesting the IRQ. It should be renamed to dgnc_request_irq() Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index ffe55a2..70e68b5 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -37,7 +37,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); * */ static int dgnc_start(void); -static int dgnc_finalize_board_init(struct dgnc_board *brd); +static int dgnc_request_irq(struct dgnc_board *brd); static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); @@ -296,7 +296,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto failed; } - rc = dgnc_finalize_board_init(brd); + rc = dgnc_request_irq(brd); if (rc < 0) { pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); goto unregister_tty; @@ -558,7 +558,7 @@ failed: return ERR_PTR(rc); } -static int dgnc_finalize_board_init(struct dgnc_board *brd) +static int dgnc_request_irq(struct dgnc_board *brd) { int rc = 0; -- 1.9.1
[PATCH 10/11] staging: dgnc: remove useless variables
The dgnc_major_serial_registered and dgnc_major_serial_registered do not need to use to check whether the tty driver is registered or not. These variables are used only in dgnc_cleanup_tty() function, This function will be called normally with initialized board structure. It means the dgnc_cleanup_tty() cannot be called with unregistered tty. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.h | 3 -- drivers/staging/dgnc/dgnc_tty.c| 64 +++--- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 747a100..8792026 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -203,9 +203,6 @@ struct dgnc_board { struct tty_driver *print_driver; charprint_name[200]; - booldgnc_major_serial_registered; - booldgnc_major_transparent_print_registered; - u16 dpatype;/* The board "type", * as defined by DPA */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 5befd28..ba724ab 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -204,15 +204,11 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(brd->serial_driver, _tty_ops); - if (!brd->dgnc_major_serial_registered) { - /* Register tty devices */ - rc = tty_register_driver(brd->serial_driver); - if (rc < 0) { - dev_dbg(>pdev->dev, - "Can't register tty device (%d)\n", rc); - goto free_serial_driver; - } - brd->dgnc_major_serial_registered = true; + rc = tty_register_driver(brd->serial_driver); + if (rc < 0) { + dev_dbg(>pdev->dev, + "Can't register tty device (%d)\n", rc); + goto free_serial_driver; } /* @@ -247,16 +243,12 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(brd->print_driver, _tty_ops); - if (!brd->dgnc_major_transparent_print_registered) { - /* Register Transparent Print devices */ - rc = tty_register_driver(brd->print_driver); - if (rc < 0) { - dev_dbg(>pdev->dev, - "Can't register Transparent Print device(%d)\n", - rc); - goto free_print_driver; - } - brd->dgnc_major_transparent_print_registered = true; + rc = tty_register_driver(brd->print_driver); + if (rc < 0) { + dev_dbg(>pdev->dev, + "Can't register Transparent Print device(%d)\n", + rc); + goto free_print_driver; } dgnc_BoardsByMajor[brd->serial_driver->major] = brd; @@ -396,29 +388,23 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; - if (brd->dgnc_major_serial_registered) { - dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_tun.un_sysfs); - tty_unregister_device(brd->serial_driver, i); - } - tty_unregister_driver(brd->serial_driver); - brd->dgnc_major_serial_registered = false; + dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; + for (i = 0; i < brd->nasync; i++) { + if (brd->channels[i]) + dgnc_remove_tty_sysfs(brd->channels[i]-> + ch_tun.un_sysfs); + tty_unregister_device(brd->serial_driver, i); } + tty_unregister_driver(brd->serial_driver); - if (brd->dgnc_major_transparent_print_registered) { - dgnc_BoardsByMajor[brd->print_driver->major] = NULL; - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_pun.un_sysfs); - tty_unregister_device(brd->print_driver, i); - } - tty_unregister_driver(brd->print_driver); - brd->dgnc_major_transparent_print_registered = false; + dgnc_BoardsByMajor[brd->print_driver->major] = NULL; + for (i = 0; i < brd->nasync; i++) { + if (brd->channels[i]) +
[PATCH 09/11] staging: dgnc: rename dgnc_tty_uninit() to
The dgnc_tty_uninit() doesn't match with dgnc_tty_init() at all. And also the dgnc_cleanup_tty() is only called for exiting the module. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 2 +- drivers/staging/dgnc/dgnc_tty.c| 4 ++-- drivers/staging/dgnc/dgnc_tty.h| 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 81ce5c4..fd372d3 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -147,7 +147,7 @@ static void cleanup(bool sysfiles) for (i = 0; i < dgnc_num_boards; ++i) { dgnc_remove_ports_sysfiles(dgnc_board[i]); - dgnc_tty_uninit(dgnc_board[i]); + dgnc_cleanup_tty(dgnc_board[i]); dgnc_cleanup_board(dgnc_board[i]); } diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 893f473..5befd28 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -387,12 +387,12 @@ void dgnc_tty_post_uninit(void) } /* - * dgnc_tty_uninit() + * dgnc_cleanup_tty() * * Uninitialize the TTY portion of this driver. Free all memory and * resources. */ -void dgnc_tty_uninit(struct dgnc_board *brd) +void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index f065c8f..24c9a41 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -25,7 +25,7 @@ int dgnc_tty_preinit(void); int dgnc_tty_init(struct dgnc_board *); void dgnc_tty_post_uninit(void); -void dgnc_tty_uninit(struct dgnc_board *); +void dgnc_cleanup_tty(struct dgnc_board *); void dgnc_input(struct channel_t *ch); void dgnc_carrier(struct channel_t *ch); -- 1.9.1
[PATCH 10/11] staging: dgnc: remove useless variables
The dgnc_major_serial_registered and dgnc_major_serial_registered do not need to use to check whether the tty driver is registered or not. These variables are used only in dgnc_cleanup_tty() function, This function will be called normally with initialized board structure. It means the dgnc_cleanup_tty() cannot be called with unregistered tty. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.h | 3 -- drivers/staging/dgnc/dgnc_tty.c| 64 +++--- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 747a100..8792026 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -203,9 +203,6 @@ struct dgnc_board { struct tty_driver *print_driver; charprint_name[200]; - booldgnc_major_serial_registered; - booldgnc_major_transparent_print_registered; - u16 dpatype;/* The board "type", * as defined by DPA */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 5befd28..ba724ab 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -204,15 +204,11 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(brd->serial_driver, _tty_ops); - if (!brd->dgnc_major_serial_registered) { - /* Register tty devices */ - rc = tty_register_driver(brd->serial_driver); - if (rc < 0) { - dev_dbg(>pdev->dev, - "Can't register tty device (%d)\n", rc); - goto free_serial_driver; - } - brd->dgnc_major_serial_registered = true; + rc = tty_register_driver(brd->serial_driver); + if (rc < 0) { + dev_dbg(>pdev->dev, + "Can't register tty device (%d)\n", rc); + goto free_serial_driver; } /* @@ -247,16 +243,12 @@ int dgnc_tty_register(struct dgnc_board *brd) */ tty_set_operations(brd->print_driver, _tty_ops); - if (!brd->dgnc_major_transparent_print_registered) { - /* Register Transparent Print devices */ - rc = tty_register_driver(brd->print_driver); - if (rc < 0) { - dev_dbg(>pdev->dev, - "Can't register Transparent Print device(%d)\n", - rc); - goto free_print_driver; - } - brd->dgnc_major_transparent_print_registered = true; + rc = tty_register_driver(brd->print_driver); + if (rc < 0) { + dev_dbg(>pdev->dev, + "Can't register Transparent Print device(%d)\n", + rc); + goto free_print_driver; } dgnc_BoardsByMajor[brd->serial_driver->major] = brd; @@ -396,29 +388,23 @@ void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; - if (brd->dgnc_major_serial_registered) { - dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_tun.un_sysfs); - tty_unregister_device(brd->serial_driver, i); - } - tty_unregister_driver(brd->serial_driver); - brd->dgnc_major_serial_registered = false; + dgnc_BoardsByMajor[brd->serial_driver->major] = NULL; + for (i = 0; i < brd->nasync; i++) { + if (brd->channels[i]) + dgnc_remove_tty_sysfs(brd->channels[i]-> + ch_tun.un_sysfs); + tty_unregister_device(brd->serial_driver, i); } + tty_unregister_driver(brd->serial_driver); - if (brd->dgnc_major_transparent_print_registered) { - dgnc_BoardsByMajor[brd->print_driver->major] = NULL; - for (i = 0; i < brd->nasync; i++) { - if (brd->channels[i]) - dgnc_remove_tty_sysfs(brd->channels[i]-> - ch_pun.un_sysfs); - tty_unregister_device(brd->print_driver, i); - } - tty_unregister_driver(brd->print_driver); - brd->dgnc_major_transparent_print_registered = false; + dgnc_BoardsByMajor[brd->print_driver->major] = NULL; + for (i = 0; i < brd->nasync; i++) { + if (brd->channels[i]) + dgnc_remove_tty_sysfs(brd->channels[i]-> +
[PATCH 09/11] staging: dgnc: rename dgnc_tty_uninit() to
The dgnc_tty_uninit() doesn't match with dgnc_tty_init() at all. And also the dgnc_cleanup_tty() is only called for exiting the module. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 2 +- drivers/staging/dgnc/dgnc_tty.c| 4 ++-- drivers/staging/dgnc/dgnc_tty.h| 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 81ce5c4..fd372d3 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -147,7 +147,7 @@ static void cleanup(bool sysfiles) for (i = 0; i < dgnc_num_boards; ++i) { dgnc_remove_ports_sysfiles(dgnc_board[i]); - dgnc_tty_uninit(dgnc_board[i]); + dgnc_cleanup_tty(dgnc_board[i]); dgnc_cleanup_board(dgnc_board[i]); } diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 893f473..5befd28 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -387,12 +387,12 @@ void dgnc_tty_post_uninit(void) } /* - * dgnc_tty_uninit() + * dgnc_cleanup_tty() * * Uninitialize the TTY portion of this driver. Free all memory and * resources. */ -void dgnc_tty_uninit(struct dgnc_board *brd) +void dgnc_cleanup_tty(struct dgnc_board *brd) { int i = 0; diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index f065c8f..24c9a41 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -25,7 +25,7 @@ int dgnc_tty_preinit(void); int dgnc_tty_init(struct dgnc_board *); void dgnc_tty_post_uninit(void); -void dgnc_tty_uninit(struct dgnc_board *); +void dgnc_cleanup_tty(struct dgnc_board *); void dgnc_input(struct channel_t *ch); void dgnc_carrier(struct channel_t *ch); -- 1.9.1
[PATCH 07/11] staging: dgnc: rename dgnc_finalize_board_init() to
The dgnc_finalize_board_init() function has only job for requesting the IRQ. It should be renamed to dgnc_request_irq() Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index ffe55a2..70e68b5 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -37,7 +37,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); * */ static int dgnc_start(void); -static int dgnc_finalize_board_init(struct dgnc_board *brd); +static int dgnc_request_irq(struct dgnc_board *brd); static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); @@ -296,7 +296,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto failed; } - rc = dgnc_finalize_board_init(brd); + rc = dgnc_request_irq(brd); if (rc < 0) { pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); goto unregister_tty; @@ -558,7 +558,7 @@ failed: return ERR_PTR(rc); } -static int dgnc_finalize_board_init(struct dgnc_board *brd) +static int dgnc_request_irq(struct dgnc_board *brd) { int rc = 0; -- 1.9.1
[PATCH 04/11] staging: dgnc: kfree for board structure in
The board structure should be freed when any function was failed in dgnc_found_board(). And the board strucure will be stored into dgnc_board array when the dgnc_found_board() function has no error. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 58cebf4..0114e78 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -353,9 +353,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) int rc = 0; /* get the board structure and prep it */ - dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL); - brd = dgnc_board[dgnc_num_boards]; - + brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) return -ENOMEM; @@ -411,7 +409,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) if (!brd->membase) { dev_err(>pdev->dev, "Card has no PCI IO resources, failing.\n"); - return -ENODEV; + rc = -ENODEV; + goto failed; } brd->membase_end = pci_resource_end(pdev, 4); @@ -502,7 +501,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) default: dev_err(>pdev->dev, "Didn't find any compatible Neo/Classic PCI boards.\n"); - return -ENXIO; + rc = -ENXIO; + goto failed; } /* @@ -539,14 +539,15 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) wake_up_interruptible(>state_wait); + dgnc_board[dgnc_num_boards] = brd; + return 0; failed: dgnc_tty_uninit(brd); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; + kfree(brd); - return -ENXIO; + return rc; } static int dgnc_finalize_board_init(struct dgnc_board *brd) -- 1.9.1
[PATCH 03/11] staging: dgnc: missing NULL check for ioremap in
The ioremap() function can be failed, so it need to have error handling in dgnc_do_remap(). And also the return type of dgnc_do_remap() should be changed from "void" to "int" Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 31 +-- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index c87b3de..58cebf4 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -43,7 +43,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static voiddgnc_do_remap(struct dgnc_board *brd); +static int dgnc_do_remap(struct dgnc_board *brd); /* * File operations permitted on Control/Management major. @@ -431,7 +431,10 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_uart_offset = 0x8; brd->bd_dividend = 921600; - dgnc_do_remap(brd); + rc = dgnc_do_remap(brd); + + if (rc < 0) + goto failed; /* Get and store the board VPD, if it exists */ brd->bd_ops->vpd(brd); @@ -483,15 +486,17 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_uart_offset = 0x200; brd->bd_dividend = 921600; - dgnc_do_remap(brd); + rc = dgnc_do_remap(brd); - if (brd->re_map_membase) { - /* Read and store the dvid after remapping */ - brd->dvid = readb(brd->re_map_membase + 0x8D); + if (rc < 0) + goto failed; + + /* Read and store the dvid after remapping */ + brd->dvid = readb(brd->re_map_membase + 0x8D); + + /* Get and store the board VPD, if it exists */ + brd->bd_ops->vpd(brd); - /* Get and store the board VPD, if it exists */ - brd->bd_ops->vpd(brd); - } break; default: @@ -566,9 +571,15 @@ static int dgnc_finalize_board_init(struct dgnc_board *brd) /* * Remap PCI memory. */ -static void dgnc_do_remap(struct dgnc_board *brd) +static int dgnc_do_remap(struct dgnc_board *brd) { + int rc = 0; + brd->re_map_membase = ioremap(brd->membase, 0x1000); + if (!brd->re_map_membase) + rc = -ENOMEM; + + return rc; } /* -- 1.9.1
[PATCH 04/11] staging: dgnc: kfree for board structure in
The board structure should be freed when any function was failed in dgnc_found_board(). And the board strucure will be stored into dgnc_board array when the dgnc_found_board() function has no error. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 58cebf4..0114e78 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -353,9 +353,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) int rc = 0; /* get the board structure and prep it */ - dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL); - brd = dgnc_board[dgnc_num_boards]; - + brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) return -ENOMEM; @@ -411,7 +409,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) if (!brd->membase) { dev_err(>pdev->dev, "Card has no PCI IO resources, failing.\n"); - return -ENODEV; + rc = -ENODEV; + goto failed; } brd->membase_end = pci_resource_end(pdev, 4); @@ -502,7 +501,8 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) default: dev_err(>pdev->dev, "Didn't find any compatible Neo/Classic PCI boards.\n"); - return -ENXIO; + rc = -ENXIO; + goto failed; } /* @@ -539,14 +539,15 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) wake_up_interruptible(>state_wait); + dgnc_board[dgnc_num_boards] = brd; + return 0; failed: dgnc_tty_uninit(brd); - brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; + kfree(brd); - return -ENXIO; + return rc; } static int dgnc_finalize_board_init(struct dgnc_board *brd) -- 1.9.1
[PATCH 03/11] staging: dgnc: missing NULL check for ioremap in
The ioremap() function can be failed, so it need to have error handling in dgnc_do_remap(). And also the return type of dgnc_do_remap() should be changed from "void" to "int" Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 31 +-- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index c87b3de..58cebf4 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -43,7 +43,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static voiddgnc_do_remap(struct dgnc_board *brd); +static int dgnc_do_remap(struct dgnc_board *brd); /* * File operations permitted on Control/Management major. @@ -431,7 +431,10 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_uart_offset = 0x8; brd->bd_dividend = 921600; - dgnc_do_remap(brd); + rc = dgnc_do_remap(brd); + + if (rc < 0) + goto failed; /* Get and store the board VPD, if it exists */ brd->bd_ops->vpd(brd); @@ -483,15 +486,17 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_uart_offset = 0x200; brd->bd_dividend = 921600; - dgnc_do_remap(brd); + rc = dgnc_do_remap(brd); - if (brd->re_map_membase) { - /* Read and store the dvid after remapping */ - brd->dvid = readb(brd->re_map_membase + 0x8D); + if (rc < 0) + goto failed; + + /* Read and store the dvid after remapping */ + brd->dvid = readb(brd->re_map_membase + 0x8D); + + /* Get and store the board VPD, if it exists */ + brd->bd_ops->vpd(brd); - /* Get and store the board VPD, if it exists */ - brd->bd_ops->vpd(brd); - } break; default: @@ -566,9 +571,15 @@ static int dgnc_finalize_board_init(struct dgnc_board *brd) /* * Remap PCI memory. */ -static void dgnc_do_remap(struct dgnc_board *brd) +static int dgnc_do_remap(struct dgnc_board *brd) { + int rc = 0; + brd->re_map_membase = ioremap(brd->membase, 0x1000); + if (!brd->re_map_membase) + rc = -ENOMEM; + + return rc; } /* -- 1.9.1
Re: [PATCH v5 0/6] Introduce ZONE_CMA
On Wed, Sep 21, 2016 at 08:17:27PM +0530, Aneesh Kumar K.V wrote: > "Aneesh Kumar K.V"writes: > > > Joonsoo Kim writes: > > > >> On Tue, Aug 30, 2016 at 04:09:37PM +0530, Aneesh Kumar K.V wrote: > >>> Joonsoo Kim writes: > >>> > >>> > 2016-08-29 18:27 GMT+09:00 Aneesh Kumar K.V > >>> > : > >>> >> js1...@gmail.com writes: > >>> >> > >>> >>> From: Joonsoo Kim > >>> >>> > >>> >>> Hello, > >>> >>> > >>> >>> Changes from v4 > >>> >>> o Rebase on next-20160825 > >>> >>> o Add general fix patch for lowmem reserve > >>> >>> o Fix lowmem reserve ratio > >>> >>> o Fix zone span optimizaion per Vlastimil > >>> >>> o Fix pageset initialization > >>> >>> o Change invocation timing on cma_init_reserved_areas() > >>> >> > >>> >> I don't see much information regarding how we interleave between > >>> >> ZONE_CMA and other zones for movable allocation. Is that explained in > >>> >> any of the patch ? The fair zone allocator got removed by > >>> >> e6cbd7f2efb433d717af72aa8510a9db6f7a7e05 > >>> > > >>> > Interleaving would not work since the fair zone allocator policy is > >>> > removed. > >>> > I don't think that it's a big problem because it is just matter of > >>> > timing to fill > >>> > up the memory. Eventually, memory on ZONE_CMA will be fully used in > >>> > any case. > >>> > >>> Does that mean a CMA allocation will now be slower because in most case we > >>> will need to reclaim ? The zone list will now have ZONE_CMA in the > >>> beginning right ? > >> > >> ZONE_CMA will be used first but I don't think that CMA allocation will > >> be slower. In most case, memory would be fully used (usually > >> by page cache). So, we need reclaim or migration in any case. > > > > Considering that the upstream kernel doesn't allow migration of THP > > pages, this would mean that migrate will fail in most case if we have > > THP enabled and the THP allocation request got satisfied via ZONE_CMA. > > Isn't that going to be a problem ? > > > > Even though we have the issues of migration failures due to pinned and > THP pages in ZONE_CMA, overall the code is simpler. IMHO we should get > this upstream now and work on solving those issues later. Yep! I will take a look on those problems after merging this patchset. > > You can add for the complete series. > > Reviewed-by: Aneesh Kumar K.V Thanks!
Re: [PATCH net-next 9/9] rxrpc: Reduce the number of ACK-Requests sent
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: arm-omap2plus_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): >> ERROR: "__aeabi_ldivmod" [net/rxrpc/af-rxrpc.ko] undefined! ERROR: "__aeabi_uldivmod" [net/rxrpc/af-rxrpc.ko] undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH 05/11] staging: dgnc: move functions unrelated with
The functions related with tty device initialization are needed to be moved from dgnc_found_board() to dgnc_init_one(). Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 81 -- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 0114e78..a95d13c 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -38,7 +38,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ static int dgnc_start(void); static int dgnc_finalize_board_init(struct dgnc_board *brd); -static int dgnc_found_board(struct pci_dev *pdev, int id); +static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); static int dgnc_init_one(struct pci_dev *pdev, @@ -274,6 +274,7 @@ failed_class: static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; + struct dgnc_board *brd; /* wake up and enable device */ rc = pci_enable_device(pdev); @@ -281,9 +282,43 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return -EIO; - rc = dgnc_found_board(pdev, ent->driver_data); - if (rc == 0) - dgnc_num_boards++; + brd = dgnc_found_board(pdev, ent->driver_data); + if (IS_ERR(brd)) + return PTR_ERR(brd); + + /* +* Do tty device initialization. +*/ + + rc = dgnc_tty_register(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); + goto failed; + } + + rc = dgnc_finalize_board_init(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); + goto failed; + } + + rc = dgnc_tty_init(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); + goto failed; + } + + brd->state = BOARD_READY; + brd->dpastatus = BD_RUNNING; + + dgnc_create_ports_sysfiles(brd); + + dgnc_board[dgnc_num_boards++] = brd; + + return 0; + +failed: + kfree(brd); return rc; } @@ -345,7 +380,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) * * A board has been found, init it. */ -static int dgnc_found_board(struct pci_dev *pdev, int id) +static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) { struct dgnc_board *brd; unsigned int pci_irq; @@ -355,7 +390,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) /* get the board structure and prep it */ brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) - return -ENOMEM; + return ERR_PTR(-ENOMEM); /* store the info for the board we've found */ brd->magic = DGNC_BOARD_MAGIC; @@ -505,33 +540,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) goto failed; } - /* -* Do tty device initialization. -*/ - - rc = dgnc_tty_register(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); - goto failed; - } - - rc = dgnc_finalize_board_init(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); - goto failed; - } - - rc = dgnc_tty_init(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto failed; - } - - brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; - - dgnc_create_ports_sysfiles(brd); - /* init our poll helper tasklet */ tasklet_init(>helper_tasklet, brd->bd_ops->tasklet, @@ -539,15 +547,12 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) wake_up_interruptible(>state_wait); - dgnc_board[dgnc_num_boards] = brd; - - return 0; + return brd; failed: - dgnc_tty_uninit(brd); kfree(brd); - return rc; + return ERR_PTR(rc); } static int dgnc_finalize_board_init(struct dgnc_board *brd) -- 1.9.1
Re: [PATCH v5 0/6] Introduce ZONE_CMA
On Wed, Sep 21, 2016 at 08:17:27PM +0530, Aneesh Kumar K.V wrote: > "Aneesh Kumar K.V" writes: > > > Joonsoo Kim writes: > > > >> On Tue, Aug 30, 2016 at 04:09:37PM +0530, Aneesh Kumar K.V wrote: > >>> Joonsoo Kim writes: > >>> > >>> > 2016-08-29 18:27 GMT+09:00 Aneesh Kumar K.V > >>> > : > >>> >> js1...@gmail.com writes: > >>> >> > >>> >>> From: Joonsoo Kim > >>> >>> > >>> >>> Hello, > >>> >>> > >>> >>> Changes from v4 > >>> >>> o Rebase on next-20160825 > >>> >>> o Add general fix patch for lowmem reserve > >>> >>> o Fix lowmem reserve ratio > >>> >>> o Fix zone span optimizaion per Vlastimil > >>> >>> o Fix pageset initialization > >>> >>> o Change invocation timing on cma_init_reserved_areas() > >>> >> > >>> >> I don't see much information regarding how we interleave between > >>> >> ZONE_CMA and other zones for movable allocation. Is that explained in > >>> >> any of the patch ? The fair zone allocator got removed by > >>> >> e6cbd7f2efb433d717af72aa8510a9db6f7a7e05 > >>> > > >>> > Interleaving would not work since the fair zone allocator policy is > >>> > removed. > >>> > I don't think that it's a big problem because it is just matter of > >>> > timing to fill > >>> > up the memory. Eventually, memory on ZONE_CMA will be fully used in > >>> > any case. > >>> > >>> Does that mean a CMA allocation will now be slower because in most case we > >>> will need to reclaim ? The zone list will now have ZONE_CMA in the > >>> beginning right ? > >> > >> ZONE_CMA will be used first but I don't think that CMA allocation will > >> be slower. In most case, memory would be fully used (usually > >> by page cache). So, we need reclaim or migration in any case. > > > > Considering that the upstream kernel doesn't allow migration of THP > > pages, this would mean that migrate will fail in most case if we have > > THP enabled and the THP allocation request got satisfied via ZONE_CMA. > > Isn't that going to be a problem ? > > > > Even though we have the issues of migration failures due to pinned and > THP pages in ZONE_CMA, overall the code is simpler. IMHO we should get > this upstream now and work on solving those issues later. Yep! I will take a look on those problems after merging this patchset. > > You can add for the complete series. > > Reviewed-by: Aneesh Kumar K.V Thanks!
Re: [PATCH net-next 9/9] rxrpc: Reduce the number of ACK-Requests sent
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: arm-omap2plus_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): >> ERROR: "__aeabi_ldivmod" [net/rxrpc/af-rxrpc.ko] undefined! ERROR: "__aeabi_uldivmod" [net/rxrpc/af-rxrpc.ko] undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH 05/11] staging: dgnc: move functions unrelated with
The functions related with tty device initialization are needed to be moved from dgnc_found_board() to dgnc_init_one(). Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 81 -- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 0114e78..a95d13c 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -38,7 +38,7 @@ MODULE_SUPPORTED_DEVICE("dgnc"); */ static int dgnc_start(void); static int dgnc_finalize_board_init(struct dgnc_board *brd); -static int dgnc_found_board(struct pci_dev *pdev, int id); +static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id); static voiddgnc_cleanup_board(struct dgnc_board *brd); static voiddgnc_poll_handler(ulong dummy); static int dgnc_init_one(struct pci_dev *pdev, @@ -274,6 +274,7 @@ failed_class: static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; + struct dgnc_board *brd; /* wake up and enable device */ rc = pci_enable_device(pdev); @@ -281,9 +282,43 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return -EIO; - rc = dgnc_found_board(pdev, ent->driver_data); - if (rc == 0) - dgnc_num_boards++; + brd = dgnc_found_board(pdev, ent->driver_data); + if (IS_ERR(brd)) + return PTR_ERR(brd); + + /* +* Do tty device initialization. +*/ + + rc = dgnc_tty_register(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); + goto failed; + } + + rc = dgnc_finalize_board_init(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); + goto failed; + } + + rc = dgnc_tty_init(brd); + if (rc < 0) { + pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); + goto failed; + } + + brd->state = BOARD_READY; + brd->dpastatus = BD_RUNNING; + + dgnc_create_ports_sysfiles(brd); + + dgnc_board[dgnc_num_boards++] = brd; + + return 0; + +failed: + kfree(brd); return rc; } @@ -345,7 +380,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) * * A board has been found, init it. */ -static int dgnc_found_board(struct pci_dev *pdev, int id) +static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) { struct dgnc_board *brd; unsigned int pci_irq; @@ -355,7 +390,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) /* get the board structure and prep it */ brd = kzalloc(sizeof(*brd), GFP_KERNEL); if (!brd) - return -ENOMEM; + return ERR_PTR(-ENOMEM); /* store the info for the board we've found */ brd->magic = DGNC_BOARD_MAGIC; @@ -505,33 +540,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) goto failed; } - /* -* Do tty device initialization. -*/ - - rc = dgnc_tty_register(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't register tty devices (%d)\n", rc); - goto failed; - } - - rc = dgnc_finalize_board_init(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't finalize board init (%d)\n", rc); - goto failed; - } - - rc = dgnc_tty_init(brd); - if (rc < 0) { - pr_err(DRVSTR ": Can't init tty devices (%d)\n", rc); - goto failed; - } - - brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; - - dgnc_create_ports_sysfiles(brd); - /* init our poll helper tasklet */ tasklet_init(>helper_tasklet, brd->bd_ops->tasklet, @@ -539,15 +547,12 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) wake_up_interruptible(>state_wait); - dgnc_board[dgnc_num_boards] = brd; - - return 0; + return brd; failed: - dgnc_tty_uninit(brd); kfree(brd); - return rc; + return ERR_PTR(rc); } static int dgnc_finalize_board_init(struct dgnc_board *brd) -- 1.9.1
[PATCH 02/11] staging: dgnc: remove useless message buffer
There is a temporary message buffer for the boot message in dgnc_found_board() but the buffer was not used anywhere in dgnc driver. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 28 drivers/staging/dgnc/dgnc_driver.h | 6 -- 2 files changed, 34 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index b598034..c87b3de 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -324,17 +324,6 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) brd->re_map_membase = NULL; } - if (brd->msgbuf_head) { - unsigned long flags; - - spin_lock_irqsave(_global_lock, flags); - brd->msgbuf = NULL; - dev_dbg(>pdev->dev, "%s\n", brd->msgbuf_head); - kfree(brd->msgbuf_head); - brd->msgbuf_head = NULL; - spin_unlock_irqrestore(_global_lock, flags); - } - /* Free all allocated channels structs */ for (i = 0; i < MAXPORTS ; i++) { if (brd->channels[i]) { @@ -362,7 +351,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) unsigned int pci_irq; int i = 0; int rc = 0; - unsigned long flags; /* get the board structure and prep it */ dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL); @@ -371,15 +359,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) if (!brd) return -ENOMEM; - /* make a temporary message buffer for the boot messages */ - brd->msgbuf_head = kcalloc(8192, sizeof(u8), GFP_KERNEL); - brd->msgbuf = brd->msgbuf_head; - - if (!brd->msgbuf) { - kfree(brd); - return -ENOMEM; - } - /* store the info for the board we've found */ brd->magic = DGNC_BOARD_MAGIC; brd->boardnum = dgnc_num_boards; @@ -553,13 +532,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_ops->tasklet, (unsigned long)brd); - spin_lock_irqsave(_global_lock, flags); - brd->msgbuf = NULL; - dev_dbg(>pdev->dev, "%s\n", brd->msgbuf_head); - kfree(brd->msgbuf_head); - brd->msgbuf_head = NULL; - spin_unlock_irqrestore(_global_lock, flags); - wake_up_interruptible(>state_wait); return 0; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 88d2696..747a100 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -213,12 +213,6 @@ struct dgnc_board { * as defined by DPA */ - /* -* Mgmt data. -*/ - char*msgbuf_head; - char*msgbuf; - uintbd_dividend;/* Board/UARTs specific dividend */ struct board_ops *bd_ops; -- 1.9.1
[PATCH 02/11] staging: dgnc: remove useless message buffer
There is a temporary message buffer for the boot message in dgnc_found_board() but the buffer was not used anywhere in dgnc driver. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 28 drivers/staging/dgnc/dgnc_driver.h | 6 -- 2 files changed, 34 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index b598034..c87b3de 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -324,17 +324,6 @@ static void dgnc_cleanup_board(struct dgnc_board *brd) brd->re_map_membase = NULL; } - if (brd->msgbuf_head) { - unsigned long flags; - - spin_lock_irqsave(_global_lock, flags); - brd->msgbuf = NULL; - dev_dbg(>pdev->dev, "%s\n", brd->msgbuf_head); - kfree(brd->msgbuf_head); - brd->msgbuf_head = NULL; - spin_unlock_irqrestore(_global_lock, flags); - } - /* Free all allocated channels structs */ for (i = 0; i < MAXPORTS ; i++) { if (brd->channels[i]) { @@ -362,7 +351,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) unsigned int pci_irq; int i = 0; int rc = 0; - unsigned long flags; /* get the board structure and prep it */ dgnc_board[dgnc_num_boards] = kzalloc(sizeof(*brd), GFP_KERNEL); @@ -371,15 +359,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) if (!brd) return -ENOMEM; - /* make a temporary message buffer for the boot messages */ - brd->msgbuf_head = kcalloc(8192, sizeof(u8), GFP_KERNEL); - brd->msgbuf = brd->msgbuf_head; - - if (!brd->msgbuf) { - kfree(brd); - return -ENOMEM; - } - /* store the info for the board we've found */ brd->magic = DGNC_BOARD_MAGIC; brd->boardnum = dgnc_num_boards; @@ -553,13 +532,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->bd_ops->tasklet, (unsigned long)brd); - spin_lock_irqsave(_global_lock, flags); - brd->msgbuf = NULL; - dev_dbg(>pdev->dev, "%s\n", brd->msgbuf_head); - kfree(brd->msgbuf_head); - brd->msgbuf_head = NULL; - spin_unlock_irqrestore(_global_lock, flags); - wake_up_interruptible(>state_wait); return 0; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 88d2696..747a100 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -213,12 +213,6 @@ struct dgnc_board { * as defined by DPA */ - /* -* Mgmt data. -*/ - char*msgbuf_head; - char*msgbuf; - uintbd_dividend;/* Board/UARTs specific dividend */ struct board_ops *bd_ops; -- 1.9.1
[PATCH 01/11] staging: dgnc: remove redundant initialization for
The channel array in board_t was initialized in dgnc_found_board() with NULL. But the channel is going to initialize in dgnc_tty_init(). So the channel array doesn't need to set NULL for initailization. Signed-off-by: Daeseok Youn--- drivers/staging/dgnc/dgnc_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 01e948c..b598034 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -400,9 +400,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->state = BOARD_FOUND; - for (i = 0; i < MAXPORTS; i++) - brd->channels[i] = NULL; - /* store which card & revision we have */ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, >subvendor); pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, >subdevice); -- 1.9.1
[PATCH 01/11] staging: dgnc: remove redundant initialization for
The channel array in board_t was initialized in dgnc_found_board() with NULL. But the channel is going to initialize in dgnc_tty_init(). So the channel array doesn't need to set NULL for initailization. Signed-off-by: Daeseok Youn --- drivers/staging/dgnc/dgnc_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 01e948c..b598034 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -400,9 +400,6 @@ static int dgnc_found_board(struct pci_dev *pdev, int id) brd->state = BOARD_FOUND; - for (i = 0; i < MAXPORTS; i++) - brd->channels[i] = NULL; - /* store which card & revision we have */ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, >subvendor); pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, >subdevice); -- 1.9.1
[PATCH 00/11] staging: dgnc: cleanup the function on dgnc driver
This series of patches will cleanup the functions in dgnc driver. Rename it and introduce new functions to split big function into smaller one. Please take a look at my patches to update the dgnc driver and provide some comments if there are something wrong. This series of patches maybe have dependency with each other. If one of these patches cannot be merged, some other patches maybe cannot be merged properly, I think. Daeseok Youn (11): staging: dgnc: remove redundant initialization for channel_t staging: dgnc: remove useless message buffer staging: dgnc: missing NULL check for ioremap in dgnc_do_remap() staging: dgnc: kfree for board structure in dgnc_found_board() staging: dgnc: move functions unrelated with dgnc_found_board() staging: dgnc: introduce the dgnc_tty_unregister() staging: dgnc: rename dgnc_finalize_board_init() to dgnc_request_irq() staging: dgnc: introduce the dgnc_free_irq() staging: dgnc: rename dgnc_tty_uninit() to dgnc_cleanup_tty() staging: dgnc: remove useless variables staging: dgnc: introduce find_board_by_major() drivers/staging/dgnc/dgnc_driver.c | 170 ++--- drivers/staging/dgnc/dgnc_driver.h | 9 -- drivers/staging/dgnc/dgnc_tty.c| 97 +++-- drivers/staging/dgnc/dgnc_tty.h| 3 +- 4 files changed, 138 insertions(+), 141 deletions(-) -- 1.9.1
[PATCH 00/11] staging: dgnc: cleanup the function on dgnc driver
This series of patches will cleanup the functions in dgnc driver. Rename it and introduce new functions to split big function into smaller one. Please take a look at my patches to update the dgnc driver and provide some comments if there are something wrong. This series of patches maybe have dependency with each other. If one of these patches cannot be merged, some other patches maybe cannot be merged properly, I think. Daeseok Youn (11): staging: dgnc: remove redundant initialization for channel_t staging: dgnc: remove useless message buffer staging: dgnc: missing NULL check for ioremap in dgnc_do_remap() staging: dgnc: kfree for board structure in dgnc_found_board() staging: dgnc: move functions unrelated with dgnc_found_board() staging: dgnc: introduce the dgnc_tty_unregister() staging: dgnc: rename dgnc_finalize_board_init() to dgnc_request_irq() staging: dgnc: introduce the dgnc_free_irq() staging: dgnc: rename dgnc_tty_uninit() to dgnc_cleanup_tty() staging: dgnc: remove useless variables staging: dgnc: introduce find_board_by_major() drivers/staging/dgnc/dgnc_driver.c | 170 ++--- drivers/staging/dgnc/dgnc_driver.h | 9 -- drivers/staging/dgnc/dgnc_tty.c| 97 +++-- drivers/staging/dgnc/dgnc_tty.h| 3 +- 4 files changed, 138 insertions(+), 141 deletions(-) -- 1.9.1
Re: [PATCH v5 1/6] mm/page_alloc: don't reserve ZONE_HIGHMEM for ZONE_MOVABLE request
On Fri, Sep 16, 2016 at 08:44:17AM +0530, Aneesh Kumar K.V wrote: > js1...@gmail.com writes: > > > From: Joonsoo Kim> > > > Freepage on ZONE_HIGHMEM doesn't work for kernel memory so it's not that > > important to reserve. When ZONE_MOVABLE is used, this problem would > > theorectically cause to decrease usable memory for GFP_HIGHUSER_MOVABLE > > allocation request which is mainly used for page cache and anon page > > allocation. So, fix it. > > > > And, defining sysctl_lowmem_reserve_ratio array by MAX_NR_ZONES - 1 size > > makes code complex. For example, if there is highmem system, following > > reserve ratio is activated for *NORMAL ZONE* which would be easyily > > misleading people. > > > > #ifdef CONFIG_HIGHMEM > > 32 > > #endif > > > > This patch also fix this situation by defining sysctl_lowmem_reserve_ratio > > array by MAX_NR_ZONES and place "#ifdef" to right place. > > > > Signed-off-by: Joonsoo Kim > > --- > > include/linux/mmzone.h | 2 +- > > mm/page_alloc.c| 7 --- > > 2 files changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > > index d572b78..e3f39af 100644 > > --- a/include/linux/mmzone.h > > +++ b/include/linux/mmzone.h > > @@ -877,7 +877,7 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *, > > int, > > void __user *, size_t *, loff_t *); > > int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, > > void __user *, size_t *, loff_t *); > > -extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1]; > > +extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES]; > > int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, > > void __user *, size_t *, loff_t *); > > int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, > > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > > index 4f7d5d7..a8310de 100644 > > --- a/mm/page_alloc.c > > +++ b/mm/page_alloc.c > > @@ -198,17 +198,18 @@ static void __free_pages_ok(struct page *page, > > unsigned int order); > > * TBD: should special case ZONE_DMA32 machines here - in those we normally > > * don't need any ZONE_NORMAL reservation > > */ > > -int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { > > +int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES] = { > > #ifdef CONFIG_ZONE_DMA > > 256, > > #endif > > #ifdef CONFIG_ZONE_DMA32 > > 256, > > #endif > > -#ifdef CONFIG_HIGHMEM > > 32, > > +#ifdef CONFIG_HIGHMEM > > +INT_MAX, > > #endif > > -32, > > +INT_MAX, > > }; > > > > EXPORT_SYMBOL(totalram_pages); > > -- > > 1.9.1 > > We can also do things like below to make it readable ? > > #ifdef CONFIG_ZONE_DMA > [ZONE_DMA] = 256, > #endif It looks more readable! I will change it. > > Reviewed-by: Aneesh Kumar K.V Thanks!
Re: [PATCH v5 1/6] mm/page_alloc: don't reserve ZONE_HIGHMEM for ZONE_MOVABLE request
On Fri, Sep 16, 2016 at 08:44:17AM +0530, Aneesh Kumar K.V wrote: > js1...@gmail.com writes: > > > From: Joonsoo Kim > > > > Freepage on ZONE_HIGHMEM doesn't work for kernel memory so it's not that > > important to reserve. When ZONE_MOVABLE is used, this problem would > > theorectically cause to decrease usable memory for GFP_HIGHUSER_MOVABLE > > allocation request which is mainly used for page cache and anon page > > allocation. So, fix it. > > > > And, defining sysctl_lowmem_reserve_ratio array by MAX_NR_ZONES - 1 size > > makes code complex. For example, if there is highmem system, following > > reserve ratio is activated for *NORMAL ZONE* which would be easyily > > misleading people. > > > > #ifdef CONFIG_HIGHMEM > > 32 > > #endif > > > > This patch also fix this situation by defining sysctl_lowmem_reserve_ratio > > array by MAX_NR_ZONES and place "#ifdef" to right place. > > > > Signed-off-by: Joonsoo Kim > > --- > > include/linux/mmzone.h | 2 +- > > mm/page_alloc.c| 7 --- > > 2 files changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > > index d572b78..e3f39af 100644 > > --- a/include/linux/mmzone.h > > +++ b/include/linux/mmzone.h > > @@ -877,7 +877,7 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *, > > int, > > void __user *, size_t *, loff_t *); > > int watermark_scale_factor_sysctl_handler(struct ctl_table *, int, > > void __user *, size_t *, loff_t *); > > -extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1]; > > +extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES]; > > int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, > > void __user *, size_t *, loff_t *); > > int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, > > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > > index 4f7d5d7..a8310de 100644 > > --- a/mm/page_alloc.c > > +++ b/mm/page_alloc.c > > @@ -198,17 +198,18 @@ static void __free_pages_ok(struct page *page, > > unsigned int order); > > * TBD: should special case ZONE_DMA32 machines here - in those we normally > > * don't need any ZONE_NORMAL reservation > > */ > > -int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { > > +int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES] = { > > #ifdef CONFIG_ZONE_DMA > > 256, > > #endif > > #ifdef CONFIG_ZONE_DMA32 > > 256, > > #endif > > -#ifdef CONFIG_HIGHMEM > > 32, > > +#ifdef CONFIG_HIGHMEM > > +INT_MAX, > > #endif > > -32, > > +INT_MAX, > > }; > > > > EXPORT_SYMBOL(totalram_pages); > > -- > > 1.9.1 > > We can also do things like below to make it readable ? > > #ifdef CONFIG_ZONE_DMA > [ZONE_DMA] = 256, > #endif It looks more readable! I will change it. > > Reviewed-by: Aneesh Kumar K.V Thanks!
Re: [PATCH v7 0/6] perf annotate: Cross arch support + few fixes
On Thursday 22 September 2016 01:04 AM, Kim Phillips wrote: > On Wed, 21 Sep 2016 21:17:50 +0530 > Ravi Bangoriawrote: > >> Kim, I don't have arm test machine. Can you please help me to test >> this on arm. > This works for me: hitting return on return instructions yields > "Invalid jump offset", but I'll get that later. Thanks Kim. Hmm.. so, ins__find_arm does not contain logic for return instructions. Navigation with return instruction is working fine for x86 and powerpc. -Ravi > Thanks, > > Kim >
Re: [PATCH v7 0/6] perf annotate: Cross arch support + few fixes
On Thursday 22 September 2016 01:04 AM, Kim Phillips wrote: > On Wed, 21 Sep 2016 21:17:50 +0530 > Ravi Bangoria wrote: > >> Kim, I don't have arm test machine. Can you please help me to test >> this on arm. > This works for me: hitting return on return instructions yields > "Invalid jump offset", but I'll get that later. Thanks Kim. Hmm.. so, ins__find_arm does not contain logic for return instructions. Navigation with return instruction is working fine for x86 and powerpc. -Ravi > Thanks, > > Kim >
Re: [PATCH v2 3/3] tools: move pcmcia crc32hash tool from Documentation
On Wed, Sep 21, 2016 at 06:51:13PM -0600, Shuah Khan wrote: > Move pcmcia crc32hash tool from Documentation to tools/pcmcia and > remove it from Documentation Makefile. Update location information > for this tool. Create a new Makefile to build pcmcia. It can be built > from top level directory or from pcmcia directory: > > Run make -C tools/pcmcia or cd tools/pcmcia; make > > Signed-off-by: Shuah Khan> --- > Documentation/Makefile | 3 +-- > Documentation/pcmcia/.gitignore | 1 - > Documentation/pcmcia/Makefile| 7 --- > Documentation/pcmcia/crc32hash.c | 32 > Documentation/pcmcia/devicetable.txt | 4 ++-- > MAINTAINERS | 1 + > tools/pcmcia/.gitignore | 1 + > tools/pcmcia/Makefile| 9 + > tools/pcmcia/crc32hash.c | 32 > 9 files changed, 46 insertions(+), 44 deletions(-) > delete mode 100644 Documentation/pcmcia/.gitignore > delete mode 100644 Documentation/pcmcia/Makefile > delete mode 100644 Documentation/pcmcia/crc32hash.c > create mode 100644 tools/pcmcia/.gitignore > create mode 100644 tools/pcmcia/Makefile > create mode 100644 tools/pcmcia/crc32hash.c Acked-by: Greg Kroah-Hartman
Re: [PATCH v2 3/3] tools: move pcmcia crc32hash tool from Documentation
On Wed, Sep 21, 2016 at 06:51:13PM -0600, Shuah Khan wrote: > Move pcmcia crc32hash tool from Documentation to tools/pcmcia and > remove it from Documentation Makefile. Update location information > for this tool. Create a new Makefile to build pcmcia. It can be built > from top level directory or from pcmcia directory: > > Run make -C tools/pcmcia or cd tools/pcmcia; make > > Signed-off-by: Shuah Khan > --- > Documentation/Makefile | 3 +-- > Documentation/pcmcia/.gitignore | 1 - > Documentation/pcmcia/Makefile| 7 --- > Documentation/pcmcia/crc32hash.c | 32 > Documentation/pcmcia/devicetable.txt | 4 ++-- > MAINTAINERS | 1 + > tools/pcmcia/.gitignore | 1 + > tools/pcmcia/Makefile| 9 + > tools/pcmcia/crc32hash.c | 32 > 9 files changed, 46 insertions(+), 44 deletions(-) > delete mode 100644 Documentation/pcmcia/.gitignore > delete mode 100644 Documentation/pcmcia/Makefile > delete mode 100644 Documentation/pcmcia/crc32hash.c > create mode 100644 tools/pcmcia/.gitignore > create mode 100644 tools/pcmcia/Makefile > create mode 100644 tools/pcmcia/crc32hash.c Acked-by: Greg Kroah-Hartman
Re: [PATCH] HID: alps: fix stick device not working after resume
On Wed, Sep 21, 2016 at 8:00 PM, Jiri Kosinawrote: > On Mon, 19 Sep 2016, Kai Heng Feng wrote: > >> >> The stick device does not work after resume, add U1_SP_ABS_MODE flag can >> >> make the device work after resume. >> > >> > Do you happen to have any more details on why it doesn't work without >> > U1_SP_ABS_MODE? Or was this a pure guesswork? >> >> It' pure guesswork, based on how the existing code uses U1_TP_ABS_MODE flag >> on both initialization and resume. >> >> I also tested the the patch on an ALPS touchpad without stick device, >> did not notice >> any side effect on suspend/resume, so I made the U1_SP_ABS_MODE flag >> mandatory. > > I'll fold this information into the patch changelog before comitting; if > you disagree, please let me know. That will be great. Appreciate! > > -- > Jiri Kosina > SUSE Labs >
Re: [PATCH] HID: alps: fix stick device not working after resume
On Wed, Sep 21, 2016 at 8:00 PM, Jiri Kosina wrote: > On Mon, 19 Sep 2016, Kai Heng Feng wrote: > >> >> The stick device does not work after resume, add U1_SP_ABS_MODE flag can >> >> make the device work after resume. >> > >> > Do you happen to have any more details on why it doesn't work without >> > U1_SP_ABS_MODE? Or was this a pure guesswork? >> >> It' pure guesswork, based on how the existing code uses U1_TP_ABS_MODE flag >> on both initialization and resume. >> >> I also tested the the patch on an ALPS touchpad without stick device, >> did not notice >> any side effect on suspend/resume, so I made the U1_SP_ABS_MODE flag >> mandatory. > > I'll fold this information into the patch changelog before comitting; if > you disagree, please let me know. That will be great. Appreciate! > > -- > Jiri Kosina > SUSE Labs >
Re: [PATCH v2 5/6] misc: sram: add Atmel securam support
On Thu, Sep 22, 2016 at 12:09:38AM +0200, Alexandre Belloni wrote: > The Atmel secure SRAM is connected to a security module and may be erased > automatically under certain conditions. For that reason, it is necessary to > wait for the security module to flag that SRAM accesses are allowed before > accessing it. > > Signed-off-by: Alexandre Belloni> --- > Cc: Arnd Bergmann > Cc: Philipp Zabel > Cc: Greg Kroah-Hartman > > drivers/misc/sram.c | 42 +++--- > 1 file changed, 35 insertions(+), 7 deletions(-) Acked-by: Greg Kroah-Hartman
Re: [PATCH v2 5/6] misc: sram: add Atmel securam support
On Thu, Sep 22, 2016 at 12:09:38AM +0200, Alexandre Belloni wrote: > The Atmel secure SRAM is connected to a security module and may be erased > automatically under certain conditions. For that reason, it is necessary to > wait for the security module to flag that SRAM accesses are allowed before > accessing it. > > Signed-off-by: Alexandre Belloni > --- > Cc: Arnd Bergmann > Cc: Philipp Zabel > Cc: Greg Kroah-Hartman > > drivers/misc/sram.c | 42 +++--- > 1 file changed, 35 insertions(+), 7 deletions(-) Acked-by: Greg Kroah-Hartman
Re: [PATCH net-next 3/9] rxrpc: Add per-peer RTT tracker
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: i386-randconfig-h0-09220655 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): net/built-in.o: In function `rxrpc_peer_add_rtt': >> (.text+0x239e99): undefined reference to `__udivdi3' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH net-next 3/9] rxrpc: Add per-peer RTT tracker
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: i386-randconfig-h0-09220655 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): net/built-in.o: In function `rxrpc_peer_add_rtt': >> (.text+0x239e99): undefined reference to `__udivdi3' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH v3] clocksource/fsl: Fix errata A-007728 for flextimer
If the FTM counter reaches the FTM_MOD value between the reading of the TOF bit and the writing of 0 to the TOF bit, the process of clearing the TOF bit does not work as expected when FTMx_CONF[NUMTOF] != 0 and the current TOF count is less than FTMx_CONF[NUMTOF]. If the above condition is met, the TOF bit remains set. If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1), the TOF interrupt also remains asserted. Above is the errata discription The workaround is clearing TOF bit until it is cleaned(FTM counter doesn't always reache the FTM_MOD anyway),which may cost some cycles. Signed-off-by: Meng Yi--- Change from V1: -add timeout into wile loop using a counter --- drivers/clocksource/fsl_ftm_timer.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c index 738515b..97bdb09 100644 --- a/drivers/clocksource/fsl_ftm_timer.c +++ b/drivers/clocksource/fsl_ftm_timer.c @@ -83,11 +83,11 @@ static inline void ftm_counter_disable(void __iomem *base) static inline void ftm_irq_acknowledge(void __iomem *base) { - u32 val; + u32 count = 100; - val = ftm_readl(base + FTM_SC); - val &= ~FTM_SC_TOF; - ftm_writel(val, base + FTM_SC); + while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && count--) + ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF), + base + FTM_SC); } static inline void ftm_irq_enable(void __iomem *base) -- 2.1.0.27.g96db324
[PATCH v3] clocksource/fsl: Fix errata A-007728 for flextimer
If the FTM counter reaches the FTM_MOD value between the reading of the TOF bit and the writing of 0 to the TOF bit, the process of clearing the TOF bit does not work as expected when FTMx_CONF[NUMTOF] != 0 and the current TOF count is less than FTMx_CONF[NUMTOF]. If the above condition is met, the TOF bit remains set. If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1), the TOF interrupt also remains asserted. Above is the errata discription The workaround is clearing TOF bit until it is cleaned(FTM counter doesn't always reache the FTM_MOD anyway),which may cost some cycles. Signed-off-by: Meng Yi --- Change from V1: -add timeout into wile loop using a counter --- drivers/clocksource/fsl_ftm_timer.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c index 738515b..97bdb09 100644 --- a/drivers/clocksource/fsl_ftm_timer.c +++ b/drivers/clocksource/fsl_ftm_timer.c @@ -83,11 +83,11 @@ static inline void ftm_counter_disable(void __iomem *base) static inline void ftm_irq_acknowledge(void __iomem *base) { - u32 val; + u32 count = 100; - val = ftm_readl(base + FTM_SC); - val &= ~FTM_SC_TOF; - ftm_writel(val, base + FTM_SC); + while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && count--) + ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF), + base + FTM_SC); } static inline void ftm_irq_enable(void __iomem *base) -- 2.1.0.27.g96db324
Re: [PATCH v3 7/9] dmaengine: edma: enable COMPILE_TEST
Hi Peter, [auto build test ERROR on linus/master] [also build test ERROR on v4.8-rc7 next-20160921] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] [Suggest to use git(>=2.9.0) format-patch --base= (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on] [Check https://git-scm.com/docs/git-format-patch for more information] url: https://github.com/0day-ci/linux/commits/Peter-Ujfalusi/dmaengine-ti-drivers-enable-COMPILE_TESTing/20160921-212008 config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): >> drivers/dma/edma.c:415:20: error: conflicting types for 'set_bits' static inline void set_bits(int offset, int len, unsigned long *p) ^~~~ In file included from include/linux/bitops.h:36:0, from include/linux/kernel.h:10, from include/linux/list.h:8, from include/linux/kobject.h:20, from include/linux/device.h:17, from include/linux/dmaengine.h:20, from drivers/dma/edma.c:16: arch/powerpc/include/asm/bitops.h:75:14: note: previous definition of 'set_bits' was here DEFINE_BITOP(set_bits, or, "") ^ arch/powerpc/include/asm/bitops.h:58:24: note: in definition of macro 'DEFINE_BITOP' static __inline__ void fn(unsigned long mask, \ ^~ >> drivers/dma/edma.c:421:20: error: conflicting types for 'clear_bits' static inline void clear_bits(int offset, int len, unsigned long *p) ^~ In file included from include/linux/bitops.h:36:0, from include/linux/kernel.h:10, from include/linux/list.h:8, from include/linux/kobject.h:20, from include/linux/device.h:17, from include/linux/dmaengine.h:20, from drivers/dma/edma.c:16: arch/powerpc/include/asm/bitops.h:76:14: note: previous definition of 'clear_bits' was here DEFINE_BITOP(clear_bits, andc, "") ^ arch/powerpc/include/asm/bitops.h:58:24: note: in definition of macro 'DEFINE_BITOP' static __inline__ void fn(unsigned long mask, \ ^~ vim +/set_bits +415 drivers/dma/edma.c d9c345d1 Peter Ujfalusi 2015-10-16 409 static inline void edma_param_or(struct edma_cc *ecc, int offset, int param_no, 2b6b3b74 Peter Ujfalusi 2015-10-14 410 unsigned or) 2b6b3b74 Peter Ujfalusi 2015-10-14 411 { 2b6b3b74 Peter Ujfalusi 2015-10-14 412 edma_or(ecc, EDMA_PARM + offset + (param_no << 5), or); 2b6b3b74 Peter Ujfalusi 2015-10-14 413 } 2b6b3b74 Peter Ujfalusi 2015-10-14 414 2b6b3b74 Peter Ujfalusi 2015-10-14 @415 static inline void set_bits(int offset, int len, unsigned long *p) 2b6b3b74 Peter Ujfalusi 2015-10-14 416 { 2b6b3b74 Peter Ujfalusi 2015-10-14 417 for (; len > 0; len--) 2b6b3b74 Peter Ujfalusi 2015-10-14 418 set_bit(offset + (len - 1), p); 2b6b3b74 Peter Ujfalusi 2015-10-14 419 } 2b6b3b74 Peter Ujfalusi 2015-10-14 420 2b6b3b74 Peter Ujfalusi 2015-10-14 @421 static inline void clear_bits(int offset, int len, unsigned long *p) 2b6b3b74 Peter Ujfalusi 2015-10-14 422 { 2b6b3b74 Peter Ujfalusi 2015-10-14 423 for (; len > 0; len--) 2b6b3b74 Peter Ujfalusi 2015-10-14 424 clear_bit(offset + (len - 1), p); :: The code at line 415 was first introduced by commit :: 2b6b3b7420190888793c49e97276e1e73bd7eaed ARM/dmaengine: edma: Merge the two drivers under drivers/dma/ :: TO: Peter Ujfalusi <peter.ujfal...@ti.com> :: CC: Vinod Koul <vinod.k...@intel.com> --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v3 7/9] dmaengine: edma: enable COMPILE_TEST
Hi Peter, [auto build test ERROR on linus/master] [also build test ERROR on v4.8-rc7 next-20160921] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] [Suggest to use git(>=2.9.0) format-patch --base= (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on] [Check https://git-scm.com/docs/git-format-patch for more information] url: https://github.com/0day-ci/linux/commits/Peter-Ujfalusi/dmaengine-ti-drivers-enable-COMPILE_TESTing/20160921-212008 config: powerpc-allyesconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): >> drivers/dma/edma.c:415:20: error: conflicting types for 'set_bits' static inline void set_bits(int offset, int len, unsigned long *p) ^~~~ In file included from include/linux/bitops.h:36:0, from include/linux/kernel.h:10, from include/linux/list.h:8, from include/linux/kobject.h:20, from include/linux/device.h:17, from include/linux/dmaengine.h:20, from drivers/dma/edma.c:16: arch/powerpc/include/asm/bitops.h:75:14: note: previous definition of 'set_bits' was here DEFINE_BITOP(set_bits, or, "") ^ arch/powerpc/include/asm/bitops.h:58:24: note: in definition of macro 'DEFINE_BITOP' static __inline__ void fn(unsigned long mask, \ ^~ >> drivers/dma/edma.c:421:20: error: conflicting types for 'clear_bits' static inline void clear_bits(int offset, int len, unsigned long *p) ^~ In file included from include/linux/bitops.h:36:0, from include/linux/kernel.h:10, from include/linux/list.h:8, from include/linux/kobject.h:20, from include/linux/device.h:17, from include/linux/dmaengine.h:20, from drivers/dma/edma.c:16: arch/powerpc/include/asm/bitops.h:76:14: note: previous definition of 'clear_bits' was here DEFINE_BITOP(clear_bits, andc, "") ^ arch/powerpc/include/asm/bitops.h:58:24: note: in definition of macro 'DEFINE_BITOP' static __inline__ void fn(unsigned long mask, \ ^~ vim +/set_bits +415 drivers/dma/edma.c d9c345d1 Peter Ujfalusi 2015-10-16 409 static inline void edma_param_or(struct edma_cc *ecc, int offset, int param_no, 2b6b3b74 Peter Ujfalusi 2015-10-14 410 unsigned or) 2b6b3b74 Peter Ujfalusi 2015-10-14 411 { 2b6b3b74 Peter Ujfalusi 2015-10-14 412 edma_or(ecc, EDMA_PARM + offset + (param_no << 5), or); 2b6b3b74 Peter Ujfalusi 2015-10-14 413 } 2b6b3b74 Peter Ujfalusi 2015-10-14 414 2b6b3b74 Peter Ujfalusi 2015-10-14 @415 static inline void set_bits(int offset, int len, unsigned long *p) 2b6b3b74 Peter Ujfalusi 2015-10-14 416 { 2b6b3b74 Peter Ujfalusi 2015-10-14 417 for (; len > 0; len--) 2b6b3b74 Peter Ujfalusi 2015-10-14 418 set_bit(offset + (len - 1), p); 2b6b3b74 Peter Ujfalusi 2015-10-14 419 } 2b6b3b74 Peter Ujfalusi 2015-10-14 420 2b6b3b74 Peter Ujfalusi 2015-10-14 @421 static inline void clear_bits(int offset, int len, unsigned long *p) 2b6b3b74 Peter Ujfalusi 2015-10-14 422 { 2b6b3b74 Peter Ujfalusi 2015-10-14 423 for (; len > 0; len--) 2b6b3b74 Peter Ujfalusi 2015-10-14 424 clear_bit(offset + (len - 1), p); :: The code at line 415 was first introduced by commit :: 2b6b3b7420190888793c49e97276e1e73bd7eaed ARM/dmaengine: edma: Merge the two drivers under drivers/dma/ :: TO: Peter Ujfalusi :: CC: Vinod Koul --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH] arm: ubsan: select ARCH_HAS_UBSAN_SANITIZE_ALL
To enable UBSAN on arm, this patch enables ARCH_HAS_UBSAN_SANITIZE_ALL from arm confiuration. Basic kernel bootup test is passed on arm with CONFIG_UBSAN_SANITIZE_ALL enabled. Signed-off-by: Seung-Woo Kim--- This is resend of the patch I already sent, [1], without RFC tag. [1] https://patchwork.kernel.org/patch/9189533/ I tested kernel build and basic boot up on Exynos5422, Exynos4412 and Exynos3250 SoC boards. At previous time on [1], there were some build error on other systems, but they were caused by driver bug or gcc bug. So I think UBSAN on ARM can be re-considered. --- arch/arm/Kconfig |1 + arch/arm/boot/compressed/Makefile |1 + arch/arm/vdso/Makefile|1 + 3 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a9c4e48..a80f9b1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -7,6 +7,7 @@ config ARM select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_USE_BUILTIN_BSWAP diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index d50430c..883374f 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -23,6 +23,7 @@ OBJS += hyp-stub.o endif GCOV_PROFILE := n +UBSAN_SANITIZE := n # # Architecture dependencies diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 59a8fa7..cb90e59 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -28,6 +28,7 @@ CFLAGS_vgettimeofday.o = -O2 # Disable gcov profiling for VDSO code GCOV_PROFILE := n +UBSAN_SANITIZE := n # Force dependency $(obj)/vdso.o : $(obj)/vdso.so -- 1.7.4.1
[PATCH] arm: ubsan: select ARCH_HAS_UBSAN_SANITIZE_ALL
To enable UBSAN on arm, this patch enables ARCH_HAS_UBSAN_SANITIZE_ALL from arm confiuration. Basic kernel bootup test is passed on arm with CONFIG_UBSAN_SANITIZE_ALL enabled. Signed-off-by: Seung-Woo Kim --- This is resend of the patch I already sent, [1], without RFC tag. [1] https://patchwork.kernel.org/patch/9189533/ I tested kernel build and basic boot up on Exynos5422, Exynos4412 and Exynos3250 SoC boards. At previous time on [1], there were some build error on other systems, but they were caused by driver bug or gcc bug. So I think UBSAN on ARM can be re-considered. --- arch/arm/Kconfig |1 + arch/arm/boot/compressed/Makefile |1 + arch/arm/vdso/Makefile|1 + 3 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a9c4e48..a80f9b1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -7,6 +7,7 @@ config ARM select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_USE_BUILTIN_BSWAP diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index d50430c..883374f 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -23,6 +23,7 @@ OBJS += hyp-stub.o endif GCOV_PROFILE := n +UBSAN_SANITIZE := n # # Architecture dependencies diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 59a8fa7..cb90e59 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -28,6 +28,7 @@ CFLAGS_vgettimeofday.o = -O2 # Disable gcov profiling for VDSO code GCOV_PROFILE := n +UBSAN_SANITIZE := n # Force dependency $(obj)/vdso.o : $(obj)/vdso.so -- 1.7.4.1
Re: [PATCH] percpu: improve generic percpu modify-return implementation
On Wed, 21 Sep 2016 10:23:43 -0400 Tejun Heowrote: > Hello, Nick. > > How have you been? :) Hey Tejun, Well thank you, how about you? > On Wed, Sep 21, 2016 at 08:57:11PM +1000, Nicholas Piggin wrote: > > On Wed, 21 Sep 2016 18:51:37 +1000 > > Nicholas Piggin wrote: > > > > > Some architectures require an additional load to find the address of > > > percpu pointers. In some implemenatations, the C aliasing rules do not > > > allow the result of that load to be kept over the store that modifies > > > the percpu variable, which causes additional loads. > > > > Sorry I picked up an old patch here. This one should be better. > > > > From d0cb9052d6f4c31d24f999b7b0cecb34681eee9b Mon Sep 17 00:00:00 2001 > > From: Nicholas Piggin > > Date: Wed, 21 Sep 2016 18:23:43 +1000 > > Subject: [PATCH] percpu: improve generic percpu modify-return > > implementations > > > > Some architectures require an additional load to find the address of > > percpu pointers. In some implemenatations, the C aliasing rules do not > > allow the result of that load to be kept over the store that modifies > > the percpu variable, which causes additional loads. > > > > Work around this by finding the pointer first, then operating on that. > > > > It's also possible to mark things as restrict and those kind of games, > > but that can require larger and arch specific changes. > > > > On powerpc, __this_cpu_inc_return compiles to: > > > > ld 10,48(13) > > ldx 9,3,10 > > addi 9,9,1 > > stdx 9,3,10 > > ld 9,48(13) > > ldx 3,9,3 > > > > With this patch it compiles to: > > > > ld 10,48(13) > > ldx 9,3,10 > > addi 9,9,1 > > stdx 9,3,10 > > > > Signed-off-by: Nicholas Piggin > > Patch looks good to me but seems QP encoded. Can you please resend? > > Thanks and it's great to see you again! > Trying a new mail client, sorry. It *seems* to be working now, how's this? From d0cb9052d6f4c31d24f999b7b0cecb34681eee9b Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 21 Sep 2016 18:23:43 +1000 Subject: [PATCH] percpu: improve generic percpu modify-return implementations Some architectures require an additional load to find the address of percpu pointers. In some implemenatations, the C aliasing rules do not allow the result of that load to be kept over the store that modifies the percpu variable, which causes additional loads. Work around this by finding the pointer first, then operating on that. It's also possible to mark things as restrict and those kind of games, but that can require larger and arch specific changes. On powerpc, __this_cpu_inc_return compiles to: ld 10,48(13) ldx 9,3,10 addi 9,9,1 stdx 9,3,10 ld 9,48(13) ldx 3,9,3 With this patch it compiles to: ld 10,48(13) ldx 9,3,10 addi 9,9,1 stdx 9,3,10 Signed-off-by: Nicholas Piggin To: Tejun Heo To: Christoph Lameter Cc: linux-kernel@vger.kernel.org Cc: linux-a...@vger.kernel.org --- include/asm-generic/percpu.h | 53 +--- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4d9f233..40e8870 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -65,6 +65,11 @@ extern void setup_per_cpu_areas(void); #define PER_CPU_DEF_ATTRIBUTES #endif +#define raw_cpu_generic_read(pcp) \ +({ \ + *raw_cpu_ptr(&(pcp)); \ +}) + #define raw_cpu_generic_to_op(pcp, val, op)\ do { \ *raw_cpu_ptr(&(pcp)) op val;\ @@ -72,34 +77,39 @@ do { \ #define raw_cpu_generic_add_return(pcp, val) \ ({ \ - raw_cpu_add(pcp, val); \ - raw_cpu_read(pcp); \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ + \ + *__p += val;\ + *__p; \ }) #define raw_cpu_generic_xchg(pcp, nval) \ ({ \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \
Re: [PATCH] percpu: improve generic percpu modify-return implementation
On Wed, 21 Sep 2016 10:23:43 -0400 Tejun Heo wrote: > Hello, Nick. > > How have you been? :) Hey Tejun, Well thank you, how about you? > On Wed, Sep 21, 2016 at 08:57:11PM +1000, Nicholas Piggin wrote: > > On Wed, 21 Sep 2016 18:51:37 +1000 > > Nicholas Piggin wrote: > > > > > Some architectures require an additional load to find the address of > > > percpu pointers. In some implemenatations, the C aliasing rules do not > > > allow the result of that load to be kept over the store that modifies > > > the percpu variable, which causes additional loads. > > > > Sorry I picked up an old patch here. This one should be better. > > > > From d0cb9052d6f4c31d24f999b7b0cecb34681eee9b Mon Sep 17 00:00:00 2001 > > From: Nicholas Piggin > > Date: Wed, 21 Sep 2016 18:23:43 +1000 > > Subject: [PATCH] percpu: improve generic percpu modify-return > > implementations > > > > Some architectures require an additional load to find the address of > > percpu pointers. In some implemenatations, the C aliasing rules do not > > allow the result of that load to be kept over the store that modifies > > the percpu variable, which causes additional loads. > > > > Work around this by finding the pointer first, then operating on that. > > > > It's also possible to mark things as restrict and those kind of games, > > but that can require larger and arch specific changes. > > > > On powerpc, __this_cpu_inc_return compiles to: > > > > ld 10,48(13) > > ldx 9,3,10 > > addi 9,9,1 > > stdx 9,3,10 > > ld 9,48(13) > > ldx 3,9,3 > > > > With this patch it compiles to: > > > > ld 10,48(13) > > ldx 9,3,10 > > addi 9,9,1 > > stdx 9,3,10 > > > > Signed-off-by: Nicholas Piggin > > Patch looks good to me but seems QP encoded. Can you please resend? > > Thanks and it's great to see you again! > Trying a new mail client, sorry. It *seems* to be working now, how's this? From d0cb9052d6f4c31d24f999b7b0cecb34681eee9b Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 21 Sep 2016 18:23:43 +1000 Subject: [PATCH] percpu: improve generic percpu modify-return implementations Some architectures require an additional load to find the address of percpu pointers. In some implemenatations, the C aliasing rules do not allow the result of that load to be kept over the store that modifies the percpu variable, which causes additional loads. Work around this by finding the pointer first, then operating on that. It's also possible to mark things as restrict and those kind of games, but that can require larger and arch specific changes. On powerpc, __this_cpu_inc_return compiles to: ld 10,48(13) ldx 9,3,10 addi 9,9,1 stdx 9,3,10 ld 9,48(13) ldx 3,9,3 With this patch it compiles to: ld 10,48(13) ldx 9,3,10 addi 9,9,1 stdx 9,3,10 Signed-off-by: Nicholas Piggin To: Tejun Heo To: Christoph Lameter Cc: linux-kernel@vger.kernel.org Cc: linux-a...@vger.kernel.org --- include/asm-generic/percpu.h | 53 +--- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4d9f233..40e8870 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -65,6 +65,11 @@ extern void setup_per_cpu_areas(void); #define PER_CPU_DEF_ATTRIBUTES #endif +#define raw_cpu_generic_read(pcp) \ +({ \ + *raw_cpu_ptr(&(pcp)); \ +}) + #define raw_cpu_generic_to_op(pcp, val, op)\ do { \ *raw_cpu_ptr(&(pcp)) op val;\ @@ -72,34 +77,39 @@ do { \ #define raw_cpu_generic_add_return(pcp, val) \ ({ \ - raw_cpu_add(pcp, val); \ - raw_cpu_read(pcp); \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ + \ + *__p += val;\ + *__p; \ }) #define raw_cpu_generic_xchg(pcp, nval) \ ({ \ + typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp)); \ typeof(pcp) __ret; \ - __ret = raw_cpu_read(pcp); \ -
Re: [PATCH] percpu: improve generic percpu modify-return implementation
On Wed, 21 Sep 2016 15:16:25 -0500 (CDT) Christoph Lameterwrote: > On Wed, 21 Sep 2016, Tejun Heo wrote: > > > Hello, Nick. > > > > How have you been? :) > > > > He is baack. Are we getting SL!B? ;-) > Hey Christoph. Sure, why not.
Re: [PATCH] percpu: improve generic percpu modify-return implementation
On Wed, 21 Sep 2016 15:16:25 -0500 (CDT) Christoph Lameter wrote: > On Wed, 21 Sep 2016, Tejun Heo wrote: > > > Hello, Nick. > > > > How have you been? :) > > > > He is baack. Are we getting SL!B? ;-) > Hey Christoph. Sure, why not.
[PATCH] MAINTAINERS: Abandon pas16, dtc and t128 ISA card SCSI host adapter drivers
I don't intend to modernize these three drivers, so as to avoid the deprecated scsi_register() API. I don't have the relevant hardware. Cc: Michael SchmitzReferences: https://lkml.kernel.org/r/20160911171249.ga7...@infradead.org Signed-off-by: Finn Thain --- Whilst I suspect that these 3 drivers have no users, I don't think my own lack of hardware and interest is itself any reason for me to remove the drivers themselves. I'll leave that to the SCSI subsystem maintainers, as they intend to remove the scsi_register() API. diff --git a/MAINTAINERS b/MAINTAINERS index 8c20323..e09df13 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7821,20 +7821,16 @@ M: Michael Schmitz L: linux-s...@vger.kernel.org S: Maintained F: Documentation/scsi/g_NCR5380.txt -F: Documentation/scsi/dtc3x80.txt F: drivers/scsi/NCR5380.* F: drivers/scsi/arm/cumana_1.c F: drivers/scsi/arm/oak.c F: drivers/scsi/atari_scsi.* F: drivers/scsi/dmx3191d.c -F: drivers/scsi/dtc.* F: drivers/scsi/g_NCR5380.* F: drivers/scsi/g_NCR5380_mmio.c F: drivers/scsi/mac_scsi.* -F: drivers/scsi/pas16.* F: drivers/scsi/sun3_scsi.* F: drivers/scsi/sun3_scsi_vme.c -F: drivers/scsi/t128.* NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) M: "James E.J. Bottomley"
[PATCH] MAINTAINERS: Abandon pas16, dtc and t128 ISA card SCSI host adapter drivers
I don't intend to modernize these three drivers, so as to avoid the deprecated scsi_register() API. I don't have the relevant hardware. Cc: Michael Schmitz References: https://lkml.kernel.org/r/20160911171249.ga7...@infradead.org Signed-off-by: Finn Thain --- Whilst I suspect that these 3 drivers have no users, I don't think my own lack of hardware and interest is itself any reason for me to remove the drivers themselves. I'll leave that to the SCSI subsystem maintainers, as they intend to remove the scsi_register() API. diff --git a/MAINTAINERS b/MAINTAINERS index 8c20323..e09df13 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7821,20 +7821,16 @@ M: Michael Schmitz L: linux-s...@vger.kernel.org S: Maintained F: Documentation/scsi/g_NCR5380.txt -F: Documentation/scsi/dtc3x80.txt F: drivers/scsi/NCR5380.* F: drivers/scsi/arm/cumana_1.c F: drivers/scsi/arm/oak.c F: drivers/scsi/atari_scsi.* F: drivers/scsi/dmx3191d.c -F: drivers/scsi/dtc.* F: drivers/scsi/g_NCR5380.* F: drivers/scsi/g_NCR5380_mmio.c F: drivers/scsi/mac_scsi.* -F: drivers/scsi/pas16.* F: drivers/scsi/sun3_scsi.* F: drivers/scsi/sun3_scsi_vme.c -F: drivers/scsi/t128.* NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) M: "James E.J. Bottomley"
Re: [PATCH net-next 3/9] rxrpc: Add per-peer RTT tracker
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: arm-omap2plus_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): >> ERROR: "__aeabi_uldivmod" [net/rxrpc/af-rxrpc.ko] undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH net-next 3/9] rxrpc: Add per-peer RTT tracker
Hi David, [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/David-Howells/rxrpc-Preparation-for-slow-start-algorithm/20160922-085242 config: arm-omap2plus_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): >> ERROR: "__aeabi_uldivmod" [net/rxrpc/af-rxrpc.ko] undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] mmc: dw_mmc: minor cleanup for dw_mci_adjust_fifoth
On 09/21/2016 11:40 AM, Shawn Lin wrote: > msize and rx_wmark are properly initialized, we dont't > need to assign them again. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin> --- > > drivers/mmc/host/dw_mmc.c | 5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 22dacae..d838428 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -876,11 +876,8 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, > struct mmc_data *data) >* MSIZE is '1', >* if blksz is not a multiple of the FIFO width >*/ > - if (blksz % fifo_width) { > - msize = 0; > - rx_wmark = 1; > + if (blksz % fifo_width) > goto done; > - } > > do { > if (!((blksz_depth % mszs[idx]) || >
Re: [PATCH] mmc: dw_mmc: minor cleanup for dw_mci_adjust_fifoth
On 09/21/2016 11:40 AM, Shawn Lin wrote: > msize and rx_wmark are properly initialized, we dont't > need to assign them again. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin > --- > > drivers/mmc/host/dw_mmc.c | 5 + > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 22dacae..d838428 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -876,11 +876,8 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, > struct mmc_data *data) >* MSIZE is '1', >* if blksz is not a multiple of the FIFO width >*/ > - if (blksz % fifo_width) { > - msize = 0; > - rx_wmark = 1; > + if (blksz % fifo_width) > goto done; > - } > > do { > if (!((blksz_depth % mszs[idx]) || >
Re: [PATCH v2 2/4] mmc: dw_mmc: avoid race condition of cpu and IDMAC
On 09/02/2016 01:14 PM, Shawn Lin wrote: > We could see an obvious race condition by test that > the former write operation by IDMAC aiming to clear > OWN bit reach right after the later configuration of > the same desc, which makes the IDMAC be in SUSPEND > state as the OWN bit was cleared by the asynchronous > write operation of IDMAC. The bug can be very easy > reproduced on RK3288 or similar when we reduce the > running rate of system buses and keep the CPU running > faster. So as two separate masters, IDMAC and cpu > write the same descriptor stored on the same address, > and this should be protected by adding check of OWN > bit before preparing new descriptors. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin> > --- > > Changes in v2: > - fallback to PIO mode if failing to wait for OWN bit > - cleanup polluted desc chain as the own bit error could > occur on any place of the chain, so we need to clr the desc > configured before that one. Use the exist function to reinit > the desc chain. As this issue is really rare, so after applied, > the fio/iozone stress test didn't show up performance regression. > > drivers/mmc/host/dw_mmc.c | 208 > -- > 1 file changed, 129 insertions(+), 79 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 782b303..daa1c52 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -467,12 +467,87 @@ static void dw_mci_dmac_complete_dma(void *arg) > } > } > > -static inline void dw_mci_prepare_desc64(struct dw_mci *host, > +static int dw_mci_idmac_init(struct dw_mci *host) > +{ > + int i; > + > + if (host->dma_64bit_address == 1) { > + struct idmac_desc_64addr *p; > + /* Number of descriptors in the ring buffer */ > + host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); > + > + /* Forward link the descriptor list */ > + for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; > + i++, p++) { > + p->des6 = (host->sg_dma + > + (sizeof(struct idmac_desc_64addr) * > + (i + 1))) & 0x; > + > + p->des7 = (u64)(host->sg_dma + > + (sizeof(struct idmac_desc_64addr) * > + (i + 1))) >> 32; > + /* Initialize reserved and buffer size fields to "0" */ > + p->des1 = 0; > + p->des2 = 0; > + p->des3 = 0; > + } > + > + /* Set the last descriptor as the end-of-ring descriptor */ > + p->des6 = host->sg_dma & 0x; > + p->des7 = (u64)host->sg_dma >> 32; > + p->des0 = IDMAC_DES0_ER; > + > + } else { > + struct idmac_desc *p; > + /* Number of descriptors in the ring buffer */ > + host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); > + > + /* Forward link the descriptor list */ > + for (i = 0, p = host->sg_cpu; > + i < host->ring_size - 1; > + i++, p++) { > + p->des3 = cpu_to_le32(host->sg_dma + > + (sizeof(struct idmac_desc) * (i + 1))); > + p->des1 = 0; > + } > + > + /* Set the last descriptor as the end-of-ring descriptor */ > + p->des3 = cpu_to_le32(host->sg_dma); > + p->des0 = cpu_to_le32(IDMAC_DES0_ER); > + } > + > + dw_mci_idmac_reset(host); > + > + if (host->dma_64bit_address == 1) { > + /* Mask out interrupts - get Tx & Rx complete only */ > + mci_writel(host, IDSTS64, IDMAC_INT_CLR); > + mci_writel(host, IDINTEN64, SDMMC_IDMAC_INT_NI | > + SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); > + > + /* Set the descriptor base address */ > + mci_writel(host, DBADDRL, host->sg_dma & 0x); > + mci_writel(host, DBADDRU, (u64)host->sg_dma >> 32); > + > + } else { > + /* Mask out interrupts - get Tx & Rx complete only */ > + mci_writel(host, IDSTS, IDMAC_INT_CLR); > + mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | > + SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); > + > + /* Set the descriptor base address */ > + mci_writel(host, DBADDR, host->sg_dma); > + } > + > + return 0; > +} > + > +static inline int dw_mci_prepare_desc64(struct dw_mci *host, >struct mmc_data *data, >unsigned int sg_len) > { >
Re: [PATCH v2 4/4] mmc: dw_mmc: use macro to define ring buffer size
On 09/02/2016 01:14 PM, Shawn Lin wrote: > It's very prone to make mistake as we might forget > to replace all PAGE_SIZEs with new values if we try > to modify the ring buffer size for whatever reasons. > Let's use a macro to define it. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin> --- > > Changes in v2: None > > drivers/mmc/host/dw_mmc.c | 15 ++- > 1 file changed, 10 insertions(+), 5 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 833b6ad..6e5926b 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -61,6 +61,8 @@ >SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ >SDMMC_IDMAC_INT_TI) > > +#define DESC_RING_BUF_SZ PAGE_SIZE > + > struct idmac_desc_64addr { > u32 des0; /* Control Descriptor */ > > @@ -474,7 +476,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) > if (host->dma_64bit_address == 1) { > struct idmac_desc_64addr *p; > /* Number of descriptors in the ring buffer */ > - host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); > + host->ring_size = > + DESC_RING_BUF_SZ / sizeof(struct idmac_desc_64addr); > > /* Forward link the descriptor list */ > for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; > @@ -500,7 +503,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) > } else { > struct idmac_desc *p; > /* Number of descriptors in the ring buffer */ > - host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); > + host->ring_size = > + DESC_RING_BUF_SZ / sizeof(struct idmac_desc); > > /* Forward link the descriptor list */ > for (i = 0, p = host->sg_cpu; > @@ -609,7 +613,7 @@ static inline int dw_mci_prepare_desc64(struct dw_mci > *host, > err_own_bit: > /* restore the descriptor chain as it's polluted */ > dev_dbg(host->dev, "desciptor is still owned by IDMAC.\n"); > - memset(host->sg_cpu, 0, PAGE_SIZE); > + memset(host->sg_cpu, 0, DESC_RING_BUF_SZ); > dw_mci_idmac_init(host); > return -EINVAL; > } > @@ -685,7 +689,7 @@ static inline int dw_mci_prepare_desc32(struct dw_mci > *host, > err_own_bit: > /* restore the descriptor chain as it's polluted */ > dev_dbg(host->dev, "desciptor is still owned by IDMAC.\n"); > - memset(host->sg_cpu, 0, PAGE_SIZE); > + memset(host->sg_cpu, 0, DESC_RING_BUF_SZ); > dw_mci_idmac_init(host); > return -EINVAL; > } > @@ -2750,7 +2754,8 @@ static void dw_mci_init_dma(struct dw_mci *host) > } > > /* Alloc memory for sg translation */ > - host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, > + host->sg_cpu = dmam_alloc_coherent(host->dev, > +DESC_RING_BUF_SZ, > >sg_dma, GFP_KERNEL); > if (!host->sg_cpu) { > dev_err(host->dev, >
Re: [PATCH v2 3/4] mmc: dw_mmc: fix misleading error print if failing to do DMA transfer
On 09/02/2016 01:14 PM, Shawn Lin wrote: > The original log didn't figure out that we could still > finish this transfer by PIO mode even if failing to use > DMA. And it should be kept for debug level instead of > error one. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin> --- > > Changes in v2: None > > drivers/mmc/host/dw_mmc.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index daa1c52..833b6ad 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -1057,8 +1057,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, > struct mmc_data *data) > spin_unlock_irqrestore(>irq_lock, irqflags); > > if (host->dma_ops->start(host, sg_len)) { > - /* We can't do DMA */ > - dev_err(host->dev, "%s: failed to start DMA.\n", __func__); > + /* We can't do DMA, try PIO for this one */ > + dev_dbg(host->dev, > + "%s: fall back to PIO mode for current transfer\n", > + __func__); > return -ENODEV; > } > >
Re: [PATCH v2 4/4] mmc: dw_mmc: use macro to define ring buffer size
On 09/02/2016 01:14 PM, Shawn Lin wrote: > It's very prone to make mistake as we might forget > to replace all PAGE_SIZEs with new values if we try > to modify the ring buffer size for whatever reasons. > Let's use a macro to define it. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin > --- > > Changes in v2: None > > drivers/mmc/host/dw_mmc.c | 15 ++- > 1 file changed, 10 insertions(+), 5 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 833b6ad..6e5926b 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -61,6 +61,8 @@ >SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ >SDMMC_IDMAC_INT_TI) > > +#define DESC_RING_BUF_SZ PAGE_SIZE > + > struct idmac_desc_64addr { > u32 des0; /* Control Descriptor */ > > @@ -474,7 +476,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) > if (host->dma_64bit_address == 1) { > struct idmac_desc_64addr *p; > /* Number of descriptors in the ring buffer */ > - host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); > + host->ring_size = > + DESC_RING_BUF_SZ / sizeof(struct idmac_desc_64addr); > > /* Forward link the descriptor list */ > for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; > @@ -500,7 +503,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) > } else { > struct idmac_desc *p; > /* Number of descriptors in the ring buffer */ > - host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); > + host->ring_size = > + DESC_RING_BUF_SZ / sizeof(struct idmac_desc); > > /* Forward link the descriptor list */ > for (i = 0, p = host->sg_cpu; > @@ -609,7 +613,7 @@ static inline int dw_mci_prepare_desc64(struct dw_mci > *host, > err_own_bit: > /* restore the descriptor chain as it's polluted */ > dev_dbg(host->dev, "desciptor is still owned by IDMAC.\n"); > - memset(host->sg_cpu, 0, PAGE_SIZE); > + memset(host->sg_cpu, 0, DESC_RING_BUF_SZ); > dw_mci_idmac_init(host); > return -EINVAL; > } > @@ -685,7 +689,7 @@ static inline int dw_mci_prepare_desc32(struct dw_mci > *host, > err_own_bit: > /* restore the descriptor chain as it's polluted */ > dev_dbg(host->dev, "desciptor is still owned by IDMAC.\n"); > - memset(host->sg_cpu, 0, PAGE_SIZE); > + memset(host->sg_cpu, 0, DESC_RING_BUF_SZ); > dw_mci_idmac_init(host); > return -EINVAL; > } > @@ -2750,7 +2754,8 @@ static void dw_mci_init_dma(struct dw_mci *host) > } > > /* Alloc memory for sg translation */ > - host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE, > + host->sg_cpu = dmam_alloc_coherent(host->dev, > +DESC_RING_BUF_SZ, > >sg_dma, GFP_KERNEL); > if (!host->sg_cpu) { > dev_err(host->dev, >
Re: [PATCH v2 3/4] mmc: dw_mmc: fix misleading error print if failing to do DMA transfer
On 09/02/2016 01:14 PM, Shawn Lin wrote: > The original log didn't figure out that we could still > finish this transfer by PIO mode even if failing to use > DMA. And it should be kept for debug level instead of > error one. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin > --- > > Changes in v2: None > > drivers/mmc/host/dw_mmc.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index daa1c52..833b6ad 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -1057,8 +1057,10 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, > struct mmc_data *data) > spin_unlock_irqrestore(>irq_lock, irqflags); > > if (host->dma_ops->start(host, sg_len)) { > - /* We can't do DMA */ > - dev_err(host->dev, "%s: failed to start DMA.\n", __func__); > + /* We can't do DMA, try PIO for this one */ > + dev_dbg(host->dev, > + "%s: fall back to PIO mode for current transfer\n", > + __func__); > return -ENODEV; > } > >
Re: [PATCH v2 2/4] mmc: dw_mmc: avoid race condition of cpu and IDMAC
On 09/02/2016 01:14 PM, Shawn Lin wrote: > We could see an obvious race condition by test that > the former write operation by IDMAC aiming to clear > OWN bit reach right after the later configuration of > the same desc, which makes the IDMAC be in SUSPEND > state as the OWN bit was cleared by the asynchronous > write operation of IDMAC. The bug can be very easy > reproduced on RK3288 or similar when we reduce the > running rate of system buses and keep the CPU running > faster. So as two separate masters, IDMAC and cpu > write the same descriptor stored on the same address, > and this should be protected by adding check of OWN > bit before preparing new descriptors. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin > > --- > > Changes in v2: > - fallback to PIO mode if failing to wait for OWN bit > - cleanup polluted desc chain as the own bit error could > occur on any place of the chain, so we need to clr the desc > configured before that one. Use the exist function to reinit > the desc chain. As this issue is really rare, so after applied, > the fio/iozone stress test didn't show up performance regression. > > drivers/mmc/host/dw_mmc.c | 208 > -- > 1 file changed, 129 insertions(+), 79 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 782b303..daa1c52 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -467,12 +467,87 @@ static void dw_mci_dmac_complete_dma(void *arg) > } > } > > -static inline void dw_mci_prepare_desc64(struct dw_mci *host, > +static int dw_mci_idmac_init(struct dw_mci *host) > +{ > + int i; > + > + if (host->dma_64bit_address == 1) { > + struct idmac_desc_64addr *p; > + /* Number of descriptors in the ring buffer */ > + host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc_64addr); > + > + /* Forward link the descriptor list */ > + for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; > + i++, p++) { > + p->des6 = (host->sg_dma + > + (sizeof(struct idmac_desc_64addr) * > + (i + 1))) & 0x; > + > + p->des7 = (u64)(host->sg_dma + > + (sizeof(struct idmac_desc_64addr) * > + (i + 1))) >> 32; > + /* Initialize reserved and buffer size fields to "0" */ > + p->des1 = 0; > + p->des2 = 0; > + p->des3 = 0; > + } > + > + /* Set the last descriptor as the end-of-ring descriptor */ > + p->des6 = host->sg_dma & 0x; > + p->des7 = (u64)host->sg_dma >> 32; > + p->des0 = IDMAC_DES0_ER; > + > + } else { > + struct idmac_desc *p; > + /* Number of descriptors in the ring buffer */ > + host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); > + > + /* Forward link the descriptor list */ > + for (i = 0, p = host->sg_cpu; > + i < host->ring_size - 1; > + i++, p++) { > + p->des3 = cpu_to_le32(host->sg_dma + > + (sizeof(struct idmac_desc) * (i + 1))); > + p->des1 = 0; > + } > + > + /* Set the last descriptor as the end-of-ring descriptor */ > + p->des3 = cpu_to_le32(host->sg_dma); > + p->des0 = cpu_to_le32(IDMAC_DES0_ER); > + } > + > + dw_mci_idmac_reset(host); > + > + if (host->dma_64bit_address == 1) { > + /* Mask out interrupts - get Tx & Rx complete only */ > + mci_writel(host, IDSTS64, IDMAC_INT_CLR); > + mci_writel(host, IDINTEN64, SDMMC_IDMAC_INT_NI | > + SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); > + > + /* Set the descriptor base address */ > + mci_writel(host, DBADDRL, host->sg_dma & 0x); > + mci_writel(host, DBADDRU, (u64)host->sg_dma >> 32); > + > + } else { > + /* Mask out interrupts - get Tx & Rx complete only */ > + mci_writel(host, IDSTS, IDMAC_INT_CLR); > + mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | > + SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); > + > + /* Set the descriptor base address */ > + mci_writel(host, DBADDR, host->sg_dma); > + } > + > + return 0; > +} > + > +static inline int dw_mci_prepare_desc64(struct dw_mci *host, >struct mmc_data *data, >unsigned int sg_len) > { > unsigned int desc_len; >
Re: [PATCH v2 1/4] mmc: dw_mmc: split out preparation of desc for IDMAC32 and IDMAC64
On 09/02/2016 01:14 PM, Shawn Lin wrote: > We intend to add more check for descriptors when > preparing desc. Let's spilt out the separate body > to make the dw_mci_translate_sglist not so lengthy. > After spliting out these two functions, we could > remove dw_mci_translate_sglist and call both of them > when staring idmac. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin> > --- > > Changes in v2: > - remove dw_mci_translate_sglist > > drivers/mmc/host/dw_mmc.c | 149 > -- > 1 file changed, 79 insertions(+), 70 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 22dacae..782b303 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -467,112 +467,121 @@ static void dw_mci_dmac_complete_dma(void *arg) > } > } > > -static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data > *data, > - unsigned int sg_len) > +static inline void dw_mci_prepare_desc64(struct dw_mci *host, > + struct mmc_data *data, > + unsigned int sg_len) > { > unsigned int desc_len; > + struct idmac_desc_64addr *desc_first, *desc_last, *desc; > int i; > > - if (host->dma_64bit_address == 1) { > - struct idmac_desc_64addr *desc_first, *desc_last, *desc; > - > - desc_first = desc_last = desc = host->sg_cpu; > + desc_first = desc_last = desc = host->sg_cpu; > > - for (i = 0; i < sg_len; i++) { > - unsigned int length = sg_dma_len(>sg[i]); > + for (i = 0; i < sg_len; i++) { > + unsigned int length = sg_dma_len(>sg[i]); > > - u64 mem_addr = sg_dma_address(>sg[i]); > + u64 mem_addr = sg_dma_address(>sg[i]); > > - for ( ; length ; desc++) { > - desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? > -length : DW_MCI_DESC_DATA_LENGTH; > + for ( ; length ; desc++) { > + desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? > +length : DW_MCI_DESC_DATA_LENGTH; > > - length -= desc_len; > + length -= desc_len; > > - /* > - * Set the OWN bit and disable interrupts > - * for this descriptor > - */ > - desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | > - IDMAC_DES0_CH; > + /* > + * Set the OWN bit and disable interrupts > + * for this descriptor > + */ > + desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | > + IDMAC_DES0_CH; > > - /* Buffer length */ > - IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); > + /* Buffer length */ > + IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); > > - /* Physical address to DMA to/from */ > - desc->des4 = mem_addr & 0x; > - desc->des5 = mem_addr >> 32; > + /* Physical address to DMA to/from */ > + desc->des4 = mem_addr & 0x; > + desc->des5 = mem_addr >> 32; > > - /* Update physical address for the next desc */ > - mem_addr += desc_len; > + /* Update physical address for the next desc */ > + mem_addr += desc_len; > > - /* Save pointer to the last descriptor */ > - desc_last = desc; > - } > + /* Save pointer to the last descriptor */ > + desc_last = desc; > } > + } > > - /* Set first descriptor */ > - desc_first->des0 |= IDMAC_DES0_FD; > + /* Set first descriptor */ > + desc_first->des0 |= IDMAC_DES0_FD; > > - /* Set last descriptor */ > - desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); > - desc_last->des0 |= IDMAC_DES0_LD; > + /* Set last descriptor */ > + desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); > + desc_last->des0 |= IDMAC_DES0_LD; > +} > > - } else { > - struct idmac_desc *desc_first, *desc_last, *desc; > > - desc_first = desc_last = desc = host->sg_cpu; > +static inline void dw_mci_prepare_desc32(struct dw_mci *host, > +
Re: [PATCH v2 1/4] mmc: dw_mmc: split out preparation of desc for IDMAC32 and IDMAC64
On 09/02/2016 01:14 PM, Shawn Lin wrote: > We intend to add more check for descriptors when > preparing desc. Let's spilt out the separate body > to make the dw_mci_translate_sglist not so lengthy. > After spliting out these two functions, we could > remove dw_mci_translate_sglist and call both of them > when staring idmac. Applied on my tree. Thanks! Best Regards, Jaehoon Chung > > Signed-off-by: Shawn Lin > > --- > > Changes in v2: > - remove dw_mci_translate_sglist > > drivers/mmc/host/dw_mmc.c | 149 > -- > 1 file changed, 79 insertions(+), 70 deletions(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 22dacae..782b303 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -467,112 +467,121 @@ static void dw_mci_dmac_complete_dma(void *arg) > } > } > > -static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data > *data, > - unsigned int sg_len) > +static inline void dw_mci_prepare_desc64(struct dw_mci *host, > + struct mmc_data *data, > + unsigned int sg_len) > { > unsigned int desc_len; > + struct idmac_desc_64addr *desc_first, *desc_last, *desc; > int i; > > - if (host->dma_64bit_address == 1) { > - struct idmac_desc_64addr *desc_first, *desc_last, *desc; > - > - desc_first = desc_last = desc = host->sg_cpu; > + desc_first = desc_last = desc = host->sg_cpu; > > - for (i = 0; i < sg_len; i++) { > - unsigned int length = sg_dma_len(>sg[i]); > + for (i = 0; i < sg_len; i++) { > + unsigned int length = sg_dma_len(>sg[i]); > > - u64 mem_addr = sg_dma_address(>sg[i]); > + u64 mem_addr = sg_dma_address(>sg[i]); > > - for ( ; length ; desc++) { > - desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? > -length : DW_MCI_DESC_DATA_LENGTH; > + for ( ; length ; desc++) { > + desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? > +length : DW_MCI_DESC_DATA_LENGTH; > > - length -= desc_len; > + length -= desc_len; > > - /* > - * Set the OWN bit and disable interrupts > - * for this descriptor > - */ > - desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | > - IDMAC_DES0_CH; > + /* > + * Set the OWN bit and disable interrupts > + * for this descriptor > + */ > + desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | > + IDMAC_DES0_CH; > > - /* Buffer length */ > - IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); > + /* Buffer length */ > + IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); > > - /* Physical address to DMA to/from */ > - desc->des4 = mem_addr & 0x; > - desc->des5 = mem_addr >> 32; > + /* Physical address to DMA to/from */ > + desc->des4 = mem_addr & 0x; > + desc->des5 = mem_addr >> 32; > > - /* Update physical address for the next desc */ > - mem_addr += desc_len; > + /* Update physical address for the next desc */ > + mem_addr += desc_len; > > - /* Save pointer to the last descriptor */ > - desc_last = desc; > - } > + /* Save pointer to the last descriptor */ > + desc_last = desc; > } > + } > > - /* Set first descriptor */ > - desc_first->des0 |= IDMAC_DES0_FD; > + /* Set first descriptor */ > + desc_first->des0 |= IDMAC_DES0_FD; > > - /* Set last descriptor */ > - desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); > - desc_last->des0 |= IDMAC_DES0_LD; > + /* Set last descriptor */ > + desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); > + desc_last->des0 |= IDMAC_DES0_LD; > +} > > - } else { > - struct idmac_desc *desc_first, *desc_last, *desc; > > - desc_first = desc_last = desc = host->sg_cpu; > +static inline void dw_mci_prepare_desc32(struct dw_mci *host, > + struct
Re: strace lockup when tracing exec in go
On Wed, 2016-09-21 at 17:29 +0200, Michal Hocko wrote: > [I am CCing strace mailing list because even if this turns out to be a > kernel bug strace seems to be doing something unexpected - more on that > below] > > Hi, > Aleksa has reported the following lockup when stracing the following go > program > > % cat exec.go > package main > > import ( > "os" > "syscall" > ) > > func main() { > syscall.Exec("/bin/echo", []string{"/bin/echo", "Hello"}, os.Environ()) > } > $ go version > go version go1.6.3 linux/amd64 > $ go build -o exec exec.go > > $ strace -f ./exec > [snip] > [pid 10349] select(0, NULL, NULL, NULL, {0, 100} > [pid 10346] <... select resumed> ) = 0 (Timeout) > [pid 10346] select(0, NULL, NULL, NULL, {0, 20} > [pid 10345] execve("/bin/echo", ["/bin/echo", "Hello"], [/* 95 vars */] > [pid 10346] <... select resumed> ) = 0 (Timeout) > [pid 10349] <... select resumed> ) = 0 (Timeout) > > execve will never finish unless the strace process get killed with > SIGKILL. The following was debugged on 3.12 kernel and the current > kernel seems to not trigger the issue as easily but I believe the same > problem is there as well. > > The further investigation shown that the tracer (strace) is stuck > waiting for cred_guard_mutex > [<>] mm_access+0x22/0xa0 > [<>] process_vm_rw_core.isra.1+0x112/0x6c0 > [<>] process_vm_rw+0xab/0x110 > [<>] SyS_process_vm_readv+0x15/0x20 > [<>] system_call_fastpath+0x16/0x1b > [<>] 0x7f186f031c3a > [<>] 0x > > while the traced process (3 threads) are trying to perform the exec. > That means that 2 threads are dead (in fact zombies) waiting in their > final schedule. > Call Trace: > [] do_exit+0x6f7/0xa70 > [] do_group_exit+0x39/0xa0 > [] get_signal_to_deliver+0x1e8/0x5c0 > [] do_signal+0x42/0x670 > [] do_notify_resume+0x78/0xc0 > [] int_signal+0x12/0x17 > [<7f3a33f3ffb9>] 0x7f3a33f3ffb8 > > and one is > Call Trace: > [] flush_old_exec+0xdf/0x890 > [] load_elf_binary+0x307/0xda0 > [] search_binary_handler+0xae/0x1f0 > [] do_execve_common.isra.26+0x64e/0x810 > [] SyS_execve+0x31/0x50 > [] stub_execve+0x69/0xa0 > [<7f3a33f16527>] 0x7f3a33f16526 > > waiting for notify_count to drop down to 0 > while (sig->notify_count) { > __set_current_state(TASK_KILLABLE); > spin_unlock_irq(lock); > schedule(); < > if (unlikely(__fatal_signal_pending(tsk))) > goto killed; > spin_lock_irq(lock); > } > > this however doesn't happen because both threads which are dead > are zombies waiting to be reaped by the parent and to call their > release_task->__exit_signal. The tracer is blocked on the lock held by > exec (in prepare_bprm_creds). This is the case in the current kernel as > well AFAICS so the same should be possible as well. So is this a bug or > something somewhere else makes sure that this will not happen in newer > kernels? master.today... crash> bt 5138 PID: 5138 TASK: 8803fb4e4c80 CPU: 6 COMMAND: "strace" #0 [88038e323b68] __schedule at 81624660 #1 [88038e323bb0] schedule at 81624b35 #2 [88038e323bc8] schedule_preempt_disabled at 81624e0e #3 [88038e323bd8] __mutex_lock_killable_slowpath at 81625f9d #4 [88038e323c30] mutex_lock_killable at 8162605a #5 [88038e323c48] mm_access at 8105bbf7 #6 [88038e323c70] process_vm_rw_core at 811823d3 #7 [88038e323dc0] process_vm_rw at 8118287d #8 [88038e323f38] sys_process_vm_readv at 811829b9 #9 [88038e323f50] entry_SYSCALL_64_fastpath at 81628736 RIP: 7faee6b2ac3a RSP: 7ffdc95b62b8 RFLAGS: 0246 RAX: ffda RBX: 019e7030 RCX: 7faee6b2ac3a RDX: 0001 RSI: 7ffdc95b62d0 RDI: 1418 RBP: 1414 R8: 0001 R9: R10: 7ffdc95b62e0 R11: 0246 R12: 7faee73e66c0 R13: R14: R15: ORIG_RAX: 0136 CS: 0033 SS: 002b crash> bt 5140 PID: 5140 TASK: 8803e703b300 CPU: 4 COMMAND: "exec" #0 [88038e0b3ce8] __schedule at 81624660 #1 [88038e0b3d30] schedule at 81624b35 #2 [88038e0b3d48] flush_old_exec at 811b1f26 #3 [88038e0b3d88] load_elf_binary at 811fd70f #4 [88038e0b3e60] search_binary_handler at 811b13ac #5 [88038e0b3e98] do_execveat_common at 811b2f8f #6 [88038e0b3f00] sys_execve at 811b33ba #7 [88038e0b3f28] do_syscall_64 at 8100194e RIP: 0045c1ef RSP: 00c820043e00 RFLAGS: 0246 RAX: ffda RBX: 00c82000e6c0 RCX: 0045c1ef RDX:
Re: strace lockup when tracing exec in go
On Wed, 2016-09-21 at 17:29 +0200, Michal Hocko wrote: > [I am CCing strace mailing list because even if this turns out to be a > kernel bug strace seems to be doing something unexpected - more on that > below] > > Hi, > Aleksa has reported the following lockup when stracing the following go > program > > % cat exec.go > package main > > import ( > "os" > "syscall" > ) > > func main() { > syscall.Exec("/bin/echo", []string{"/bin/echo", "Hello"}, os.Environ()) > } > $ go version > go version go1.6.3 linux/amd64 > $ go build -o exec exec.go > > $ strace -f ./exec > [snip] > [pid 10349] select(0, NULL, NULL, NULL, {0, 100} > [pid 10346] <... select resumed> ) = 0 (Timeout) > [pid 10346] select(0, NULL, NULL, NULL, {0, 20} > [pid 10345] execve("/bin/echo", ["/bin/echo", "Hello"], [/* 95 vars */] > [pid 10346] <... select resumed> ) = 0 (Timeout) > [pid 10349] <... select resumed> ) = 0 (Timeout) > > execve will never finish unless the strace process get killed with > SIGKILL. The following was debugged on 3.12 kernel and the current > kernel seems to not trigger the issue as easily but I believe the same > problem is there as well. > > The further investigation shown that the tracer (strace) is stuck > waiting for cred_guard_mutex > [<>] mm_access+0x22/0xa0 > [<>] process_vm_rw_core.isra.1+0x112/0x6c0 > [<>] process_vm_rw+0xab/0x110 > [<>] SyS_process_vm_readv+0x15/0x20 > [<>] system_call_fastpath+0x16/0x1b > [<>] 0x7f186f031c3a > [<>] 0x > > while the traced process (3 threads) are trying to perform the exec. > That means that 2 threads are dead (in fact zombies) waiting in their > final schedule. > Call Trace: > [] do_exit+0x6f7/0xa70 > [] do_group_exit+0x39/0xa0 > [] get_signal_to_deliver+0x1e8/0x5c0 > [] do_signal+0x42/0x670 > [] do_notify_resume+0x78/0xc0 > [] int_signal+0x12/0x17 > [<7f3a33f3ffb9>] 0x7f3a33f3ffb8 > > and one is > Call Trace: > [] flush_old_exec+0xdf/0x890 > [] load_elf_binary+0x307/0xda0 > [] search_binary_handler+0xae/0x1f0 > [] do_execve_common.isra.26+0x64e/0x810 > [] SyS_execve+0x31/0x50 > [] stub_execve+0x69/0xa0 > [<7f3a33f16527>] 0x7f3a33f16526 > > waiting for notify_count to drop down to 0 > while (sig->notify_count) { > __set_current_state(TASK_KILLABLE); > spin_unlock_irq(lock); > schedule(); < > if (unlikely(__fatal_signal_pending(tsk))) > goto killed; > spin_lock_irq(lock); > } > > this however doesn't happen because both threads which are dead > are zombies waiting to be reaped by the parent and to call their > release_task->__exit_signal. The tracer is blocked on the lock held by > exec (in prepare_bprm_creds). This is the case in the current kernel as > well AFAICS so the same should be possible as well. So is this a bug or > something somewhere else makes sure that this will not happen in newer > kernels? master.today... crash> bt 5138 PID: 5138 TASK: 8803fb4e4c80 CPU: 6 COMMAND: "strace" #0 [88038e323b68] __schedule at 81624660 #1 [88038e323bb0] schedule at 81624b35 #2 [88038e323bc8] schedule_preempt_disabled at 81624e0e #3 [88038e323bd8] __mutex_lock_killable_slowpath at 81625f9d #4 [88038e323c30] mutex_lock_killable at 8162605a #5 [88038e323c48] mm_access at 8105bbf7 #6 [88038e323c70] process_vm_rw_core at 811823d3 #7 [88038e323dc0] process_vm_rw at 8118287d #8 [88038e323f38] sys_process_vm_readv at 811829b9 #9 [88038e323f50] entry_SYSCALL_64_fastpath at 81628736 RIP: 7faee6b2ac3a RSP: 7ffdc95b62b8 RFLAGS: 0246 RAX: ffda RBX: 019e7030 RCX: 7faee6b2ac3a RDX: 0001 RSI: 7ffdc95b62d0 RDI: 1418 RBP: 1414 R8: 0001 R9: R10: 7ffdc95b62e0 R11: 0246 R12: 7faee73e66c0 R13: R14: R15: ORIG_RAX: 0136 CS: 0033 SS: 002b crash> bt 5140 PID: 5140 TASK: 8803e703b300 CPU: 4 COMMAND: "exec" #0 [88038e0b3ce8] __schedule at 81624660 #1 [88038e0b3d30] schedule at 81624b35 #2 [88038e0b3d48] flush_old_exec at 811b1f26 #3 [88038e0b3d88] load_elf_binary at 811fd70f #4 [88038e0b3e60] search_binary_handler at 811b13ac #5 [88038e0b3e98] do_execveat_common at 811b2f8f #6 [88038e0b3f00] sys_execve at 811b33ba #7 [88038e0b3f28] do_syscall_64 at 8100194e RIP: 0045c1ef RSP: 00c820043e00 RFLAGS: 0246 RAX: ffda RBX: 00c82000e6c0 RCX: 0045c1ef RDX:
RE: [PATCH v2] clocksource/fsl: Fix errata A-007728 for flextimer
> > __iomem *base) > > > > static inline void ftm_irq_acknowledge(void __iomem *base) { > > - u32 val; > > + unsigned long timeout = jiffies + msecs_to_jiffies(100); > > Do you expect the jiffies to be updated when we are in the timer irq handler ? > Oops, my bad. Will correct that using "for" loop. Thanks, Meng
RE: [PATCH v2] clocksource/fsl: Fix errata A-007728 for flextimer
> > __iomem *base) > > > > static inline void ftm_irq_acknowledge(void __iomem *base) { > > - u32 val; > > + unsigned long timeout = jiffies + msecs_to_jiffies(100); > > Do you expect the jiffies to be updated when we are in the timer irq handler ? > Oops, my bad. Will correct that using "for" loop. Thanks, Meng
[PATCH 3/4] f2fs: avoid gc in cp_error case
Otherwise, we can hit f2fs_bug_on(sbi, !PageUptodate(sum_page)); Signed-off-by: Jaegeuk Kim--- fs/f2fs/gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index a9a3c9f..b9d6c42 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -847,7 +847,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, for (segno = start_segno; segno < end_segno; segno++) { - if (get_valid_blocks(sbi, segno, 1) == 0) + if (get_valid_blocks(sbi, segno, 1) == 0 || + unlikely(f2fs_cp_error(sbi))) goto next; /* find segment summary of victim */ -- 2.8.3
[PATCH 3/4] f2fs: avoid gc in cp_error case
Otherwise, we can hit f2fs_bug_on(sbi, !PageUptodate(sum_page)); Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index a9a3c9f..b9d6c42 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -847,7 +847,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, for (segno = start_segno; segno < end_segno; segno++) { - if (get_valid_blocks(sbi, segno, 1) == 0) + if (get_valid_blocks(sbi, segno, 1) == 0 || + unlikely(f2fs_cp_error(sbi))) goto next; /* find segment summary of victim */ -- 2.8.3
[PATCH 1/4] f2fs: assign return value in f2fs_gc
This patch adds a return value of write_checkpoint for f2fs_gc. Signed-off-by: Jaegeuk Kim--- fs/f2fs/gc.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 24acbbb..400bc6d 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -925,10 +925,14 @@ gc_more: */ if (__get_victim(sbi, , gc_type) || prefree_segments(sbi)) { - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); + if (ret) + goto stop; segno = NULL_SEGNO; } else if (has_not_enough_free_secs(sbi, 0, 0)) { - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); + if (ret) + goto stop; } } @@ -948,7 +952,7 @@ gc_more: goto gc_more; if (gc_type == FG_GC) - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); } stop: mutex_unlock(>gc_mutex); -- 2.8.3
[PATCH 1/4] f2fs: assign return value in f2fs_gc
This patch adds a return value of write_checkpoint for f2fs_gc. Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 24acbbb..400bc6d 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -925,10 +925,14 @@ gc_more: */ if (__get_victim(sbi, , gc_type) || prefree_segments(sbi)) { - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); + if (ret) + goto stop; segno = NULL_SEGNO; } else if (has_not_enough_free_secs(sbi, 0, 0)) { - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); + if (ret) + goto stop; } } @@ -948,7 +952,7 @@ gc_more: goto gc_more; if (gc_type == FG_GC) - write_checkpoint(sbi, ); + ret = write_checkpoint(sbi, ); } stop: mutex_unlock(>gc_mutex); -- 2.8.3
[PATCH 2/4] f2fs: should put_page for summary page
We should call put_page for preloaded summary pages in do_garbage_collect. Signed-off-by: Jaegeuk Kim--- fs/f2fs/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 400bc6d..a9a3c9f 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -848,7 +848,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, for (segno = start_segno; segno < end_segno; segno++) { if (get_valid_blocks(sbi, segno, 1) == 0) - continue; + goto next; /* find segment summary of victim */ sum_page = find_get_page(META_MAPPING(sbi), @@ -874,7 +874,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, gc_type); stat_inc_seg_count(sbi, type, gc_type); - +next: f2fs_put_page(sum_page, 0); } -- 2.8.3
[PATCH 4/4] f2fs: handle errors during recover_orphan_inodes
This patch fixes to handle EIO during recover_orphan_inode() given the below panic. F2FS-fs : inject IO error in f2fs_read_end_io+0xe6/0x100 [f2fs] [ cut here ] RIP: 0010:[] [] f2fs_evict_inode+0x433/0x470 [f2fs] RSP: 0018:92f8b7fb7c30 EFLAGS: 00010246 RAX: 92fb88a13500 RBX: 92f890566ea0 RCX: fd3c255c RDX: 0001 RSI: 92fb88a13d90 RDI: 92fb8ee127e8 RBP: 92f8b7fb7c58 R08: 0001 R09: 92fb88a13d58 R10: 5a6a9373 R11: 0001 R12: fffb R13: 92fb8ee12000 R14: 34ca R15: 92fb8ee12620 FS: 7f1fefd8e880() GS:92fb9560() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7fc211d34cdb CR3: 00012d43a000 CR4: 001406e0 Stack: 92f890566ea0 92f890567078 c0b5a0c0 92f890566f28 92fb888b2000 92f8b7fb7c80 bc27ff55 92f890566ea0 92fb8bf1 c0b5a0c0 92f8b7fb7cb0 bc28090d Call Trace: [] evict+0xc5/0x1a0 [] iput+0x1ad/0x2c0 [] recover_orphan_inodes+0x10c/0x2e0 [f2fs] [] f2fs_fill_super+0x884/0x1150 [f2fs] [] mount_bdev+0x18c/0x1c0 [] ? f2fs_commit_super+0x100/0x100 [f2fs] [] f2fs_mount+0x15/0x20 [f2fs] [] mount_fs+0x39/0x170 [] vfs_kern_mount+0x6b/0x160 [] do_mount+0x1cf/0xd00 [] ? copy_mount_options+0xac/0x170 [] SyS_mount+0x83/0xd0 [] entry_SYSCALL_64_fastpath+0x23/0xc1 Signed-off-by: Jaegeuk Kim--- fs/f2fs/checkpoint.c | 27 +-- fs/f2fs/super.c | 1 + 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index cd9fd7b..d1560bb 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -535,6 +535,17 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) { struct inode *inode; struct node_info ni; + int err = acquire_orphan_inode(sbi); + + if (err) { + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_msg(sbi->sb, KERN_WARNING, + "%s: orphan failed (ino=%x), run fsck to fix.", + __func__, ino); + return err; + } + + __add_ino_entry(sbi, ino, ORPHAN_INO); inode = f2fs_iget_retry(sbi->sb, ino); if (IS_ERR(inode)) { @@ -555,17 +566,13 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) /* ENOMEM was fully retried in f2fs_evict_inode. */ if (ni.blk_addr != NULL_ADDR) { - int err = acquire_orphan_inode(sbi); - - if (err) { - set_sbi_flag(sbi, SBI_NEED_FSCK); - f2fs_msg(sbi->sb, KERN_WARNING, - "%s: orphan failed (ino=%x), run fsck to fix.", - __func__, ino); - return err; - } - __add_ino_entry(sbi, ino, ORPHAN_INO); + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_msg(sbi->sb, KERN_WARNING, + "%s: orphan failed (ino=%x), run fsck to fix.", + __func__, ino); + return -EIO; } + __remove_ino_entry(sbi, ino, ORPHAN_INO); return 0; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 95986a9..e7bb153 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1893,6 +1893,7 @@ free_root_inode: sb->s_root = NULL; free_node_inode: mutex_lock(>umount_mutex); + release_ino_entry(sbi, true); f2fs_leave_shrinker(sbi); iput(sbi->node_inode); mutex_unlock(>umount_mutex); -- 2.8.3
[PATCH 2/4] f2fs: should put_page for summary page
We should call put_page for preloaded summary pages in do_garbage_collect. Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 400bc6d..a9a3c9f 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -848,7 +848,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, for (segno = start_segno; segno < end_segno; segno++) { if (get_valid_blocks(sbi, segno, 1) == 0) - continue; + goto next; /* find segment summary of victim */ sum_page = find_get_page(META_MAPPING(sbi), @@ -874,7 +874,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, gc_type); stat_inc_seg_count(sbi, type, gc_type); - +next: f2fs_put_page(sum_page, 0); } -- 2.8.3
[PATCH 4/4] f2fs: handle errors during recover_orphan_inodes
This patch fixes to handle EIO during recover_orphan_inode() given the below panic. F2FS-fs : inject IO error in f2fs_read_end_io+0xe6/0x100 [f2fs] [ cut here ] RIP: 0010:[] [] f2fs_evict_inode+0x433/0x470 [f2fs] RSP: 0018:92f8b7fb7c30 EFLAGS: 00010246 RAX: 92fb88a13500 RBX: 92f890566ea0 RCX: fd3c255c RDX: 0001 RSI: 92fb88a13d90 RDI: 92fb8ee127e8 RBP: 92f8b7fb7c58 R08: 0001 R09: 92fb88a13d58 R10: 5a6a9373 R11: 0001 R12: fffb R13: 92fb8ee12000 R14: 34ca R15: 92fb8ee12620 FS: 7f1fefd8e880() GS:92fb9560() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7fc211d34cdb CR3: 00012d43a000 CR4: 001406e0 Stack: 92f890566ea0 92f890567078 c0b5a0c0 92f890566f28 92fb888b2000 92f8b7fb7c80 bc27ff55 92f890566ea0 92fb8bf1 c0b5a0c0 92f8b7fb7cb0 bc28090d Call Trace: [] evict+0xc5/0x1a0 [] iput+0x1ad/0x2c0 [] recover_orphan_inodes+0x10c/0x2e0 [f2fs] [] f2fs_fill_super+0x884/0x1150 [f2fs] [] mount_bdev+0x18c/0x1c0 [] ? f2fs_commit_super+0x100/0x100 [f2fs] [] f2fs_mount+0x15/0x20 [f2fs] [] mount_fs+0x39/0x170 [] vfs_kern_mount+0x6b/0x160 [] do_mount+0x1cf/0xd00 [] ? copy_mount_options+0xac/0x170 [] SyS_mount+0x83/0xd0 [] entry_SYSCALL_64_fastpath+0x23/0xc1 Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 27 +-- fs/f2fs/super.c | 1 + 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index cd9fd7b..d1560bb 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -535,6 +535,17 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) { struct inode *inode; struct node_info ni; + int err = acquire_orphan_inode(sbi); + + if (err) { + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_msg(sbi->sb, KERN_WARNING, + "%s: orphan failed (ino=%x), run fsck to fix.", + __func__, ino); + return err; + } + + __add_ino_entry(sbi, ino, ORPHAN_INO); inode = f2fs_iget_retry(sbi->sb, ino); if (IS_ERR(inode)) { @@ -555,17 +566,13 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) /* ENOMEM was fully retried in f2fs_evict_inode. */ if (ni.blk_addr != NULL_ADDR) { - int err = acquire_orphan_inode(sbi); - - if (err) { - set_sbi_flag(sbi, SBI_NEED_FSCK); - f2fs_msg(sbi->sb, KERN_WARNING, - "%s: orphan failed (ino=%x), run fsck to fix.", - __func__, ino); - return err; - } - __add_ino_entry(sbi, ino, ORPHAN_INO); + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_msg(sbi->sb, KERN_WARNING, + "%s: orphan failed (ino=%x), run fsck to fix.", + __func__, ino); + return -EIO; } + __remove_ino_entry(sbi, ino, ORPHAN_INO); return 0; } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 95986a9..e7bb153 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1893,6 +1893,7 @@ free_root_inode: sb->s_root = NULL; free_node_inode: mutex_lock(>umount_mutex); + release_ino_entry(sbi, true); f2fs_leave_shrinker(sbi); iput(sbi->node_inode); mutex_unlock(>umount_mutex); -- 2.8.3
net/sunrpc/stats.c:204: undefined reference to `_GLOBAL_OFFSET_TABLE_'
Hi Nicolas, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 7d1e042314619115153a0f6f06e4552c09a50e13 commit: 461a5e51060c93f5844113f4be9dba513cc92830 do_div(): generic optimization for constant divisor on 32-bit machines date: 10 months ago config: microblaze-mmu_defconfig (attached as .config) compiler: microblaze-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 461a5e51060c93f5844113f4be9dba513cc92830 # save the attached .config to linux build tree make.cross ARCH=microblaze All errors (new ones prefixed by >>): net/built-in.o: In function `rpc_print_iostats': >> net/sunrpc/stats.c:204: undefined reference to `_GLOBAL_OFFSET_TABLE_' scripts/link-vmlinux.sh: line 52: 5714 Segmentation fault ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds} ${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} vim +204 net/sunrpc/stats.c 840210fc Weston Andros Adamson 2014-06-24 188 [task->tk_msg.rpc_proc->p_statidx]); 840210fc Weston Andros Adamson 2014-06-24 189 } 0a702195 Weston Andros Adamson 2012-02-17 190 EXPORT_SYMBOL_GPL(rpc_count_iostats); 11c556b3 Chuck Lever 2006-03-20 191 ec535ce1 Adrian Bunk 2006-04-18 192 static void _print_name(struct seq_file *seq, unsigned int op, ec535ce1 Adrian Bunk 2006-04-18 193 struct rpc_procinfo *procs) cc0175c1 Chuck Lever 2006-03-20 194 { cc0175c1 Chuck Lever 2006-03-20 195 if (procs[op].p_name) cc0175c1 Chuck Lever 2006-03-20 196 seq_printf(seq, "\t%12s: ", procs[op].p_name); cc0175c1 Chuck Lever 2006-03-20 197 else if (op == 0) cc0175c1 Chuck Lever 2006-03-20 198 seq_printf(seq, "\tNULL: "); cc0175c1 Chuck Lever 2006-03-20 199 else cc0175c1 Chuck Lever 2006-03-20 200 seq_printf(seq, "\t%12u: ", op); cc0175c1 Chuck Lever 2006-03-20 201 } cc0175c1 Chuck Lever 2006-03-20 202 11c556b3 Chuck Lever 2006-03-20 203 void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) 11c556b3 Chuck Lever 2006-03-20 @204 { 11c556b3 Chuck Lever 2006-03-20 205 struct rpc_iostats *stats = clnt->cl_metrics; 2446ab60 Trond Myklebust 2012-03-01 206 struct rpc_xprt *xprt; 11c556b3 Chuck Lever 2006-03-20 207 unsigned int op, maxproc = clnt->cl_maxproc; 11c556b3 Chuck Lever 2006-03-20 208 11c556b3 Chuck Lever 2006-03-20 209 if (!stats) 11c556b3 Chuck Lever 2006-03-20 210 return; 11c556b3 Chuck Lever 2006-03-20 211 11c556b3 Chuck Lever 2006-03-20 212 seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS); :: The code at line 204 was first introduced by commit :: 11c556b3d8d481829ab5f9933a25d29b00913b5a SUNRPC: provide a mechanism for collecting stats in the RPC client :: TO: Chuck Lever:: CC: Trond Myklebust --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
net/sunrpc/stats.c:204: undefined reference to `_GLOBAL_OFFSET_TABLE_'
Hi Nicolas, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 7d1e042314619115153a0f6f06e4552c09a50e13 commit: 461a5e51060c93f5844113f4be9dba513cc92830 do_div(): generic optimization for constant divisor on 32-bit machines date: 10 months ago config: microblaze-mmu_defconfig (attached as .config) compiler: microblaze-linux-gcc (GCC) 6.2.0 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 461a5e51060c93f5844113f4be9dba513cc92830 # save the attached .config to linux build tree make.cross ARCH=microblaze All errors (new ones prefixed by >>): net/built-in.o: In function `rpc_print_iostats': >> net/sunrpc/stats.c:204: undefined reference to `_GLOBAL_OFFSET_TABLE_' scripts/link-vmlinux.sh: line 52: 5714 Segmentation fault ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} -T ${lds} ${KBUILD_VMLINUX_INIT} --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} vim +204 net/sunrpc/stats.c 840210fc Weston Andros Adamson 2014-06-24 188 [task->tk_msg.rpc_proc->p_statidx]); 840210fc Weston Andros Adamson 2014-06-24 189 } 0a702195 Weston Andros Adamson 2012-02-17 190 EXPORT_SYMBOL_GPL(rpc_count_iostats); 11c556b3 Chuck Lever 2006-03-20 191 ec535ce1 Adrian Bunk 2006-04-18 192 static void _print_name(struct seq_file *seq, unsigned int op, ec535ce1 Adrian Bunk 2006-04-18 193 struct rpc_procinfo *procs) cc0175c1 Chuck Lever 2006-03-20 194 { cc0175c1 Chuck Lever 2006-03-20 195 if (procs[op].p_name) cc0175c1 Chuck Lever 2006-03-20 196 seq_printf(seq, "\t%12s: ", procs[op].p_name); cc0175c1 Chuck Lever 2006-03-20 197 else if (op == 0) cc0175c1 Chuck Lever 2006-03-20 198 seq_printf(seq, "\tNULL: "); cc0175c1 Chuck Lever 2006-03-20 199 else cc0175c1 Chuck Lever 2006-03-20 200 seq_printf(seq, "\t%12u: ", op); cc0175c1 Chuck Lever 2006-03-20 201 } cc0175c1 Chuck Lever 2006-03-20 202 11c556b3 Chuck Lever 2006-03-20 203 void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) 11c556b3 Chuck Lever 2006-03-20 @204 { 11c556b3 Chuck Lever 2006-03-20 205 struct rpc_iostats *stats = clnt->cl_metrics; 2446ab60 Trond Myklebust 2012-03-01 206 struct rpc_xprt *xprt; 11c556b3 Chuck Lever 2006-03-20 207 unsigned int op, maxproc = clnt->cl_maxproc; 11c556b3 Chuck Lever 2006-03-20 208 11c556b3 Chuck Lever 2006-03-20 209 if (!stats) 11c556b3 Chuck Lever 2006-03-20 210 return; 11c556b3 Chuck Lever 2006-03-20 211 11c556b3 Chuck Lever 2006-03-20 212 seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS); :: The code at line 204 was first introduced by commit :: 11c556b3d8d481829ab5f9933a25d29b00913b5a SUNRPC: provide a mechanism for collecting stats in the RPC client :: TO: Chuck Lever :: CC: Trond Myklebust --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH] KVM: nVMX: Fix the NMI IDT-vectoring info handling
From: Wanpeng LiRun kvm-unit-tests/eventinj.flat in L1: Sending NMI to self After NMI to self FAIL: NMI This test scenario is to test whether VMM can handle NMI IDT-vectoring info correctly. At the beginning, L2 writes LAPIC to send a self NMI, the EPT page tables on both L1 and L0 are empty so: - The L2 accesses memory can generate EPT violation which can be intercepted by L0. The EPT violation vmexit occurred during delivery of this NMI, and the NMI info is recorded in vmcs02's IDT-vectoring info. - L0 walks L1's EPT12 and L0 sees the mapping is invalid, it injects the EPT violation into L1. The vmcs02's IDT-vectoring info is reflected to vmcs12's IDT-vectoring info since it is a nested vmexit. - L1 receives the EPT violation, then fixes its EPT12. - L1 executes VMRESUME to resume L2 which generates vmexit and causes L1 exits to L0. - L0 emulates VMRESUME which is called from L1, then return to L2. L0 merges the requirement of vmcs12's IDT-vectoring info and injects it to L2 through vmcs02. - The L2 re-executes the fault instruction and cause EPT violation again. - Since the L1's EPT12 is valid, L0 can fix its EPT02 - L0 resume L2 The EPT violation vmexit occurred during delivery of this NMI again, and the NMI info is recorded in vmcs02's IDT-vectoring info. L0 should inject the NMI through vmentry event injection since it is caused by EPT02's EPT violation. However, vmx_inject_nmi() refuses to inject NMI from IDT-vectoring info if vCPU is in guest mode, this patch fix it by permitting to inject NMI from IDT-vectoring if it is the L0's responsibility to inject NMI from IDT-vectoring info to L2. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Jan Kiszka Cc: Bandan Das Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 41 - 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 813658d..c883d73 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5309,28 +5309,27 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - if (is_guest_mode(vcpu)) - return; - - if (!cpu_has_virtual_nmis()) { - /* -* Tracking the NMI-blocked state in software is built upon -* finding the next open IRQ window. This, in turn, depends on -* well-behaving guests: They have to keep IRQs disabled at -* least as long as the NMI handler runs. Otherwise we may -* cause NMI nesting, maybe breaking the guest. But as this is -* highly unlikely, we can live with the residual risk. -*/ - vmx->soft_vnmi_blocked = 1; - vmx->vnmi_blocked_time = 0; - } + if (!is_guest_mode(vcpu)) { + if (!cpu_has_virtual_nmis()) { + /* +* Tracking the NMI-blocked state in software is built upon +* finding the next open IRQ window. This, in turn, depends on +* well-behaving guests: They have to keep IRQs disabled at +* least as long as the NMI handler runs. Otherwise we may +* cause NMI nesting, maybe breaking the guest. But as this is +* highly unlikely, we can live with the residual risk. +*/ + vmx->soft_vnmi_blocked = 1; + vmx->vnmi_blocked_time = 0; + } - ++vcpu->stat.nmi_injections; - vmx->nmi_known_unmasked = false; - if (vmx->rmode.vm86_active) { - if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE) - kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); - return; + ++vcpu->stat.nmi_injections; + vmx->nmi_known_unmasked = false; + if (vmx->rmode.vm86_active) { + if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE) + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); + return; + } } vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR); -- 1.9.1
[PATCH] KVM: nVMX: Fix the NMI IDT-vectoring info handling
From: Wanpeng Li Run kvm-unit-tests/eventinj.flat in L1: Sending NMI to self After NMI to self FAIL: NMI This test scenario is to test whether VMM can handle NMI IDT-vectoring info correctly. At the beginning, L2 writes LAPIC to send a self NMI, the EPT page tables on both L1 and L0 are empty so: - The L2 accesses memory can generate EPT violation which can be intercepted by L0. The EPT violation vmexit occurred during delivery of this NMI, and the NMI info is recorded in vmcs02's IDT-vectoring info. - L0 walks L1's EPT12 and L0 sees the mapping is invalid, it injects the EPT violation into L1. The vmcs02's IDT-vectoring info is reflected to vmcs12's IDT-vectoring info since it is a nested vmexit. - L1 receives the EPT violation, then fixes its EPT12. - L1 executes VMRESUME to resume L2 which generates vmexit and causes L1 exits to L0. - L0 emulates VMRESUME which is called from L1, then return to L2. L0 merges the requirement of vmcs12's IDT-vectoring info and injects it to L2 through vmcs02. - The L2 re-executes the fault instruction and cause EPT violation again. - Since the L1's EPT12 is valid, L0 can fix its EPT02 - L0 resume L2 The EPT violation vmexit occurred during delivery of this NMI again, and the NMI info is recorded in vmcs02's IDT-vectoring info. L0 should inject the NMI through vmentry event injection since it is caused by EPT02's EPT violation. However, vmx_inject_nmi() refuses to inject NMI from IDT-vectoring info if vCPU is in guest mode, this patch fix it by permitting to inject NMI from IDT-vectoring if it is the L0's responsibility to inject NMI from IDT-vectoring info to L2. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Jan Kiszka Cc: Bandan Das Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 41 - 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 813658d..c883d73 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5309,28 +5309,27 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); - if (is_guest_mode(vcpu)) - return; - - if (!cpu_has_virtual_nmis()) { - /* -* Tracking the NMI-blocked state in software is built upon -* finding the next open IRQ window. This, in turn, depends on -* well-behaving guests: They have to keep IRQs disabled at -* least as long as the NMI handler runs. Otherwise we may -* cause NMI nesting, maybe breaking the guest. But as this is -* highly unlikely, we can live with the residual risk. -*/ - vmx->soft_vnmi_blocked = 1; - vmx->vnmi_blocked_time = 0; - } + if (!is_guest_mode(vcpu)) { + if (!cpu_has_virtual_nmis()) { + /* +* Tracking the NMI-blocked state in software is built upon +* finding the next open IRQ window. This, in turn, depends on +* well-behaving guests: They have to keep IRQs disabled at +* least as long as the NMI handler runs. Otherwise we may +* cause NMI nesting, maybe breaking the guest. But as this is +* highly unlikely, we can live with the residual risk. +*/ + vmx->soft_vnmi_blocked = 1; + vmx->vnmi_blocked_time = 0; + } - ++vcpu->stat.nmi_injections; - vmx->nmi_known_unmasked = false; - if (vmx->rmode.vm86_active) { - if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE) - kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); - return; + ++vcpu->stat.nmi_injections; + vmx->nmi_known_unmasked = false; + if (vmx->rmode.vm86_active) { + if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE) + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); + return; + } } vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR); -- 1.9.1
Re: [PATCH 5/5] arm64: Add uprobe support
On 21/09/2016:06:04:04 PM, Catalin Marinas wrote: > On Wed, Sep 21, 2016 at 04:30:47PM +0530, Pratyush Anand wrote: > > On 20/09/2016:05:59:46 PM, Catalin Marinas wrote: > > > > +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct > > > > mm_struct *mm, > > > > + unsigned long addr) > > > > +{ > > > > + probe_opcode_t insn; > > > > + > > > > + /* TODO: Currently we do not support AARCH32 instruction > > > > probing */ > > > > > > Is there a way to check (not necessarily in this file) that we don't > > > probe 32-bit tasks? > > > > - Well, I do not have complete idea about it that, how it can be done. I > > think > > we can not check that just by looking a single bit in an instruction. > > My understanding is that, we can only know about it when we are executing > > the > > instruction, by reading pstate, but that would not be useful for uprobe > > instruction analysis. > > > > I hope, instruction encoding for aarch32 and aarch64 are different, and by > > analyzing for all types of aarch32 instructions, we will be able to decide > > that whether instruction is 32 bit trace-able or not. Accordingly, we > > can use > > either BRK or BKPT instruction for breakpoint generation. > > We may have some unrelated instruction encoding overlapping but I > haven't checked. I was more thinking about whether we know which task is > being probed and check is_compat_task() or maybe using > compat_user_mode(regs). I had thought of this, but problem is that we might not have task in existence when we enable uprobes. For example: Lets say we are inserting a trace probe at offset 0x690 in a executable binary. echo "p test:0x690" > /sys/kernel/debug/tracing/uprobe_events echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable In the 'enable' step, it is decided that whether instruction is traceable or not. (1) But at this point 'test' executable might not be running. (2) Even if it is running, is_compat_task() or compat_user_mode() might not be usable, as they work with 'current' task. What I was thinking that, let it go with 'TODO' as of now. Later on, we propose some changes in core layer, so that we can read the elf headers of executable binary. ELFCLASS will be able to tell us, whether its a 32 bit or 64 bit executable. I think, moving "struct uprobe" from kernel/events/uprobes.c to a include/linux header file will do the job. "struct arch_uprobe" is part of "struct uprobe". "struct arch_uprobe" is passed in arch_uprobe_analyze_insn(). So, we can access struct uprobe's "inode" element with this change. ~Pratyush
Re: [PATCH 5/5] arm64: Add uprobe support
On 21/09/2016:06:04:04 PM, Catalin Marinas wrote: > On Wed, Sep 21, 2016 at 04:30:47PM +0530, Pratyush Anand wrote: > > On 20/09/2016:05:59:46 PM, Catalin Marinas wrote: > > > > +int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct > > > > mm_struct *mm, > > > > + unsigned long addr) > > > > +{ > > > > + probe_opcode_t insn; > > > > + > > > > + /* TODO: Currently we do not support AARCH32 instruction > > > > probing */ > > > > > > Is there a way to check (not necessarily in this file) that we don't > > > probe 32-bit tasks? > > > > - Well, I do not have complete idea about it that, how it can be done. I > > think > > we can not check that just by looking a single bit in an instruction. > > My understanding is that, we can only know about it when we are executing > > the > > instruction, by reading pstate, but that would not be useful for uprobe > > instruction analysis. > > > > I hope, instruction encoding for aarch32 and aarch64 are different, and by > > analyzing for all types of aarch32 instructions, we will be able to decide > > that whether instruction is 32 bit trace-able or not. Accordingly, we > > can use > > either BRK or BKPT instruction for breakpoint generation. > > We may have some unrelated instruction encoding overlapping but I > haven't checked. I was more thinking about whether we know which task is > being probed and check is_compat_task() or maybe using > compat_user_mode(regs). I had thought of this, but problem is that we might not have task in existence when we enable uprobes. For example: Lets say we are inserting a trace probe at offset 0x690 in a executable binary. echo "p test:0x690" > /sys/kernel/debug/tracing/uprobe_events echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable In the 'enable' step, it is decided that whether instruction is traceable or not. (1) But at this point 'test' executable might not be running. (2) Even if it is running, is_compat_task() or compat_user_mode() might not be usable, as they work with 'current' task. What I was thinking that, let it go with 'TODO' as of now. Later on, we propose some changes in core layer, so that we can read the elf headers of executable binary. ELFCLASS will be able to tell us, whether its a 32 bit or 64 bit executable. I think, moving "struct uprobe" from kernel/events/uprobes.c to a include/linux header file will do the job. "struct arch_uprobe" is part of "struct uprobe". "struct arch_uprobe" is passed in arch_uprobe_analyze_insn(). So, we can access struct uprobe's "inode" element with this change. ~Pratyush
Re: [BUG] perf report --pid not reporting correctly
On Wed, Sep 21, 2016 at 07:22:29PM -0700, Stephane Eranian wrote: > On Wed, Sep 21, 2016 at 6:34 PM, Namhyung Kimwrote: > > On Wed, Sep 21, 2016 at 01:18:52PM -0700, Stephane Eranian wrote: > >> On Wed, Sep 21, 2016 at 9:34 AM, Jiri Olsa wrote: > >> > On Wed, Sep 21, 2016 at 12:37:53PM -0300, Arnaldo Carvalho de Melo wrote: > >> >> Em Tue, Sep 20, 2016 at 06:29:59PM -0700, Stephane Eranian escreveu: > >> >> > Hi Arnaldo, > >> >> > > >> >> > I ran into an issue trying to use the --pid filtering option of perf > >> >> > report. > >> >> > > >> >> > I do a system-wide collection and then I want to narrow down the > >> >> > reporting to a specific process: > >> >> > > >> >> > $ perf record -a -e cycles:pp sleep 10 > >> >> > $ perf report --sort cpu,comm --pid X > >> >> > > >> >> > Where X is a process sampled during the run (easy to catch with perf > >> >> > report -D) > >> >> > If you do it this way, it works, but if you do: > >> >> > > >> >> > $ perf report --sort cpu --pid X > >> >> > > >> >> > Then you get an empty output. > >> >> > > >> >> > I suspect it has to do with the way hist entries are added to the > >> >> > histogram and aggregated. If the first event for a sort criteria is > >> >> > not coming from pid X, it will > >> >> > still be added in the histogram. if pid X aggregates to the same > >> >> > sample criteria, then you will lose the pid information. And then > >> >> > later when you try to apply the filter, > >> >> > it will mark the hist entry as FILTERED because it does not have a > >> >> > matching pid > >> >> > and nothing will be printed. > >> >> > I suspect you want to apply the filtering upfront for pid. It will > >> >> > only add to the histograms matching samples. It changes the > >> >> > percentages you will see. They will > >> >> > only report the breakdown for the pid. > >> >> > > >> >> > I have a quick hack to do upfront filtering which does something as > >> >> > follows but I am not sure this is the correct way of doing this. > >> >> > > >> >> > Let me know what you think. > >> >> > >> >> From a first look I think this makes sense, i.e. we should do the first > >> >> round of filtering, one that trows away stuff, for things in the command > >> >> line, when creating the histogram entries. > >> >> > >> >> Later, as we have now, we can apply further filters for non-collapsed > >> >> fields of hist_entry. > >> >> > >> >> Jiri, Namhyung, are you ok with this? > >> > > >> > Stephan is correct with analysis, but I think we need to add both > >> > non/filtered > >> > entries in, because we provide that 'F' key for non/filtered counts > >> > switch in tui > >> > > >> > how about something like below > >> > > >> > thanks, > >> > jirka > >> > > >> > --- > >> > diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c > >> > index b02992efb513..659e0357be68 100644 > >> > --- a/tools/perf/util/hist.c > >> > +++ b/tools/perf/util/hist.c > >> > @@ -536,6 +536,14 @@ static struct hist_entry > >> > *hists__findnew_entry(struct hists *hists, > >> > map__put(he->ms.map); > >> > he->ms.map = map__get(entry->ms.map); > >> > } > >> > + > >> > + /* > >> > +* We have at least one entry in which is not > >> > +* filtered, we want to display the entry. > >> > +*/ > >> > + if (he->filtered && !entry->filtered) > >> > + he->filtered = 0; > >> > + > >> > goto out; > >> > } > >> > > >> Works for me. So with this approach the % shown with --pid still > >> represents % of total samples and not just for that pid. > >> I think this is okay as long as this is documented and understood by users. > >> Thanks. > > > > I think we should show correct value depending on the --percentage > > option. I wrote a patch to implement it by addding a > > total_early_filtered_period stat to hists. Following is the result: > > > > > > $ perf report -s cpu,comm --pid 0 --stdio > > # > > # Overhead CPU Command > > # ... ... > > # > > 12.16% 000 swapper > >3.09% 001 swapper > >2.76% 002 swapper > >2.23% 003 swapper > >1.65% 007 swapper > >1.65% 008 swapper > >1.52% 009 swapper > >1.51% 006 swapper > >1.46% 004 swapper > >1.34% 005 swapper > >0.94% 010 swapper > >0.90% 011 swapper > > > So how do I interpret this? > > Is this that 12.16% of all samples comes from pid 0 (swapper) running on > CPU0? Yep, it's same when no filter used. $ perf report -s cpu,comm | grep swapper 12.16% 000 swapper 3.09% 001 swapper 2.76% 002 swapper 2.23% 003 swapper 1.65% 007 swapper 1.65%
Re: [BUG] perf report --pid not reporting correctly
On Wed, Sep 21, 2016 at 07:22:29PM -0700, Stephane Eranian wrote: > On Wed, Sep 21, 2016 at 6:34 PM, Namhyung Kim wrote: > > On Wed, Sep 21, 2016 at 01:18:52PM -0700, Stephane Eranian wrote: > >> On Wed, Sep 21, 2016 at 9:34 AM, Jiri Olsa wrote: > >> > On Wed, Sep 21, 2016 at 12:37:53PM -0300, Arnaldo Carvalho de Melo wrote: > >> >> Em Tue, Sep 20, 2016 at 06:29:59PM -0700, Stephane Eranian escreveu: > >> >> > Hi Arnaldo, > >> >> > > >> >> > I ran into an issue trying to use the --pid filtering option of perf > >> >> > report. > >> >> > > >> >> > I do a system-wide collection and then I want to narrow down the > >> >> > reporting to a specific process: > >> >> > > >> >> > $ perf record -a -e cycles:pp sleep 10 > >> >> > $ perf report --sort cpu,comm --pid X > >> >> > > >> >> > Where X is a process sampled during the run (easy to catch with perf > >> >> > report -D) > >> >> > If you do it this way, it works, but if you do: > >> >> > > >> >> > $ perf report --sort cpu --pid X > >> >> > > >> >> > Then you get an empty output. > >> >> > > >> >> > I suspect it has to do with the way hist entries are added to the > >> >> > histogram and aggregated. If the first event for a sort criteria is > >> >> > not coming from pid X, it will > >> >> > still be added in the histogram. if pid X aggregates to the same > >> >> > sample criteria, then you will lose the pid information. And then > >> >> > later when you try to apply the filter, > >> >> > it will mark the hist entry as FILTERED because it does not have a > >> >> > matching pid > >> >> > and nothing will be printed. > >> >> > I suspect you want to apply the filtering upfront for pid. It will > >> >> > only add to the histograms matching samples. It changes the > >> >> > percentages you will see. They will > >> >> > only report the breakdown for the pid. > >> >> > > >> >> > I have a quick hack to do upfront filtering which does something as > >> >> > follows but I am not sure this is the correct way of doing this. > >> >> > > >> >> > Let me know what you think. > >> >> > >> >> From a first look I think this makes sense, i.e. we should do the first > >> >> round of filtering, one that trows away stuff, for things in the command > >> >> line, when creating the histogram entries. > >> >> > >> >> Later, as we have now, we can apply further filters for non-collapsed > >> >> fields of hist_entry. > >> >> > >> >> Jiri, Namhyung, are you ok with this? > >> > > >> > Stephan is correct with analysis, but I think we need to add both > >> > non/filtered > >> > entries in, because we provide that 'F' key for non/filtered counts > >> > switch in tui > >> > > >> > how about something like below > >> > > >> > thanks, > >> > jirka > >> > > >> > --- > >> > diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c > >> > index b02992efb513..659e0357be68 100644 > >> > --- a/tools/perf/util/hist.c > >> > +++ b/tools/perf/util/hist.c > >> > @@ -536,6 +536,14 @@ static struct hist_entry > >> > *hists__findnew_entry(struct hists *hists, > >> > map__put(he->ms.map); > >> > he->ms.map = map__get(entry->ms.map); > >> > } > >> > + > >> > + /* > >> > +* We have at least one entry in which is not > >> > +* filtered, we want to display the entry. > >> > +*/ > >> > + if (he->filtered && !entry->filtered) > >> > + he->filtered = 0; > >> > + > >> > goto out; > >> > } > >> > > >> Works for me. So with this approach the % shown with --pid still > >> represents % of total samples and not just for that pid. > >> I think this is okay as long as this is documented and understood by users. > >> Thanks. > > > > I think we should show correct value depending on the --percentage > > option. I wrote a patch to implement it by addding a > > total_early_filtered_period stat to hists. Following is the result: > > > > > > $ perf report -s cpu,comm --pid 0 --stdio > > # > > # Overhead CPU Command > > # ... ... > > # > > 12.16% 000 swapper > >3.09% 001 swapper > >2.76% 002 swapper > >2.23% 003 swapper > >1.65% 007 swapper > >1.65% 008 swapper > >1.52% 009 swapper > >1.51% 006 swapper > >1.46% 004 swapper > >1.34% 005 swapper > >0.94% 010 swapper > >0.90% 011 swapper > > > So how do I interpret this? > > Is this that 12.16% of all samples comes from pid 0 (swapper) running on > CPU0? Yep, it's same when no filter used. $ perf report -s cpu,comm | grep swapper 12.16% 000 swapper 3.09% 001 swapper 2.76% 002 swapper 2.23% 003 swapper 1.65% 007 swapper 1.65% 008 swapper 1.52% 009
Re: [PATCH net-next v2 0/3] add support for RGMII on GMAC0 through TRGMII hardware module
Le 21/09/2016 à 19:33, sean.w...@mediatek.com a écrit : > From: Sean Wang> > By default, GMAC0 is connected to built-in switch called > MT7530 through the proprietary interface called Turbo RGMII > (TRGMII). TRGMII also supports well for RGMII as generic external > PHY uses but requires some slight changes to the setup of TRGMII > and doesn't have well support on current driver. > > So this patchset > 1) provides the slight changes of the setup for RGMII can work >through TRGMII > 2) adds additional setting "trgmii" as PHY_INTERFACE_MODE_TRGMII >about phy-mode on device tree to make GMAC0 distinguish which >mode it runs > 3) changes dynamically source clock, TX/RX delay and interface >mode on TRGMII for adapting various link > > Changes since v1: > - fixed the style of comment which doesn't have a space at >the beginning and end of comment lines > - add support for phy-mode "trgmii" as PHY_INTERFACE_MODE_TRGMII >into linux/phy.h > - enhance the Documentation about device tree binding for trgmii > which is applicable only for GMAC0 which uses fixed-link Looks good to me: Reviewed-by: Florian Fainelli Thanks Sean! -- Florian
Re: [PATCH net-next v2 0/3] add support for RGMII on GMAC0 through TRGMII hardware module
Le 21/09/2016 à 19:33, sean.w...@mediatek.com a écrit : > From: Sean Wang > > By default, GMAC0 is connected to built-in switch called > MT7530 through the proprietary interface called Turbo RGMII > (TRGMII). TRGMII also supports well for RGMII as generic external > PHY uses but requires some slight changes to the setup of TRGMII > and doesn't have well support on current driver. > > So this patchset > 1) provides the slight changes of the setup for RGMII can work >through TRGMII > 2) adds additional setting "trgmii" as PHY_INTERFACE_MODE_TRGMII >about phy-mode on device tree to make GMAC0 distinguish which >mode it runs > 3) changes dynamically source clock, TX/RX delay and interface >mode on TRGMII for adapting various link > > Changes since v1: > - fixed the style of comment which doesn't have a space at >the beginning and end of comment lines > - add support for phy-mode "trgmii" as PHY_INTERFACE_MODE_TRGMII >into linux/phy.h > - enhance the Documentation about device tree binding for trgmii > which is applicable only for GMAC0 which uses fixed-link Looks good to me: Reviewed-by: Florian Fainelli Thanks Sean! -- Florian
Re: [PATCH] arm64: Call numa_store_cpu_info() earlier.
On 2016/9/21 2:46, David Daney wrote: > From: David Daney> > Fix by moving call to numa_store_cpu_info() for all CPUs into > smp_prepare_cpus(), which happens before wq_numa_init(). Since > smp_store_cpu_info() now contains only a single function call, > simplify by removing the function and out-lining its contents. > > Suggested-by: Robert Richter > fixes: 1a2db300348b ("arm64, numa: Add NUMA support for arm64 platforms.") > Cc: # 4.7.x- > Signed-off-by: David Daney > --- Tested-by: Yisheng Xie Thanks. > arch/arm64/kernel/smp.c | 14 ++ > 1 file changed, 6 insertions(+), 8 deletions(-) > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index d93d433..3ff173e 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -201,12 +201,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) > return ret; > } > > -static void smp_store_cpu_info(unsigned int cpuid) > -{ > - store_cpu_topology(cpuid); > - numa_store_cpu_info(cpuid); > -} > - > /* > * This is the secondary CPU boot entry. We're using this CPUs > * idle thread stack, but a set of temporary page tables. > @@ -254,7 +248,7 @@ asmlinkage void secondary_start_kernel(void) >*/ > notify_cpu_starting(cpu); > > - smp_store_cpu_info(cpu); > + store_cpu_topology(cpu); > > /* >* OK, now it's safe to let the boot CPU continue. Wait for > @@ -689,10 +683,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > { > int err; > unsigned int cpu; > + unsigned int this_cpu; > > init_cpu_topology(); > > - smp_store_cpu_info(smp_processor_id()); > + this_cpu = smp_processor_id(); > + store_cpu_topology(this_cpu); > + numa_store_cpu_info(this_cpu); > > /* >* If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set > @@ -719,6 +716,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > continue; > > set_cpu_present(cpu, true); > + numa_store_cpu_info(cpu); > } > } > >
Re: [PATCH] arm64: Call numa_store_cpu_info() earlier.
On 2016/9/21 2:46, David Daney wrote: > From: David Daney > > Fix by moving call to numa_store_cpu_info() for all CPUs into > smp_prepare_cpus(), which happens before wq_numa_init(). Since > smp_store_cpu_info() now contains only a single function call, > simplify by removing the function and out-lining its contents. > > Suggested-by: Robert Richter > fixes: 1a2db300348b ("arm64, numa: Add NUMA support for arm64 platforms.") > Cc: # 4.7.x- > Signed-off-by: David Daney > --- Tested-by: Yisheng Xie Thanks. > arch/arm64/kernel/smp.c | 14 ++ > 1 file changed, 6 insertions(+), 8 deletions(-) > > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c > index d93d433..3ff173e 100644 > --- a/arch/arm64/kernel/smp.c > +++ b/arch/arm64/kernel/smp.c > @@ -201,12 +201,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) > return ret; > } > > -static void smp_store_cpu_info(unsigned int cpuid) > -{ > - store_cpu_topology(cpuid); > - numa_store_cpu_info(cpuid); > -} > - > /* > * This is the secondary CPU boot entry. We're using this CPUs > * idle thread stack, but a set of temporary page tables. > @@ -254,7 +248,7 @@ asmlinkage void secondary_start_kernel(void) >*/ > notify_cpu_starting(cpu); > > - smp_store_cpu_info(cpu); > + store_cpu_topology(cpu); > > /* >* OK, now it's safe to let the boot CPU continue. Wait for > @@ -689,10 +683,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > { > int err; > unsigned int cpu; > + unsigned int this_cpu; > > init_cpu_topology(); > > - smp_store_cpu_info(smp_processor_id()); > + this_cpu = smp_processor_id(); > + store_cpu_topology(this_cpu); > + numa_store_cpu_info(this_cpu); > > /* >* If UP is mandated by "nosmp" (which implies "maxcpus=0"), don't set > @@ -719,6 +716,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) > continue; > > set_cpu_present(cpu, true); > + numa_store_cpu_info(cpu); > } > } > >
Re: [PATCH v3 07/15] lockdep: Implement crossrelease feature
On Mon, Sep 19, 2016 at 10:50:09AM +0200, Peter Zijlstra wrote: > Clearly I'm still missing stuff... By the way.. do I have to explain more? Lack of explanation? It would be the best to consider 'all valid acquires', which can occur deadlock, but it looks impossible without parsing all code in head. So it would be the safest to rely on 'acquires which actually happened', even though it might be 'random acquires' among all valid acquires. This conservative appoach is exactly same as how original lockdep is doing. Let me explain more if you doubt it.
Re: [PATCH v3 07/15] lockdep: Implement crossrelease feature
On Mon, Sep 19, 2016 at 10:50:09AM +0200, Peter Zijlstra wrote: > Clearly I'm still missing stuff... By the way.. do I have to explain more? Lack of explanation? It would be the best to consider 'all valid acquires', which can occur deadlock, but it looks impossible without parsing all code in head. So it would be the safest to rely on 'acquires which actually happened', even though it might be 'random acquires' among all valid acquires. This conservative appoach is exactly same as how original lockdep is doing. Let me explain more if you doubt it.