Re: [PATCH v2 2/2] lib/uuid.c: eliminate uuid_[bl]e_index arrays
Hi, [auto build test WARNING on v4.7-rc1] [cannot apply to next-20160603] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/George-Spelvin/Clean-up-and-shrink-uuid-input-output/20160604-131729 config: x86_64-lkp (attached as .config) compiler: gcc-4.9 (Debian 4.9.3-14) 4.9.3 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): lib/uuid.c: In function '__uuid_to_bin': >> lib/uuid.c:107:3: warning: ignoring return value of 'hex2bin', declared with >> attribute warn_unused_result [-Wunused-result] hex2bin(b + i, uuid + pos[i], 1); ^ vim +/hex2bin +107 lib/uuid.c 91 return true; 92 } 93 EXPORT_SYMBOL(uuid_is_valid); 94 95 /* For each binary byte, string offset in ASCII UUID where it appears */ 96 const u8 uuid_be_pos[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; 97 const u8 uuid_le_pos[16] = {6,4,2,0,11,9,16,14,19,21,24,26,28,30,32,34}; 98 99 static int __uuid_to_bin(const char uuid[36], __u8 b[16], const u8 pos[16]) 100 { 101 unsigned int i; 102 103 if (!uuid_is_valid(uuid)) 104 return -EINVAL; 105 106 for (i = 0; i < 16; i++) > 107 hex2bin(b + i, uuid + pos[i], 1); 108 109 return 0; 110 } 111 112 int uuid_le_to_bin(const char *uuid, uuid_le *u) 113 { 114 return __uuid_to_bin(uuid, u->b, uuid_le_pos); 115 } --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
Re: [PATCH v2 2/2] lib/uuid.c: eliminate uuid_[bl]e_index arrays
Hi, [auto build test WARNING on v4.7-rc1] [cannot apply to next-20160603] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/George-Spelvin/Clean-up-and-shrink-uuid-input-output/20160604-131729 config: x86_64-lkp (attached as .config) compiler: gcc-4.9 (Debian 4.9.3-14) 4.9.3 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): lib/uuid.c: In function '__uuid_to_bin': >> lib/uuid.c:107:3: warning: ignoring return value of 'hex2bin', declared with >> attribute warn_unused_result [-Wunused-result] hex2bin(b + i, uuid + pos[i], 1); ^ vim +/hex2bin +107 lib/uuid.c 91 return true; 92 } 93 EXPORT_SYMBOL(uuid_is_valid); 94 95 /* For each binary byte, string offset in ASCII UUID where it appears */ 96 const u8 uuid_be_pos[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; 97 const u8 uuid_le_pos[16] = {6,4,2,0,11,9,16,14,19,21,24,26,28,30,32,34}; 98 99 static int __uuid_to_bin(const char uuid[36], __u8 b[16], const u8 pos[16]) 100 { 101 unsigned int i; 102 103 if (!uuid_is_valid(uuid)) 104 return -EINVAL; 105 106 for (i = 0; i < 16; i++) > 107 hex2bin(b + i, uuid + pos[i], 1); 108 109 return 0; 110 } 111 112 int uuid_le_to_bin(const char *uuid, uuid_le *u) 113 { 114 return __uuid_to_bin(uuid, u->b, uuid_le_pos); 115 } --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
[PATCH] usb: gadget: bdc: fix spelling mistake: "allocted" -> "allocated"
From: Colin Ian Kingtrivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index d619950..b48b259 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -81,7 +81,7 @@ static void ep_bd_list_free(struct bdc_ep *ep, u32 num_tabs) continue; } if (!bd_table->start_bd) { - dev_dbg(bdc->dev, "bd dma pool not allocted\n"); + dev_dbg(bdc->dev, "bd dma pool not allocated\n"); continue; } -- 2.8.1
[PATCH] usb: gadget: bdc: fix spelling mistake: "allocted" -> "allocated"
From: Colin Ian King trivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/usb/gadget/udc/bdc/bdc_ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index d619950..b48b259 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -81,7 +81,7 @@ static void ep_bd_list_free(struct bdc_ep *ep, u32 num_tabs) continue; } if (!bd_table->start_bd) { - dev_dbg(bdc->dev, "bd dma pool not allocted\n"); + dev_dbg(bdc->dev, "bd dma pool not allocated\n"); continue; } -- 2.8.1
Re: [PATCH v9 00/14] Add support for remote unwind
在 2016/6/4 5:09, Arnaldo Carvalho de Melo 写道: Em Fri, Jun 03, 2016 at 06:06:02PM -0300, Arnaldo Carvalho de Melo escreveu: Em Fri, Jun 03, 2016 at 04:42:05PM -0300, Arnaldo Carvalho de Melo escreveu: Em Fri, Jun 03, 2016 at 09:06:29AM +0200, Jiri Olsa escreveu: On Fri, Jun 03, 2016 at 03:33:09AM +, He Kuang wrote: v9: - Change function unwind__register_ops() to static. - Move up unwind__prepare_access() in thread__insert_map() and save map_groups__remove() call. - Enclose multiple line if/else into braces. - Fix miss modified function declaration for unwind__prepare_access() in patch 10. for patchset: Acked-by: Jiri OlsaThanks, applied, build testing. Build tested went ok, but then 'perf top' crashes: [root@jouet ~]# perf top perf: Segmentation fault backtrace perf[0x55591b] /lib64/libc.so.6(+0x34ab0)[0x7f38ad9c1ab0] perf(normalize_arch+0x27)[0x534797] perf(unwind__prepare_access+0xbb)[0x52b15b] perf(thread__insert_map+0x27)[0x4d4837] perf(machine__process_mmap2_event+0xd7)[0x4ca187] perf(perf_event__synthesize_mmap_events+0x3e2)[0x491b32] perf(perf_event__synthesize_threads+0x445)[0x492635] perf(cmd_top+0xee0)[0x442f50] perf[0x486a91] perf(main+0x6ee)[0x42485e] /lib64/libc.so.6(__libc_start_main+0xf0)[0x7f38ad9ad580] perf(_start+0x29)[0x424949] [0x0] [root@jouet ~]# And I bet that 'perf trace' will too, lemme see, well, it crashes even more spetacularly, but that is the topic of another bug report, will send soon. Anyway, please try your patchkit with 'perf top' and 'perf trace', as both don't use perf.data files, i.e. they work 'live', so probably things that you touch in normalize_arch() are not initialized and need to be setup. Ah, no need to resend the whole patchkit, just find out what is the bug and send me a patch and I'll insert it at the right point to avoid introducing a bisect breaking point. Your patchkit is in my perf/unwind branch at my tree, I already added Jiri's Acked-by in all the patches. git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git Thanks, - Arnaldo - I send the updated one after PATCH 10/14, env->arch is null in live mode, comments are added and "perf top/trace" works now. Thanks.
Re: [PATCH v9 00/14] Add support for remote unwind
在 2016/6/4 5:09, Arnaldo Carvalho de Melo 写道: Em Fri, Jun 03, 2016 at 06:06:02PM -0300, Arnaldo Carvalho de Melo escreveu: Em Fri, Jun 03, 2016 at 04:42:05PM -0300, Arnaldo Carvalho de Melo escreveu: Em Fri, Jun 03, 2016 at 09:06:29AM +0200, Jiri Olsa escreveu: On Fri, Jun 03, 2016 at 03:33:09AM +, He Kuang wrote: v9: - Change function unwind__register_ops() to static. - Move up unwind__prepare_access() in thread__insert_map() and save map_groups__remove() call. - Enclose multiple line if/else into braces. - Fix miss modified function declaration for unwind__prepare_access() in patch 10. for patchset: Acked-by: Jiri Olsa Thanks, applied, build testing. Build tested went ok, but then 'perf top' crashes: [root@jouet ~]# perf top perf: Segmentation fault backtrace perf[0x55591b] /lib64/libc.so.6(+0x34ab0)[0x7f38ad9c1ab0] perf(normalize_arch+0x27)[0x534797] perf(unwind__prepare_access+0xbb)[0x52b15b] perf(thread__insert_map+0x27)[0x4d4837] perf(machine__process_mmap2_event+0xd7)[0x4ca187] perf(perf_event__synthesize_mmap_events+0x3e2)[0x491b32] perf(perf_event__synthesize_threads+0x445)[0x492635] perf(cmd_top+0xee0)[0x442f50] perf[0x486a91] perf(main+0x6ee)[0x42485e] /lib64/libc.so.6(__libc_start_main+0xf0)[0x7f38ad9ad580] perf(_start+0x29)[0x424949] [0x0] [root@jouet ~]# And I bet that 'perf trace' will too, lemme see, well, it crashes even more spetacularly, but that is the topic of another bug report, will send soon. Anyway, please try your patchkit with 'perf top' and 'perf trace', as both don't use perf.data files, i.e. they work 'live', so probably things that you touch in normalize_arch() are not initialized and need to be setup. Ah, no need to resend the whole patchkit, just find out what is the bug and send me a patch and I'll insert it at the right point to avoid introducing a bisect breaking point. Your patchkit is in my perf/unwind branch at my tree, I already added Jiri's Acked-by in all the patches. git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git Thanks, - Arnaldo - I send the updated one after PATCH 10/14, env->arch is null in live mode, comments are added and "perf top/trace" works now. Thanks.
[PATCH v2 1/2] locking/rwsem: Convert sem->count to atomic_long_t
Convert the rwsem count variable to an atomic_long_t since we use it as an atomic variable. This also allows us to remove the rwsem_atomic_{add,update} "abstraction" which would now be an unnecesary level of indirection. In follow up patches, we also remove the rwsem_atomic_{add,update} definitions across the various architectures. Suggested-by: Peter ZijlstraSigned-off-by: Jason Low --- arch/alpha/include/asm/rwsem.h | 26 +- arch/ia64/include/asm/rwsem.h | 24 include/asm-generic/rwsem.h| 6 +++--- include/linux/rwsem.h | 6 +++--- kernel/locking/rwsem-xadd.c| 32 +--- 5 files changed, 48 insertions(+), 46 deletions(-) diff --git a/arch/alpha/include/asm/rwsem.h b/arch/alpha/include/asm/rwsem.h index 0131a70..b40021a 100644 --- a/arch/alpha/include/asm/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h @@ -25,8 +25,8 @@ static inline void __down_read(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count += RWSEM_ACTIVE_READ_BIAS; + oldcount = sem->count.counter; + sem->count.counter += RWSEM_ACTIVE_READ_BIAS; #else long temp; __asm__ __volatile__( @@ -52,13 +52,13 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) { long old, new, res; - res = sem->count; + res = atomic_long_read(>count); do { new = res + RWSEM_ACTIVE_READ_BIAS; if (new <= 0) break; old = res; - res = cmpxchg(>count, old, new); + res = atomic_long_cmpxchg(>count, old, new); } while (res != old); return res >= 0 ? 1 : 0; } @@ -67,8 +67,8 @@ static inline long ___down_write(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count += RWSEM_ACTIVE_WRITE_BIAS; + oldcount = sem->count.counter; + sem->count.counter += RWSEM_ACTIVE_WRITE_BIAS; #else long temp; __asm__ __volatile__( @@ -106,7 +106,7 @@ static inline int __down_write_killable(struct rw_semaphore *sem) */ static inline int __down_write_trylock(struct rw_semaphore *sem) { - long ret = cmpxchg(>count, RWSEM_UNLOCKED_VALUE, + long ret = atomic_long_cmpxchg(>count, RWSEM_UNLOCKED_VALUE, RWSEM_ACTIVE_WRITE_BIAS); if (ret == RWSEM_UNLOCKED_VALUE) return 1; @@ -117,8 +117,8 @@ static inline void __up_read(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count -= RWSEM_ACTIVE_READ_BIAS; + oldcount = sem->count.counter; + sem->count.counter -= RWSEM_ACTIVE_READ_BIAS; #else long temp; __asm__ __volatile__( @@ -142,8 +142,8 @@ static inline void __up_write(struct rw_semaphore *sem) { long count; #ifndefCONFIG_SMP - sem->count -= RWSEM_ACTIVE_WRITE_BIAS; - count = sem->count; + sem->count.counter -= RWSEM_ACTIVE_WRITE_BIAS; + count = sem->count.counter; #else long temp; __asm__ __volatile__( @@ -171,8 +171,8 @@ static inline void __downgrade_write(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count -= RWSEM_WAITING_BIAS; + oldcount = sem->count.counter; + sem->count.counter -= RWSEM_WAITING_BIAS; #else long temp; __asm__ __volatile__( diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index 8b23e07..c5d544f 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -40,7 +40,7 @@ static inline void __down_read (struct rw_semaphore *sem) { - long result = ia64_fetchadd8_acq((unsigned long *)>count, 1); + long result = ia64_fetchadd8_acq((unsigned long *)>count.counter, 1); if (result < 0) rwsem_down_read_failed(sem); @@ -55,9 +55,9 @@ ___down_write (struct rw_semaphore *sem) long old, new; do { - old = sem->count; + old = atomic_long_read(>count); new = old + RWSEM_ACTIVE_WRITE_BIAS; - } while (cmpxchg_acq(>count, old, new) != old); + } while (atomic_long_cmpxchg_acquire(>count, old, new) != old); return old; } @@ -85,7 +85,7 @@ __down_write_killable (struct rw_semaphore *sem) static inline void __up_read (struct rw_semaphore *sem) { - long result = ia64_fetchadd8_rel((unsigned long *)>count, -1); + long result = ia64_fetchadd8_rel((unsigned long *)>count.counter, -1); if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0) rwsem_wake(sem); @@ -100,9 +100,9 @@ __up_write (struct rw_semaphore *sem) long old, new; do { -
[PATCH v2 2/2] Remove rwsem_atomic_add() and rwsem_atomic_update()
The rwsem-xadd count has been converted to an atomic variable and the rwsem code now directly uses atomic_long_add() and atomic_long_add_return(), so we can remove the arch implementations of rwsem_atomic_add() and rwsem_atomic_update(). Signed-off-by: Jason Low--- arch/alpha/include/asm/rwsem.h | 42 -- arch/ia64/include/asm/rwsem.h | 7 --- arch/s390/include/asm/rwsem.h | 37 - arch/x86/include/asm/rwsem.h | 18 -- include/asm-generic/rwsem.h| 16 5 files changed, 120 deletions(-) diff --git a/arch/alpha/include/asm/rwsem.h b/arch/alpha/include/asm/rwsem.h index b40021a..77873d0 100644 --- a/arch/alpha/include/asm/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h @@ -191,47 +191,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -static inline void rwsem_atomic_add(long val, struct rw_semaphore *sem) -{ -#ifndefCONFIG_SMP - sem->count += val; -#else - long temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq%0,%2,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=" (temp), "=m" (sem->count) - :"Ir" (val), "m" (sem->count)); -#endif -} - -static inline long rwsem_atomic_update(long val, struct rw_semaphore *sem) -{ -#ifndefCONFIG_SMP - sem->count += val; - return sem->count; -#else - long ret, temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq%0,%3,%2\n" - " addq%0,%3,%0\n" - " stq_c %2,%1\n" - " beq %2,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=" (ret), "=m" (sem->count), "=" (temp) - :"Ir" (val), "m" (sem->count)); - - return ret; -#endif -} - #endif /* __KERNEL__ */ #endif /* _ALPHA_RWSEM_H */ diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index c5d544f..8fa98dd 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -151,11 +151,4 @@ __downgrade_write (struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -/* - * Implement atomic add functionality. These used to be "inline" functions, but GCC v3.1 - * doesn't quite optimize this stuff right and ends up with bad calls to fetchandadd. - */ -#define rwsem_atomic_add(delta, sem) atomic64_add(delta, (atomic64_t *)(&(sem)->count)) -#define rwsem_atomic_update(delta, sem)atomic64_add_return(delta, (atomic64_t *)(&(sem)->count)) - #endif /* _ASM_IA64_RWSEM_H */ diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h index c75e447..597e7e9 100644 --- a/arch/s390/include/asm/rwsem.h +++ b/arch/s390/include/asm/rwsem.h @@ -207,41 +207,4 @@ static inline void __downgrade_write(struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) -{ - signed long old, new; - - asm volatile( - " lg %0,%2\n" - "0: lgr %1,%0\n" - " agr %1,%4\n" - " csg %0,%1,%2\n" - " jl 0b" - : "=" (old), "=" (new), "=Q" (sem->count) - : "Q" (sem->count), "d" (delta) - : "cc", "memory"); -} - -/* - * implement exchange and add functionality - */ -static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) -{ - signed long old, new; - - asm volatile( - " lg %0,%2\n" - "0: lgr %1,%0\n" - " agr %1,%4\n" - " csg %0,%1,%2\n" - " jl 0b" - : "=" (old), "=" (new), "=Q" (sem->count) - : "Q" (sem->count), "d" (delta) - : "cc", "memory"); - return new; -} - #endif /* _S390_RWSEM_H */ diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index 453744c..089ced4 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -213,23 +213,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem) : "memory", "cc"); } -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) -{ - asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" -: "+m" (sem->count) -: "er" (delta)); -} - -/* - * implement exchange and add functionality - */ -static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) -{ - return delta + xadd(>count, delta); -} - #endif /* __KERNEL__ */
[PATCH v2 1/2] locking/rwsem: Convert sem->count to atomic_long_t
Convert the rwsem count variable to an atomic_long_t since we use it as an atomic variable. This also allows us to remove the rwsem_atomic_{add,update} "abstraction" which would now be an unnecesary level of indirection. In follow up patches, we also remove the rwsem_atomic_{add,update} definitions across the various architectures. Suggested-by: Peter Zijlstra Signed-off-by: Jason Low --- arch/alpha/include/asm/rwsem.h | 26 +- arch/ia64/include/asm/rwsem.h | 24 include/asm-generic/rwsem.h| 6 +++--- include/linux/rwsem.h | 6 +++--- kernel/locking/rwsem-xadd.c| 32 +--- 5 files changed, 48 insertions(+), 46 deletions(-) diff --git a/arch/alpha/include/asm/rwsem.h b/arch/alpha/include/asm/rwsem.h index 0131a70..b40021a 100644 --- a/arch/alpha/include/asm/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h @@ -25,8 +25,8 @@ static inline void __down_read(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count += RWSEM_ACTIVE_READ_BIAS; + oldcount = sem->count.counter; + sem->count.counter += RWSEM_ACTIVE_READ_BIAS; #else long temp; __asm__ __volatile__( @@ -52,13 +52,13 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) { long old, new, res; - res = sem->count; + res = atomic_long_read(>count); do { new = res + RWSEM_ACTIVE_READ_BIAS; if (new <= 0) break; old = res; - res = cmpxchg(>count, old, new); + res = atomic_long_cmpxchg(>count, old, new); } while (res != old); return res >= 0 ? 1 : 0; } @@ -67,8 +67,8 @@ static inline long ___down_write(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count += RWSEM_ACTIVE_WRITE_BIAS; + oldcount = sem->count.counter; + sem->count.counter += RWSEM_ACTIVE_WRITE_BIAS; #else long temp; __asm__ __volatile__( @@ -106,7 +106,7 @@ static inline int __down_write_killable(struct rw_semaphore *sem) */ static inline int __down_write_trylock(struct rw_semaphore *sem) { - long ret = cmpxchg(>count, RWSEM_UNLOCKED_VALUE, + long ret = atomic_long_cmpxchg(>count, RWSEM_UNLOCKED_VALUE, RWSEM_ACTIVE_WRITE_BIAS); if (ret == RWSEM_UNLOCKED_VALUE) return 1; @@ -117,8 +117,8 @@ static inline void __up_read(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count -= RWSEM_ACTIVE_READ_BIAS; + oldcount = sem->count.counter; + sem->count.counter -= RWSEM_ACTIVE_READ_BIAS; #else long temp; __asm__ __volatile__( @@ -142,8 +142,8 @@ static inline void __up_write(struct rw_semaphore *sem) { long count; #ifndefCONFIG_SMP - sem->count -= RWSEM_ACTIVE_WRITE_BIAS; - count = sem->count; + sem->count.counter -= RWSEM_ACTIVE_WRITE_BIAS; + count = sem->count.counter; #else long temp; __asm__ __volatile__( @@ -171,8 +171,8 @@ static inline void __downgrade_write(struct rw_semaphore *sem) { long oldcount; #ifndefCONFIG_SMP - oldcount = sem->count; - sem->count -= RWSEM_WAITING_BIAS; + oldcount = sem->count.counter; + sem->count.counter -= RWSEM_WAITING_BIAS; #else long temp; __asm__ __volatile__( diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index 8b23e07..c5d544f 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -40,7 +40,7 @@ static inline void __down_read (struct rw_semaphore *sem) { - long result = ia64_fetchadd8_acq((unsigned long *)>count, 1); + long result = ia64_fetchadd8_acq((unsigned long *)>count.counter, 1); if (result < 0) rwsem_down_read_failed(sem); @@ -55,9 +55,9 @@ ___down_write (struct rw_semaphore *sem) long old, new; do { - old = sem->count; + old = atomic_long_read(>count); new = old + RWSEM_ACTIVE_WRITE_BIAS; - } while (cmpxchg_acq(>count, old, new) != old); + } while (atomic_long_cmpxchg_acquire(>count, old, new) != old); return old; } @@ -85,7 +85,7 @@ __down_write_killable (struct rw_semaphore *sem) static inline void __up_read (struct rw_semaphore *sem) { - long result = ia64_fetchadd8_rel((unsigned long *)>count, -1); + long result = ia64_fetchadd8_rel((unsigned long *)>count.counter, -1); if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0) rwsem_wake(sem); @@ -100,9 +100,9 @@ __up_write (struct rw_semaphore *sem) long old, new; do { - old = sem->count; + old =
[PATCH v2 2/2] Remove rwsem_atomic_add() and rwsem_atomic_update()
The rwsem-xadd count has been converted to an atomic variable and the rwsem code now directly uses atomic_long_add() and atomic_long_add_return(), so we can remove the arch implementations of rwsem_atomic_add() and rwsem_atomic_update(). Signed-off-by: Jason Low --- arch/alpha/include/asm/rwsem.h | 42 -- arch/ia64/include/asm/rwsem.h | 7 --- arch/s390/include/asm/rwsem.h | 37 - arch/x86/include/asm/rwsem.h | 18 -- include/asm-generic/rwsem.h| 16 5 files changed, 120 deletions(-) diff --git a/arch/alpha/include/asm/rwsem.h b/arch/alpha/include/asm/rwsem.h index b40021a..77873d0 100644 --- a/arch/alpha/include/asm/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h @@ -191,47 +191,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -static inline void rwsem_atomic_add(long val, struct rw_semaphore *sem) -{ -#ifndefCONFIG_SMP - sem->count += val; -#else - long temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq%0,%2,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=" (temp), "=m" (sem->count) - :"Ir" (val), "m" (sem->count)); -#endif -} - -static inline long rwsem_atomic_update(long val, struct rw_semaphore *sem) -{ -#ifndefCONFIG_SMP - sem->count += val; - return sem->count; -#else - long ret, temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq%0,%3,%2\n" - " addq%0,%3,%0\n" - " stq_c %2,%1\n" - " beq %2,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=" (ret), "=m" (sem->count), "=" (temp) - :"Ir" (val), "m" (sem->count)); - - return ret; -#endif -} - #endif /* __KERNEL__ */ #endif /* _ALPHA_RWSEM_H */ diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index c5d544f..8fa98dd 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -151,11 +151,4 @@ __downgrade_write (struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -/* - * Implement atomic add functionality. These used to be "inline" functions, but GCC v3.1 - * doesn't quite optimize this stuff right and ends up with bad calls to fetchandadd. - */ -#define rwsem_atomic_add(delta, sem) atomic64_add(delta, (atomic64_t *)(&(sem)->count)) -#define rwsem_atomic_update(delta, sem)atomic64_add_return(delta, (atomic64_t *)(&(sem)->count)) - #endif /* _ASM_IA64_RWSEM_H */ diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h index c75e447..597e7e9 100644 --- a/arch/s390/include/asm/rwsem.h +++ b/arch/s390/include/asm/rwsem.h @@ -207,41 +207,4 @@ static inline void __downgrade_write(struct rw_semaphore *sem) rwsem_downgrade_wake(sem); } -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) -{ - signed long old, new; - - asm volatile( - " lg %0,%2\n" - "0: lgr %1,%0\n" - " agr %1,%4\n" - " csg %0,%1,%2\n" - " jl 0b" - : "=" (old), "=" (new), "=Q" (sem->count) - : "Q" (sem->count), "d" (delta) - : "cc", "memory"); -} - -/* - * implement exchange and add functionality - */ -static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) -{ - signed long old, new; - - asm volatile( - " lg %0,%2\n" - "0: lgr %1,%0\n" - " agr %1,%4\n" - " csg %0,%1,%2\n" - " jl 0b" - : "=" (old), "=" (new), "=Q" (sem->count) - : "Q" (sem->count), "d" (delta) - : "cc", "memory"); - return new; -} - #endif /* _S390_RWSEM_H */ diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index 453744c..089ced4 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -213,23 +213,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem) : "memory", "cc"); } -/* - * implement atomic add functionality - */ -static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) -{ - asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" -: "+m" (sem->count) -: "er" (delta)); -} - -/* - * implement exchange and add functionality - */ -static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) -{ - return delta + xadd(>count, delta); -} - #endif /* __KERNEL__ */ #endif /*
[PATCH v2 0/2] locking/rwsem: Convert rwsem count to atomic_long_t
v1->v2: - Also convert sem->count usages in arch/{alph,ia64}/include/asm/rwsem.h to be used as atomic_long_t. - Merge the patches to remove rwsem_atomic_add() and rwsem_atomic_update() across the various architectures into one patch. This series converts the rwsem count variable to an atomic_long_t since it is used it as an atomic variable. This allows us to also remove the rwsem_atomic_{add,update} abstraction and reduce 100+ lines of code. Jason Low (2): locking/rwsem: Convert sem->count to atomic_long_t Remove rwsem_atomic_add() and rwsem_atomic_update() arch/alpha/include/asm/rwsem.h | 68 -- arch/ia64/include/asm/rwsem.h | 31 --- arch/s390/include/asm/rwsem.h | 37 --- arch/x86/include/asm/rwsem.h | 18 --- include/asm-generic/rwsem.h| 22 ++ include/linux/rwsem.h | 6 ++-- kernel/locking/rwsem-xadd.c| 32 ++-- 7 files changed, 48 insertions(+), 166 deletions(-) -- 2.1.4
[PATCH v2 0/2] locking/rwsem: Convert rwsem count to atomic_long_t
v1->v2: - Also convert sem->count usages in arch/{alph,ia64}/include/asm/rwsem.h to be used as atomic_long_t. - Merge the patches to remove rwsem_atomic_add() and rwsem_atomic_update() across the various architectures into one patch. This series converts the rwsem count variable to an atomic_long_t since it is used it as an atomic variable. This allows us to also remove the rwsem_atomic_{add,update} abstraction and reduce 100+ lines of code. Jason Low (2): locking/rwsem: Convert sem->count to atomic_long_t Remove rwsem_atomic_add() and rwsem_atomic_update() arch/alpha/include/asm/rwsem.h | 68 -- arch/ia64/include/asm/rwsem.h | 31 --- arch/s390/include/asm/rwsem.h | 37 --- arch/x86/include/asm/rwsem.h | 18 --- include/asm-generic/rwsem.h| 22 ++ include/linux/rwsem.h | 6 ++-- kernel/locking/rwsem-xadd.c| 32 ++-- 7 files changed, 48 insertions(+), 166 deletions(-) -- 2.1.4
[PATCH v9 10/14 UPDATE] perf tools: Check the target platform before assigning unwind methods
Currently, perf script uses host unwind methods to parse perf.data callchain info regardless of the target architecture. So we get wrong result without any warnings when unwinding callchains of x86(32-bit) on x86(64-bit) machine. This patch adds extra step that check the target platform before assigning unwind methods. In the latter patches in this series, we can use this info to assign the right unwind methods for supported platforms. Signed-off-by: He KuangAcked-by: Jiri Olsa --- tools/perf/util/thread.c | 2 +- tools/perf/util/unwind-libunwind.c | 25 - tools/perf/util/unwind.h | 8 +--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index d05843e..d1a12144e 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -202,7 +202,7 @@ int thread__insert_map(struct thread *thread, struct map *map) { int ret; - ret = unwind__prepare_access(thread); + ret = unwind__prepare_access(thread, map); if (ret) return ret; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 9365f0e..452b4e1 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -1,5 +1,8 @@ #include "unwind.h" #include "thread.h" +#include "session.h" +#include "debug.h" +#include "arch/common.h" struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; @@ -9,8 +12,28 @@ static void unwind__register_ops(struct thread *thread, thread->unwind_libunwind_ops = ops; } -int unwind__prepare_access(struct thread *thread) +int unwind__prepare_access(struct thread *thread, struct map *map) { + const char *arch; + enum dso_type dso_type; + + if (thread->addr_space) { + pr_debug("unwind: thread map already set, dso=%s\n", +map->dso->name); + return 0; + } + + /* env->arch is NULL for live-mode (i.e. perf top) */ + if (!thread->mg->machine->env || !thread->mg->machine->env->arch) + return 0; + + dso_type = dso__type(map->dso, thread->mg->machine); + if (dso_type == DSO__TYPE_UNKNOWN) + return 0; + + arch = normalize_arch(thread->mg->machine->env->arch); + pr_debug("unwind: target platform=%s\n", arch); + unwind__register_ops(thread, local_unwind_libunwind_ops); return thread->unwind_libunwind_ops->prepare_access(thread); diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index bbd73d9..bf9f593 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -30,11 +30,12 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, /* libunwind specific */ #ifdef HAVE_LIBUNWIND_SUPPORT int libunwind__arch_reg_id(int regnum); -int unwind__prepare_access(struct thread *thread); +int unwind__prepare_access(struct thread *thread, struct map *map); void unwind__flush_access(struct thread *thread); void unwind__finish_access(struct thread *thread); #else -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +struct map *map __maybe_unused) { return 0; } @@ -53,7 +54,8 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, return 0; } -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +struct map *map __maybe_unused) { return 0; } -- 1.8.5.2
[PATCH v9 10/14 UPDATE] perf tools: Check the target platform before assigning unwind methods
Currently, perf script uses host unwind methods to parse perf.data callchain info regardless of the target architecture. So we get wrong result without any warnings when unwinding callchains of x86(32-bit) on x86(64-bit) machine. This patch adds extra step that check the target platform before assigning unwind methods. In the latter patches in this series, we can use this info to assign the right unwind methods for supported platforms. Signed-off-by: He Kuang Acked-by: Jiri Olsa --- tools/perf/util/thread.c | 2 +- tools/perf/util/unwind-libunwind.c | 25 - tools/perf/util/unwind.h | 8 +--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index d05843e..d1a12144e 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -202,7 +202,7 @@ int thread__insert_map(struct thread *thread, struct map *map) { int ret; - ret = unwind__prepare_access(thread); + ret = unwind__prepare_access(thread, map); if (ret) return ret; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 9365f0e..452b4e1 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -1,5 +1,8 @@ #include "unwind.h" #include "thread.h" +#include "session.h" +#include "debug.h" +#include "arch/common.h" struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; @@ -9,8 +12,28 @@ static void unwind__register_ops(struct thread *thread, thread->unwind_libunwind_ops = ops; } -int unwind__prepare_access(struct thread *thread) +int unwind__prepare_access(struct thread *thread, struct map *map) { + const char *arch; + enum dso_type dso_type; + + if (thread->addr_space) { + pr_debug("unwind: thread map already set, dso=%s\n", +map->dso->name); + return 0; + } + + /* env->arch is NULL for live-mode (i.e. perf top) */ + if (!thread->mg->machine->env || !thread->mg->machine->env->arch) + return 0; + + dso_type = dso__type(map->dso, thread->mg->machine); + if (dso_type == DSO__TYPE_UNKNOWN) + return 0; + + arch = normalize_arch(thread->mg->machine->env->arch); + pr_debug("unwind: target platform=%s\n", arch); + unwind__register_ops(thread, local_unwind_libunwind_ops); return thread->unwind_libunwind_ops->prepare_access(thread); diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index bbd73d9..bf9f593 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -30,11 +30,12 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, /* libunwind specific */ #ifdef HAVE_LIBUNWIND_SUPPORT int libunwind__arch_reg_id(int regnum); -int unwind__prepare_access(struct thread *thread); +int unwind__prepare_access(struct thread *thread, struct map *map); void unwind__flush_access(struct thread *thread); void unwind__finish_access(struct thread *thread); #else -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +struct map *map __maybe_unused) { return 0; } @@ -53,7 +54,8 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, return 0; } -static inline int unwind__prepare_access(struct thread *thread __maybe_unused) +static inline int unwind__prepare_access(struct thread *thread __maybe_unused, +struct map *map __maybe_unused) { return 0; } -- 1.8.5.2
[PATCH] staging: comedi: adl_pci9118: fix spelling mistake "acqusition" -> "acquisition"
From: Colin Ian Kingtrivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/staging/comedi/drivers/adl_pci9118.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4437ea3..be70bd3 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -570,7 +570,7 @@ static int pci9118_ai_cancel(struct comedi_device *dev, /* set default config (disable burst and triggers) */ devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG; outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG); - /* reset acqusition control */ + /* reset acquisition control */ devpriv->ai_ctrl = 0; outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG); outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG); @@ -1022,12 +1022,12 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* * Configure analog input and load the chanlist. -* The acqusition control bits are enabled later. +* The acquisition control bits are enabled later. */ pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist, devpriv->ai_add_front, devpriv->ai_add_back); - /* Determine acqusition mode and calculate timing */ + /* Determine acquisition mode and calculate timing */ devpriv->ai_do = 0; if (cmd->scan_begin_src != TRIG_TIMER && cmd->convert_src == TRIG_TIMER) { @@ -1097,7 +1097,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ai_do == 0) { dev_err(dev->class_dev, - "Unable to determine acqusition mode! BUG in (*do_cmdtest)?\n"); + "Unable to determine acquisition mode! BUG in (*do_cmdtest)?\n"); return -EINVAL; } -- 2.8.1
[PATCH] staging: comedi: adl_pci9118: fix spelling mistake "acqusition" -> "acquisition"
From: Colin Ian King trivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/staging/comedi/drivers/adl_pci9118.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4437ea3..be70bd3 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -570,7 +570,7 @@ static int pci9118_ai_cancel(struct comedi_device *dev, /* set default config (disable burst and triggers) */ devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG; outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG); - /* reset acqusition control */ + /* reset acquisition control */ devpriv->ai_ctrl = 0; outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG); outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG); @@ -1022,12 +1022,12 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* * Configure analog input and load the chanlist. -* The acqusition control bits are enabled later. +* The acquisition control bits are enabled later. */ pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist, devpriv->ai_add_front, devpriv->ai_add_back); - /* Determine acqusition mode and calculate timing */ + /* Determine acquisition mode and calculate timing */ devpriv->ai_do = 0; if (cmd->scan_begin_src != TRIG_TIMER && cmd->convert_src == TRIG_TIMER) { @@ -1097,7 +1097,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->ai_do == 0) { dev_err(dev->class_dev, - "Unable to determine acqusition mode! BUG in (*do_cmdtest)?\n"); + "Unable to determine acquisition mode! BUG in (*do_cmdtest)?\n"); return -EINVAL; } -- 2.8.1
[PATCH] regulator: lp8755: fix spelling mistake "acceess" -> "access"
From: Colin Ian Kingtrivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/regulator/lp8755.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index d6773da..6e810e9 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -99,7 +99,7 @@ static int lp8755_buck_enable_time(struct regulator_dev *rdev) ret = lp8755_read(pchip, 0x12 + id, ); if (ret < 0) { - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } return (regval & 0xff) * 100; @@ -144,7 +144,7 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -175,7 +175,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return 0; } @@ -223,7 +223,7 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -295,7 +295,7 @@ static int lp8755_init_data(struct lp8755_chip *pchip) return ret; out_i2c_error: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -404,7 +404,7 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) return IRQ_HANDLED; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return IRQ_NONE; } @@ -420,7 +420,7 @@ static int lp8755_int_config(struct lp8755_chip *pchip) ret = lp8755_read(pchip, 0x0F, ); if (ret < 0) { - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } -- 2.8.1
[PATCH] regulator: lp8755: fix spelling mistake "acceess" -> "access"
From: Colin Ian King trivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/regulator/lp8755.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index d6773da..6e810e9 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -99,7 +99,7 @@ static int lp8755_buck_enable_time(struct regulator_dev *rdev) ret = lp8755_read(pchip, 0x12 + id, ); if (ret < 0) { - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } return (regval & 0xff) * 100; @@ -144,7 +144,7 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -175,7 +175,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return 0; } @@ -223,7 +223,7 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -295,7 +295,7 @@ static int lp8755_init_data(struct lp8755_chip *pchip) return ret; out_i2c_error: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } @@ -404,7 +404,7 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) return IRQ_HANDLED; err_i2c: - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return IRQ_NONE; } @@ -420,7 +420,7 @@ static int lp8755_int_config(struct lp8755_chip *pchip) ret = lp8755_read(pchip, 0x0F, ); if (ret < 0) { - dev_err(pchip->dev, "i2c acceess error %s\n", __func__); + dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; } -- 2.8.1
Re: [PATCH] ASoC: sgtl5000: only check VDDD-supply, not revision
Hi Fabio and Clemens, On 06/03/2016 06:23 PM, Eric Nelson wrote: > Hi Fabio, > > On 06/02/2016 05:48 PM, Fabio Estevam wrote: >> Hi Clemens, >> >> On Thu, Jun 2, 2016 at 9:47 AM, Clemens Gruber >>wrote: >>> Instead of checking the SGTL5000 chip revision, we should only check if >>> the VDDD regulator exists and only call sgtl5000_replace_vddd_with_ldo >>> if the regulator is missing. >>> Otherwise, the user reads in the kernel log that the internal LDO is >>> used, even though he did follow the NXP recommendation to use external >>> VDDD and also specified VDDD-supply in the devicetree. >>> >>> Also remove the comment, which incorrectly states that external VDDD is >>> only supported for SGTL5000 chip revisions < 0x11. >>> Official NXP documentation recommends using external VDDD and not the >>> internal LDO due to the SGTL5000 erratum ER1. This also applies to >>> revisions >= 0x11. >>> >>> Tested on an i.MX6Q board with SGTL5000 rev 0x11 and external VDDD. >> >> Patch looks good to me. >> >> Eric, >> >> Sometime ago you were looking at this. What do you think about this patch? >> > > Sorry. I'm traveling and haven't had a chance to review this, but it's > on my to-do. > > AFAIK, the SGTL5000 versions < 0x11 are like Sasquatch: I've seen no real proof of their existence. I tried to chase down when this code was introduced, but it seems to have been around since the dawn of the driver. Clemens, if you're really trying to control an external regulator, I think you'll need lots more than this patch. There are some fundamental flaws in regulator handling and I put together some RFC patches to address them in February 2015: http://mailman.alsa-project.org/pipermail/alsa-devel/2015-February/thread.html#88353 The long and short of it is that at least one of the regulators would need to be initialized before the SGTL5000 probes. Regards, Eric
Re: [PATCH] ASoC: sgtl5000: only check VDDD-supply, not revision
Hi Fabio and Clemens, On 06/03/2016 06:23 PM, Eric Nelson wrote: > Hi Fabio, > > On 06/02/2016 05:48 PM, Fabio Estevam wrote: >> Hi Clemens, >> >> On Thu, Jun 2, 2016 at 9:47 AM, Clemens Gruber >> wrote: >>> Instead of checking the SGTL5000 chip revision, we should only check if >>> the VDDD regulator exists and only call sgtl5000_replace_vddd_with_ldo >>> if the regulator is missing. >>> Otherwise, the user reads in the kernel log that the internal LDO is >>> used, even though he did follow the NXP recommendation to use external >>> VDDD and also specified VDDD-supply in the devicetree. >>> >>> Also remove the comment, which incorrectly states that external VDDD is >>> only supported for SGTL5000 chip revisions < 0x11. >>> Official NXP documentation recommends using external VDDD and not the >>> internal LDO due to the SGTL5000 erratum ER1. This also applies to >>> revisions >= 0x11. >>> >>> Tested on an i.MX6Q board with SGTL5000 rev 0x11 and external VDDD. >> >> Patch looks good to me. >> >> Eric, >> >> Sometime ago you were looking at this. What do you think about this patch? >> > > Sorry. I'm traveling and haven't had a chance to review this, but it's > on my to-do. > > AFAIK, the SGTL5000 versions < 0x11 are like Sasquatch: I've seen no real proof of their existence. I tried to chase down when this code was introduced, but it seems to have been around since the dawn of the driver. Clemens, if you're really trying to control an external regulator, I think you'll need lots more than this patch. There are some fundamental flaws in regulator handling and I put together some RFC patches to address them in February 2015: http://mailman.alsa-project.org/pipermail/alsa-devel/2015-February/thread.html#88353 The long and short of it is that at least one of the regulators would need to be initialized before the SGTL5000 probes. Regards, Eric
SIGSYS annoyance
https://bugzilla.mozilla.org/show_bug.cgi?id=1176099 Should SIGSYS be delivered to the handler even if blocked? What, if anything, does POSIX say? All I can find is in pthread_sigmask(3p): If any of the SIGFPE, SIGILL, SIGSEGV, or SIGBUS signals are generated while they are blocked, the result is undefined, unless the signal was generated by the action of another process, or by one of the functions kill(), pthread_kill(), raise(), or sigqueue(). It would be easy enough to change our behavior so that we deliver the signal even if it's blocked or to at least add a flag so that users can request that behavior.
SIGSYS annoyance
https://bugzilla.mozilla.org/show_bug.cgi?id=1176099 Should SIGSYS be delivered to the handler even if blocked? What, if anything, does POSIX say? All I can find is in pthread_sigmask(3p): If any of the SIGFPE, SIGILL, SIGSEGV, or SIGBUS signals are generated while they are blocked, the result is undefined, unless the signal was generated by the action of another process, or by one of the functions kill(), pthread_kill(), raise(), or sigqueue(). It would be easy enough to change our behavior so that we deliver the signal even if it's blocked or to at least add a flag so that users can request that behavior.
[PATCH v2 2/2] lib/uuid.c: eliminate uuid_[bl]e_index arrays
Both input and output code is simplified if we use a mapping from binary UUID index to ASCII UUID position. This lets us combine hyphen-skipping and endian-swapping into one table. This significantly simplifies __uuid_to_bin(), which was using *two* lookup tables. uuid_[bl]e_index were EXPORT_SYMBOLed for no obvious reason; all users are compiled unconditionally into the kernel. The replacement uuid_[bl]e_pos arrays are not exported until a need appears. Benefits: * The source code is shorter and simpler, * it executes faster, * initialized data is 16 bytes smaller, and * compiled code is smaller. Since this is not hot code, the important benchmark is not run time but code size: uuid_string() __uuid_to_bin() Before After Delta Percent Before After Delta Percent x86-32 199 196 -3 -1.5% 122 90 -32 -26.2% x86-64 186 162 -24 -12.9% 127 90 -37 -29.1% arm 264 216 -48 -18.2% 116 92 -24 -20.7% thumb 160 136 -24 -15.0% 100 50 -50 -50.0% arm64 244 188 -56 -23.0% 148 116 -32 -21.6% Signed-off-by: George Spelvin--- include/linux/uuid.h | 5 +++-- lib/uuid.c | 24 +--- lib/vsprintf.c | 26 ++ 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/include/linux/uuid.h b/include/linux/uuid.h index 2d095fc6..238f16f7 100644 --- a/include/linux/uuid.h +++ b/include/linux/uuid.h @@ -41,8 +41,9 @@ extern void uuid_be_gen(uuid_be *u); bool __must_check uuid_is_valid(const char *uuid); -extern const u8 uuid_le_index[16]; -extern const u8 uuid_be_index[16]; +/* For each binary byte, string offset in ASCII UUID where it appears */ +extern const u8 uuid_be_pos[16]; +extern const u8 uuid_le_pos[16]; int uuid_le_to_bin(const char *uuid, uuid_le *u); int uuid_be_to_bin(const char *uuid, uuid_be *u); diff --git a/lib/uuid.c b/lib/uuid.c index e116ae5f..93945915 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -21,11 +21,6 @@ #include #include -const u8 uuid_le_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; -EXPORT_SYMBOL(uuid_le_index); -const u8 uuid_be_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; -EXPORT_SYMBOL(uuid_be_index); - /*** * Random UUID interface * @@ -97,32 +92,31 @@ bool uuid_is_valid(const char *uuid) } EXPORT_SYMBOL(uuid_is_valid); -static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 ei[16]) +/* For each binary byte, string offset in ASCII UUID where it appears */ +const u8 uuid_be_pos[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; +const u8 uuid_le_pos[16] = {6,4,2,0,11,9,16,14,19,21,24,26,28,30,32,34}; + +static int __uuid_to_bin(const char uuid[36], __u8 b[16], const u8 pos[16]) { - static const u8 si[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; unsigned int i; if (!uuid_is_valid(uuid)) return -EINVAL; - for (i = 0; i < 16; i++) { - int hi = hex_to_bin(uuid[si[i]] + 0); - int lo = hex_to_bin(uuid[si[i]] + 1); - - b[ei[i]] = (hi << 4) | lo; - } + for (i = 0; i < 16; i++) + hex2bin(b + i, uuid + pos[i], 1); return 0; } int uuid_le_to_bin(const char *uuid, uuid_le *u) { - return __uuid_to_bin(uuid, u->b, uuid_le_index); + return __uuid_to_bin(uuid, u->b, uuid_le_pos); } EXPORT_SYMBOL(uuid_le_to_bin); int uuid_be_to_bin(const char *uuid, uuid_be *u) { - return __uuid_to_bin(uuid, u->b, uuid_be_index); + return __uuid_to_bin(uuid, u->b, uuid_be_pos); } EXPORT_SYMBOL(uuid_be_to_bin); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4ee07e89..f02cfd9f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1313,38 +1313,32 @@ char *uuid_string(char *buf, char *end, const u8 *addr, struct printf_spec spec, const char *fmt) { char uuid[UUID_STRING_LEN + 1]; - char *p = uuid; int i; - const u8 *index = uuid_be_index; + const u8 *pos = uuid_be_pos; const char *hex = hex_asc; switch (fmt[1]) { case 'L': hex = hex_asc_upper;/* fall-through */ case 'l': - index = uuid_le_index; + pos = uuid_le_pos; break; case 'B': hex = hex_asc_upper; break; } + /* Format each byte of the raw uuid into the buffer */ for (i = 0; i < 16; i++) { - u8 byte = addr[index[i]]; + u8 byte = addr[i]; + char *p = uuid + pos[i]; - *p++ = hex[byte >> 4]; - *p++ = hex[byte & 0x0f]; - switch (i) { - case 3: - case 5: - case 7: - case 9: -
[PATCH v2 2/2] lib/uuid.c: eliminate uuid_[bl]e_index arrays
Both input and output code is simplified if we use a mapping from binary UUID index to ASCII UUID position. This lets us combine hyphen-skipping and endian-swapping into one table. This significantly simplifies __uuid_to_bin(), which was using *two* lookup tables. uuid_[bl]e_index were EXPORT_SYMBOLed for no obvious reason; all users are compiled unconditionally into the kernel. The replacement uuid_[bl]e_pos arrays are not exported until a need appears. Benefits: * The source code is shorter and simpler, * it executes faster, * initialized data is 16 bytes smaller, and * compiled code is smaller. Since this is not hot code, the important benchmark is not run time but code size: uuid_string() __uuid_to_bin() Before After Delta Percent Before After Delta Percent x86-32 199 196 -3 -1.5% 122 90 -32 -26.2% x86-64 186 162 -24 -12.9% 127 90 -37 -29.1% arm 264 216 -48 -18.2% 116 92 -24 -20.7% thumb 160 136 -24 -15.0% 100 50 -50 -50.0% arm64 244 188 -56 -23.0% 148 116 -32 -21.6% Signed-off-by: George Spelvin --- include/linux/uuid.h | 5 +++-- lib/uuid.c | 24 +--- lib/vsprintf.c | 26 ++ 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/include/linux/uuid.h b/include/linux/uuid.h index 2d095fc6..238f16f7 100644 --- a/include/linux/uuid.h +++ b/include/linux/uuid.h @@ -41,8 +41,9 @@ extern void uuid_be_gen(uuid_be *u); bool __must_check uuid_is_valid(const char *uuid); -extern const u8 uuid_le_index[16]; -extern const u8 uuid_be_index[16]; +/* For each binary byte, string offset in ASCII UUID where it appears */ +extern const u8 uuid_be_pos[16]; +extern const u8 uuid_le_pos[16]; int uuid_le_to_bin(const char *uuid, uuid_le *u); int uuid_be_to_bin(const char *uuid, uuid_be *u); diff --git a/lib/uuid.c b/lib/uuid.c index e116ae5f..93945915 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -21,11 +21,6 @@ #include #include -const u8 uuid_le_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; -EXPORT_SYMBOL(uuid_le_index); -const u8 uuid_be_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; -EXPORT_SYMBOL(uuid_be_index); - /*** * Random UUID interface * @@ -97,32 +92,31 @@ bool uuid_is_valid(const char *uuid) } EXPORT_SYMBOL(uuid_is_valid); -static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 ei[16]) +/* For each binary byte, string offset in ASCII UUID where it appears */ +const u8 uuid_be_pos[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; +const u8 uuid_le_pos[16] = {6,4,2,0,11,9,16,14,19,21,24,26,28,30,32,34}; + +static int __uuid_to_bin(const char uuid[36], __u8 b[16], const u8 pos[16]) { - static const u8 si[16] = {0,2,4,6,9,11,14,16,19,21,24,26,28,30,32,34}; unsigned int i; if (!uuid_is_valid(uuid)) return -EINVAL; - for (i = 0; i < 16; i++) { - int hi = hex_to_bin(uuid[si[i]] + 0); - int lo = hex_to_bin(uuid[si[i]] + 1); - - b[ei[i]] = (hi << 4) | lo; - } + for (i = 0; i < 16; i++) + hex2bin(b + i, uuid + pos[i], 1); return 0; } int uuid_le_to_bin(const char *uuid, uuid_le *u) { - return __uuid_to_bin(uuid, u->b, uuid_le_index); + return __uuid_to_bin(uuid, u->b, uuid_le_pos); } EXPORT_SYMBOL(uuid_le_to_bin); int uuid_be_to_bin(const char *uuid, uuid_be *u) { - return __uuid_to_bin(uuid, u->b, uuid_be_index); + return __uuid_to_bin(uuid, u->b, uuid_be_pos); } EXPORT_SYMBOL(uuid_be_to_bin); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4ee07e89..f02cfd9f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1313,38 +1313,32 @@ char *uuid_string(char *buf, char *end, const u8 *addr, struct printf_spec spec, const char *fmt) { char uuid[UUID_STRING_LEN + 1]; - char *p = uuid; int i; - const u8 *index = uuid_be_index; + const u8 *pos = uuid_be_pos; const char *hex = hex_asc; switch (fmt[1]) { case 'L': hex = hex_asc_upper;/* fall-through */ case 'l': - index = uuid_le_index; + pos = uuid_le_pos; break; case 'B': hex = hex_asc_upper; break; } + /* Format each byte of the raw uuid into the buffer */ for (i = 0; i < 16; i++) { - u8 byte = addr[index[i]]; + u8 byte = addr[i]; + char *p = uuid + pos[i]; - *p++ = hex[byte >> 4]; - *p++ = hex[byte & 0x0f]; - switch (i) { - case 3: - case 5: - case 7: - case 9: - *p++ =
[PATCH v2 1/2] lib/vsprintf.c: Simplify uuid_string()
Rather than have a second pass to upcase the buffer, just make the hex lookup table a variable. Removing the conditional branch from the inner loop is also a speedup, but since this is not hot code, the important factor it shrinks both source and compiled forms: Before After Delta Percentage x86-32 245 199 -46 -18.8% x86-64 246 186 -60 -24.4% arm 292 264 -28 -9.6% thumb 220 160 -60 -27.3% arm64 296 244 -52 -17.6% Signed-off-by: George Spelvin--- lib/vsprintf.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7332a5d7..4ee07e89 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1316,24 +1316,24 @@ char *uuid_string(char *buf, char *end, const u8 *addr, char *p = uuid; int i; const u8 *index = uuid_be_index; - bool uc = false; + const char *hex = hex_asc; - switch (*(++fmt)) { + switch (fmt[1]) { case 'L': - uc = true; /* fall-through */ + hex = hex_asc_upper;/* fall-through */ case 'l': index = uuid_le_index; break; case 'B': - uc = true; + hex = hex_asc_upper; break; } for (i = 0; i < 16; i++) { - if (uc) - p = hex_byte_pack_upper(p, addr[index[i]]); - else - p = hex_byte_pack(p, addr[index[i]]); + u8 byte = addr[index[i]]; + + *p++ = hex[byte >> 4]; + *p++ = hex[byte & 0x0f]; switch (i) { case 3: case 5: -- 2.8.1
[PATCH v2 1/2] lib/vsprintf.c: Simplify uuid_string()
Rather than have a second pass to upcase the buffer, just make the hex lookup table a variable. Removing the conditional branch from the inner loop is also a speedup, but since this is not hot code, the important factor it shrinks both source and compiled forms: Before After Delta Percentage x86-32 245 199 -46 -18.8% x86-64 246 186 -60 -24.4% arm 292 264 -28 -9.6% thumb 220 160 -60 -27.3% arm64 296 244 -52 -17.6% Signed-off-by: George Spelvin --- lib/vsprintf.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7332a5d7..4ee07e89 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1316,24 +1316,24 @@ char *uuid_string(char *buf, char *end, const u8 *addr, char *p = uuid; int i; const u8 *index = uuid_be_index; - bool uc = false; + const char *hex = hex_asc; - switch (*(++fmt)) { + switch (fmt[1]) { case 'L': - uc = true; /* fall-through */ + hex = hex_asc_upper;/* fall-through */ case 'l': index = uuid_le_index; break; case 'B': - uc = true; + hex = hex_asc_upper; break; } for (i = 0; i < 16; i++) { - if (uc) - p = hex_byte_pack_upper(p, addr[index[i]]); - else - p = hex_byte_pack(p, addr[index[i]]); + u8 byte = addr[index[i]]; + + *p++ = hex[byte >> 4]; + *p++ = hex[byte & 0x0f]; switch (i) { case 3: case 5: -- 2.8.1
[PATCH v2 0/2] Clean up and shrink uuid input & output
Okay, here's a more formal submission. Net code size changes for both patches: uuid_string() __uuid_to_bin() Before After Delta Percent Before After Delta Percent x86-32 245 196 -49-20.0% 122 90 -32 -26.2% x86-64 246 162 -84-34.1% 127 90 -37 -29.1% arm 292 216 -76-26.0% 116 92 -24 -20.7% thumb 220 136 -84-38.2% 100 50 -50 -50.0% arm64 296 188 -108-36.5% 148 116 -32 -21.6% I haven't measured the speedup because, although it's obviously faster, speed is not particularly important. (I wouldn't be using out-of-line hex2bin() if it were.) Andy Shevchenko wrote > Be honest, you increase rodata for almost the same amount of bytes. No, my original patch didn't increase rodata at all, because it replaced tables of the same size. Bringing that patch forward in the simplest way (the first copy, which I sent you privately) broke the sharing of the arrays with lib/uuid.c and thereby increased rodata by 32 bytes. But patching lib/uuid.c to share the new tables as is done in this patch series ends up with a net 16-byte reduction in rodata. > Also, please fix Cc list (I got bounce response) and add some key people > like Rasmus. Mea culpa. I manually copied the e-mail addresses and managed to typo "bjorn" into "bbjorn". >> The arrays are combined in one contiguous uuid_byte_pos[2][16] >> array as a micro-optimization for uuid_string(). > Oh, it makes readability worse. It's truly marginal, deleted. > How hex2bin is better here? We have validation done, no need to repeat. > So, I suggest not to touch this piece of code. hex2bin is better than hex_to_bin because it's does more of what we want in one call rather than needing two. As for checking the return value, it's a longish story. However, at your prompting, I've deleted it (more size savings!). Now, the story... Originally, I had eliminated the uuid_is_valid() call entirely, and just checked that the hyphens were in the right place and the digits all converted: static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 si[16]) { unsigned int i; if (uuid[ 8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-') return -EINVAL; for (i = 0; i < 16; i++) if (hex2bin(b + i, uuid + si[i], 1) < 0) return -EINVAL; return 0; } ... but I was worried that some callers might be passing in an arbitrary null-terminated string, and reading uuid[23] before checking that the preceding characters were all non-null might be a bad thing. So I put the uuid_is_valid() call back. However, I left the second return value check, on general principles, because it was cheap and I wasn't sure it wasn't useful. i was thinking about about time-of-check to time-of-use race conditions. I had just determined that I didn't know the callers and what they were doing, so I wasn't sure the source uuid would be stable for the duration of the call. However, this isn't a real TOCTTOU security bug. The only thing that corrupting the buffer can do is insert a 0xff byte in the uuid. Which is nothing that couldn't be done with a static input. So it's unnecessary. George Spelvin (2): lib/vsprintf.c: Simplify uuid_string() lib/uuid.c: eliminate uuid_[bl]e_index arrays include/linux/uuid.h | 6 -- lib/uuid.c | 24 ++-- lib/vsprintf.c | 40 +--- 3 files changed, 31 insertions(+), 39 deletions(-) -- 2.8.1
[PATCH v2 0/2] Clean up and shrink uuid input & output
Okay, here's a more formal submission. Net code size changes for both patches: uuid_string() __uuid_to_bin() Before After Delta Percent Before After Delta Percent x86-32 245 196 -49-20.0% 122 90 -32 -26.2% x86-64 246 162 -84-34.1% 127 90 -37 -29.1% arm 292 216 -76-26.0% 116 92 -24 -20.7% thumb 220 136 -84-38.2% 100 50 -50 -50.0% arm64 296 188 -108-36.5% 148 116 -32 -21.6% I haven't measured the speedup because, although it's obviously faster, speed is not particularly important. (I wouldn't be using out-of-line hex2bin() if it were.) Andy Shevchenko wrote > Be honest, you increase rodata for almost the same amount of bytes. No, my original patch didn't increase rodata at all, because it replaced tables of the same size. Bringing that patch forward in the simplest way (the first copy, which I sent you privately) broke the sharing of the arrays with lib/uuid.c and thereby increased rodata by 32 bytes. But patching lib/uuid.c to share the new tables as is done in this patch series ends up with a net 16-byte reduction in rodata. > Also, please fix Cc list (I got bounce response) and add some key people > like Rasmus. Mea culpa. I manually copied the e-mail addresses and managed to typo "bjorn" into "bbjorn". >> The arrays are combined in one contiguous uuid_byte_pos[2][16] >> array as a micro-optimization for uuid_string(). > Oh, it makes readability worse. It's truly marginal, deleted. > How hex2bin is better here? We have validation done, no need to repeat. > So, I suggest not to touch this piece of code. hex2bin is better than hex_to_bin because it's does more of what we want in one call rather than needing two. As for checking the return value, it's a longish story. However, at your prompting, I've deleted it (more size savings!). Now, the story... Originally, I had eliminated the uuid_is_valid() call entirely, and just checked that the hyphens were in the right place and the digits all converted: static int __uuid_to_bin(const char *uuid, __u8 b[16], const u8 si[16]) { unsigned int i; if (uuid[ 8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-') return -EINVAL; for (i = 0; i < 16; i++) if (hex2bin(b + i, uuid + si[i], 1) < 0) return -EINVAL; return 0; } ... but I was worried that some callers might be passing in an arbitrary null-terminated string, and reading uuid[23] before checking that the preceding characters were all non-null might be a bad thing. So I put the uuid_is_valid() call back. However, I left the second return value check, on general principles, because it was cheap and I wasn't sure it wasn't useful. i was thinking about about time-of-check to time-of-use race conditions. I had just determined that I didn't know the callers and what they were doing, so I wasn't sure the source uuid would be stable for the duration of the call. However, this isn't a real TOCTTOU security bug. The only thing that corrupting the buffer can do is insert a 0xff byte in the uuid. Which is nothing that couldn't be done with a static input. So it's unnecessary. George Spelvin (2): lib/vsprintf.c: Simplify uuid_string() lib/uuid.c: eliminate uuid_[bl]e_index arrays include/linux/uuid.h | 6 -- lib/uuid.c | 24 ++-- lib/vsprintf.c | 40 +--- 3 files changed, 31 insertions(+), 39 deletions(-) -- 2.8.1
[PATCH v3 2/2] checkpatch: testing more config for Kconfig help text
Current help text check only check a config option if it is followed by another config. Adding check for help text if the next entry is menuconfig, choice/ endchoice, comment, menu/endmenu, if/endif, source or end of file. Signed-off-by: Yingjoe Chen--- scripts/checkpatch.pl | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index f5ce804..8e17593 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2646,6 +2646,12 @@ sub process { next if ($f =~ /^-/); last if (!$file && $f =~ /^\@\@/); + if ($f !~ /^[+\- ]/) { + # End of file + $is_end = 1; + last; + } + if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { $is_start = 1; } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { @@ -2656,7 +2662,7 @@ sub process { $f =~ s/#.*//; $f =~ s/^\s+//; next if ($f =~ /^$/); - if ($f =~ /^\s*config\s/) { + if ($f =~ /^(?:config\s|menuconfig\s|choice\s|endchoice\s*$|comment\s|menu\s|endmenu\s*$|if\s|endif\s*$|source\s)/) { $is_end = 1; last; } -- 1.9.1
[PATCH v3 1/2] checkpatch: add Kconfig 'default n' test
If a Kconfig config option doesn't specify 'default', the default will be n. Adding 'default n' is unnecessary. Add a test to warn about this. Signed-off-by: Yingjoe Chen--- For this series, rebase to v4.7-rc1 and dropped 'relax Kconfig help text line number threshold' patch. Let me know what you think. Thanks. Change in v3: - Rebase to v4.7-rc1 Change in v2: - Change according to Joe Perches' suggesti scripts/checkpatch.pl | 7 +++ 1 file changed, 7 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6750595..f5ce804 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2683,6 +2683,13 @@ sub process { "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); } +# discourage the use of default n + if ($realfile =~ /Kconfig/ && + $line =~ /^\+\s*default\s*n\s*(#.*|$)/i) { + WARN("CONFIG_DEFAULT_N", +"Use of default n is unnecessary, default is n when omitted.\n" . $herecurr); + } + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { my $flag = $1; -- 1.9.1
[PATCH v3 2/2] checkpatch: testing more config for Kconfig help text
Current help text check only check a config option if it is followed by another config. Adding check for help text if the next entry is menuconfig, choice/ endchoice, comment, menu/endmenu, if/endif, source or end of file. Signed-off-by: Yingjoe Chen --- scripts/checkpatch.pl | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index f5ce804..8e17593 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2646,6 +2646,12 @@ sub process { next if ($f =~ /^-/); last if (!$file && $f =~ /^\@\@/); + if ($f !~ /^[+\- ]/) { + # End of file + $is_end = 1; + last; + } + if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { $is_start = 1; } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { @@ -2656,7 +2662,7 @@ sub process { $f =~ s/#.*//; $f =~ s/^\s+//; next if ($f =~ /^$/); - if ($f =~ /^\s*config\s/) { + if ($f =~ /^(?:config\s|menuconfig\s|choice\s|endchoice\s*$|comment\s|menu\s|endmenu\s*$|if\s|endif\s*$|source\s)/) { $is_end = 1; last; } -- 1.9.1
[PATCH v3 1/2] checkpatch: add Kconfig 'default n' test
If a Kconfig config option doesn't specify 'default', the default will be n. Adding 'default n' is unnecessary. Add a test to warn about this. Signed-off-by: Yingjoe Chen --- For this series, rebase to v4.7-rc1 and dropped 'relax Kconfig help text line number threshold' patch. Let me know what you think. Thanks. Change in v3: - Rebase to v4.7-rc1 Change in v2: - Change according to Joe Perches' suggesti scripts/checkpatch.pl | 7 +++ 1 file changed, 7 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 6750595..f5ce804 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2683,6 +2683,13 @@ sub process { "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); } +# discourage the use of default n + if ($realfile =~ /Kconfig/ && + $line =~ /^\+\s*default\s*n\s*(#.*|$)/i) { + WARN("CONFIG_DEFAULT_N", +"Use of default n is unnecessary, default is n when omitted.\n" . $herecurr); + } + if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { my $flag = $1; -- 1.9.1
Re: [PATCH 6/6] x86/signal: add SA_{X32,IA32}_ABI sa_flags
On Jun 1, 2016 6:13 AM, "Dmitry Safonov"wrote: > > Introduce new flags that defines which ABI to use on creating sigframe. > Those flags kernel will set according to sigaction syscall ABI, > which set handler for the signal being delivered. > > So that will drop the dependency on TIF_IA32/TIF_X32 flags on signal deliver. > Those flags will be used only under CONFIG_COMPAT. > > Similar way ARM uses sa_flags to differ in which mode deliver signal > for 26-bit applications (look at SA_THIRYTWO). > > Cc: Andy Lutomirski > Cc: Ingo Molnar > Cc: Thomas Gleixner > Cc: "H. Peter Anvin" > Cc: Oleg Nesterov > Signed-off-by: Dmitry Safonov > --- > arch/x86/ia32/ia32_signal.c| 2 +- > arch/x86/include/asm/fpu/signal.h | 6 ++ > arch/x86/include/uapi/asm/signal.h | 6 +- > arch/x86/kernel/signal.c | 19 ++- > arch/x86/kernel/signal_compat.c| 30 +++--- > kernel/signal.c| 5 + > 6 files changed, 54 insertions(+), 14 deletions(-) > > diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c > index 2f29f4e407c3..cb13c0564ea7 100644 > --- a/arch/x86/ia32/ia32_signal.c > +++ b/arch/x86/ia32/ia32_signal.c > @@ -378,7 +378,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, > put_user_ex(*((u64 *)), (u64 __user *)frame->retcode); > } put_user_catch(err); > > - err |= copy_siginfo_to_user32(>info, >info); > + err |= __copy_siginfo_to_user32(>info, >info, false); > err |= ia32_setup_sigcontext(>uc.uc_mcontext, fpstate, > regs, set->sig[0]); > err |= __copy_to_user(>uc.uc_sigmask, set, sizeof(*set)); > diff --git a/arch/x86/include/asm/fpu/signal.h > b/arch/x86/include/asm/fpu/signal.h > index 0e970d00dfcd..20a1fbf7fe4e 100644 > --- a/arch/x86/include/asm/fpu/signal.h > +++ b/arch/x86/include/asm/fpu/signal.h > @@ -19,6 +19,12 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, > # define ia32_setup_rt_frame __setup_rt_frame > #endif > > +#ifdef CONFIG_COMPAT > +int __copy_siginfo_to_user32(compat_siginfo_t __user *to, > + const siginfo_t *from, bool x32_ABI); > +#endif > + > + > extern void convert_from_fxsr(struct user_i387_ia32_struct *env, > struct task_struct *tsk); > extern void convert_to_fxsr(struct task_struct *tsk, > diff --git a/arch/x86/include/uapi/asm/signal.h > b/arch/x86/include/uapi/asm/signal.h > index 8264f47cf53e..9c663b6fc023 100644 > --- a/arch/x86/include/uapi/asm/signal.h > +++ b/arch/x86/include/uapi/asm/signal.h > @@ -70,6 +70,8 @@ typedef unsigned long sigset_t; > * SA_RESETHAND clears the handler when the signal is delivered. > * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. > * SA_NODEFER prevents the current signal from being masked in the handler. > + * SA_IA32_ABI/SA_X32_ABI indicates ABI for a signal frame, > + * if neither is set, the kernel will set them according to a syscall ABI I would prefer if these weren't in the UAPI header. If you want a foreign signal frame type, do a foreign syscall. This also means that you should strip these flags if a user sets them directly. --Andy
Re: [PATCH 2/2] x86/entry: Inline enter_from_user_mode
On May 30, 2016 5:30 AM, "Paolo Bonzini"wrote: > > This matches what is already done for prepare_exit_to_usermode, > and saves about 60 clock cycles (4% speedup) with the benchmark > in the previous commit message. > > Cc: Andy Lutomirski > Cc: Peter Zijlstra > Cc: Rik van Riel > Cc: H. Peter Anvin > Cc: Ingo Molnar > Cc: Thomas Gleixner > Signed-off-by: Paolo Bonzini > --- > arch/x86/entry/common.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c > index 946bc1a..582bbc8 100644 > --- a/arch/x86/entry/common.c > +++ b/arch/x86/entry/common.c > @@ -40,7 +40,7 @@ static struct thread_info *pt_regs_to_thread_info(struct > pt_regs *regs) > > #ifdef CONFIG_CONTEXT_TRACKING > /* Called on entry from user mode with IRQs off. */ > -__visible void enter_from_user_mode(void) > +__visible inline void enter_from_user_mode(void) > { > CT_WARN_ON(ct_state() != CONTEXT_USER); > __user_exit(); I wonder if an extern inline *declaration* is needed as well in this C file. At least C99 suggests it is. Maybe __visible is sufficient to force an external definition to be emitted.
Re: [PATCH 6/6] x86/signal: add SA_{X32,IA32}_ABI sa_flags
On Jun 1, 2016 6:13 AM, "Dmitry Safonov" wrote: > > Introduce new flags that defines which ABI to use on creating sigframe. > Those flags kernel will set according to sigaction syscall ABI, > which set handler for the signal being delivered. > > So that will drop the dependency on TIF_IA32/TIF_X32 flags on signal deliver. > Those flags will be used only under CONFIG_COMPAT. > > Similar way ARM uses sa_flags to differ in which mode deliver signal > for 26-bit applications (look at SA_THIRYTWO). > > Cc: Andy Lutomirski > Cc: Ingo Molnar > Cc: Thomas Gleixner > Cc: "H. Peter Anvin" > Cc: Oleg Nesterov > Signed-off-by: Dmitry Safonov > --- > arch/x86/ia32/ia32_signal.c| 2 +- > arch/x86/include/asm/fpu/signal.h | 6 ++ > arch/x86/include/uapi/asm/signal.h | 6 +- > arch/x86/kernel/signal.c | 19 ++- > arch/x86/kernel/signal_compat.c| 30 +++--- > kernel/signal.c| 5 + > 6 files changed, 54 insertions(+), 14 deletions(-) > > diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c > index 2f29f4e407c3..cb13c0564ea7 100644 > --- a/arch/x86/ia32/ia32_signal.c > +++ b/arch/x86/ia32/ia32_signal.c > @@ -378,7 +378,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig, > put_user_ex(*((u64 *)), (u64 __user *)frame->retcode); > } put_user_catch(err); > > - err |= copy_siginfo_to_user32(>info, >info); > + err |= __copy_siginfo_to_user32(>info, >info, false); > err |= ia32_setup_sigcontext(>uc.uc_mcontext, fpstate, > regs, set->sig[0]); > err |= __copy_to_user(>uc.uc_sigmask, set, sizeof(*set)); > diff --git a/arch/x86/include/asm/fpu/signal.h > b/arch/x86/include/asm/fpu/signal.h > index 0e970d00dfcd..20a1fbf7fe4e 100644 > --- a/arch/x86/include/asm/fpu/signal.h > +++ b/arch/x86/include/asm/fpu/signal.h > @@ -19,6 +19,12 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, > # define ia32_setup_rt_frame __setup_rt_frame > #endif > > +#ifdef CONFIG_COMPAT > +int __copy_siginfo_to_user32(compat_siginfo_t __user *to, > + const siginfo_t *from, bool x32_ABI); > +#endif > + > + > extern void convert_from_fxsr(struct user_i387_ia32_struct *env, > struct task_struct *tsk); > extern void convert_to_fxsr(struct task_struct *tsk, > diff --git a/arch/x86/include/uapi/asm/signal.h > b/arch/x86/include/uapi/asm/signal.h > index 8264f47cf53e..9c663b6fc023 100644 > --- a/arch/x86/include/uapi/asm/signal.h > +++ b/arch/x86/include/uapi/asm/signal.h > @@ -70,6 +70,8 @@ typedef unsigned long sigset_t; > * SA_RESETHAND clears the handler when the signal is delivered. > * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. > * SA_NODEFER prevents the current signal from being masked in the handler. > + * SA_IA32_ABI/SA_X32_ABI indicates ABI for a signal frame, > + * if neither is set, the kernel will set them according to a syscall ABI I would prefer if these weren't in the UAPI header. If you want a foreign signal frame type, do a foreign syscall. This also means that you should strip these flags if a user sets them directly. --Andy
Re: [PATCH 2/2] x86/entry: Inline enter_from_user_mode
On May 30, 2016 5:30 AM, "Paolo Bonzini" wrote: > > This matches what is already done for prepare_exit_to_usermode, > and saves about 60 clock cycles (4% speedup) with the benchmark > in the previous commit message. > > Cc: Andy Lutomirski > Cc: Peter Zijlstra > Cc: Rik van Riel > Cc: H. Peter Anvin > Cc: Ingo Molnar > Cc: Thomas Gleixner > Signed-off-by: Paolo Bonzini > --- > arch/x86/entry/common.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c > index 946bc1a..582bbc8 100644 > --- a/arch/x86/entry/common.c > +++ b/arch/x86/entry/common.c > @@ -40,7 +40,7 @@ static struct thread_info *pt_regs_to_thread_info(struct > pt_regs *regs) > > #ifdef CONFIG_CONTEXT_TRACKING > /* Called on entry from user mode with IRQs off. */ > -__visible void enter_from_user_mode(void) > +__visible inline void enter_from_user_mode(void) > { > CT_WARN_ON(ct_state() != CONTEXT_USER); > __user_exit(); I wonder if an extern inline *declaration* is needed as well in this C file. At least C99 suggests it is. Maybe __visible is sufficient to force an external definition to be emitted.
Re: [PATCH 1/2] x86/entry: Avoid interrupt flag save and restore
On May 30, 2016 5:30 AM, "Paolo Bonzini"wrote: > > Thanks to all the work that was done by Andy Lutomirski and others, > enter_from_user_mode and prepare_exit_to_usermode are now called only with > interrupts disabled. Let's provide them a version of user_enter/user_exit > that skips saving and restoring the interrupt flag. > +/* Called with interrupts disabled. */ > +static inline void __user_enter(void) > +{ > + if (context_tracking_is_enabled()) > + __context_tracking_enter(CONTEXT_USER); > + > +} Would user_enter_irqs_off be a better name? --Andy
Re: [PATCH 1/2] x86/entry: Avoid interrupt flag save and restore
On May 30, 2016 5:30 AM, "Paolo Bonzini" wrote: > > Thanks to all the work that was done by Andy Lutomirski and others, > enter_from_user_mode and prepare_exit_to_usermode are now called only with > interrupts disabled. Let's provide them a version of user_enter/user_exit > that skips saving and restoring the interrupt flag. > +/* Called with interrupts disabled. */ > +static inline void __user_enter(void) > +{ > + if (context_tracking_is_enabled()) > + __context_tracking_enter(CONTEXT_USER); > + > +} Would user_enter_irqs_off be a better name? --Andy
Re: [PATCH] LSM: Fix for security_inode_getsecurity and -EOPNOTSUPP
On Tue, May 31, 2016 at 05:24:15PM -0700, Casey Schaufler wrote: > Subject: [PATCH] LSM: Fix for security_inode_getsecurity and -EOPNOTSUPP > > Serge Hallyn pointed out that the current implementation of > security_inode_getsecurity() works if there is only one hook > provided for it, but will fail if there is more than one and > the attribute requested isn't supplied by the first module. > This isn't a problem today, since only SELinux and Smack > provide this hook and there is (currently) no way to enable > both of those modules at the same time. Serge, however, wants > to introduce a capability attribute and an inode_getsecurity > hook in the capability security module to handle it. This > addresses that upcoming problem, will be required for "extreme > stacking" and is just a better implementation. > > Signed-off-by: Casey SchauflerThanks, Casey. Acked-by: Serge Hallyn > --- > > security/security.c | 29 + > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/security/security.c b/security/security.c > index 3644b03..5a749ed 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -699,18 +699,39 @@ int security_inode_killpriv(struct dentry *dentry) > > int security_inode_getsecurity(struct inode *inode, const char *name, void > **buffer, bool alloc) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, > - buffer, alloc); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, _hook_heads.inode_getsecurity, list) { > + rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_setsecurity(struct inode *inode, const char *name, const > void *value, size_t size, int flags) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, > - value, size, flags); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, _hook_heads.inode_setsecurity, list) { > + rc = hp->hook.inode_setsecurity(inode, name, value, size, > + flags); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_listsecurity(struct inode *inode, char *buffer, size_t > buffer_size)
Re: [PATCH] LSM: Fix for security_inode_getsecurity and -EOPNOTSUPP
On Tue, May 31, 2016 at 05:24:15PM -0700, Casey Schaufler wrote: > Subject: [PATCH] LSM: Fix for security_inode_getsecurity and -EOPNOTSUPP > > Serge Hallyn pointed out that the current implementation of > security_inode_getsecurity() works if there is only one hook > provided for it, but will fail if there is more than one and > the attribute requested isn't supplied by the first module. > This isn't a problem today, since only SELinux and Smack > provide this hook and there is (currently) no way to enable > both of those modules at the same time. Serge, however, wants > to introduce a capability attribute and an inode_getsecurity > hook in the capability security module to handle it. This > addresses that upcoming problem, will be required for "extreme > stacking" and is just a better implementation. > > Signed-off-by: Casey Schaufler Thanks, Casey. Acked-by: Serge Hallyn > --- > > security/security.c | 29 + > 1 file changed, 25 insertions(+), 4 deletions(-) > > diff --git a/security/security.c b/security/security.c > index 3644b03..5a749ed 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -699,18 +699,39 @@ int security_inode_killpriv(struct dentry *dentry) > > int security_inode_getsecurity(struct inode *inode, const char *name, void > **buffer, bool alloc) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_getsecurity, -EOPNOTSUPP, inode, name, > - buffer, alloc); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, _hook_heads.inode_getsecurity, list) { > + rc = hp->hook.inode_getsecurity(inode, name, buffer, alloc); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_setsecurity(struct inode *inode, const char *name, const > void *value, size_t size, int flags) > { > + struct security_hook_list *hp; > + int rc; > + > if (unlikely(IS_PRIVATE(inode))) > return -EOPNOTSUPP; > - return call_int_hook(inode_setsecurity, -EOPNOTSUPP, inode, name, > - value, size, flags); > + /* > + * Only one module will provide an attribute with a given name. > + */ > + list_for_each_entry(hp, _hook_heads.inode_setsecurity, list) { > + rc = hp->hook.inode_setsecurity(inode, name, value, size, > + flags); > + if (rc != -EOPNOTSUPP) > + return rc; > + } > + return -EOPNOTSUPP; > } > > int security_inode_listsecurity(struct inode *inode, char *buffer, size_t > buffer_size)
[power_supply] 7f8d22d52d: WARNING: CPU: 0 PID: 1 at drivers/power/power_supply_core.c:569 power_supply_read_temp+0x87/0x90
FYI, we noticed the following commit: https://github.com/0day-ci/linux Rhyland-Klein/power_supply-power_supply_read_temp-only-if-use_cnt-0/20160604-043353 commit 7f8d22d52dade417e135fd1c08ab9977882ff0b6 ("power_supply: power_supply_read_temp only if use_cnt > 0") on test machine: vm-kbuild-yocto-x86_64: 1 threads qemu-system-x86_64 -enable-kvm -cpu SandyBridge with 320M memory caused below changes: ++++ || 4a99fa06a8 | 7f8d22d52d | ++++ | boot_successes | 4 | 0 | ++++ [2.427327] power_supply test_battery: uevent [2.427748] power_supply test_battery: POWER_SUPPLY_NAME=test_battery [2.428409] [ cut here ] [2.428895] WARNING: CPU: 0 PID: 1 at drivers/power/power_supply_core.c:569 power_supply_read_temp+0x87/0x90 [2.430001] CPU: 0 PID: 1 Comm: swapper Not tainted 4.6.0-rc2-6-g7f8d22d #1 [2.430700] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014 [2.431570] 880012857cd0 81493375 880012857d10 [2.432524] 81082d09 023912857d18 88000e8ad000 880012857d84 [2.433723] 88000e8adbc0 823f6ec0 88000e8ad800 880012857d20 [2.434597] Call Trace: [2.434843] [] dump_stack+0x19/0x24 [2.435341] [] __warn+0xb9/0xe0 [2.435799] [] warn_slowpath_null+0x18/0x20 [2.436358] [] power_supply_read_temp+0x87/0x90 [2.436939] [] thermal_zone_get_temp+0x4f/0x70 [2.437519] [] thermal_zone_device_update+0x17/0x110 [2.438214] [] ? debug_object_init+0x16/0x20 [2.438778] [] thermal_zone_device_register+0x834/0x920 [2.439431] [] __power_supply_register+0x242/0x500 [2.440041] [] power_supply_register+0xe/0x10 [2.440626] [] test_power_init+0x4b/0xb2 [2.441160] [] ? wm831x_backup_driver_init+0x14/0x14 [2.441799] [] do_one_initcall+0xf1/0x182 [2.442344] [] ? set_debug_rodata+0x12/0x12 [2.442896] [] kernel_init_freeable+0x11f/0x1a7 [2.443488] [] kernel_init+0x9/0xf0 [2.443995] [] ret_from_fork+0x22/0x40 [2.444522] [] ? rest_init+0x80/0x80 [2.445028] ---[ end trace cc5ecf4c9ffecec6 ]--- [2.445495] __power_supply_register: Expected proper parent device for 'test_usb' FYI, raw QEMU command line is: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -kernel /pkg/linux/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/vmlinuz-4.6.0-rc2-6-g7f8d22d -append 'root=/dev/ram0 user=lkp job=/lkp/scheduled/vm-kbuild-yocto-x86_64-6/bisect_boot-1-yocto-minimal-x86_64.cgz-x86_64-randconfig-s2-06040635-7f8d22d52dade417e135fd1c08ab9977882ff0b6-20160604-100904-1gq6z3z-1.yaml ARCH=x86_64 kconfig=x86_64-randconfig-s2-06040635 branch=linux-devel/devel-spot-201606040556 commit=7f8d22d52dade417e135fd1c08ab9977882ff0b6 BOOT_IMAGE=/pkg/linux/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/vmlinuz-4.6.0-rc2-6-g7f8d22d max_uptime=600 RESULT_ROOT=/result/boot/1/vm-kbuild-yocto-x86_64/yocto-minimal-x86_64.cgz/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/0 LKP_SERVER=inn earlyprintk=ttyS0,115200 systemd.log_level=err debug apic=debug sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic load_ramdisk=2 prompt_ramdisk=0 console=ttyS0,115200 console=tty0 vga=normal rw ip=vm-kbuild-yocto-x86_64-6::dhcp drbd.minor_count=8' -initrd /fs/sdc1/initrd-vm-kbuild-yocto-x86_64-6 -m 320 -smp 1 -device e1000,netdev=net0 -netdev user,id=net0 -boot order=nc -no-reboot -watchdog i6300esb -rtc base=localtime -drive file=/fs/sdc1/disk0-vm-kbuild-yocto-x86_64-6,media=disk,if=virtio -pidfile /dev/shm/kboot/pid-vm-kbuild-yocto-x86_64-6 -serial file:/dev/shm/kboot/serial-vm-kbuild-yocto-x86_64-6 -daemonize -display none -monitor null Thanks, Kernel Test Robot # # Automatically generated file; DO NOT EDIT. # Linux/x86_64 4.6.0-rc2 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_PERF_EVENTS_INTEL_UNCORE=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=28 CONFIG_ARCH_MMAP_RND_BITS_MAX=32 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y
[power_supply] 7f8d22d52d: WARNING: CPU: 0 PID: 1 at drivers/power/power_supply_core.c:569 power_supply_read_temp+0x87/0x90
FYI, we noticed the following commit: https://github.com/0day-ci/linux Rhyland-Klein/power_supply-power_supply_read_temp-only-if-use_cnt-0/20160604-043353 commit 7f8d22d52dade417e135fd1c08ab9977882ff0b6 ("power_supply: power_supply_read_temp only if use_cnt > 0") on test machine: vm-kbuild-yocto-x86_64: 1 threads qemu-system-x86_64 -enable-kvm -cpu SandyBridge with 320M memory caused below changes: ++++ || 4a99fa06a8 | 7f8d22d52d | ++++ | boot_successes | 4 | 0 | ++++ [2.427327] power_supply test_battery: uevent [2.427748] power_supply test_battery: POWER_SUPPLY_NAME=test_battery [2.428409] [ cut here ] [2.428895] WARNING: CPU: 0 PID: 1 at drivers/power/power_supply_core.c:569 power_supply_read_temp+0x87/0x90 [2.430001] CPU: 0 PID: 1 Comm: swapper Not tainted 4.6.0-rc2-6-g7f8d22d #1 [2.430700] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Debian-1.8.2-1 04/01/2014 [2.431570] 880012857cd0 81493375 880012857d10 [2.432524] 81082d09 023912857d18 88000e8ad000 880012857d84 [2.433723] 88000e8adbc0 823f6ec0 88000e8ad800 880012857d20 [2.434597] Call Trace: [2.434843] [] dump_stack+0x19/0x24 [2.435341] [] __warn+0xb9/0xe0 [2.435799] [] warn_slowpath_null+0x18/0x20 [2.436358] [] power_supply_read_temp+0x87/0x90 [2.436939] [] thermal_zone_get_temp+0x4f/0x70 [2.437519] [] thermal_zone_device_update+0x17/0x110 [2.438214] [] ? debug_object_init+0x16/0x20 [2.438778] [] thermal_zone_device_register+0x834/0x920 [2.439431] [] __power_supply_register+0x242/0x500 [2.440041] [] power_supply_register+0xe/0x10 [2.440626] [] test_power_init+0x4b/0xb2 [2.441160] [] ? wm831x_backup_driver_init+0x14/0x14 [2.441799] [] do_one_initcall+0xf1/0x182 [2.442344] [] ? set_debug_rodata+0x12/0x12 [2.442896] [] kernel_init_freeable+0x11f/0x1a7 [2.443488] [] kernel_init+0x9/0xf0 [2.443995] [] ret_from_fork+0x22/0x40 [2.444522] [] ? rest_init+0x80/0x80 [2.445028] ---[ end trace cc5ecf4c9ffecec6 ]--- [2.445495] __power_supply_register: Expected proper parent device for 'test_usb' FYI, raw QEMU command line is: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -kernel /pkg/linux/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/vmlinuz-4.6.0-rc2-6-g7f8d22d -append 'root=/dev/ram0 user=lkp job=/lkp/scheduled/vm-kbuild-yocto-x86_64-6/bisect_boot-1-yocto-minimal-x86_64.cgz-x86_64-randconfig-s2-06040635-7f8d22d52dade417e135fd1c08ab9977882ff0b6-20160604-100904-1gq6z3z-1.yaml ARCH=x86_64 kconfig=x86_64-randconfig-s2-06040635 branch=linux-devel/devel-spot-201606040556 commit=7f8d22d52dade417e135fd1c08ab9977882ff0b6 BOOT_IMAGE=/pkg/linux/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/vmlinuz-4.6.0-rc2-6-g7f8d22d max_uptime=600 RESULT_ROOT=/result/boot/1/vm-kbuild-yocto-x86_64/yocto-minimal-x86_64.cgz/x86_64-randconfig-s2-06040635/gcc-6/7f8d22d52dade417e135fd1c08ab9977882ff0b6/0 LKP_SERVER=inn earlyprintk=ttyS0,115200 systemd.log_level=err debug apic=debug sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic load_ramdisk=2 prompt_ramdisk=0 console=ttyS0,115200 console=tty0 vga=normal rw ip=vm-kbuild-yocto-x86_64-6::dhcp drbd.minor_count=8' -initrd /fs/sdc1/initrd-vm-kbuild-yocto-x86_64-6 -m 320 -smp 1 -device e1000,netdev=net0 -netdev user,id=net0 -boot order=nc -no-reboot -watchdog i6300esb -rtc base=localtime -drive file=/fs/sdc1/disk0-vm-kbuild-yocto-x86_64-6,media=disk,if=virtio -pidfile /dev/shm/kboot/pid-vm-kbuild-yocto-x86_64-6 -serial file:/dev/shm/kboot/serial-vm-kbuild-yocto-x86_64-6 -daemonize -display none -monitor null Thanks, Kernel Test Robot # # Automatically generated file; DO NOT EDIT. # Linux/x86_64 4.6.0-rc2 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_PERF_EVENTS_INTEL_UNCORE=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=28 CONFIG_ARCH_MMAP_RND_BITS_MAX=32 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y
Re: [PATCH] hwmon: (tmp401) Add support for TI TMP461
On 05/31/2016 09:27 AM, Andrew F. Davis wrote: Signed-off-by: Andrew F. Davis--- Documentation/hwmon/tmp401 | 18 +-- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/tmp401.c | 81 ++ 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 index 711f75e..eaa2d3b 100644 --- a/Documentation/hwmon/tmp401 +++ b/Documentation/hwmon/tmp401 @@ -22,6 +22,9 @@ Supported chips: Prefix: 'tmp435' Addresses scanned: I2C 0x48 - 0x4f Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html + * Texas Instruments TMP461 +Prefix: 'tmp461' +Datasheet: http://www.ti.com/product/tmp461 Authors: Hans de Goede @@ -31,8 +34,8 @@ Description --- This driver implements support for Texas Instruments TMP401, TMP411, -TMP431, TMP432 and TMP435 chips. These chips implement one or two remote -and one local temperature sensors. Temperature is measured in degrees +TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two +remote and one local temperature sensors. Temperature is measured in degrees Celsius. Resolution of the remote sensor is 0.0625 degree. Local sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not supported by the driver so far, so using the default resolution of 0.5 @@ -55,3 +58,14 @@ some additional features. TMP432 is compatible with TMP401 and TMP431. It supports two external temperature sensors. + +TMP461 is compatible with TMP401. It supports offset and n-factor correction +that is applied to the remote sensor. + +* Sensor offset values are temperature values + + Exported via sysfs attribute tempX_offset + +* n-factor correction, values are in raw form as described in the datasheet + If you don't mind, I would prefer if you would drop this attribute, at least for now, for a number of reasons. It should not really be controlled by a sysfs attribute, but either with devicetree data or platform data. Exposing a raw register value through sysfs isn't really desirable; sysfs is supposed to provide some kind of abstraction. It enables setting the n-factor, but not beta-compensation which is probably equally desirable. Last but not least, other chips supported by this driver, as well as other chips supported by hwmon, also support n-factor correction and beta-compensation. If we provide this functionality we should provide it for all chips in a generic way. In short, this needs more discussion. Couple of additional additional comments below. Thanks, Guenter + Exported via sysfs attribute tempX_nfactor diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ff94007..c571dcf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1561,7 +1561,7 @@ config SENSORS_TMP401 depends on I2C help If you say yes here you get support for Texas Instruments TMP401, - TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. + TMP411, TMP431, TMP432, TMP435, and TMP461 temperature sensor chips. This driver can also be built as a module. If so, the module will be called tmp401. diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ccf4cff..280065b 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -47,7 +47,8 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; -enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; + Please no double empty lines. /* * The TMP401 registers, note some registers have different addresses for @@ -62,31 +63,37 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; #define TMP401_MANUFACTURER_ID_REG0xFE #define TMP401_DEVICE_ID_REG 0xFF -static const u8 TMP401_TEMP_MSB_READ[6][2] = { +static const u8 TMP401_TEMP_MSB_READ[8][2] = { { 0x00, 0x01 }, /* temp */ { 0x06, 0x08 }, /* low limit */ { 0x05, 0x07 }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 },/* offset */ + { 0, 0x23 },/* nfactor */ }; -static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { +static const u8 TMP401_TEMP_MSB_WRITE[8][2] = { { 0, 0 }, /* temp (unused) */ { 0x0C, 0x0E }, /* low limit */ { 0x0B, 0x0D }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 },/* offset */ + { 0, 0x23 },/* nfactor */ }; -static const u8 TMP401_TEMP_LSB[6][2] = { +static const u8 TMP401_TEMP_LSB[8][2] = { { 0x15, 0x10 }, /* temp */ { 0x17, 0x14 }, /* low limit */ { 0x16, 0x13
Re: [PATCH] hwmon: (tmp401) Add support for TI TMP461
On 05/31/2016 09:27 AM, Andrew F. Davis wrote: Signed-off-by: Andrew F. Davis --- Documentation/hwmon/tmp401 | 18 +-- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/tmp401.c | 81 ++ 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/Documentation/hwmon/tmp401 b/Documentation/hwmon/tmp401 index 711f75e..eaa2d3b 100644 --- a/Documentation/hwmon/tmp401 +++ b/Documentation/hwmon/tmp401 @@ -22,6 +22,9 @@ Supported chips: Prefix: 'tmp435' Addresses scanned: I2C 0x48 - 0x4f Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html + * Texas Instruments TMP461 +Prefix: 'tmp461' +Datasheet: http://www.ti.com/product/tmp461 Authors: Hans de Goede @@ -31,8 +34,8 @@ Description --- This driver implements support for Texas Instruments TMP401, TMP411, -TMP431, TMP432 and TMP435 chips. These chips implement one or two remote -and one local temperature sensors. Temperature is measured in degrees +TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two +remote and one local temperature sensors. Temperature is measured in degrees Celsius. Resolution of the remote sensor is 0.0625 degree. Local sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not supported by the driver so far, so using the default resolution of 0.5 @@ -55,3 +58,14 @@ some additional features. TMP432 is compatible with TMP401 and TMP431. It supports two external temperature sensors. + +TMP461 is compatible with TMP401. It supports offset and n-factor correction +that is applied to the remote sensor. + +* Sensor offset values are temperature values + + Exported via sysfs attribute tempX_offset + +* n-factor correction, values are in raw form as described in the datasheet + If you don't mind, I would prefer if you would drop this attribute, at least for now, for a number of reasons. It should not really be controlled by a sysfs attribute, but either with devicetree data or platform data. Exposing a raw register value through sysfs isn't really desirable; sysfs is supposed to provide some kind of abstraction. It enables setting the n-factor, but not beta-compensation which is probably equally desirable. Last but not least, other chips supported by this driver, as well as other chips supported by hwmon, also support n-factor correction and beta-compensation. If we provide this functionality we should provide it for all chips in a generic way. In short, this needs more discussion. Couple of additional additional comments below. Thanks, Guenter + Exported via sysfs attribute tempX_nfactor diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ff94007..c571dcf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1561,7 +1561,7 @@ config SENSORS_TMP401 depends on I2C help If you say yes here you get support for Texas Instruments TMP401, - TMP411, TMP431, TMP432 and TMP435 temperature sensor chips. + TMP411, TMP431, TMP432, TMP435, and TMP461 temperature sensor chips. This driver can also be built as a module. If so, the module will be called tmp401. diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index ccf4cff..280065b 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -47,7 +47,8 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; -enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; +enum chips { tmp401, tmp411, tmp431, tmp432, tmp435, tmp461 }; + Please no double empty lines. /* * The TMP401 registers, note some registers have different addresses for @@ -62,31 +63,37 @@ enum chips { tmp401, tmp411, tmp431, tmp432, tmp435 }; #define TMP401_MANUFACTURER_ID_REG0xFE #define TMP401_DEVICE_ID_REG 0xFF -static const u8 TMP401_TEMP_MSB_READ[6][2] = { +static const u8 TMP401_TEMP_MSB_READ[8][2] = { { 0x00, 0x01 }, /* temp */ { 0x06, 0x08 }, /* low limit */ { 0x05, 0x07 }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 },/* offset */ + { 0, 0x23 },/* nfactor */ }; -static const u8 TMP401_TEMP_MSB_WRITE[6][2] = { +static const u8 TMP401_TEMP_MSB_WRITE[8][2] = { { 0, 0 }, /* temp (unused) */ { 0x0C, 0x0E }, /* low limit */ { 0x0B, 0x0D }, /* high limit */ { 0x20, 0x19 }, /* therm (crit) limit */ { 0x30, 0x34 }, /* lowest */ { 0x32, 0x36 }, /* highest */ + { 0, 0x11 },/* offset */ + { 0, 0x23 },/* nfactor */ }; -static const u8 TMP401_TEMP_LSB[6][2] = { +static const u8 TMP401_TEMP_LSB[8][2] = { { 0x15, 0x10 }, /* temp */ { 0x17, 0x14 }, /* low limit */ { 0x16, 0x13 }, /* high limit */ { 0, 0
Re: [PATCH 1/1 v6] hwmon: add support for Sensirion SHT3x sensors
On 06/02/2016 12:59 AM, Pascal Sachs wrote: From: David FreyThis driver implements support for the Sensirion SHT3x-DIS chip, a humidity and temperature sensor. Temperature is measured in degrees celsius, relative humidity is expressed as a percentage. In the sysfs interface, all values are scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. Signed-off-by: Pascal Sachs Applied to -next. Thanks, Guenter
Re: [PATCH 1/1 v6] hwmon: add support for Sensirion SHT3x sensors
On 06/02/2016 12:59 AM, Pascal Sachs wrote: From: David Frey This driver implements support for the Sensirion SHT3x-DIS chip, a humidity and temperature sensor. Temperature is measured in degrees celsius, relative humidity is expressed as a percentage. In the sysfs interface, all values are scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500. Signed-off-by: Pascal Sachs Applied to -next. Thanks, Guenter
Re: [PATCH] hwmon: ina2xx: Document compatible for INA231
On 06/01/2016 02:43 AM, Krzysztof Kozlowski wrote: Document the compatible for INA231 sensor. Signed-off-by: Krzysztof KozlowskiApplied. Thanks, Guenter --- Documentation/devicetree/bindings/hwmon/ina2xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/hwmon/ina2xx.txt b/Documentation/devicetree/bindings/hwmon/ina2xx.txt index 9bcd5e87830d..02af0d94e921 100644 --- a/Documentation/devicetree/bindings/hwmon/ina2xx.txt +++ b/Documentation/devicetree/bindings/hwmon/ina2xx.txt @@ -7,6 +7,7 @@ Required properties: - "ti,ina220" for ina220 - "ti,ina226" for ina226 - "ti,ina230" for ina230 + - "ti,ina231" for ina231 - reg: I2C address Optional properties:
Re: [PATCH] hwmon: ina2xx: Document compatible for INA231
On 06/01/2016 02:43 AM, Krzysztof Kozlowski wrote: Document the compatible for INA231 sensor. Signed-off-by: Krzysztof Kozlowski Applied. Thanks, Guenter --- Documentation/devicetree/bindings/hwmon/ina2xx.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/hwmon/ina2xx.txt b/Documentation/devicetree/bindings/hwmon/ina2xx.txt index 9bcd5e87830d..02af0d94e921 100644 --- a/Documentation/devicetree/bindings/hwmon/ina2xx.txt +++ b/Documentation/devicetree/bindings/hwmon/ina2xx.txt @@ -7,6 +7,7 @@ Required properties: - "ti,ina220" for ina220 - "ti,ina226" for ina226 - "ti,ina230" for ina230 + - "ti,ina231" for ina231 - reg: I2C address Optional properties:
[PATCH v2 1/2] b43: Remove unused phy_a code
gcc-6 reports the following error with -Werror=unused-const-variable. drivers/net/wireless/broadcom/b43/phy_a.c:576:40: error: 'b43_phyops_a' defined but not used Per Michael Büsch: "All a-phy code is usused", so remove phy_a.c completely. Move the remaining Type-G initialization code into phy_g.c. Reported-by: Fengguang Wu[0-day test robot] Signed-off-by: Guenter Roeck --- v2: Remove phy_a.c; move left-over code into phy_g.c Remove now unused data structure drivers/net/wireless/broadcom/b43/Makefile | 2 +- drivers/net/wireless/broadcom/b43/phy_a.c | 595 - drivers/net/wireless/broadcom/b43/phy_a.h | 22 - drivers/net/wireless/broadcom/b43/phy_common.h | 3 - drivers/net/wireless/broadcom/b43/phy_g.c | 27 +- 5 files changed, 22 insertions(+), 627 deletions(-) delete mode 100644 drivers/net/wireless/broadcom/b43/phy_a.c diff --git a/drivers/net/wireless/broadcom/b43/Makefile b/drivers/net/wireless/broadcom/b43/Makefile index ddc4df46656f..27fab958e3d5 100644 --- a/drivers/net/wireless/broadcom/b43/Makefile +++ b/drivers/net/wireless/broadcom/b43/Makefile @@ -1,6 +1,6 @@ b43-y += main.o b43-y += bus.o -b43-$(CONFIG_B43_PHY_G)+= phy_a.o phy_g.o tables.o lo.o wa.o +b43-$(CONFIG_B43_PHY_G)+= phy_g.o tables.o lo.o wa.o b43-$(CONFIG_B43_PHY_N)+= tables_nphy.o b43-$(CONFIG_B43_PHY_N)+= radio_2055.o b43-$(CONFIG_B43_PHY_N)+= radio_2056.o diff --git a/drivers/net/wireless/broadcom/b43/phy_a.c b/drivers/net/wireless/broadcom/b43/phy_a.c deleted file mode 100644 index 99c036f5ecb7.. --- a/drivers/net/wireless/broadcom/b43/phy_a.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - - Broadcom B43 wireless driver - IEEE 802.11a PHY driver - - Copyright (c) 2005 Martin Langer , - Copyright (c) 2005-2007 Stefano Brivio - Copyright (c) 2005-2008 Michael Buesch - Copyright (c) 2005, 2006 Danny van Dyk - Copyright (c) 2005, 2006 Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "b43.h" -#include "phy_a.h" -#include "phy_common.h" -#include "wa.h" -#include "tables.h" -#include "main.h" - - -/* Get the freq, as it has to be written to the device. */ -static inline u16 channel2freq_a(u8 channel) -{ - B43_WARN_ON(channel > 200); - - return (5000 + 5 * channel); -} - -static inline u16 freq_r3A_value(u16 frequency) -{ - u16 value; - - if (frequency < 5091) - value = 0x0040; - else if (frequency < 5321) - value = 0x; - else if (frequency < 5806) - value = 0x0080; - else - value = 0x0040; - - return value; -} - -#if 0 -/* This function converts a TSSI value to dBm in Q5.2 */ -static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi) -{ - struct b43_phy *phy = >phy; - struct b43_phy_a *aphy = phy->a; - s8 dbm = 0; - s32 tmp; - - tmp = (aphy->tgt_idle_tssi - aphy->cur_idle_tssi + tssi); - tmp += 0x80; - tmp = clamp_val(tmp, 0x00, 0xFF); - dbm = aphy->tssi2dbm[tmp]; - //TODO: There's a FIXME on the specs - - return dbm; -} -#endif - -static void b43_radio_set_tx_iq(struct b43_wldev *dev) -{ - static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; - static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; - u16 tmp = b43_radio_read16(dev, 0x001E); - int i, j; - - for (i = 0; i < 5; i++) { - for (j = 0; j < 5; j++) { - if (tmp == (data_high[i] << 4 | data_low[j])) { - b43_phy_write(dev, 0x0069, - (i - j) << 8 | 0x00C0); - return; - } - } - } -} - -static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel) -{ - u16 freq, r8, tmp; - - freq = channel2freq_a(channel); - - r8 = b43_radio_read16(dev, 0x0008); -
[PATCH v2 2/2] b43: Completely remove support for phy_a
Per Michael Büsch: "All a-phy code is usused", so remove it all. Signed-off-by: Guenter Roeck--- v2: Added patch drivers/net/wireless/broadcom/b43/main.c | 31 +--- drivers/net/wireless/broadcom/b43/wa.c | 283 +++ drivers/net/wireless/broadcom/b43/xmit.c | 17 +- 3 files changed, 24 insertions(+), 307 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 4ee5c5853f9f..6e5d9095b195 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -3180,7 +3180,6 @@ static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) static void b43_rate_memory_init(struct b43_wldev *dev) { switch (dev->phy.type) { - case B43_PHYTYPE_A: case B43_PHYTYPE_G: case B43_PHYTYPE_N: case B43_PHYTYPE_LP: @@ -3194,8 +3193,6 @@ static void b43_rate_memory_init(struct b43_wldev *dev) b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1); - if (dev->phy.type == B43_PHYTYPE_A) - break; /* fallthrough */ case B43_PHYTYPE_B: b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0); @@ -4604,14 +4601,6 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_manuf != 0x17F /* Broadcom */) unsupported = 1; switch (phy_type) { - case B43_PHYTYPE_A: - if (radio_id != 0x2060) - unsupported = 1; - if (radio_rev != 1) - unsupported = 1; - if (radio_manuf != 0x17F) - unsupported = 1; - break; case B43_PHYTYPE_B: if ((radio_id & 0xFFF0) != 0x2050) unsupported = 1; @@ -4766,10 +4755,7 @@ static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle) u16 pu_delay; /* The time value is in microseconds. */ - if (dev->phy.type == B43_PHYTYPE_A) - pu_delay = 3700; - else - pu_delay = 1050; + pu_delay = 1050; if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle) pu_delay = 500; if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8)) @@ -4784,14 +4770,10 @@ static void b43_set_pretbtt(struct b43_wldev *dev) u16 pretbtt; /* The time value is in microseconds. */ - if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) { + if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) pretbtt = 2; - } else { - if (dev->phy.type == B43_PHYTYPE_A) - pretbtt = 120; - else - pretbtt = 250; - } + else + pretbtt = 250; b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt); b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt); } @@ -5380,10 +5362,6 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy, /* As a fallback, try to guess using PHY type */ switch (dev->phy.type) { - case B43_PHYTYPE_A: - *have_2ghz_phy = false; - *have_5ghz_phy = true; - return; case B43_PHYTYPE_G: case B43_PHYTYPE_N: case B43_PHYTYPE_LP: @@ -5455,7 +5433,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) /* We don't support 5 GHz on some PHYs yet */ if (have_5ghz_phy) { switch (dev->phy.type) { - case B43_PHYTYPE_A: case B43_PHYTYPE_G: case B43_PHYTYPE_LP: case B43_PHYTYPE_HT: diff --git a/drivers/net/wireless/broadcom/b43/wa.c b/drivers/net/wireless/broadcom/b43/wa.c index c218c08fb2f5..0e96c08d1e17 100644 --- a/drivers/net/wireless/broadcom/b43/wa.c +++ b/drivers/net/wireless/broadcom/b43/wa.c @@ -30,33 +30,6 @@ #include "phy_common.h" #include "wa.h" -static void b43_wa_papd(struct b43_wldev *dev) -{ - u16 backup; - - backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); - b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); - b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); - b43_dummy_transmission(dev, true, true); - b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); -} - -static void b43_wa_auxclipthr(struct b43_wldev *dev) -{ - b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); -} - -static void b43_wa_afcdac(struct b43_wldev *dev) -{ - b43_phy_write(dev, 0x0035, 0x03FF); - b43_phy_write(dev, 0x0036, 0x0400); -} - -static void b43_wa_txdc_offset(struct b43_wldev *dev) -{ - b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); -} - void b43_wa_initgains(struct b43_wldev
[PATCH v2 1/2] b43: Remove unused phy_a code
gcc-6 reports the following error with -Werror=unused-const-variable. drivers/net/wireless/broadcom/b43/phy_a.c:576:40: error: 'b43_phyops_a' defined but not used Per Michael Büsch: "All a-phy code is usused", so remove phy_a.c completely. Move the remaining Type-G initialization code into phy_g.c. Reported-by: Fengguang Wu [0-day test robot] Signed-off-by: Guenter Roeck --- v2: Remove phy_a.c; move left-over code into phy_g.c Remove now unused data structure drivers/net/wireless/broadcom/b43/Makefile | 2 +- drivers/net/wireless/broadcom/b43/phy_a.c | 595 - drivers/net/wireless/broadcom/b43/phy_a.h | 22 - drivers/net/wireless/broadcom/b43/phy_common.h | 3 - drivers/net/wireless/broadcom/b43/phy_g.c | 27 +- 5 files changed, 22 insertions(+), 627 deletions(-) delete mode 100644 drivers/net/wireless/broadcom/b43/phy_a.c diff --git a/drivers/net/wireless/broadcom/b43/Makefile b/drivers/net/wireless/broadcom/b43/Makefile index ddc4df46656f..27fab958e3d5 100644 --- a/drivers/net/wireless/broadcom/b43/Makefile +++ b/drivers/net/wireless/broadcom/b43/Makefile @@ -1,6 +1,6 @@ b43-y += main.o b43-y += bus.o -b43-$(CONFIG_B43_PHY_G)+= phy_a.o phy_g.o tables.o lo.o wa.o +b43-$(CONFIG_B43_PHY_G)+= phy_g.o tables.o lo.o wa.o b43-$(CONFIG_B43_PHY_N)+= tables_nphy.o b43-$(CONFIG_B43_PHY_N)+= radio_2055.o b43-$(CONFIG_B43_PHY_N)+= radio_2056.o diff --git a/drivers/net/wireless/broadcom/b43/phy_a.c b/drivers/net/wireless/broadcom/b43/phy_a.c deleted file mode 100644 index 99c036f5ecb7.. --- a/drivers/net/wireless/broadcom/b43/phy_a.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - - Broadcom B43 wireless driver - IEEE 802.11a PHY driver - - Copyright (c) 2005 Martin Langer , - Copyright (c) 2005-2007 Stefano Brivio - Copyright (c) 2005-2008 Michael Buesch - Copyright (c) 2005, 2006 Danny van Dyk - Copyright (c) 2005, 2006 Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "b43.h" -#include "phy_a.h" -#include "phy_common.h" -#include "wa.h" -#include "tables.h" -#include "main.h" - - -/* Get the freq, as it has to be written to the device. */ -static inline u16 channel2freq_a(u8 channel) -{ - B43_WARN_ON(channel > 200); - - return (5000 + 5 * channel); -} - -static inline u16 freq_r3A_value(u16 frequency) -{ - u16 value; - - if (frequency < 5091) - value = 0x0040; - else if (frequency < 5321) - value = 0x; - else if (frequency < 5806) - value = 0x0080; - else - value = 0x0040; - - return value; -} - -#if 0 -/* This function converts a TSSI value to dBm in Q5.2 */ -static s8 b43_aphy_estimate_power_out(struct b43_wldev *dev, s8 tssi) -{ - struct b43_phy *phy = >phy; - struct b43_phy_a *aphy = phy->a; - s8 dbm = 0; - s32 tmp; - - tmp = (aphy->tgt_idle_tssi - aphy->cur_idle_tssi + tssi); - tmp += 0x80; - tmp = clamp_val(tmp, 0x00, 0xFF); - dbm = aphy->tssi2dbm[tmp]; - //TODO: There's a FIXME on the specs - - return dbm; -} -#endif - -static void b43_radio_set_tx_iq(struct b43_wldev *dev) -{ - static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; - static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; - u16 tmp = b43_radio_read16(dev, 0x001E); - int i, j; - - for (i = 0; i < 5; i++) { - for (j = 0; j < 5; j++) { - if (tmp == (data_high[i] << 4 | data_low[j])) { - b43_phy_write(dev, 0x0069, - (i - j) << 8 | 0x00C0); - return; - } - } - } -} - -static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel) -{ - u16 freq, r8, tmp; - - freq = channel2freq_a(channel); - - r8 = b43_radio_read16(dev, 0x0008); - b43_write16(dev, 0x03F0, freq); - b43_radio_write16(dev, 0x0008, r8); - - //TODO: write max channel TX power? to Radio 0x2D - tmp =
[PATCH v2 2/2] b43: Completely remove support for phy_a
Per Michael Büsch: "All a-phy code is usused", so remove it all. Signed-off-by: Guenter Roeck --- v2: Added patch drivers/net/wireless/broadcom/b43/main.c | 31 +--- drivers/net/wireless/broadcom/b43/wa.c | 283 +++ drivers/net/wireless/broadcom/b43/xmit.c | 17 +- 3 files changed, 24 insertions(+), 307 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index 4ee5c5853f9f..6e5d9095b195 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -3180,7 +3180,6 @@ static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) static void b43_rate_memory_init(struct b43_wldev *dev) { switch (dev->phy.type) { - case B43_PHYTYPE_A: case B43_PHYTYPE_G: case B43_PHYTYPE_N: case B43_PHYTYPE_LP: @@ -3194,8 +3193,6 @@ static void b43_rate_memory_init(struct b43_wldev *dev) b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1); - if (dev->phy.type == B43_PHYTYPE_A) - break; /* fallthrough */ case B43_PHYTYPE_B: b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0); @@ -4604,14 +4601,6 @@ static int b43_phy_versioning(struct b43_wldev *dev) if (radio_manuf != 0x17F /* Broadcom */) unsupported = 1; switch (phy_type) { - case B43_PHYTYPE_A: - if (radio_id != 0x2060) - unsupported = 1; - if (radio_rev != 1) - unsupported = 1; - if (radio_manuf != 0x17F) - unsupported = 1; - break; case B43_PHYTYPE_B: if ((radio_id & 0xFFF0) != 0x2050) unsupported = 1; @@ -4766,10 +4755,7 @@ static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle) u16 pu_delay; /* The time value is in microseconds. */ - if (dev->phy.type == B43_PHYTYPE_A) - pu_delay = 3700; - else - pu_delay = 1050; + pu_delay = 1050; if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle) pu_delay = 500; if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8)) @@ -4784,14 +4770,10 @@ static void b43_set_pretbtt(struct b43_wldev *dev) u16 pretbtt; /* The time value is in microseconds. */ - if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) { + if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) pretbtt = 2; - } else { - if (dev->phy.type == B43_PHYTYPE_A) - pretbtt = 120; - else - pretbtt = 250; - } + else + pretbtt = 250; b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt); b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt); } @@ -5380,10 +5362,6 @@ static void b43_supported_bands(struct b43_wldev *dev, bool *have_2ghz_phy, /* As a fallback, try to guess using PHY type */ switch (dev->phy.type) { - case B43_PHYTYPE_A: - *have_2ghz_phy = false; - *have_5ghz_phy = true; - return; case B43_PHYTYPE_G: case B43_PHYTYPE_N: case B43_PHYTYPE_LP: @@ -5455,7 +5433,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) /* We don't support 5 GHz on some PHYs yet */ if (have_5ghz_phy) { switch (dev->phy.type) { - case B43_PHYTYPE_A: case B43_PHYTYPE_G: case B43_PHYTYPE_LP: case B43_PHYTYPE_HT: diff --git a/drivers/net/wireless/broadcom/b43/wa.c b/drivers/net/wireless/broadcom/b43/wa.c index c218c08fb2f5..0e96c08d1e17 100644 --- a/drivers/net/wireless/broadcom/b43/wa.c +++ b/drivers/net/wireless/broadcom/b43/wa.c @@ -30,33 +30,6 @@ #include "phy_common.h" #include "wa.h" -static void b43_wa_papd(struct b43_wldev *dev) -{ - u16 backup; - - backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); - b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); - b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); - b43_dummy_transmission(dev, true, true); - b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); -} - -static void b43_wa_auxclipthr(struct b43_wldev *dev) -{ - b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); -} - -static void b43_wa_afcdac(struct b43_wldev *dev) -{ - b43_phy_write(dev, 0x0035, 0x03FF); - b43_phy_write(dev, 0x0036, 0x0400); -} - -static void b43_wa_txdc_offset(struct b43_wldev *dev) -{ - b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); -} - void b43_wa_initgains(struct b43_wldev *dev) {
Re: [PATCH v13 03/10] arm64: add conditional instruction simulation support
On Thu, 2 Jun 2016 23:26:17 -0400 David Longwrote: > From: "David A. Long" > > Cease using the arm32 arm_check_condition() function and replace it with > a local version for use in deprecated instruction support on arm64. Also > make the function table used by this available for future use by kprobes > and/or uprobes. > > This function is dervied from code written by Sandeepa Prabhu. > Basically looks good to me. I have some comments; > Signed-off-by: Sandeepa Prabhu > Signed-off-by: David A. Long > --- > arch/arm64/include/asm/insn.h| 3 ++ > arch/arm64/kernel/Makefile | 3 +- > arch/arm64/kernel/armv8_deprecated.c | 19 ++- > arch/arm64/kernel/insn.c | 98 > > 4 files changed, 119 insertions(+), 4 deletions(-) > > diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h > index 9785d10..98e4edd 100644 > --- a/arch/arm64/include/asm/insn.h > +++ b/arch/arm64/include/asm/insn.h > @@ -406,6 +406,9 @@ u32 aarch64_extract_system_register(u32 insn); > u32 aarch32_insn_extract_reg_num(u32 insn, int offset); > u32 aarch32_insn_mcr_extract_opc2(u32 insn); > u32 aarch32_insn_mcr_extract_crm(u32 insn); > + > +typedef bool (pstate_check_t)(unsigned long); > +extern pstate_check_t * const opcode_condition_checks[16]; Are those condition checkers only for aarch32 opcode? or general for aarch64 too? If it is only for aarch32, we'd better add aarch32 prefix. > #endif /* __ASSEMBLY__ */ > > #endif /* __ASM_INSN_H */ > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile > index 2173149..4653aca 100644 > --- a/arch/arm64/kernel/Makefile > +++ b/arch/arm64/kernel/Makefile > @@ -26,8 +26,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE > $(call if_changed,objcopy) > > arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o > \ > -sys_compat.o entry32.o > \ > -../../arm/kernel/opcodes.o > +sys_compat.o entry32.o > arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o > arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o > arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)+= module-plts.o > diff --git a/arch/arm64/kernel/armv8_deprecated.c > b/arch/arm64/kernel/armv8_deprecated.c > index c37202c..88b9165 100644 > --- a/arch/arm64/kernel/armv8_deprecated.c > +++ b/arch/arm64/kernel/armv8_deprecated.c > @@ -366,6 +366,21 @@ static int emulate_swpX(unsigned int address, unsigned > int *data, > return res; > } > > +#define ARM_OPCODE_CONDITION_UNCOND 0xf > + > +static unsigned int __kprobes arm32_check_condition(u32 opcode, u32 psr) Would you be OK for using arm32 instead of aarch32 prefix? > +{ > + u32 cc_bits = opcode >> 28; > + > + if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) { > + if ((*opcode_condition_checks[cc_bits])(psr)) > + return ARM_OPCODE_CONDTEST_PASS; > + else > + return ARM_OPCODE_CONDTEST_FAIL; > + } > + return ARM_OPCODE_CONDTEST_UNCOND; > +} Thank you, -- Masami Hiramatsu
Re: [PATCH v13 03/10] arm64: add conditional instruction simulation support
On Thu, 2 Jun 2016 23:26:17 -0400 David Long wrote: > From: "David A. Long" > > Cease using the arm32 arm_check_condition() function and replace it with > a local version for use in deprecated instruction support on arm64. Also > make the function table used by this available for future use by kprobes > and/or uprobes. > > This function is dervied from code written by Sandeepa Prabhu. > Basically looks good to me. I have some comments; > Signed-off-by: Sandeepa Prabhu > Signed-off-by: David A. Long > --- > arch/arm64/include/asm/insn.h| 3 ++ > arch/arm64/kernel/Makefile | 3 +- > arch/arm64/kernel/armv8_deprecated.c | 19 ++- > arch/arm64/kernel/insn.c | 98 > > 4 files changed, 119 insertions(+), 4 deletions(-) > > diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h > index 9785d10..98e4edd 100644 > --- a/arch/arm64/include/asm/insn.h > +++ b/arch/arm64/include/asm/insn.h > @@ -406,6 +406,9 @@ u32 aarch64_extract_system_register(u32 insn); > u32 aarch32_insn_extract_reg_num(u32 insn, int offset); > u32 aarch32_insn_mcr_extract_opc2(u32 insn); > u32 aarch32_insn_mcr_extract_crm(u32 insn); > + > +typedef bool (pstate_check_t)(unsigned long); > +extern pstate_check_t * const opcode_condition_checks[16]; Are those condition checkers only for aarch32 opcode? or general for aarch64 too? If it is only for aarch32, we'd better add aarch32 prefix. > #endif /* __ASSEMBLY__ */ > > #endif /* __ASM_INSN_H */ > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile > index 2173149..4653aca 100644 > --- a/arch/arm64/kernel/Makefile > +++ b/arch/arm64/kernel/Makefile > @@ -26,8 +26,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE > $(call if_changed,objcopy) > > arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o > \ > -sys_compat.o entry32.o > \ > -../../arm/kernel/opcodes.o > +sys_compat.o entry32.o > arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o > arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o > arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)+= module-plts.o > diff --git a/arch/arm64/kernel/armv8_deprecated.c > b/arch/arm64/kernel/armv8_deprecated.c > index c37202c..88b9165 100644 > --- a/arch/arm64/kernel/armv8_deprecated.c > +++ b/arch/arm64/kernel/armv8_deprecated.c > @@ -366,6 +366,21 @@ static int emulate_swpX(unsigned int address, unsigned > int *data, > return res; > } > > +#define ARM_OPCODE_CONDITION_UNCOND 0xf > + > +static unsigned int __kprobes arm32_check_condition(u32 opcode, u32 psr) Would you be OK for using arm32 instead of aarch32 prefix? > +{ > + u32 cc_bits = opcode >> 28; > + > + if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) { > + if ((*opcode_condition_checks[cc_bits])(psr)) > + return ARM_OPCODE_CONDTEST_PASS; > + else > + return ARM_OPCODE_CONDTEST_FAIL; > + } > + return ARM_OPCODE_CONDTEST_UNCOND; > +} Thank you, -- Masami Hiramatsu
Re: [PATCH 2/2] aer: add support aer interrupt with none MSI/MSI-X/INTx mode
On Fri, Jun 03, 2016 at 01:31:11PM -0400, Murali Karicheri wrote: > Po, > > Sorry to hijack your discussion, but the problem seems to be same for > Keystone PCI controller which is also designware (old version) based. > > On 06/03/2016 12:09 AM, Bjorn Helgaas wrote: > > On Thu, Jun 02, 2016 at 11:37:28AM -0400, Murali Karicheri wrote: > >> On 06/02/2016 09:55 AM, Bjorn Helgaas wrote: > >>> On Thu, Jun 02, 2016 at 05:01:19AM +, Po Liu wrote: > > -Original Message- > > From: Bjorn Helgaas [mailto:helg...@kernel.org] > > Sent: Thursday, June 02, 2016 11:48 AM > > To: Po Liu > > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; > > linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; Arnd > > Bergmann; > > Roy Zang; Marc Zyngier; Stuart Yoder; Yang-Leo Li; Minghuan Lian; Bjorn > > Helgaas; Shawn Guo; Mingkai Hu; Rob Herring > > Subject: Re: [PATCH 2/2] aer: add support aer interrupt with none > > MSI/MSI-X/INTx mode > > > > [+cc Rob] > > > > Hi Po, > > > > On Thu, May 26, 2016 at 02:00:06PM +0800, Po Liu wrote: > > > On some platforms, root port doesn't support MSI/MSI-X/INTx in RC > > mode. > > > When chip support the aer interrupt with none MSI/MSI-X/INTx mode, > > > maybe there is interrupt line for aer pme etc. Search the interrupt > > > number in the fdt file. > > > > My understanding is that AER interrupt signaling can be done via INTx, > > MSI, or MSI-X (PCIe spec r3.0, sec 6.2.4.1.2). Apparently your device > > doesn't support MSI or MSI-X. Are you saying it doesn't support INTx > > either? How is the interrupt you're requesting here different from > > INTx? > > Layerscape use none of MSI or MSI-X or INTx to indicate the devices > or root error in RC mode. But use an independent SPI interrupt(arm > interrupt controller) line. > >>> > >>> The Root Port is a PCI device and should follow the normal PCI rules > >>> for interrupts. As far as I understand, that means it should use MSI, > >>> MSI-X, or INTx. If your Root Port doesn't use MSI or MSI-X, it should > >>> use INTx, the PCI_INTERRUPT_PIN register should tell us which (INTA/ > >>> INTB/etc.), and PCI_COMMAND_INTX_DISABLE should work to disable it. > >>> That's all from the PCI point of view, of course. > >> > >> I am faced with the same issue on Keystone PCI hardware and it has been > >> on my TODO list for quite some time. Keystone PCI hardware also doesn't > >> use MSI or MSI-X or INTx for reporting errors received at the root port, > >> but use a platform interrupt instead (not complaint to PCI standard as > >> per PCI base spec). So I would need similar change to have the error > >> interrupt passed to the aer driver. So there are hardware out there > >> like Keystone which requires to support this through platform IRQ. > > > > This is not a new area of the spec, and it's hard for me to believe > > that these two new PCIe controllers are both broken the same way > > (although I guess both are DesignWare-based, so maybe this is the same > > underlying problem in both cases?). I think it's more likely that we > > just haven't figured out the right way to describe this in the DT. > > Keystone is using an older version of the designware IP and it implements > all of the interrupts in the application register space unlike other > newer version of the hardware. So I assume, the version used on Layerscape > is also an older version and the both have same issue in terms of > non standard platform interrupt used for error reporting. > > > I assume you have a Root Port with an AER capability, no MSI > > capability, and no MSI-X capability, right? > > Has AER capability and both MSI and INTx (legacy) capability > > > What does its Interrupt > > Pin register contain? If it's zero, it doesn't use INTx either, so > > according to the spec it should generate no interrupts. > > > At address offset 0x3C by default has a value of 1, but it is writable > by software. So default is INTx A. 0x3c is the Interrupt *Line*, which is read/write. The Interrupt *Pin* is at 0x3d and should be read-only. Does your Keystone driver support MSI? If so, since your Root Port supports MSI, I would think we would use that by default, and the INTx stuff wouldn't even matter. > > But if Interrupt Pin is non-zero, that means the Root Port should be > > able to generate virtual INTx interrupts. Presumably the Root Complex > > connects those interrupts to something; maybe to your platform > > interrupt? > > Probably that is what is happening. Both Power management and Error > interrupts are raised on platform interrupt lines. > > 12 Error Interrupts > > [0] System error (OR of fatal, nonfatal, correctable errors) (RC mode only) > [1] PCIe fatal error (RC mode only) > [2] PCIe non-fatal error (RC mode only) > [3] PCIe correctable error (RC mode only) > [4] AXI
Re: [PATCH 2/2] aer: add support aer interrupt with none MSI/MSI-X/INTx mode
On Fri, Jun 03, 2016 at 01:31:11PM -0400, Murali Karicheri wrote: > Po, > > Sorry to hijack your discussion, but the problem seems to be same for > Keystone PCI controller which is also designware (old version) based. > > On 06/03/2016 12:09 AM, Bjorn Helgaas wrote: > > On Thu, Jun 02, 2016 at 11:37:28AM -0400, Murali Karicheri wrote: > >> On 06/02/2016 09:55 AM, Bjorn Helgaas wrote: > >>> On Thu, Jun 02, 2016 at 05:01:19AM +, Po Liu wrote: > > -Original Message- > > From: Bjorn Helgaas [mailto:helg...@kernel.org] > > Sent: Thursday, June 02, 2016 11:48 AM > > To: Po Liu > > Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; > > linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; Arnd > > Bergmann; > > Roy Zang; Marc Zyngier; Stuart Yoder; Yang-Leo Li; Minghuan Lian; Bjorn > > Helgaas; Shawn Guo; Mingkai Hu; Rob Herring > > Subject: Re: [PATCH 2/2] aer: add support aer interrupt with none > > MSI/MSI-X/INTx mode > > > > [+cc Rob] > > > > Hi Po, > > > > On Thu, May 26, 2016 at 02:00:06PM +0800, Po Liu wrote: > > > On some platforms, root port doesn't support MSI/MSI-X/INTx in RC > > mode. > > > When chip support the aer interrupt with none MSI/MSI-X/INTx mode, > > > maybe there is interrupt line for aer pme etc. Search the interrupt > > > number in the fdt file. > > > > My understanding is that AER interrupt signaling can be done via INTx, > > MSI, or MSI-X (PCIe spec r3.0, sec 6.2.4.1.2). Apparently your device > > doesn't support MSI or MSI-X. Are you saying it doesn't support INTx > > either? How is the interrupt you're requesting here different from > > INTx? > > Layerscape use none of MSI or MSI-X or INTx to indicate the devices > or root error in RC mode. But use an independent SPI interrupt(arm > interrupt controller) line. > >>> > >>> The Root Port is a PCI device and should follow the normal PCI rules > >>> for interrupts. As far as I understand, that means it should use MSI, > >>> MSI-X, or INTx. If your Root Port doesn't use MSI or MSI-X, it should > >>> use INTx, the PCI_INTERRUPT_PIN register should tell us which (INTA/ > >>> INTB/etc.), and PCI_COMMAND_INTX_DISABLE should work to disable it. > >>> That's all from the PCI point of view, of course. > >> > >> I am faced with the same issue on Keystone PCI hardware and it has been > >> on my TODO list for quite some time. Keystone PCI hardware also doesn't > >> use MSI or MSI-X or INTx for reporting errors received at the root port, > >> but use a platform interrupt instead (not complaint to PCI standard as > >> per PCI base spec). So I would need similar change to have the error > >> interrupt passed to the aer driver. So there are hardware out there > >> like Keystone which requires to support this through platform IRQ. > > > > This is not a new area of the spec, and it's hard for me to believe > > that these two new PCIe controllers are both broken the same way > > (although I guess both are DesignWare-based, so maybe this is the same > > underlying problem in both cases?). I think it's more likely that we > > just haven't figured out the right way to describe this in the DT. > > Keystone is using an older version of the designware IP and it implements > all of the interrupts in the application register space unlike other > newer version of the hardware. So I assume, the version used on Layerscape > is also an older version and the both have same issue in terms of > non standard platform interrupt used for error reporting. > > > I assume you have a Root Port with an AER capability, no MSI > > capability, and no MSI-X capability, right? > > Has AER capability and both MSI and INTx (legacy) capability > > > What does its Interrupt > > Pin register contain? If it's zero, it doesn't use INTx either, so > > according to the spec it should generate no interrupts. > > > At address offset 0x3C by default has a value of 1, but it is writable > by software. So default is INTx A. 0x3c is the Interrupt *Line*, which is read/write. The Interrupt *Pin* is at 0x3d and should be read-only. Does your Keystone driver support MSI? If so, since your Root Port supports MSI, I would think we would use that by default, and the INTx stuff wouldn't even matter. > > But if Interrupt Pin is non-zero, that means the Root Port should be > > able to generate virtual INTx interrupts. Presumably the Root Complex > > connects those interrupts to something; maybe to your platform > > interrupt? > > Probably that is what is happening. Both Power management and Error > interrupts are raised on platform interrupt lines. > > 12 Error Interrupts > > [0] System error (OR of fatal, nonfatal, correctable errors) (RC mode only) > [1] PCIe fatal error (RC mode only) > [2] PCIe non-fatal error (RC mode only) > [3] PCIe correctable error (RC mode only) > [4] AXI
Re: [PATCH v13 04/10] arm64: Blacklist non-kprobe-able symbol
Hi David, On Thu, 2 Jun 2016 23:26:18 -0400 David Longwrote: > From: Pratyush Anand > > Add all function symbols which are called from do_debug_exception under > NOKPROBE_SYMBOL, as they can not kprobed. I see, but this patch should be applied after kprobes are implemented on arm64. And also, I have a comment below. > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index 5954881..4359ca8 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -563,6 +563,7 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long > addr, > info.si_addr = (void __user *)addr; > arm64_notify_die("Oops - SP/PC alignment exception", regs, , esr); > } > +NOKPROBE_SYMBOL(do_debug_exception) This seems at wrong place. Please correct it in this patch. Thank you, -- Masami Hiramatsu
Re: [PATCH v13 04/10] arm64: Blacklist non-kprobe-able symbol
Hi David, On Thu, 2 Jun 2016 23:26:18 -0400 David Long wrote: > From: Pratyush Anand > > Add all function symbols which are called from do_debug_exception under > NOKPROBE_SYMBOL, as they can not kprobed. I see, but this patch should be applied after kprobes are implemented on arm64. And also, I have a comment below. > diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c > index 5954881..4359ca8 100644 > --- a/arch/arm64/mm/fault.c > +++ b/arch/arm64/mm/fault.c > @@ -563,6 +563,7 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long > addr, > info.si_addr = (void __user *)addr; > arm64_notify_die("Oops - SP/PC alignment exception", regs, , esr); > } > +NOKPROBE_SYMBOL(do_debug_exception) This seems at wrong place. Please correct it in this patch. Thank you, -- Masami Hiramatsu
[PATCH v3 5/7] zram: delete custom lzo/lz4
Remove lzo/lz4 backends, we use crypto API now. Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/Kconfig | 9 --- drivers/block/zram/Makefile| 4 +-- drivers/block/zram/zcomp.c | 2 +- drivers/block/zram/zcomp.h | 15 --- drivers/block/zram/zcomp_lz4.c | 56 -- drivers/block/zram/zcomp_lz4.h | 17 - drivers/block/zram/zcomp_lzo.c | 56 -- drivers/block/zram/zcomp_lzo.h | 17 - 8 files changed, 2 insertions(+), 174 deletions(-) delete mode 100644 drivers/block/zram/zcomp_lz4.c delete mode 100644 drivers/block/zram/zcomp_lz4.h delete mode 100644 drivers/block/zram/zcomp_lzo.c delete mode 100644 drivers/block/zram/zcomp_lzo.h diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 2252cd7..b8ecba6 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig @@ -13,12 +13,3 @@ config ZRAM disks and maybe many more. See zram.txt for more information. - -config ZRAM_LZ4_COMPRESS - bool "Enable LZ4 algorithm support" - depends on ZRAM - select CRYPTO_LZ4 - default n - help - This option enables LZ4 compression algorithm support. Compression - algorithm can be changed using `comp_algorithm' device attribute. diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile index be0763f..9e2b79e 100644 --- a/drivers/block/zram/Makefile +++ b/drivers/block/zram/Makefile @@ -1,5 +1,3 @@ -zram-y := zcomp_lzo.o zcomp.o zram_drv.o - -zram-$(CONFIG_ZRAM_LZ4_COMPRESS) += zcomp_lz4.o +zram-y := zcomp.o zram_drv.o obj-$(CONFIG_ZRAM) += zram.o diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index a2b4eb8..9ab45d4 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -20,7 +20,7 @@ static const char * const backends[] = { "lzo", -#ifdef CONFIG_ZRAM_LZ4_COMPRESS +#if IS_ENABLED(CONFIG_CRYPTO_LZ4) "lz4", #endif NULL diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index c914ab7..478cac2 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -16,24 +16,9 @@ struct zcomp_strm { struct crypto_comp *tfm; }; -/* static compression backend */ -struct zcomp_backend { - int (*compress)(const unsigned char *src, unsigned char *dst, - size_t *dst_len, void *private); - - int (*decompress)(const unsigned char *src, size_t src_len, - unsigned char *dst); - - void *(*create)(gfp_t flags); - void (*destroy)(void *private); - - const char *name; -}; - /* dynamic per-device compression frontend */ struct zcomp { struct zcomp_strm * __percpu *stream; - struct zcomp_backend *backend; struct notifier_block notifier; const char *name; diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c deleted file mode 100644 index 0110086..000 --- a/drivers/block/zram/zcomp_lz4.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2014 Sergey Senozhatsky. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#include "zcomp_lz4.h" - -static void *zcomp_lz4_create(gfp_t flags) -{ - void *ret; - - ret = kmalloc(LZ4_MEM_COMPRESS, flags); - if (!ret) - ret = __vmalloc(LZ4_MEM_COMPRESS, - flags | __GFP_HIGHMEM, - PAGE_KERNEL); - return ret; -} - -static void zcomp_lz4_destroy(void *private) -{ - kvfree(private); -} - -static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst, - size_t *dst_len, void *private) -{ - /* return : Success if return 0 */ - return lz4_compress(src, PAGE_SIZE, dst, dst_len, private); -} - -static int zcomp_lz4_decompress(const unsigned char *src, size_t src_len, - unsigned char *dst) -{ - size_t dst_len = PAGE_SIZE; - /* return : Success if return 0 */ - return lz4_decompress_unknownoutputsize(src, src_len, dst, _len); -} - -struct zcomp_backend zcomp_lz4 = { - .compress = zcomp_lz4_compress, - .decompress = zcomp_lz4_decompress, - .create = zcomp_lz4_create, - .destroy = zcomp_lz4_destroy, - .name = "lz4", -}; diff --git a/drivers/block/zram/zcomp_lz4.h b/drivers/block/zram/zcomp_lz4.h deleted file mode 100644 index 60613fb..000 --- a/drivers/block/zram/zcomp_lz4.h +++ /dev/null @@
[PATCH v3 2/7] zram: switch to crypto compress API
We don't have an idle zstreams list anymore and our write path now works absolutely differently, preventing preemption during compression. This removes possibilities of read paths preempting writes at wrong places (which could badly affect the performance of both paths) and at the same time opens the door for a move from custom LZO/LZ4 compression backends implementation to a more generic one, using crypto compress API. Joonsoo Kim [1] attempted to do this a while ago, but faced with the need of introducing a new crypto API interface. The root cause was the fact that crypto API compression algorithms require a compression stream structure (in zram terminology) for both compression and decompression ops, while in reality only several of compression algorithms really need it. This resulted in a concept of context-less crypto API compression backends [2]. Both write and read paths, though, would have been executed with the preemption enabled, which in the worst case could have resulted in a decreased worst-case performance, e.g. consider the following case: CPU0 zram_write() spin_lock() take the last idle stream spin_unlock() << preempted >> zram_read() spin_lock() no idle streams spin_unlock() schedule() resuming zram_write compression() but it took me some time to realize that, and it took even longer to evolve zram and to make it ready for crypto API. The key turned out to be -- drop the idle streams list entirely. Without the idle streams list we are free to use compression algorithms that require compression stream for decompression (read), because streams are now placed in per-cpu data and each write path has to disable preemption for compression op, almost completely eliminating the aforementioned case (technically, we still have a small chance, because write path has a fast and a slow paths and the slow path is executed with the preemption enabled; but the frequency of failed fast path is too low). TEST - 4 CPUs, x86_64 system - 3G zram, lzo - fio tests: read, randread, write, randwrite, rw, randrw test script [3] command: ZRAM_SIZE=3G LOG_SUFFIX= FIO_LOOPS=5 ./zram-fio-test.sh BASE PATCHED jobs1 READ: 2527.2MB/s 2482.7MB/s READ: 2102.7MB/s 2045.0MB/s WRITE: 1284.3MB/s 1324.3MB/s WRITE: 1080.7MB/s 1101.9MB/s READ: 430125KB/s 437498KB/s WRITE: 430538KB/s 437919KB/s READ: 399593KB/s 403987KB/s WRITE: 399910KB/s 404308KB/s jobs2 READ: 8133.5MB/s 7854.8MB/s READ: 7086.6MB/s 6912.8MB/s WRITE: 3177.2MB/s 3298.3MB/s WRITE: 2810.2MB/s 2871.4MB/s READ: 1017.6MB/s 1023.4MB/s WRITE: 1018.2MB/s 1023.1MB/s READ: 977836KB/s 984205KB/s WRITE: 979435KB/s 985814KB/s jobs3 READ: 13557MB/s13391MB/s READ: 11876MB/s11752MB/s WRITE: 4641.5MB/s 4682.1MB/s WRITE: 4164.9MB/s 4179.3MB/s READ: 1453.8MB/s 1455.1MB/s WRITE: 1455.1MB/s 1458.2MB/s READ: 1387.7MB/s 1395.7MB/s WRITE: 1386.1MB/s 1394.9MB/s jobs4 READ: 20271MB/s20078MB/s READ: 18033MB/s17928MB/s WRITE: 6176.8MB/s 6180.5MB/s WRITE: 5686.3MB/s 5705.3MB/s READ: 2009.4MB/s 2006.7MB/s WRITE: 2007.5MB/s 2004.9MB/s READ: 1929.7MB/s 1935.6MB/s WRITE: 1926.8MB/s 1932.6MB/s jobs5 READ: 18823MB/s19024MB/s READ: 18968MB/s19071MB/s WRITE: 6191.6MB/s 6372.1MB/s WRITE: 5818.7MB/s 5787.1MB/s READ: 2011.7MB/s 1981.3MB/s WRITE: 2011.4MB/s 1980.1MB/s READ: 1949.3MB/s 1935.7MB/s WRITE: 1940.4MB/s 1926.1MB/s jobs6 READ: 21870MB/s21715MB/s READ: 19957MB/s19879MB/s WRITE: 6528.4MB/s 6537.6MB/s WRITE: 6098.9MB/s 6073.6MB/s READ: 2048.6MB/s 2049.9MB/s WRITE: 2041.7MB/s 2042.9MB/s READ: 2013.4MB/s 1990.4MB/s WRITE: 2009.4MB/s 1986.5MB/s jobs7 READ: 21359MB/s21124MB/s READ: 19746MB/s19293MB/s WRITE: 6660.4MB/s 6518.8MB/s WRITE: 6211.6MB/s 6193.1MB/s READ: 2089.7MB/s 2080.6MB/s WRITE: 2085.8MB/s 2076.5MB/s READ: 2041.2MB/s 2052.5MB/s WRITE: 2037.5MB/s 2048.8MB/s jobs8 READ: 20477MB/s19974MB/s READ: 18922MB/s18576MB/s WRITE: 6851.9MB/s 6788.3MB/s WRITE:
[PATCH v3 6/7] zram: add more compression algorithms
Add "deflate", "lz4hc", "842" algorithms to the list of known compression backends. The real availability of those algorithms, however, depends on the corresponding CONFIG_CRYPTO_FOO config options. Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim --- drivers/block/zram/zcomp.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index 9ab45d4..32e521a 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -23,6 +23,15 @@ static const char * const backends[] = { #if IS_ENABLED(CONFIG_CRYPTO_LZ4) "lz4", #endif +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) + "deflate", +#endif +#if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) + "lz4hc", +#endif +#if IS_ENABLED(CONFIG_CRYPTO_842) + "842", +#endif NULL }; -- 2.8.3.394.g3916adf
[PATCH v3 5/7] zram: delete custom lzo/lz4
Remove lzo/lz4 backends, we use crypto API now. Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/Kconfig | 9 --- drivers/block/zram/Makefile| 4 +-- drivers/block/zram/zcomp.c | 2 +- drivers/block/zram/zcomp.h | 15 --- drivers/block/zram/zcomp_lz4.c | 56 -- drivers/block/zram/zcomp_lz4.h | 17 - drivers/block/zram/zcomp_lzo.c | 56 -- drivers/block/zram/zcomp_lzo.h | 17 - 8 files changed, 2 insertions(+), 174 deletions(-) delete mode 100644 drivers/block/zram/zcomp_lz4.c delete mode 100644 drivers/block/zram/zcomp_lz4.h delete mode 100644 drivers/block/zram/zcomp_lzo.c delete mode 100644 drivers/block/zram/zcomp_lzo.h diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 2252cd7..b8ecba6 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig @@ -13,12 +13,3 @@ config ZRAM disks and maybe many more. See zram.txt for more information. - -config ZRAM_LZ4_COMPRESS - bool "Enable LZ4 algorithm support" - depends on ZRAM - select CRYPTO_LZ4 - default n - help - This option enables LZ4 compression algorithm support. Compression - algorithm can be changed using `comp_algorithm' device attribute. diff --git a/drivers/block/zram/Makefile b/drivers/block/zram/Makefile index be0763f..9e2b79e 100644 --- a/drivers/block/zram/Makefile +++ b/drivers/block/zram/Makefile @@ -1,5 +1,3 @@ -zram-y := zcomp_lzo.o zcomp.o zram_drv.o - -zram-$(CONFIG_ZRAM_LZ4_COMPRESS) += zcomp_lz4.o +zram-y := zcomp.o zram_drv.o obj-$(CONFIG_ZRAM) += zram.o diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index a2b4eb8..9ab45d4 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -20,7 +20,7 @@ static const char * const backends[] = { "lzo", -#ifdef CONFIG_ZRAM_LZ4_COMPRESS +#if IS_ENABLED(CONFIG_CRYPTO_LZ4) "lz4", #endif NULL diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index c914ab7..478cac2 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -16,24 +16,9 @@ struct zcomp_strm { struct crypto_comp *tfm; }; -/* static compression backend */ -struct zcomp_backend { - int (*compress)(const unsigned char *src, unsigned char *dst, - size_t *dst_len, void *private); - - int (*decompress)(const unsigned char *src, size_t src_len, - unsigned char *dst); - - void *(*create)(gfp_t flags); - void (*destroy)(void *private); - - const char *name; -}; - /* dynamic per-device compression frontend */ struct zcomp { struct zcomp_strm * __percpu *stream; - struct zcomp_backend *backend; struct notifier_block notifier; const char *name; diff --git a/drivers/block/zram/zcomp_lz4.c b/drivers/block/zram/zcomp_lz4.c deleted file mode 100644 index 0110086..000 --- a/drivers/block/zram/zcomp_lz4.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2014 Sergey Senozhatsky. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include - -#include "zcomp_lz4.h" - -static void *zcomp_lz4_create(gfp_t flags) -{ - void *ret; - - ret = kmalloc(LZ4_MEM_COMPRESS, flags); - if (!ret) - ret = __vmalloc(LZ4_MEM_COMPRESS, - flags | __GFP_HIGHMEM, - PAGE_KERNEL); - return ret; -} - -static void zcomp_lz4_destroy(void *private) -{ - kvfree(private); -} - -static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst, - size_t *dst_len, void *private) -{ - /* return : Success if return 0 */ - return lz4_compress(src, PAGE_SIZE, dst, dst_len, private); -} - -static int zcomp_lz4_decompress(const unsigned char *src, size_t src_len, - unsigned char *dst) -{ - size_t dst_len = PAGE_SIZE; - /* return : Success if return 0 */ - return lz4_decompress_unknownoutputsize(src, src_len, dst, _len); -} - -struct zcomp_backend zcomp_lz4 = { - .compress = zcomp_lz4_compress, - .decompress = zcomp_lz4_decompress, - .create = zcomp_lz4_create, - .destroy = zcomp_lz4_destroy, - .name = "lz4", -}; diff --git a/drivers/block/zram/zcomp_lz4.h b/drivers/block/zram/zcomp_lz4.h deleted file mode 100644 index 60613fb..000 --- a/drivers/block/zram/zcomp_lz4.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2014 Sergey Senozhatsky. - * - * This program is free
[PATCH v3 2/7] zram: switch to crypto compress API
We don't have an idle zstreams list anymore and our write path now works absolutely differently, preventing preemption during compression. This removes possibilities of read paths preempting writes at wrong places (which could badly affect the performance of both paths) and at the same time opens the door for a move from custom LZO/LZ4 compression backends implementation to a more generic one, using crypto compress API. Joonsoo Kim [1] attempted to do this a while ago, but faced with the need of introducing a new crypto API interface. The root cause was the fact that crypto API compression algorithms require a compression stream structure (in zram terminology) for both compression and decompression ops, while in reality only several of compression algorithms really need it. This resulted in a concept of context-less crypto API compression backends [2]. Both write and read paths, though, would have been executed with the preemption enabled, which in the worst case could have resulted in a decreased worst-case performance, e.g. consider the following case: CPU0 zram_write() spin_lock() take the last idle stream spin_unlock() << preempted >> zram_read() spin_lock() no idle streams spin_unlock() schedule() resuming zram_write compression() but it took me some time to realize that, and it took even longer to evolve zram and to make it ready for crypto API. The key turned out to be -- drop the idle streams list entirely. Without the idle streams list we are free to use compression algorithms that require compression stream for decompression (read), because streams are now placed in per-cpu data and each write path has to disable preemption for compression op, almost completely eliminating the aforementioned case (technically, we still have a small chance, because write path has a fast and a slow paths and the slow path is executed with the preemption enabled; but the frequency of failed fast path is too low). TEST - 4 CPUs, x86_64 system - 3G zram, lzo - fio tests: read, randread, write, randwrite, rw, randrw test script [3] command: ZRAM_SIZE=3G LOG_SUFFIX= FIO_LOOPS=5 ./zram-fio-test.sh BASE PATCHED jobs1 READ: 2527.2MB/s 2482.7MB/s READ: 2102.7MB/s 2045.0MB/s WRITE: 1284.3MB/s 1324.3MB/s WRITE: 1080.7MB/s 1101.9MB/s READ: 430125KB/s 437498KB/s WRITE: 430538KB/s 437919KB/s READ: 399593KB/s 403987KB/s WRITE: 399910KB/s 404308KB/s jobs2 READ: 8133.5MB/s 7854.8MB/s READ: 7086.6MB/s 6912.8MB/s WRITE: 3177.2MB/s 3298.3MB/s WRITE: 2810.2MB/s 2871.4MB/s READ: 1017.6MB/s 1023.4MB/s WRITE: 1018.2MB/s 1023.1MB/s READ: 977836KB/s 984205KB/s WRITE: 979435KB/s 985814KB/s jobs3 READ: 13557MB/s13391MB/s READ: 11876MB/s11752MB/s WRITE: 4641.5MB/s 4682.1MB/s WRITE: 4164.9MB/s 4179.3MB/s READ: 1453.8MB/s 1455.1MB/s WRITE: 1455.1MB/s 1458.2MB/s READ: 1387.7MB/s 1395.7MB/s WRITE: 1386.1MB/s 1394.9MB/s jobs4 READ: 20271MB/s20078MB/s READ: 18033MB/s17928MB/s WRITE: 6176.8MB/s 6180.5MB/s WRITE: 5686.3MB/s 5705.3MB/s READ: 2009.4MB/s 2006.7MB/s WRITE: 2007.5MB/s 2004.9MB/s READ: 1929.7MB/s 1935.6MB/s WRITE: 1926.8MB/s 1932.6MB/s jobs5 READ: 18823MB/s19024MB/s READ: 18968MB/s19071MB/s WRITE: 6191.6MB/s 6372.1MB/s WRITE: 5818.7MB/s 5787.1MB/s READ: 2011.7MB/s 1981.3MB/s WRITE: 2011.4MB/s 1980.1MB/s READ: 1949.3MB/s 1935.7MB/s WRITE: 1940.4MB/s 1926.1MB/s jobs6 READ: 21870MB/s21715MB/s READ: 19957MB/s19879MB/s WRITE: 6528.4MB/s 6537.6MB/s WRITE: 6098.9MB/s 6073.6MB/s READ: 2048.6MB/s 2049.9MB/s WRITE: 2041.7MB/s 2042.9MB/s READ: 2013.4MB/s 1990.4MB/s WRITE: 2009.4MB/s 1986.5MB/s jobs7 READ: 21359MB/s21124MB/s READ: 19746MB/s19293MB/s WRITE: 6660.4MB/s 6518.8MB/s WRITE: 6211.6MB/s 6193.1MB/s READ: 2089.7MB/s 2080.6MB/s WRITE: 2085.8MB/s 2076.5MB/s READ: 2041.2MB/s 2052.5MB/s WRITE: 2037.5MB/s 2048.8MB/s jobs8 READ: 20477MB/s19974MB/s READ: 18922MB/s18576MB/s WRITE: 6851.9MB/s 6788.3MB/s WRITE:
[PATCH v3 6/7] zram: add more compression algorithms
Add "deflate", "lz4hc", "842" algorithms to the list of known compression backends. The real availability of those algorithms, however, depends on the corresponding CONFIG_CRYPTO_FOO config options. Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim --- drivers/block/zram/zcomp.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index 9ab45d4..32e521a 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -23,6 +23,15 @@ static const char * const backends[] = { #if IS_ENABLED(CONFIG_CRYPTO_LZ4) "lz4", #endif +#if IS_ENABLED(CONFIG_CRYPTO_DEFLATE) + "deflate", +#endif +#if IS_ENABLED(CONFIG_CRYPTO_LZ4HC) + "lz4hc", +#endif +#if IS_ENABLED(CONFIG_CRYPTO_842) + "842", +#endif NULL }; -- 2.8.3.394.g3916adf
[PATCH v3 3/7] zram: use crypto api to check alg availability
There is no way to get a string with all the crypto comp algorithms supported by the crypto comp engine, so we need to maintain our own backends list. At the same time we additionally need to use crypto_has_comp() to make sure that the user has requested a compression algorithm that is recognized by the crypto comp engine. Relying on /proc/crypto is not an options here, because it does not show not-yet-inserted compression modules. Example: modprobe zram cat /proc/crypto | grep -i lz4 modprobe lz4 cat /proc/crypto | grep -i lz4 name : lz4 driver : lz4-generic module : lz4 So the user can't tell exactly if the lz4 is really supported from /proc/crypto output, unless someone or something has loaded it. This patch also adds crypto_has_comp() to zcomp_available_show(). We store all the compression algorithms names in zcomp's `backends' array, regardless the CONFIG_CRYPTO_FOO configuration, but show only those that are also supported by crypto engine. This helps user to know the exact list of compression algorithms that can be used. Example: module lz4 is not loaded yet, but is supported by the crypto engine. /proc/crypto has no information on this module, while zram's `comp_algorithm' lists it: cat /proc/crypto | grep -i lz4 cat /sys/block/zram0/comp_algorithm [lzo] lz4 deflate lz4hc 842 We still use the `backends' array to determine if the requested compression backend is known to crypto api. This array, however, may not contain some entries, therefore as the last step we call crypto_has_comp() function which attempts to insmod the requested compression algorithm to determine if crypto api supports it. The advantage of this method is that now we permit the usage of out-of-tree crypto compression modules (implementing S/W or H/W compression). Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim --- Documentation/blockdev/zram.txt | 11 drivers/block/zram/zcomp.c | 61 + drivers/block/zram/zram_drv.c | 16 ++- drivers/block/zram/zram_drv.h | 5 ++-- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 13100fb..7c05357 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -83,6 +83,17 @@ pre-created. Default: 1. #select lzo compression algorithm echo lzo > /sys/block/zram0/comp_algorithm + For the time being, the `comp_algorithm' content does not necessarily + show every compression algorithm supported by the kernel. We keep this + list primarily to simplify device configuration and one can configure + a new device with a compression algorithm that is not listed in + `comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API + and, if some of the algorithms were built as modules, it's impossible + to list all of them using, for instance, /proc/crypto or any other + method. This, however, has an advantage of permitting the usage of + custom crypto compression modules (implementing S/W or H/W + compression). + 4) Set Disksize Set disk size by writing the value to sysfs node 'disksize'. The value can be either in bytes or you can use mem suffixes. diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index f357268..a2b4eb8 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -26,17 +26,6 @@ static const char * const backends[] = { NULL }; -static const char *find_backend(const char *compress) -{ - int i = 0; - while (backends[i]) { - if (sysfs_streq(compress, backends[i])) - break; - i++; - } - return backends[i]; -} - static void zcomp_strm_free(struct zcomp_strm *zstrm) { if (!IS_ERR_OR_NULL(zstrm->tfm)) @@ -68,30 +57,56 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) return zstrm; } +bool zcomp_available_algorithm(const char *comp) +{ + int i = 0; + + while (backends[i]) { + if (sysfs_streq(comp, backends[i])) + return true; + i++; + } + + /* +* Crypto does not ignore a trailing new line symbol, +* so make sure you don't supply a string containing +* one. +* This also means that we permit zcomp initialisation +* with any compressing algorithm known to crypto api. +*/ + return crypto_has_comp(comp, 0, 0) == 1; +} + /* show available compressors */ ssize_t zcomp_available_show(const char *comp, char *buf) { + bool known_algorithm = false; ssize_t sz = 0; int i = 0; - while (backends[i]) { - if (!strcmp(comp, backends[i])) + for (; backends[i]; i++)
[PATCH v3 3/7] zram: use crypto api to check alg availability
There is no way to get a string with all the crypto comp algorithms supported by the crypto comp engine, so we need to maintain our own backends list. At the same time we additionally need to use crypto_has_comp() to make sure that the user has requested a compression algorithm that is recognized by the crypto comp engine. Relying on /proc/crypto is not an options here, because it does not show not-yet-inserted compression modules. Example: modprobe zram cat /proc/crypto | grep -i lz4 modprobe lz4 cat /proc/crypto | grep -i lz4 name : lz4 driver : lz4-generic module : lz4 So the user can't tell exactly if the lz4 is really supported from /proc/crypto output, unless someone or something has loaded it. This patch also adds crypto_has_comp() to zcomp_available_show(). We store all the compression algorithms names in zcomp's `backends' array, regardless the CONFIG_CRYPTO_FOO configuration, but show only those that are also supported by crypto engine. This helps user to know the exact list of compression algorithms that can be used. Example: module lz4 is not loaded yet, but is supported by the crypto engine. /proc/crypto has no information on this module, while zram's `comp_algorithm' lists it: cat /proc/crypto | grep -i lz4 cat /sys/block/zram0/comp_algorithm [lzo] lz4 deflate lz4hc 842 We still use the `backends' array to determine if the requested compression backend is known to crypto api. This array, however, may not contain some entries, therefore as the last step we call crypto_has_comp() function which attempts to insmod the requested compression algorithm to determine if crypto api supports it. The advantage of this method is that now we permit the usage of out-of-tree crypto compression modules (implementing S/W or H/W compression). Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim --- Documentation/blockdev/zram.txt | 11 drivers/block/zram/zcomp.c | 61 + drivers/block/zram/zram_drv.c | 16 ++- drivers/block/zram/zram_drv.h | 5 ++-- 4 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 13100fb..7c05357 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -83,6 +83,17 @@ pre-created. Default: 1. #select lzo compression algorithm echo lzo > /sys/block/zram0/comp_algorithm + For the time being, the `comp_algorithm' content does not necessarily + show every compression algorithm supported by the kernel. We keep this + list primarily to simplify device configuration and one can configure + a new device with a compression algorithm that is not listed in + `comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API + and, if some of the algorithms were built as modules, it's impossible + to list all of them using, for instance, /proc/crypto or any other + method. This, however, has an advantage of permitting the usage of + custom crypto compression modules (implementing S/W or H/W + compression). + 4) Set Disksize Set disk size by writing the value to sysfs node 'disksize'. The value can be either in bytes or you can use mem suffixes. diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index f357268..a2b4eb8 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -26,17 +26,6 @@ static const char * const backends[] = { NULL }; -static const char *find_backend(const char *compress) -{ - int i = 0; - while (backends[i]) { - if (sysfs_streq(compress, backends[i])) - break; - i++; - } - return backends[i]; -} - static void zcomp_strm_free(struct zcomp_strm *zstrm) { if (!IS_ERR_OR_NULL(zstrm->tfm)) @@ -68,30 +57,56 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) return zstrm; } +bool zcomp_available_algorithm(const char *comp) +{ + int i = 0; + + while (backends[i]) { + if (sysfs_streq(comp, backends[i])) + return true; + i++; + } + + /* +* Crypto does not ignore a trailing new line symbol, +* so make sure you don't supply a string containing +* one. +* This also means that we permit zcomp initialisation +* with any compressing algorithm known to crypto api. +*/ + return crypto_has_comp(comp, 0, 0) == 1; +} + /* show available compressors */ ssize_t zcomp_available_show(const char *comp, char *buf) { + bool known_algorithm = false; ssize_t sz = 0; int i = 0; - while (backends[i]) { - if (!strcmp(comp, backends[i])) + for (; backends[i]; i++) { + if (!strcmp(comp, backends[i])) { +
[PATCH v3 1/7] zram: rename zstrm find-release functions
We don't perform any zstream idle list lookup anymore, so zcomp_strm_find()/zcomp_strm_release() names are not representative. Rename to zcomp_stream_get()/zcomp_stream_put(). Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/zcomp.c| 4 ++-- drivers/block/zram/zcomp.h| 4 ++-- drivers/block/zram/zram_drv.c | 8 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index b51a816..400f826 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -95,12 +95,12 @@ bool zcomp_available_algorithm(const char *comp) return find_backend(comp) != NULL; } -struct zcomp_strm *zcomp_strm_find(struct zcomp *comp) +struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) { return *get_cpu_ptr(comp->stream); } -void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm) +void zcomp_stream_put(struct zcomp *comp) { put_cpu_ptr(comp->stream); } diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index ffd88cb..944b8e6 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -48,8 +48,8 @@ bool zcomp_available_algorithm(const char *comp); struct zcomp *zcomp_create(const char *comp); void zcomp_destroy(struct zcomp *comp); -struct zcomp_strm *zcomp_strm_find(struct zcomp *comp); -void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm); +struct zcomp_strm *zcomp_stream_get(struct zcomp *comp); +void zcomp_stream_put(struct zcomp *comp); int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm, const unsigned char *src, size_t *dst_len); diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 8fcad8b..9361a5d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -695,7 +695,7 @@ compress_again: goto out; } - zstrm = zcomp_strm_find(zram->comp); + zstrm = zcomp_stream_get(zram->comp); ret = zcomp_compress(zram->comp, zstrm, uncmem, ); if (!is_partial_io(bvec)) { kunmap_atomic(user_mem); @@ -734,7 +734,7 @@ compress_again: __GFP_NOWARN | __GFP_HIGHMEM); if (!handle) { - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); zstrm = NULL; atomic64_inc(>stats.writestall); @@ -769,7 +769,7 @@ compress_again: memcpy(cmem, src, clen); } - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); zstrm = NULL; zs_unmap_object(meta->mem_pool, handle); @@ -789,7 +789,7 @@ compress_again: atomic64_inc(>stats.pages_stored); out: if (zstrm) - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); if (is_partial_io(bvec)) kfree(uncmem); return ret; -- 2.8.3.394.g3916adf
[PATCH v3 0/7] zram: switch to crypto api
Hello, This has started as a 'add zlib support' work, but after some thinking I saw no blockers for a bigger change -- a switch to crypto API. We don't have an idle zstreams list anymore and our write path now works absolutely differently, preventing preemption during compression. This removes possibilities of read paths preempting writes at wrong places and opens the door for a move from custom LZO/LZ4 compression backends implementation to a more generic one, using crypto compress API. This patch set also eliminates the need of a new context-less crypto API interface, which was quite hard to sell, so we can move along faster. v3: -- use IS_ENABLED in the backends array, so crypto_has_comp() can be avoided (saving some time and memory). v2: -- addressed Minchan's review points -- allow out-of-tree comp algorithms, per Minchan -- some other cleanups, reworks and improvements Sergey Senozhatsky (7): zram: rename zstrm find-release functions zram: switch to crypto compress API zram: use crypto api to check alg availability zram: cosmetic: cleanup documentation zram: delete custom lzo/lz4 zram: add more compression algorithms zram: drop gfp_t from zcomp_strm_alloc() Documentation/blockdev/zram.txt | 82 -- drivers/block/zram/Kconfig | 15 +--- drivers/block/zram/Makefile | 4 +- drivers/block/zram/zcomp.c | 150 +--- drivers/block/zram/zcomp.h | 36 +++--- drivers/block/zram/zcomp_lz4.c | 56 --- drivers/block/zram/zcomp_lz4.h | 17 - drivers/block/zram/zcomp_lzo.c | 56 --- drivers/block/zram/zcomp_lzo.h | 17 - drivers/block/zram/zram_drv.c | 42 ++- drivers/block/zram/zram_drv.h | 5 +- 11 files changed, 180 insertions(+), 300 deletions(-) delete mode 100644 drivers/block/zram/zcomp_lz4.c delete mode 100644 drivers/block/zram/zcomp_lz4.h delete mode 100644 drivers/block/zram/zcomp_lzo.c delete mode 100644 drivers/block/zram/zcomp_lzo.h -- 2.8.3.394.g3916adf
[PATCH v3 7/7] zram: drop gfp_t from zcomp_strm_alloc()
We now allocate streams from CPU_UP hot-plug path, there are no context-dependent stream allocations anymore and we can schedule from zcomp_strm_alloc(). Use GFP_KERNEL directly and drop a gfp_t parameter. Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/zcomp.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index 32e521a..4b5cd3a 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -47,9 +47,9 @@ static void zcomp_strm_free(struct zcomp_strm *zstrm) * allocate new zcomp_strm structure with ->tfm initialized by * backend, return NULL on error */ -static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) +static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) { - struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), flags); + struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); if (!zstrm) return NULL; @@ -58,7 +58,7 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) * allocate 2 pages. 1 for compressed data, plus 1 extra for the * case when compressed size is larger than the original one */ - zstrm->buffer = (void *)__get_free_pages(flags | __GFP_ZERO, 1); + zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) { zcomp_strm_free(zstrm); zstrm = NULL; @@ -169,7 +169,7 @@ static int __zcomp_cpu_notifier(struct zcomp *comp, case CPU_UP_PREPARE: if (WARN_ON(*per_cpu_ptr(comp->stream, cpu))) break; - zstrm = zcomp_strm_alloc(comp, GFP_KERNEL); + zstrm = zcomp_strm_alloc(comp); if (IS_ERR_OR_NULL(zstrm)) { pr_err("Can't allocate a compression stream\n"); return NOTIFY_BAD; -- 2.8.3.394.g3916adf
[PATCH v3 4/7] zram: cosmetic: cleanup documentation
zram documentation is a mix of different styles: spaces, tabs, tabs + spaces, etc. clean it up. Signed-off-by: Sergey SenozhatskyCc: Minchan Kim Cc: Joonsoo Kim Cc: Jonathan Corbet Acked-by: Minchan Kim --- Documentation/blockdev/zram.txt | 91 - 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 7c05357..0535ae1 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -59,23 +59,23 @@ num_devices parameter is optional and tells zram how many devices should be pre-created. Default: 1. 2) Set max number of compression streams - Regardless the value passed to this attribute, ZRAM will always - allocate multiple compression streams - one per online CPUs - thus - allowing several concurrent compression operations. The number of - allocated compression streams goes down when some of the CPUs - become offline. There is no single-compression-stream mode anymore, - unless you are running a UP system or has only 1 CPU online. - - To find out how many streams are currently available: +Regardless the value passed to this attribute, ZRAM will always +allocate multiple compression streams - one per online CPUs - thus +allowing several concurrent compression operations. The number of +allocated compression streams goes down when some of the CPUs +become offline. There is no single-compression-stream mode anymore, +unless you are running a UP system or has only 1 CPU online. + +To find out how many streams are currently available: cat /sys/block/zram0/max_comp_streams 3) Select compression algorithm - Using comp_algorithm device attribute one can see available and - currently selected (shown in square brackets) compression algorithms, - change selected compression algorithm (once the device is initialised - there is no way to change compression algorithm). +Using comp_algorithm device attribute one can see available and +currently selected (shown in square brackets) compression algorithms, +change selected compression algorithm (once the device is initialised +there is no way to change compression algorithm). - Examples: +Examples: #show supported compression algorithms cat /sys/block/zram0/comp_algorithm lzo [lz4] @@ -83,28 +83,27 @@ pre-created. Default: 1. #select lzo compression algorithm echo lzo > /sys/block/zram0/comp_algorithm - For the time being, the `comp_algorithm' content does not necessarily - show every compression algorithm supported by the kernel. We keep this - list primarily to simplify device configuration and one can configure - a new device with a compression algorithm that is not listed in - `comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API - and, if some of the algorithms were built as modules, it's impossible - to list all of them using, for instance, /proc/crypto or any other - method. This, however, has an advantage of permitting the usage of - custom crypto compression modules (implementing S/W or H/W - compression). +For the time being, the `comp_algorithm' content does not necessarily +show every compression algorithm supported by the kernel. We keep this +list primarily to simplify device configuration and one can configure +a new device with a compression algorithm that is not listed in +`comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API +and, if some of the algorithms were built as modules, it's impossible +to list all of them using, for instance, /proc/crypto or any other +method. This, however, has an advantage of permitting the usage of +custom crypto compression modules (implementing S/W or H/W compression). 4) Set Disksize -Set disk size by writing the value to sysfs node 'disksize'. -The value can be either in bytes or you can use mem suffixes. -Examples: -# Initialize /dev/zram0 with 50MB disksize -echo $((50*1024*1024)) > /sys/block/zram0/disksize +Set disk size by writing the value to sysfs node 'disksize'. +The value can be either in bytes or you can use mem suffixes. +Examples: + # Initialize /dev/zram0 with 50MB disksize + echo $((50*1024*1024)) > /sys/block/zram0/disksize -# Using mem suffixes -echo 256K > /sys/block/zram0/disksize -echo 512M > /sys/block/zram0/disksize -echo 1G > /sys/block/zram0/disksize + # Using mem suffixes + echo 256K > /sys/block/zram0/disksize + echo 512M > /sys/block/zram0/disksize + echo 1G > /sys/block/zram0/disksize Note: There is little point creating a zram of greater than twice the size of memory @@ -112,20
[PATCH v3 1/7] zram: rename zstrm find-release functions
We don't perform any zstream idle list lookup anymore, so zcomp_strm_find()/zcomp_strm_release() names are not representative. Rename to zcomp_stream_get()/zcomp_stream_put(). Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/zcomp.c| 4 ++-- drivers/block/zram/zcomp.h| 4 ++-- drivers/block/zram/zram_drv.c | 8 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index b51a816..400f826 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -95,12 +95,12 @@ bool zcomp_available_algorithm(const char *comp) return find_backend(comp) != NULL; } -struct zcomp_strm *zcomp_strm_find(struct zcomp *comp) +struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) { return *get_cpu_ptr(comp->stream); } -void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm) +void zcomp_stream_put(struct zcomp *comp) { put_cpu_ptr(comp->stream); } diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index ffd88cb..944b8e6 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h @@ -48,8 +48,8 @@ bool zcomp_available_algorithm(const char *comp); struct zcomp *zcomp_create(const char *comp); void zcomp_destroy(struct zcomp *comp); -struct zcomp_strm *zcomp_strm_find(struct zcomp *comp); -void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm); +struct zcomp_strm *zcomp_stream_get(struct zcomp *comp); +void zcomp_stream_put(struct zcomp *comp); int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm, const unsigned char *src, size_t *dst_len); diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 8fcad8b..9361a5d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -695,7 +695,7 @@ compress_again: goto out; } - zstrm = zcomp_strm_find(zram->comp); + zstrm = zcomp_stream_get(zram->comp); ret = zcomp_compress(zram->comp, zstrm, uncmem, ); if (!is_partial_io(bvec)) { kunmap_atomic(user_mem); @@ -734,7 +734,7 @@ compress_again: __GFP_NOWARN | __GFP_HIGHMEM); if (!handle) { - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); zstrm = NULL; atomic64_inc(>stats.writestall); @@ -769,7 +769,7 @@ compress_again: memcpy(cmem, src, clen); } - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); zstrm = NULL; zs_unmap_object(meta->mem_pool, handle); @@ -789,7 +789,7 @@ compress_again: atomic64_inc(>stats.pages_stored); out: if (zstrm) - zcomp_strm_release(zram->comp, zstrm); + zcomp_stream_put(zram->comp); if (is_partial_io(bvec)) kfree(uncmem); return ret; -- 2.8.3.394.g3916adf
[PATCH v3 0/7] zram: switch to crypto api
Hello, This has started as a 'add zlib support' work, but after some thinking I saw no blockers for a bigger change -- a switch to crypto API. We don't have an idle zstreams list anymore and our write path now works absolutely differently, preventing preemption during compression. This removes possibilities of read paths preempting writes at wrong places and opens the door for a move from custom LZO/LZ4 compression backends implementation to a more generic one, using crypto compress API. This patch set also eliminates the need of a new context-less crypto API interface, which was quite hard to sell, so we can move along faster. v3: -- use IS_ENABLED in the backends array, so crypto_has_comp() can be avoided (saving some time and memory). v2: -- addressed Minchan's review points -- allow out-of-tree comp algorithms, per Minchan -- some other cleanups, reworks and improvements Sergey Senozhatsky (7): zram: rename zstrm find-release functions zram: switch to crypto compress API zram: use crypto api to check alg availability zram: cosmetic: cleanup documentation zram: delete custom lzo/lz4 zram: add more compression algorithms zram: drop gfp_t from zcomp_strm_alloc() Documentation/blockdev/zram.txt | 82 -- drivers/block/zram/Kconfig | 15 +--- drivers/block/zram/Makefile | 4 +- drivers/block/zram/zcomp.c | 150 +--- drivers/block/zram/zcomp.h | 36 +++--- drivers/block/zram/zcomp_lz4.c | 56 --- drivers/block/zram/zcomp_lz4.h | 17 - drivers/block/zram/zcomp_lzo.c | 56 --- drivers/block/zram/zcomp_lzo.h | 17 - drivers/block/zram/zram_drv.c | 42 ++- drivers/block/zram/zram_drv.h | 5 +- 11 files changed, 180 insertions(+), 300 deletions(-) delete mode 100644 drivers/block/zram/zcomp_lz4.c delete mode 100644 drivers/block/zram/zcomp_lz4.h delete mode 100644 drivers/block/zram/zcomp_lzo.c delete mode 100644 drivers/block/zram/zcomp_lzo.h -- 2.8.3.394.g3916adf
[PATCH v3 7/7] zram: drop gfp_t from zcomp_strm_alloc()
We now allocate streams from CPU_UP hot-plug path, there are no context-dependent stream allocations anymore and we can schedule from zcomp_strm_alloc(). Use GFP_KERNEL directly and drop a gfp_t parameter. Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim Acked-by: Minchan Kim --- drivers/block/zram/zcomp.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index 32e521a..4b5cd3a 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -47,9 +47,9 @@ static void zcomp_strm_free(struct zcomp_strm *zstrm) * allocate new zcomp_strm structure with ->tfm initialized by * backend, return NULL on error */ -static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) +static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) { - struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), flags); + struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); if (!zstrm) return NULL; @@ -58,7 +58,7 @@ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp, gfp_t flags) * allocate 2 pages. 1 for compressed data, plus 1 extra for the * case when compressed size is larger than the original one */ - zstrm->buffer = (void *)__get_free_pages(flags | __GFP_ZERO, 1); + zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); if (IS_ERR_OR_NULL(zstrm->tfm) || !zstrm->buffer) { zcomp_strm_free(zstrm); zstrm = NULL; @@ -169,7 +169,7 @@ static int __zcomp_cpu_notifier(struct zcomp *comp, case CPU_UP_PREPARE: if (WARN_ON(*per_cpu_ptr(comp->stream, cpu))) break; - zstrm = zcomp_strm_alloc(comp, GFP_KERNEL); + zstrm = zcomp_strm_alloc(comp); if (IS_ERR_OR_NULL(zstrm)) { pr_err("Can't allocate a compression stream\n"); return NOTIFY_BAD; -- 2.8.3.394.g3916adf
[PATCH v3 4/7] zram: cosmetic: cleanup documentation
zram documentation is a mix of different styles: spaces, tabs, tabs + spaces, etc. clean it up. Signed-off-by: Sergey Senozhatsky Cc: Minchan Kim Cc: Joonsoo Kim Cc: Jonathan Corbet Acked-by: Minchan Kim --- Documentation/blockdev/zram.txt | 91 - 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 7c05357..0535ae1 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -59,23 +59,23 @@ num_devices parameter is optional and tells zram how many devices should be pre-created. Default: 1. 2) Set max number of compression streams - Regardless the value passed to this attribute, ZRAM will always - allocate multiple compression streams - one per online CPUs - thus - allowing several concurrent compression operations. The number of - allocated compression streams goes down when some of the CPUs - become offline. There is no single-compression-stream mode anymore, - unless you are running a UP system or has only 1 CPU online. - - To find out how many streams are currently available: +Regardless the value passed to this attribute, ZRAM will always +allocate multiple compression streams - one per online CPUs - thus +allowing several concurrent compression operations. The number of +allocated compression streams goes down when some of the CPUs +become offline. There is no single-compression-stream mode anymore, +unless you are running a UP system or has only 1 CPU online. + +To find out how many streams are currently available: cat /sys/block/zram0/max_comp_streams 3) Select compression algorithm - Using comp_algorithm device attribute one can see available and - currently selected (shown in square brackets) compression algorithms, - change selected compression algorithm (once the device is initialised - there is no way to change compression algorithm). +Using comp_algorithm device attribute one can see available and +currently selected (shown in square brackets) compression algorithms, +change selected compression algorithm (once the device is initialised +there is no way to change compression algorithm). - Examples: +Examples: #show supported compression algorithms cat /sys/block/zram0/comp_algorithm lzo [lz4] @@ -83,28 +83,27 @@ pre-created. Default: 1. #select lzo compression algorithm echo lzo > /sys/block/zram0/comp_algorithm - For the time being, the `comp_algorithm' content does not necessarily - show every compression algorithm supported by the kernel. We keep this - list primarily to simplify device configuration and one can configure - a new device with a compression algorithm that is not listed in - `comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API - and, if some of the algorithms were built as modules, it's impossible - to list all of them using, for instance, /proc/crypto or any other - method. This, however, has an advantage of permitting the usage of - custom crypto compression modules (implementing S/W or H/W - compression). +For the time being, the `comp_algorithm' content does not necessarily +show every compression algorithm supported by the kernel. We keep this +list primarily to simplify device configuration and one can configure +a new device with a compression algorithm that is not listed in +`comp_algorithm'. The thing is that, internally, ZRAM uses Crypto API +and, if some of the algorithms were built as modules, it's impossible +to list all of them using, for instance, /proc/crypto or any other +method. This, however, has an advantage of permitting the usage of +custom crypto compression modules (implementing S/W or H/W compression). 4) Set Disksize -Set disk size by writing the value to sysfs node 'disksize'. -The value can be either in bytes or you can use mem suffixes. -Examples: -# Initialize /dev/zram0 with 50MB disksize -echo $((50*1024*1024)) > /sys/block/zram0/disksize +Set disk size by writing the value to sysfs node 'disksize'. +The value can be either in bytes or you can use mem suffixes. +Examples: + # Initialize /dev/zram0 with 50MB disksize + echo $((50*1024*1024)) > /sys/block/zram0/disksize -# Using mem suffixes -echo 256K > /sys/block/zram0/disksize -echo 512M > /sys/block/zram0/disksize -echo 1G > /sys/block/zram0/disksize + # Using mem suffixes + echo 256K > /sys/block/zram0/disksize + echo 512M > /sys/block/zram0/disksize + echo 1G > /sys/block/zram0/disksize Note: There is little point creating a zram of greater than twice the size of memory @@ -112,20 +111,20 @@ since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the size of the disk when
Re: [PATCH v10 2/7] usb: mux: add generic code for dual role port mux
On Sat, Jun 04, 2016 at 12:06:06AM +0800, Lu Baolu wrote: > Hi Peter, > > On 06/03/2016 03:41 PM, Peter Chen wrote: > > On Thu, Jun 02, 2016 at 09:37:24AM +0800, Lu Baolu wrote: > >> > Several Intel platforms implement USB dual role by having completely > >> > separate xHCI and dwc3 IPs in PCH or SOC silicons. These two IPs share > >> > a single USB port. There is another external port mux which controls > >> > where the data lines should go. While the USB controllers are part of > >> > the silicon, the port mux design are platform specific. > >> > > >> > This patch adds the generic code to handle such multiple roles of a > >> > usb port. It exports the necessary interfaces for other components to > >> > register or unregister a usb mux device, and to control its role. > >> > It registers the mux device with sysfs as well, so that users are able > >> > to control the port role from user space. > >> > > >> > Some other archs (e.g. Renesas R-Car gen2 SoCs) need an external mux to > >> > swap usb roles as well. This code could also be leveraged for those > >> > archs. > >> > > > Sorry to review this so late, > > It doesn't matter. Thanks for review. Comments are always welcome.:-) > > > from my point,it is a dual-role switch > > driver too, > > No, it's not a dual-role switch driver, but a driver for USB port > multiplexing. > > One example of port multiplexing can be found in several Intel SOC and PCH > chips, inside of which, there are two independent USB controllers: host and > device. They might share a single port and this port could be configured to > route the line to one of these two controllers. This patch introduced a > generic > framework for port mux drivers. It aids the drivers to handle port mux by > providing interfaces to 1) register/unregister a mux device; 2) lookup the > mux device; and 3) switch the port. > For this case, I can't see it is different with dual-role switch. Your case is just like Renesas case, which uses two different drivers between peripheral and host[1]. > Port multiplexing isn't equal to USB dual role. There are other cases in > today's > systems. In several Intel PCH chips, there equips two USB host controllers: > ehci > and xhci. The xhci USB2 ports are multiplexed with ehci. This guarantees all > USB ports work even running an old version of OS which lacks of USB3 support. > In theory, we can create a driver for the port mux and switch the ports > between > xhci and ehci, but that's silly, isn't it? Why not always USB3?:-) > > Another case is xHCI debug capability. The xHCI host controller might equip > a unit for system debugging (refer to 7.6 of xHCI spec). The debugging unit is > independent of xhci host controller. But it shares its port with xhci. > Software > could switch the port between xhci and the debugging unit through the > registers > defined in xHCI spec. > Yes, above two are different with dual role switch. But in your code and Kconfig, it seems this framework is dedicated for dual-role. Eg: +menuconfig USB_PORTMUX + bool "USB dual role port MUX support" + help + Generic USB dual role port mux support. I think a general dual role port mux is necessary, it can be used to manage different dual-role switch method, eg - ID pin - External connector through GPIO - SoC register - sysfs - type-C events But this code is better co-work with OTG/Dual-role framework, we'd better have only interface that the user can know which role for the current port. [1] https://lkml.org/lkml/2016/4/7/115 -- Best Regards, Peter Chen
Re: [PATCH v10 2/7] usb: mux: add generic code for dual role port mux
On Sat, Jun 04, 2016 at 12:06:06AM +0800, Lu Baolu wrote: > Hi Peter, > > On 06/03/2016 03:41 PM, Peter Chen wrote: > > On Thu, Jun 02, 2016 at 09:37:24AM +0800, Lu Baolu wrote: > >> > Several Intel platforms implement USB dual role by having completely > >> > separate xHCI and dwc3 IPs in PCH or SOC silicons. These two IPs share > >> > a single USB port. There is another external port mux which controls > >> > where the data lines should go. While the USB controllers are part of > >> > the silicon, the port mux design are platform specific. > >> > > >> > This patch adds the generic code to handle such multiple roles of a > >> > usb port. It exports the necessary interfaces for other components to > >> > register or unregister a usb mux device, and to control its role. > >> > It registers the mux device with sysfs as well, so that users are able > >> > to control the port role from user space. > >> > > >> > Some other archs (e.g. Renesas R-Car gen2 SoCs) need an external mux to > >> > swap usb roles as well. This code could also be leveraged for those > >> > archs. > >> > > > Sorry to review this so late, > > It doesn't matter. Thanks for review. Comments are always welcome.:-) > > > from my point,it is a dual-role switch > > driver too, > > No, it's not a dual-role switch driver, but a driver for USB port > multiplexing. > > One example of port multiplexing can be found in several Intel SOC and PCH > chips, inside of which, there are two independent USB controllers: host and > device. They might share a single port and this port could be configured to > route the line to one of these two controllers. This patch introduced a > generic > framework for port mux drivers. It aids the drivers to handle port mux by > providing interfaces to 1) register/unregister a mux device; 2) lookup the > mux device; and 3) switch the port. > For this case, I can't see it is different with dual-role switch. Your case is just like Renesas case, which uses two different drivers between peripheral and host[1]. > Port multiplexing isn't equal to USB dual role. There are other cases in > today's > systems. In several Intel PCH chips, there equips two USB host controllers: > ehci > and xhci. The xhci USB2 ports are multiplexed with ehci. This guarantees all > USB ports work even running an old version of OS which lacks of USB3 support. > In theory, we can create a driver for the port mux and switch the ports > between > xhci and ehci, but that's silly, isn't it? Why not always USB3?:-) > > Another case is xHCI debug capability. The xHCI host controller might equip > a unit for system debugging (refer to 7.6 of xHCI spec). The debugging unit is > independent of xhci host controller. But it shares its port with xhci. > Software > could switch the port between xhci and the debugging unit through the > registers > defined in xHCI spec. > Yes, above two are different with dual role switch. But in your code and Kconfig, it seems this framework is dedicated for dual-role. Eg: +menuconfig USB_PORTMUX + bool "USB dual role port MUX support" + help + Generic USB dual role port mux support. I think a general dual role port mux is necessary, it can be used to manage different dual-role switch method, eg - ID pin - External connector through GPIO - SoC register - sysfs - type-C events But this code is better co-work with OTG/Dual-role framework, we'd better have only interface that the user can know which role for the current port. [1] https://lkml.org/lkml/2016/4/7/115 -- Best Regards, Peter Chen
[PATCH] dmaengine: bcm2835: Fix polling for completion of DMA with interrupts masked.
The tx_status hook is supposed to be safe to call from interrupt context, but it wouldn't ever return completion for the last transfer, meaning you couldn't poll for DMA completion with interrupts masked. This fixes IRQ handling for bcm2835's DSI1, which requires using the DMA engine to write its registers due to a bug in the AXI bridge. Signed-off-by: Eric Anholt--- drivers/dma/bcm2835-dma.c | 24 +++- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6149b27c33ad..320461c578e3 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -570,16 +570,16 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, struct virt_dma_desc *vd; enum dma_status ret; unsigned long flags; + u32 residue; ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE || !txstate) + if (ret == DMA_COMPLETE) return ret; spin_lock_irqsave(>vc.lock, flags); vd = vchan_find_desc(>vc, cookie); if (vd) { - txstate->residue = - bcm2835_dma_desc_size(to_bcm2835_dma_desc(>tx)); + residue = bcm2835_dma_desc_size(to_bcm2835_dma_desc(>tx)); } else if (c->desc && c->desc->vd.tx.cookie == cookie) { struct bcm2835_desc *d = c->desc; dma_addr_t pos; @@ -591,11 +591,25 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, else pos = 0; - txstate->residue = bcm2835_dma_desc_size_pos(d, pos); + residue = bcm2835_dma_desc_size_pos(d, pos); + + /* +* If our non-cyclic transfer is done, then report +* complete and trigger the next tx now. This lets +* the dmaengine API be used synchronously from an IRQ +* handler. +*/ + if (!d->cyclic && residue == 0) { + vchan_cookie_complete(>desc->vd); + bcm2835_dma_start_desc(c); + ret = dma_cookie_status(chan, cookie, txstate); + } } else { - txstate->residue = 0; + residue = 0; } + dma_set_residue(txstate, residue); + spin_unlock_irqrestore(>vc.lock, flags); return ret; -- 2.8.0.rc3
[PATCH] dmaengine: bcm2835: Fix polling for completion of DMA with interrupts masked.
The tx_status hook is supposed to be safe to call from interrupt context, but it wouldn't ever return completion for the last transfer, meaning you couldn't poll for DMA completion with interrupts masked. This fixes IRQ handling for bcm2835's DSI1, which requires using the DMA engine to write its registers due to a bug in the AXI bridge. Signed-off-by: Eric Anholt --- drivers/dma/bcm2835-dma.c | 24 +++- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6149b27c33ad..320461c578e3 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -570,16 +570,16 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, struct virt_dma_desc *vd; enum dma_status ret; unsigned long flags; + u32 residue; ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE || !txstate) + if (ret == DMA_COMPLETE) return ret; spin_lock_irqsave(>vc.lock, flags); vd = vchan_find_desc(>vc, cookie); if (vd) { - txstate->residue = - bcm2835_dma_desc_size(to_bcm2835_dma_desc(>tx)); + residue = bcm2835_dma_desc_size(to_bcm2835_dma_desc(>tx)); } else if (c->desc && c->desc->vd.tx.cookie == cookie) { struct bcm2835_desc *d = c->desc; dma_addr_t pos; @@ -591,11 +591,25 @@ static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan, else pos = 0; - txstate->residue = bcm2835_dma_desc_size_pos(d, pos); + residue = bcm2835_dma_desc_size_pos(d, pos); + + /* +* If our non-cyclic transfer is done, then report +* complete and trigger the next tx now. This lets +* the dmaengine API be used synchronously from an IRQ +* handler. +*/ + if (!d->cyclic && residue == 0) { + vchan_cookie_complete(>desc->vd); + bcm2835_dma_start_desc(c); + ret = dma_cookie_status(chan, cookie, txstate); + } } else { - txstate->residue = 0; + residue = 0; } + dma_set_residue(txstate, residue); + spin_unlock_irqrestore(>vc.lock, flags); return ret; -- 2.8.0.rc3
[PATCH] dma: bcm2835: Fix compiler warning on arm64.
The min() macro was complaining about mismatched types. The max len is at most SZ_1G, so we can just put it in an unsigned int. Signed-off-by: Eric Anholt--- Vinod, if you ack it, this one would be nice to be able to merge through the -soc tree, so that when we enable of arm64 builds of this driver we don't introduce a new compiler warning. drivers/dma/bcm2835-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6149b27c33ad..1fa11fc067c6 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -393,7 +393,7 @@ static void bcm2835_dma_fill_cb_chain_with_sg( unsigned int sg_len) { struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); - size_t max_len = bcm2835_dma_max_frame_length(c); + unsigned int max_len = bcm2835_dma_max_frame_length(c); unsigned int i, len; dma_addr_t addr; struct scatterlist *sgent; -- 2.8.0.rc3
[PATCH] dma: bcm2835: Fix compiler warning on arm64.
The min() macro was complaining about mismatched types. The max len is at most SZ_1G, so we can just put it in an unsigned int. Signed-off-by: Eric Anholt --- Vinod, if you ack it, this one would be nice to be able to merge through the -soc tree, so that when we enable of arm64 builds of this driver we don't introduce a new compiler warning. drivers/dma/bcm2835-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6149b27c33ad..1fa11fc067c6 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -393,7 +393,7 @@ static void bcm2835_dma_fill_cb_chain_with_sg( unsigned int sg_len) { struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); - size_t max_len = bcm2835_dma_max_frame_length(c); + unsigned int max_len = bcm2835_dma_max_frame_length(c); unsigned int i, len; dma_addr_t addr; struct scatterlist *sgent; -- 2.8.0.rc3
[PATCH] sd: remove redundant check for BLK_DEF_MAX_SECTORS
q->limits.max_sectors is already checked against BLK_DEF_MAX_SECTORS in __scsi_alloc_queue(), when it calls blk_queue_max_hw_sectors(). There is no need to check it again in sd. This change also allows a SCSI driver set an maximum sector size bigger than BLK_DEF_MAX_SECTORS, without returning values on optional VPD page 0xb0 "Block Limits". Signed-off-by: Long Li--- drivers/scsi/sd.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 60bff78..d8c4047 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2870,11 +2870,8 @@ static int sd_revalidate_disk(struct gendisk *disk) logical_to_bytes(sdp, sdkp->opt_xfer_blocks) >= PAGE_SIZE) { q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); - } else - rw_max = BLK_DEF_MAX_SECTORS; - - /* Combine with controller limits */ - q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); + q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); + } set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); sd_config_write_same(sdkp); -- 2.7.4
[PATCH] sd: remove redundant check for BLK_DEF_MAX_SECTORS
q->limits.max_sectors is already checked against BLK_DEF_MAX_SECTORS in __scsi_alloc_queue(), when it calls blk_queue_max_hw_sectors(). There is no need to check it again in sd. This change also allows a SCSI driver set an maximum sector size bigger than BLK_DEF_MAX_SECTORS, without returning values on optional VPD page 0xb0 "Block Limits". Signed-off-by: Long Li --- drivers/scsi/sd.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 60bff78..d8c4047 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2870,11 +2870,8 @@ static int sd_revalidate_disk(struct gendisk *disk) logical_to_bytes(sdp, sdkp->opt_xfer_blocks) >= PAGE_SIZE) { q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); - } else - rw_max = BLK_DEF_MAX_SECTORS; - - /* Combine with controller limits */ - q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); + q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); + } set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity)); sd_config_write_same(sdkp); -- 2.7.4
[PATCH v12 08/15] powerpc/PCI: Keep resource idx order with bridge register number
Same as sparc version. Make resource with consistent sequence like other arch or directly from pci_read_bridge_bases(), even when non-pref mmio is missing, or out of ordering in firmware reporting. Just hold i = 1 for non pref mmio, and i = 2 for pref mmio. Signed-off-by: Yinghai LuCc: linuxppc-...@lists.ozlabs.org --- arch/powerpc/kernel/pci_of_scan.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 526ac67..719f225 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -252,7 +252,7 @@ void of_scan_pci_bridge(struct pci_dev *dev) bus->resource[i] = res; ++res; } - i = 1; + i = 3; for (; len >= 32; len -= 32, ranges += 8) { flags = pci_parse_of_flags(of_read_number(ranges, 1), 1); size = of_read_number([6], 2); @@ -265,6 +265,12 @@ void of_scan_pci_bridge(struct pci_dev *dev) " for bridge %s\n", node->full_name); continue; } + } else if ((flags & IORESOURCE_PREFETCH) && + !bus->resource[2]->flags) { + res = bus->resource[2]; + } else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) == + IORESOURCE_MEM) && !bus->resource[1]->flags) { + res = bus->resource[1]; } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" -- 2.8.3
[PATCH v12 08/15] powerpc/PCI: Keep resource idx order with bridge register number
Same as sparc version. Make resource with consistent sequence like other arch or directly from pci_read_bridge_bases(), even when non-pref mmio is missing, or out of ordering in firmware reporting. Just hold i = 1 for non pref mmio, and i = 2 for pref mmio. Signed-off-by: Yinghai Lu Cc: linuxppc-...@lists.ozlabs.org --- arch/powerpc/kernel/pci_of_scan.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 526ac67..719f225 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -252,7 +252,7 @@ void of_scan_pci_bridge(struct pci_dev *dev) bus->resource[i] = res; ++res; } - i = 1; + i = 3; for (; len >= 32; len -= 32, ranges += 8) { flags = pci_parse_of_flags(of_read_number(ranges, 1), 1); size = of_read_number([6], 2); @@ -265,6 +265,12 @@ void of_scan_pci_bridge(struct pci_dev *dev) " for bridge %s\n", node->full_name); continue; } + } else if ((flags & IORESOURCE_PREFETCH) && + !bus->resource[2]->flags) { + res = bus->resource[2]; + } else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) == + IORESOURCE_MEM) && !bus->resource[1]->flags) { + res = bus->resource[1]; } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" -- 2.8.3
Re: Dcache oops
On Fri, Jun 03, 2016 at 07:58:37PM -0400, Oleg Drokin wrote: > > EOPENSTALE, that is... Oleg, could you check if the following works? > > Yes, this one lasted for an hour with no crashing, so it must be good. > Thanks. > (note, I am not equipped to verify correctness of NFS operations, though). I suspect that Jeff Layton might have relevant regression tests. Incidentally, we really need a consolidated regression testsuite, including the tests you'd been running. Right now there's some stuff in xfstests, LTP and cthon; if anything, this mess shows just why we need all of that and then some in a single place. Lustre stuff has caught a 3 years old NFS bug (missing d_drop() in nfs_atomic_open()) and a year-old bug in handling of EOPENSTALE retries on the last component of a trailing non-embedded symlink. Neither is hard to trigger; it's just that relevant tests hadn't been run on NFS, period. Jeff, could you verify that the following does not cause regressions in stale fhandles treatment? I want to rip the damn retry logics out of do_last() and if the staleness had only been discovered inside of nfs4_file_open() just have the upper-level logics handle it by doing a normal LOOKUP_REVAL pass from scratch. To hell with trying to be clever; a few roundtrips it saves us in some cases is not worth the complexity and potential for bugs. I'm fairly sure that the time spent debugging this particular turd exceeds the total amount of time it has ever saved, and do_last() is in dire need of simplification. All talk about "enough eyes" isn't worth much when the readers of code in question feel like ripping their eyes out... diff --git a/fs/namei.c b/fs/namei.c index 4c4f95a..3d9511e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3166,9 +3166,7 @@ static int do_last(struct nameidata *nd, int acc_mode = op->acc_mode; unsigned seq; struct inode *inode; - struct path save_parent = { .dentry = NULL, .mnt = NULL }; struct path path; - bool retried = false; int error; nd->flags &= ~LOOKUP_PARENT; @@ -3211,7 +3209,6 @@ static int do_last(struct nameidata *nd, return -EISDIR; } -retry_lookup: if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) { error = mnt_want_write(nd->path.mnt); if (!error) @@ -3292,23 +3289,14 @@ finish_lookup: if (unlikely(error)) return error; - if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) { - path_to_nameidata(, nd); - } else { - save_parent.dentry = nd->path.dentry; - save_parent.mnt = mntget(path.mnt); - nd->path.dentry = path.dentry; - - } + path_to_nameidata(, nd); nd->inode = inode; nd->seq = seq; /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ finish_open: error = complete_walk(nd); - if (error) { - path_put(_parent); + if (error) return error; - } audit_inode(nd->name, nd->path.dentry, 0); error = -EISDIR; if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) @@ -3331,13 +3319,9 @@ finish_open_created: goto out; BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ error = vfs_open(>path, file, current_cred()); - if (!error) { - *opened |= FILE_OPENED; - } else { - if (error == -EOPENSTALE) - goto stale_open; + if (error) goto out; - } + *opened |= FILE_OPENED; opened: error = open_check_o_direct(file); if (!error) @@ -3353,26 +3337,7 @@ out: } if (got_write) mnt_drop_write(nd->path.mnt); - path_put(_parent); return error; - -stale_open: - /* If no saved parent or already retried then can't retry */ - if (!save_parent.dentry || retried) - goto out; - - BUG_ON(save_parent.dentry != dir); - path_put(>path); - nd->path = save_parent; - nd->inode = dir->d_inode; - save_parent.mnt = NULL; - save_parent.dentry = NULL; - if (got_write) { - mnt_drop_write(nd->path.mnt); - got_write = false; - } - retried = true; - goto retry_lookup; } static int do_tmpfile(struct nameidata *nd, unsigned flags,
Re: Dcache oops
On Fri, Jun 03, 2016 at 07:58:37PM -0400, Oleg Drokin wrote: > > EOPENSTALE, that is... Oleg, could you check if the following works? > > Yes, this one lasted for an hour with no crashing, so it must be good. > Thanks. > (note, I am not equipped to verify correctness of NFS operations, though). I suspect that Jeff Layton might have relevant regression tests. Incidentally, we really need a consolidated regression testsuite, including the tests you'd been running. Right now there's some stuff in xfstests, LTP and cthon; if anything, this mess shows just why we need all of that and then some in a single place. Lustre stuff has caught a 3 years old NFS bug (missing d_drop() in nfs_atomic_open()) and a year-old bug in handling of EOPENSTALE retries on the last component of a trailing non-embedded symlink. Neither is hard to trigger; it's just that relevant tests hadn't been run on NFS, period. Jeff, could you verify that the following does not cause regressions in stale fhandles treatment? I want to rip the damn retry logics out of do_last() and if the staleness had only been discovered inside of nfs4_file_open() just have the upper-level logics handle it by doing a normal LOOKUP_REVAL pass from scratch. To hell with trying to be clever; a few roundtrips it saves us in some cases is not worth the complexity and potential for bugs. I'm fairly sure that the time spent debugging this particular turd exceeds the total amount of time it has ever saved, and do_last() is in dire need of simplification. All talk about "enough eyes" isn't worth much when the readers of code in question feel like ripping their eyes out... diff --git a/fs/namei.c b/fs/namei.c index 4c4f95a..3d9511e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3166,9 +3166,7 @@ static int do_last(struct nameidata *nd, int acc_mode = op->acc_mode; unsigned seq; struct inode *inode; - struct path save_parent = { .dentry = NULL, .mnt = NULL }; struct path path; - bool retried = false; int error; nd->flags &= ~LOOKUP_PARENT; @@ -3211,7 +3209,6 @@ static int do_last(struct nameidata *nd, return -EISDIR; } -retry_lookup: if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) { error = mnt_want_write(nd->path.mnt); if (!error) @@ -3292,23 +3289,14 @@ finish_lookup: if (unlikely(error)) return error; - if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) { - path_to_nameidata(, nd); - } else { - save_parent.dentry = nd->path.dentry; - save_parent.mnt = mntget(path.mnt); - nd->path.dentry = path.dentry; - - } + path_to_nameidata(, nd); nd->inode = inode; nd->seq = seq; /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ finish_open: error = complete_walk(nd); - if (error) { - path_put(_parent); + if (error) return error; - } audit_inode(nd->name, nd->path.dentry, 0); error = -EISDIR; if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) @@ -3331,13 +3319,9 @@ finish_open_created: goto out; BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ error = vfs_open(>path, file, current_cred()); - if (!error) { - *opened |= FILE_OPENED; - } else { - if (error == -EOPENSTALE) - goto stale_open; + if (error) goto out; - } + *opened |= FILE_OPENED; opened: error = open_check_o_direct(file); if (!error) @@ -3353,26 +3337,7 @@ out: } if (got_write) mnt_drop_write(nd->path.mnt); - path_put(_parent); return error; - -stale_open: - /* If no saved parent or already retried then can't retry */ - if (!save_parent.dentry || retried) - goto out; - - BUG_ON(save_parent.dentry != dir); - path_put(>path); - nd->path = save_parent; - nd->inode = dir->d_inode; - save_parent.mnt = NULL; - save_parent.dentry = NULL; - if (got_write) { - mnt_drop_write(nd->path.mnt); - got_write = false; - } - retried = true; - goto retry_lookup; } static int do_tmpfile(struct nameidata *nd, unsigned flags,
Re: [PATCH] b43: Remove unused phy_a code
On 06/03/2016 02:35 PM, Michael Büsch wrote: On Fri, 3 Jun 2016 14:32:46 -0700 Guenter Roeckwrote: gcc-6 reports the following error with -Werror=unused-const-variable. drivers/net/wireless/broadcom/b43/phy_a.c:576:40: error: 'b43_phyops_a' defined but not used Turns out a lot of code in this file is unused, so let's remove it. All a-phy code is usused. So you can basically remove the whole file and any other A-PHY code. I love removing code. I'll resend with more code removed. Guenter
Re: [PATCH] b43: Remove unused phy_a code
On 06/03/2016 02:35 PM, Michael Büsch wrote: On Fri, 3 Jun 2016 14:32:46 -0700 Guenter Roeck wrote: gcc-6 reports the following error with -Werror=unused-const-variable. drivers/net/wireless/broadcom/b43/phy_a.c:576:40: error: 'b43_phyops_a' defined but not used Turns out a lot of code in this file is unused, so let's remove it. All a-phy code is usused. So you can basically remove the whole file and any other A-PHY code. I love removing code. I'll resend with more code removed. Guenter
[PATCH] Drivers: ssb: Fix bare unsigned and changed to trailing comments
I changed drivers/ssb/driver_gpio.c to better fit the coding style. I changed unsigned to unsigned int Two comments were changed to not end on a line with the text. Signed-off-by: Hugh Sipiere--- drivers/ssb/driver_gpio.c | 26 ++ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index 180e027..49f858c 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c @@ -23,7 +23,7 @@ **/ #if IS_ENABLED(CONFIG_SSB_EMBEDDED) -static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -38,14 +38,14 @@ static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) * ChipCommon **/ -static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); return !!ssb_chipco_gpio_in(>chipco, 1 << gpio); } -static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, +static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -54,7 +54,7 @@ static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, } static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, - unsigned gpio) + unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -63,7 +63,7 @@ static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, } static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) + unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -72,7 +72,7 @@ static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, return 0; } -static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -85,7 +85,7 @@ static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) return 0; } -static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio) +static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -231,7 +231,8 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) chip->ngpio = 16; /* There is just one SoC in one device and its GPIO addresses should be * deterministic to address them more easily. The other buses could get -* a random base number. */ +* a random base number. +*/ if (bus->bustype == SSB_BUSTYPE_SSB) chip->base = 0; else @@ -256,14 +257,14 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) #ifdef CONFIG_SSB_DRIVER_EXTIF -static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); return !!ssb_extif_gpio_in(>extif, 1 << gpio); } -static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio, +static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -281,7 +282,7 @@ static int ssb_gpio_extif_direction_input(struct gpio_chip *chip, } static int ssb_gpio_extif_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) + unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -424,7 +425,8 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus) chip->ngpio = 5; /* There is just one SoC in one device and its GPIO addresses should be * deterministic to address them more easily. The other buses could get -* a random base number. */ +* a random base number. +*/ if (bus->bustype == SSB_BUSTYPE_SSB) chip->base = 0; else -- 2.5.5
[PATCH] Drivers: ssb: Fix bare unsigned and changed to trailing comments
I changed drivers/ssb/driver_gpio.c to better fit the coding style. I changed unsigned to unsigned int Two comments were changed to not end on a line with the text. Signed-off-by: Hugh Sipiere --- drivers/ssb/driver_gpio.c | 26 ++ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index 180e027..49f858c 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c @@ -23,7 +23,7 @@ **/ #if IS_ENABLED(CONFIG_SSB_EMBEDDED) -static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -38,14 +38,14 @@ static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) * ChipCommon **/ -static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); return !!ssb_chipco_gpio_in(>chipco, 1 << gpio); } -static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, +static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -54,7 +54,7 @@ static void ssb_gpio_chipco_set_value(struct gpio_chip *chip, unsigned gpio, } static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, - unsigned gpio) + unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -63,7 +63,7 @@ static int ssb_gpio_chipco_direction_input(struct gpio_chip *chip, } static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) + unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -72,7 +72,7 @@ static int ssb_gpio_chipco_direction_output(struct gpio_chip *chip, return 0; } -static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -85,7 +85,7 @@ static int ssb_gpio_chipco_request(struct gpio_chip *chip, unsigned gpio) return 0; } -static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio) +static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -231,7 +231,8 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) chip->ngpio = 16; /* There is just one SoC in one device and its GPIO addresses should be * deterministic to address them more easily. The other buses could get -* a random base number. */ +* a random base number. +*/ if (bus->bustype == SSB_BUSTYPE_SSB) chip->base = 0; else @@ -256,14 +257,14 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) #ifdef CONFIG_SSB_DRIVER_EXTIF -static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) +static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned int gpio) { struct ssb_bus *bus = gpiochip_get_data(chip); return !!ssb_extif_gpio_in(>extif, 1 << gpio); } -static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned gpio, +static void ssb_gpio_extif_set_value(struct gpio_chip *chip, unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -281,7 +282,7 @@ static int ssb_gpio_extif_direction_input(struct gpio_chip *chip, } static int ssb_gpio_extif_direction_output(struct gpio_chip *chip, - unsigned gpio, int value) + unsigned int gpio, int value) { struct ssb_bus *bus = gpiochip_get_data(chip); @@ -424,7 +425,8 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus) chip->ngpio = 5; /* There is just one SoC in one device and its GPIO addresses should be * deterministic to address them more easily. The other buses could get -* a random base number. */ +* a random base number. +*/ if (bus->bustype == SSB_BUSTYPE_SSB) chip->base = 0; else -- 2.5.5
Re: Builtin microcode does nothing..
On 03.06.2016 10:02, Borislav Petkov wrote: On Thu, May 26, 2016 at 02:46:06PM +0200, Borislav Petkov wrote: In the meantime, I've simplified the code even more and testing here with your .config looks good. I'll prepare another patchset next week and post it here in case you guys feel bored and want to test it too. Ok, here's a new version, it passes testing here but we've heard that before :-\ http://git.kernel.org/cgit/linux/kernel/git/bp/bp.git/log/?h=tip-microcode If you guys could give it a quick run again, it'll be much appreciated. I tested your patches on both boxes on top 4.7-rc1 and they work just fine for me. The test was done as before: CONFIG_FIRMWARE_IN_KERNEL=y CONFIG_EXTRA_FIRMWARE="intel-ucode/" ( to match my CPU ) CONFIG_BLK_DEV_INITRD=y Kernel booted with initrd *without* grub microcode. If you wish any other tests please let me know. Regards
Re: Builtin microcode does nothing..
On 03.06.2016 10:02, Borislav Petkov wrote: On Thu, May 26, 2016 at 02:46:06PM +0200, Borislav Petkov wrote: In the meantime, I've simplified the code even more and testing here with your .config looks good. I'll prepare another patchset next week and post it here in case you guys feel bored and want to test it too. Ok, here's a new version, it passes testing here but we've heard that before :-\ http://git.kernel.org/cgit/linux/kernel/git/bp/bp.git/log/?h=tip-microcode If you guys could give it a quick run again, it'll be much appreciated. I tested your patches on both boxes on top 4.7-rc1 and they work just fine for me. The test was done as before: CONFIG_FIRMWARE_IN_KERNEL=y CONFIG_EXTRA_FIRMWARE="intel-ucode/" ( to match my CPU ) CONFIG_BLK_DEV_INITRD=y Kernel booted with initrd *without* grub microcode. If you wish any other tests please let me know. Regards
[PATCH v12 07/15] sparc/PCI: Keep resource idx order with bridge register number
On one system found strange "no compatible bridge window" warning even we already had pref_compat support that add extra pref bit for device resource. PCI: Claiming :00:01.0: Resource 14: 00020001..000200010fff [10220c] PCI: Claiming :01:00.0: Resource 1: 00020001..00020001 [100214] pci :01:00.0: can't claim BAR 1 [mem 0x20001-0x20001 64bit]: no compatible bridge window It turns out that pci_resource_compatible()/pci_up_path_over_pref_mem64() just check resource with bridge pref mmio register idx 15, and we have put resource to use mmio register idx 14 during of_scan_pci_bridge() as the bridge does not have mmio resource. We already fix pci_up_path_over_pref_mem64() to check all bus resources. And at the same time, this patch make resource to have consistent sequence like other arch or directly from pci_read_bridge_bases(), even when non-pref mmio is missing, or out of ordering in firmware reporting. Just hold i = 1 for non pref mmio, and i = 2 for pref mmio. Signed-off-by: Yinghai LuTested-by: Khalid Aziz Cc: sparcli...@vger.kernel.org --- arch/sparc/kernel/pci.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index e7fbf56..e84fa8c 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -481,7 +481,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_read_bridge_bases(bus); goto after_ranges; } - i = 1; + i = 3; for (; len >= 32; len -= 32, ranges += 8) { u64 start; @@ -513,6 +513,12 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, " for bridge %s\n", node->full_name); continue; } + } else if ((flags & IORESOURCE_PREFETCH) && + !bus->resource[2]->flags) { + res = bus->resource[2]; + } else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) == + IORESOURCE_MEM) && !bus->resource[1]->flags) { + res = bus->resource[1]; } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" -- 2.8.3
[PATCH v12 07/15] sparc/PCI: Keep resource idx order with bridge register number
On one system found strange "no compatible bridge window" warning even we already had pref_compat support that add extra pref bit for device resource. PCI: Claiming :00:01.0: Resource 14: 00020001..000200010fff [10220c] PCI: Claiming :01:00.0: Resource 1: 00020001..00020001 [100214] pci :01:00.0: can't claim BAR 1 [mem 0x20001-0x20001 64bit]: no compatible bridge window It turns out that pci_resource_compatible()/pci_up_path_over_pref_mem64() just check resource with bridge pref mmio register idx 15, and we have put resource to use mmio register idx 14 during of_scan_pci_bridge() as the bridge does not have mmio resource. We already fix pci_up_path_over_pref_mem64() to check all bus resources. And at the same time, this patch make resource to have consistent sequence like other arch or directly from pci_read_bridge_bases(), even when non-pref mmio is missing, or out of ordering in firmware reporting. Just hold i = 1 for non pref mmio, and i = 2 for pref mmio. Signed-off-by: Yinghai Lu Tested-by: Khalid Aziz Cc: sparcli...@vger.kernel.org --- arch/sparc/kernel/pci.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index e7fbf56..e84fa8c 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -481,7 +481,7 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_read_bridge_bases(bus); goto after_ranges; } - i = 1; + i = 3; for (; len >= 32; len -= 32, ranges += 8) { u64 start; @@ -513,6 +513,12 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, " for bridge %s\n", node->full_name); continue; } + } else if ((flags & IORESOURCE_PREFETCH) && + !bus->resource[2]->flags) { + res = bus->resource[2]; + } else if (((flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) == + IORESOURCE_MEM) && !bus->resource[1]->flags) { + res = bus->resource[1]; } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" -- 2.8.3
[PATCH v12 12/15] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64
If any bridge up to root only have 32bit pref mmio, We don't need to treat device non-pref mmio64 as as pref mmio64. We need to move pci_bridge_check_ranges calling early. For parent bridges pref mmio BAR may not allocated by BIOS, res flags is still 0, we need to have it correct set before we check them for child device resources. -v2: check all bus resources instead of just res[15]. Signed-off-by: Yinghai LuTested-by: Khalid Aziz --- drivers/pci/setup-bus.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index b3b1565..ffb1941 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -738,6 +738,29 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i) return -EINVAL; } +static bool pci_up_path_over_pref_mem64(struct pci_bus *bus) +{ + if (pci_is_root_bus(bus)) + return true; + + if (bus->self) { + int i; + bool found = false; + struct resource *res; + + pci_bus_for_each_resource(bus, res, i) + if (res->flags & IORESOURCE_MEM_64) { + found = true; + break; + } + + if (!found) + return false; + } + + return pci_up_path_over_pref_mem64(bus->parent); +} + int pci_resource_pref_compatible(const struct pci_dev *dev, struct resource *res) { @@ -746,7 +769,8 @@ int pci_resource_pref_compatible(const struct pci_dev *dev, if ((res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_MEM_64) && - dev->on_all_pcie_path) + dev->on_all_pcie_path && + pci_up_path_over_pref_mem64(dev->bus)) return res->flags | IORESOURCE_PREFETCH; return res->flags; @@ -1239,6 +1263,10 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) struct resource *b_res; int ret; + if (!pci_is_root_bus(bus) && + (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI) + pci_bridge_check_ranges(bus); + list_for_each_entry(dev, >devices, bus_list) { struct pci_bus *b = dev->subordinate; if (!b) @@ -1266,7 +1294,6 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) break; case PCI_CLASS_BRIDGE_PCI: - pci_bridge_check_ranges(bus); if (bus->self->is_hotplug_bridge) { additional_io_size = pci_hotplug_io_size; additional_mem_size = pci_hotplug_mem_size; -- 2.8.3
[PATCH v12 05/15] sparc/PCI: Reserve legacy mmio after PCI mmio
On one system found bunch of claim resource fail from pci device. pci_sun4v f02b894c: PCI host bridge to bus :00 pci_bus :00: root bus resource [io 0x2007e-0x2007e0fff] (bus address [0x-0xfff]) pci_bus :00: root bus resource [mem 0x2-0x27eff] (bus address [0x-0x7eff]) pci_bus :00: root bus resource [mem 0x20001-0x20007] (bus address [0x1-0x7]) ... PCI: Claiming :00:02.0: Resource 14: 0002..0002004f [200] pci :00:02.0: can't claim BAR 14 [mem 0x2-0x2004f]: address conflict with Video RAM area [??? 0x2000a-0x2000b flags 0x8000] pci :02:00.0: can't claim BAR 0 [mem 0x2-0x2000f]: no compatible bridge window PCI: Claiming :02:00.0: Resource 3: 00020010..000200103fff [200] pci :02:00.0: can't claim BAR 3 [mem 0x20010-0x200103fff]: no compatible bridge window PCI: Claiming :02:00.1: Resource 0: 00020020..0002002f [200] pci :02:00.1: can't claim BAR 0 [mem 0x20020-0x2002f]: no compatible bridge window PCI: Claiming :02:00.1: Resource 3: 000200104000..000200107fff [200] pci :02:00.1: can't claim BAR 3 [mem 0x200104000-0x200107fff]: no compatible bridge window PCI: Claiming :02:00.2: Resource 0: 00020030..0002003f [200] pci :02:00.2: can't claim BAR 0 [mem 0x20030-0x2003f]: no compatible bridge window PCI: Claiming :02:00.2: Resource 3: 000200108000..00020010bfff [200] pci :02:00.2: can't claim BAR 3 [mem 0x200108000-0x20010bfff]: no compatible bridge window PCI: Claiming :02:00.3: Resource 0: 00020040..0002004f [200] pci :02:00.3: can't claim BAR 0 [mem 0x20040-0x2004f]: no compatible bridge window PCI: Claiming :02:00.3: Resource 3: 00020010c000..00020010 [200] pci :02:00.3: can't claim BAR 3 [mem 0x20010c000-0x20010]: no compatible bridge window The bridge 00:02.0 resource does not get reserved as Video RAM take the position early, and following children resources reservation all fail. Move down Video RAM area reservation after pci mmio get reserved, so we leave pci driver to use those regions. -v5: merge simplify one and use pcibios_bus_to_resource() -v6: use pci_find_bus_resource() Signed-off-by: Yinghai LuTested-by: Khalid Aziz Cc: sparcli...@vger.kernel.org --- arch/sparc/kernel/pci.c| 1 + arch/sparc/kernel/pci_common.c | 59 ++ arch/sparc/kernel/pci_impl.h | 1 + 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 4245dc4..e7fbf56 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_bus_register_of_sysfs(bus); pci_claim_bus_resources(bus); + pci_register_legacy_regions(bus); pci_bus_add_devices(bus); return bus; } diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 76998f8..1ebc7ff 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm) } } -static void pci_register_legacy_regions(struct resource *io_res, - struct resource *mem_res) +static void pci_register_region(struct pci_bus *bus, const char *name, + resource_size_t rstart, resource_size_t size) { - struct resource *p; + struct resource *res, *conflict, *bus_res; + struct pci_bus_region region; - /* VGA Video RAM. */ - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) return; - p->name = "Video RAM area"; - p->start = mem_res->start + 0xaUL; - p->end = p->start + 0x1UL; - p->flags = IORESOURCE_BUSY; - request_resource(mem_res, p); + res->flags = IORESOURCE_MEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) + region.start = rstart; + region.end = rstart + size - 1UL; + pcibios_bus_to_resource(bus, res, ); + bus_res = pci_find_bus_resource(bus, res); + if (!bus_res) { + kfree(res); return; + } + + res->name = name; + res->flags |= IORESOURCE_BUSY; + conflict = request_resource_conflict(bus_res, res); + if (conflict) { + dev_printk(KERN_DEBUG, >dev, + " can't claim %s %pR: address conflict with %s %pR\n", + res->name, res, conflict->name, conflict); + kfree(res); + } +}
[PATCH v12 12/15] PCI: Only treat non-pref mmio64 as pref if all bridges have MEM_64
If any bridge up to root only have 32bit pref mmio, We don't need to treat device non-pref mmio64 as as pref mmio64. We need to move pci_bridge_check_ranges calling early. For parent bridges pref mmio BAR may not allocated by BIOS, res flags is still 0, we need to have it correct set before we check them for child device resources. -v2: check all bus resources instead of just res[15]. Signed-off-by: Yinghai Lu Tested-by: Khalid Aziz --- drivers/pci/setup-bus.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index b3b1565..ffb1941 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -738,6 +738,29 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i) return -EINVAL; } +static bool pci_up_path_over_pref_mem64(struct pci_bus *bus) +{ + if (pci_is_root_bus(bus)) + return true; + + if (bus->self) { + int i; + bool found = false; + struct resource *res; + + pci_bus_for_each_resource(bus, res, i) + if (res->flags & IORESOURCE_MEM_64) { + found = true; + break; + } + + if (!found) + return false; + } + + return pci_up_path_over_pref_mem64(bus->parent); +} + int pci_resource_pref_compatible(const struct pci_dev *dev, struct resource *res) { @@ -746,7 +769,8 @@ int pci_resource_pref_compatible(const struct pci_dev *dev, if ((res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_MEM_64) && - dev->on_all_pcie_path) + dev->on_all_pcie_path && + pci_up_path_over_pref_mem64(dev->bus)) return res->flags | IORESOURCE_PREFETCH; return res->flags; @@ -1239,6 +1263,10 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) struct resource *b_res; int ret; + if (!pci_is_root_bus(bus) && + (bus->self->class >> 8) == PCI_CLASS_BRIDGE_PCI) + pci_bridge_check_ranges(bus); + list_for_each_entry(dev, >devices, bus_list) { struct pci_bus *b = dev->subordinate; if (!b) @@ -1266,7 +1294,6 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) break; case PCI_CLASS_BRIDGE_PCI: - pci_bridge_check_ranges(bus); if (bus->self->is_hotplug_bridge) { additional_io_size = pci_hotplug_io_size; additional_mem_size = pci_hotplug_mem_size; -- 2.8.3
[PATCH v12 05/15] sparc/PCI: Reserve legacy mmio after PCI mmio
On one system found bunch of claim resource fail from pci device. pci_sun4v f02b894c: PCI host bridge to bus :00 pci_bus :00: root bus resource [io 0x2007e-0x2007e0fff] (bus address [0x-0xfff]) pci_bus :00: root bus resource [mem 0x2-0x27eff] (bus address [0x-0x7eff]) pci_bus :00: root bus resource [mem 0x20001-0x20007] (bus address [0x1-0x7]) ... PCI: Claiming :00:02.0: Resource 14: 0002..0002004f [200] pci :00:02.0: can't claim BAR 14 [mem 0x2-0x2004f]: address conflict with Video RAM area [??? 0x2000a-0x2000b flags 0x8000] pci :02:00.0: can't claim BAR 0 [mem 0x2-0x2000f]: no compatible bridge window PCI: Claiming :02:00.0: Resource 3: 00020010..000200103fff [200] pci :02:00.0: can't claim BAR 3 [mem 0x20010-0x200103fff]: no compatible bridge window PCI: Claiming :02:00.1: Resource 0: 00020020..0002002f [200] pci :02:00.1: can't claim BAR 0 [mem 0x20020-0x2002f]: no compatible bridge window PCI: Claiming :02:00.1: Resource 3: 000200104000..000200107fff [200] pci :02:00.1: can't claim BAR 3 [mem 0x200104000-0x200107fff]: no compatible bridge window PCI: Claiming :02:00.2: Resource 0: 00020030..0002003f [200] pci :02:00.2: can't claim BAR 0 [mem 0x20030-0x2003f]: no compatible bridge window PCI: Claiming :02:00.2: Resource 3: 000200108000..00020010bfff [200] pci :02:00.2: can't claim BAR 3 [mem 0x200108000-0x20010bfff]: no compatible bridge window PCI: Claiming :02:00.3: Resource 0: 00020040..0002004f [200] pci :02:00.3: can't claim BAR 0 [mem 0x20040-0x2004f]: no compatible bridge window PCI: Claiming :02:00.3: Resource 3: 00020010c000..00020010 [200] pci :02:00.3: can't claim BAR 3 [mem 0x20010c000-0x20010]: no compatible bridge window The bridge 00:02.0 resource does not get reserved as Video RAM take the position early, and following children resources reservation all fail. Move down Video RAM area reservation after pci mmio get reserved, so we leave pci driver to use those regions. -v5: merge simplify one and use pcibios_bus_to_resource() -v6: use pci_find_bus_resource() Signed-off-by: Yinghai Lu Tested-by: Khalid Aziz Cc: sparcli...@vger.kernel.org --- arch/sparc/kernel/pci.c| 1 + arch/sparc/kernel/pci_common.c | 59 ++ arch/sparc/kernel/pci_impl.h | 1 + 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 4245dc4..e7fbf56 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -686,6 +686,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_bus_register_of_sysfs(bus); pci_claim_bus_resources(bus); + pci_register_legacy_regions(bus); pci_bus_add_devices(bus); return bus; } diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 76998f8..1ebc7ff 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -328,41 +328,46 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm) } } -static void pci_register_legacy_regions(struct resource *io_res, - struct resource *mem_res) +static void pci_register_region(struct pci_bus *bus, const char *name, + resource_size_t rstart, resource_size_t size) { - struct resource *p; + struct resource *res, *conflict, *bus_res; + struct pci_bus_region region; - /* VGA Video RAM. */ - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) return; - p->name = "Video RAM area"; - p->start = mem_res->start + 0xaUL; - p->end = p->start + 0x1UL; - p->flags = IORESOURCE_BUSY; - request_resource(mem_res, p); + res->flags = IORESOURCE_MEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) + region.start = rstart; + region.end = rstart + size - 1UL; + pcibios_bus_to_resource(bus, res, ); + bus_res = pci_find_bus_resource(bus, res); + if (!bus_res) { + kfree(res); return; + } + + res->name = name; + res->flags |= IORESOURCE_BUSY; + conflict = request_resource_conflict(bus_res, res); + if (conflict) { + dev_printk(KERN_DEBUG, >dev, + " can't claim %s %pR: address conflict with %s %pR\n", + res->name, res, conflict->name, conflict); + kfree(res); + } +} - p->name = "System ROM"; -
[PATCH v12 02/15] PCI: Let pci_mmap_page_range() take resource address
In 8c05cd08a7 ("PCI: fix offset check for sysfs mmapped files"), try to check exposed value with resource start/end in proc mmap path. |start = vma->vm_pgoff; |size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |pci_start = (mmap_api == PCI_MMAP_PROCFS) ? |pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; |if (start >= pci_start && start < pci_start + size && |start + nr <= pci_start + size) That breaks sparc that exposed value is BAR value, and need to be offseted to resource address. Original pci_mmap_page_range() is taking PCI BAR value aka usr_address. Bjorn found out that it would be much simple to pass resource address directly and avoid extra those __pci_mmap_make_offset. In this patch: 1. in proc path: proc_bus_pci_mmap, try convert back to resource before calling pci_mmap_page_range 2. in sysfs path: pci_mmap_resource will just offset with resource start. 3. all pci_mmap_page_range will have vma->vm_pgoff with in resource range instead of BAR value. 4. remove __pci_mmap_make_offset, as the checking is done in pci_mmap_fits(). -v2: add pci_user_to_resource and remove __pci_mmap_make_offset -v3: pass resource pointer with pci_mmap_page_range() Signed-off-by: Yinghai LuCc: linuxppc-...@lists.ozlabs.org Cc: sparcli...@vger.kernel.org Cc: linux-xte...@linux-xtensa.org --- arch/microblaze/pci/pci-common.c | 78 +++--- arch/powerpc/kernel/pci-common.c | 78 +++--- arch/sparc/kernel/pci.c | 117 --- arch/xtensa/kernel/pci.c | 75 - drivers/pci/pci-sysfs.c | 33 --- drivers/pci/proc.c | 63 ++--- 6 files changed, 104 insertions(+), 340 deletions(-) diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 95146b0..4e21993 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -156,69 +156,6 @@ void pcibios_set_master(struct pci_dev *dev) */ /* - * Adjust vm_pgoff of VMA such that it is the physical page offset - * corresponding to the 32-bit pci bus offset for DEV requested by the user. - * - * Basically, the user finds the base address for his device which he wishes - * to mmap. They read the 32-bit value from the config space base register, - * add whatever PAGE_SIZE multiple offset they wish, and feed this into the - * offset parameter of mmap on /proc/bus/pci/XXX for that device. - * - * Returns negative error code on failure, zero on success. - */ -static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - resource_size_t *offset, - enum pci_mmap_state mmap_state) -{ - struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long io_offset = 0; - int i, res_bit; - - if (!hose) - return NULL;/* should never happen */ - - /* If memory, add on the PCI bridge address offset */ - if (mmap_state == pci_mmap_mem) { -#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ - *offset += hose->pci_mem_offset; -#endif - res_bit = IORESOURCE_MEM; - } else { - io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; - *offset += io_offset; - res_bit = IORESOURCE_IO; - } - - /* -* Check that the offset requested corresponds to one of the -* resources of the device. -*/ - for (i = 0; i <= PCI_ROM_RESOURCE; i++) { - struct resource *rp = >resource[i]; - int flags = rp->flags; - - /* treat ROM as memory (should be already) */ - if (i == PCI_ROM_RESOURCE) - flags |= IORESOURCE_MEM; - - /* Active and same type? */ - if ((flags & res_bit) == 0) - continue; - - /* In the range of this resource? */ - if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) - continue; - - /* found it! construct the final physical address */ - if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; - return rp; - } - - return NULL; -} - -/* * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci * device mapping. */ @@ -310,12 +247,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct resource *rp, { resource_size_t offset = ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; - struct resource *rp; int ret; - rp = __pci_mmap_make_offset(dev, , mmap_state); - if (rp == NULL) - return -EINVAL; + if
[PATCH v12 02/15] PCI: Let pci_mmap_page_range() take resource address
In 8c05cd08a7 ("PCI: fix offset check for sysfs mmapped files"), try to check exposed value with resource start/end in proc mmap path. |start = vma->vm_pgoff; |size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |pci_start = (mmap_api == PCI_MMAP_PROCFS) ? |pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0; |if (start >= pci_start && start < pci_start + size && |start + nr <= pci_start + size) That breaks sparc that exposed value is BAR value, and need to be offseted to resource address. Original pci_mmap_page_range() is taking PCI BAR value aka usr_address. Bjorn found out that it would be much simple to pass resource address directly and avoid extra those __pci_mmap_make_offset. In this patch: 1. in proc path: proc_bus_pci_mmap, try convert back to resource before calling pci_mmap_page_range 2. in sysfs path: pci_mmap_resource will just offset with resource start. 3. all pci_mmap_page_range will have vma->vm_pgoff with in resource range instead of BAR value. 4. remove __pci_mmap_make_offset, as the checking is done in pci_mmap_fits(). -v2: add pci_user_to_resource and remove __pci_mmap_make_offset -v3: pass resource pointer with pci_mmap_page_range() Signed-off-by: Yinghai Lu Cc: linuxppc-...@lists.ozlabs.org Cc: sparcli...@vger.kernel.org Cc: linux-xte...@linux-xtensa.org --- arch/microblaze/pci/pci-common.c | 78 +++--- arch/powerpc/kernel/pci-common.c | 78 +++--- arch/sparc/kernel/pci.c | 117 --- arch/xtensa/kernel/pci.c | 75 - drivers/pci/pci-sysfs.c | 33 --- drivers/pci/proc.c | 63 ++--- 6 files changed, 104 insertions(+), 340 deletions(-) diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 95146b0..4e21993 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -156,69 +156,6 @@ void pcibios_set_master(struct pci_dev *dev) */ /* - * Adjust vm_pgoff of VMA such that it is the physical page offset - * corresponding to the 32-bit pci bus offset for DEV requested by the user. - * - * Basically, the user finds the base address for his device which he wishes - * to mmap. They read the 32-bit value from the config space base register, - * add whatever PAGE_SIZE multiple offset they wish, and feed this into the - * offset parameter of mmap on /proc/bus/pci/XXX for that device. - * - * Returns negative error code on failure, zero on success. - */ -static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - resource_size_t *offset, - enum pci_mmap_state mmap_state) -{ - struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long io_offset = 0; - int i, res_bit; - - if (!hose) - return NULL;/* should never happen */ - - /* If memory, add on the PCI bridge address offset */ - if (mmap_state == pci_mmap_mem) { -#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ - *offset += hose->pci_mem_offset; -#endif - res_bit = IORESOURCE_MEM; - } else { - io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; - *offset += io_offset; - res_bit = IORESOURCE_IO; - } - - /* -* Check that the offset requested corresponds to one of the -* resources of the device. -*/ - for (i = 0; i <= PCI_ROM_RESOURCE; i++) { - struct resource *rp = >resource[i]; - int flags = rp->flags; - - /* treat ROM as memory (should be already) */ - if (i == PCI_ROM_RESOURCE) - flags |= IORESOURCE_MEM; - - /* Active and same type? */ - if ((flags & res_bit) == 0) - continue; - - /* In the range of this resource? */ - if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) - continue; - - /* found it! construct the final physical address */ - if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; - return rp; - } - - return NULL; -} - -/* * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci * device mapping. */ @@ -310,12 +247,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct resource *rp, { resource_size_t offset = ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; - struct resource *rp; int ret; - rp = __pci_mmap_make_offset(dev, , mmap_state); - if (rp == NULL) - return -EINVAL; + if (mmap_state ==