mm/slub.o:undefined reference to `_GLOBAL_OFFSET_TABLE_'

2016-09-21 Thread kbuild test robot
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_'

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread xinhui

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

2016-09-21 Thread xinhui

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

2016-09-21 Thread David Miller
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] cxgb4: fix signed wrap around when decrementing index idx

2016-09-21 Thread David Miller
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread hejianet



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

2016-09-21 Thread hejianet



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()

2016-09-21 Thread Daeseok Youn
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()

2016-09-21 Thread Daeseok Youn
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()

2016-09-21 Thread Daeseok Youn
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()

2016-09-21 Thread Daeseok Youn
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()

2016-09-21 Thread Daeseok Youn
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()

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Daeseok Youn
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread Joonsoo Kim
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

2016-09-21 Thread Ravi Bangoria


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 v7 0/6] perf annotate: Cross arch support + few fixes

2016-09-21 Thread Ravi Bangoria


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

2016-09-21 Thread Greg KH
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

2016-09-21 Thread Greg KH
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

2016-09-21 Thread Kai Heng Feng
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] HID: alps: fix stick device not working after resume

2016-09-21 Thread Kai Heng Feng
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

2016-09-21 Thread Greg Kroah-Hartman
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

2016-09-21 Thread Greg Kroah-Hartman
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Meng Yi
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

2016-09-21 Thread Meng Yi
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Seung-Woo Kim
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

2016-09-21 Thread Seung-Woo Kim
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

2016-09-21 Thread Nicholas Piggin
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));   \

Re: [PATCH] percpu: improve generic percpu modify-return implementation

2016-09-21 Thread Nicholas Piggin
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

2016-09-21 Thread Nicholas Piggin
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.


Re: [PATCH] percpu: improve generic percpu modify-return implementation

2016-09-21 Thread Nicholas Piggin
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

2016-09-21 Thread Finn Thain

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" 


[PATCH] MAINTAINERS: Abandon pas16, dtc and t128 ISA card SCSI host adapter drivers

2016-09-21 Thread Finn Thain

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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Jaehoon Chung
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

2016-09-21 Thread Mike Galbraith
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

2016-09-21 Thread Mike Galbraith
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

2016-09-21 Thread Meng Yi

> > __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

2016-09-21 Thread Meng Yi

> > __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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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

2016-09-21 Thread Jaegeuk Kim
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_'

2016-09-21 Thread kbuild test robot
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_'

2016-09-21 Thread kbuild test robot
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

2016-09-21 Thread Wanpeng Li
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



[PATCH] KVM: nVMX: Fix the NMI IDT-vectoring info handling

2016-09-21 Thread Wanpeng Li
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

2016-09-21 Thread Pratyush Anand
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

2016-09-21 Thread Pratyush Anand
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

2016-09-21 Thread Namhyung Kim
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%  

Re: [BUG] perf report --pid not reporting correctly

2016-09-21 Thread Namhyung Kim
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

2016-09-21 Thread Florian Fainelli
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

2016-09-21 Thread Florian Fainelli
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.

2016-09-21 Thread Yisheng Xie


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.

2016-09-21 Thread Yisheng Xie


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

2016-09-21 Thread Byungchul Park
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

2016-09-21 Thread Byungchul Park
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.



  1   2   3   4   5   6   7   8   9   10   >