* [PATCH 0/5] kfifo cleanup and log based kfifo API @ 2013-01-08 14:57 Yuanhan Liu 2013-01-08 14:57 ` [PATCH 1/5] kfifo: remove unnecessary type check Yuanhan Liu ` (5 more replies) 0 siblings, 6 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel Cc: Yuanhan Liu, Stefani Seibold, Andrew Morton, James E.J. Bottomley, iscsi list, Mike Christie The current kfifo API take the kfifo size as input, while it rounds _down_ the size to power of 2 at __kfifo_alloc/init. This may introduce several potential issues. First, the kfifo size is not what we want. Say, if we want to allocate a kfifo with size of 127 elements. Then in the end, we can only hold 64 elements. Here is a similar example at drivers/hid/hid-logitech-dj.c: if (kfifo_alloc(&djrcv_dev->notif_fifo, DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), GFP_KERNEL)) { Where, DJ_MAX_NUMBER_NOTIFICATIONS is 8, and sizeo of(struct dj_report) is 15. Which means it wants to allocate a kfifo buffer which can store 8 dj_report entries at once. The expected kfifo buffer size would be 8 * 15 = 120 then. While, in the end, __kfifo_alloc will turn the size to rounddown_power_of_2(120) = 64, and then allocate a buf with 64 bytes, which I don't think this is the original author want. With the new log API, we can do something like following: int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report)); if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, GFP_KERNEL)) { This make sure we will allocate enough kfifo buffer for holding DJ_MAX_NUMBER_NOTIFICATIONS dj_report entries. Second, kfifo_init used a pre-allocated buffer, and the actual buffer size is determined in caller side, while the actual kfifo buffer size is maintained in kfifo_init, which will be rounded down power of 2 without notifying to caller. Take the example of code at drivers/scsi/libiscsi.c: /* If the user passed an items pointer, he wants a copy of * the array. */ if (items) num_arrays++; q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); if (q->pool == NULL) return -ENOMEM; kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*)); for (i = 0; i < max; i++) { q->pool[i] = kzalloc(item_size, GFP_KERNEL); if (q->pool[i] == NULL) { q->max = i; goto enomem; } kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*)); } Assume max is not power of 2, this piece of code will not work! As it assumes the kfifo will hold max elements, but actually it can only hold rounddown_power_of_2(max). My proposal is to replace kfifo_init with kfifo_alloc, where it allocate buffer and maintain fifo size inside kfifo. Then we can remove buggy kfifo_init. After we change the kfifo_alloc to be a log API, all above issue will be gone as said by Stefani. Here is the patch summary: patch 1 is a cleanup patch to cleanup the unneeded type check. patch 2 and 3 turn the only 2 users of kfifo_init to kfifo_alloc patch 4 remove kfifo_init patch 5 log based kfifo API Thanks! --yliu Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: James E.J. Bottomley <JBottomley@parallels.com> Cc: iscsi list <open-iscsi@googlegroups.com> Cc: Mike Christie <michaelc@cs.wisc.edu> --- Yuanhan Liu (5): kfifo: remove unnecessary type check libsrp: replace kfifo_init with kfifo_alloc libiscsi: replace kfifo_init with kfifo_alloc kfifo: remove kfifo_init kfifo: log based kfifo API arch/arm/plat-omap/Kconfig | 2 +- arch/arm/plat-omap/mailbox.c | 6 +- arch/powerpc/sysdev/fsl_rmu.c | 2 +- drivers/char/sonypi.c | 9 ++- drivers/hid/hid-logitech-dj.c | 7 +- drivers/iio/industrialio-event.c | 2 +- drivers/iio/kfifo_buf.c | 3 +- drivers/infiniband/hw/cxgb3/cxio_resource.c | 8 ++- drivers/media/i2c/cx25840/cx25840-ir.c | 9 ++- drivers/media/pci/cx23885/cx23888-ir.c | 9 ++- drivers/media/pci/meye/meye.c | 6 +- drivers/media/pci/meye/meye.h | 2 + drivers/media/rc/ir-raw.c | 7 +- drivers/memstick/host/r592.h | 2 +- drivers/mmc/card/sdio_uart.c | 4 +- drivers/mtd/sm_ftl.c | 5 +- drivers/net/wireless/libertas/main.c | 4 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 5 +- drivers/pci/pcie/aer/aerdrv_core.c | 3 +- drivers/platform/x86/fujitsu-laptop.c | 5 +- drivers/platform/x86/sony-laptop.c | 6 +- drivers/rapidio/devices/tsi721.c | 5 +- drivers/scsi/libiscsi.c | 59 ++++++++-------- drivers/scsi/libiscsi_tcp.c | 6 +- drivers/scsi/libsrp.c | 22 +++--- drivers/staging/omapdrm/omap_plane.c | 5 +- drivers/tty/n_gsm.c | 4 +- drivers/tty/nozomi.c | 5 +- drivers/tty/serial/ifx6x60.c | 2 +- drivers/tty/serial/ifx6x60.h | 3 +- drivers/tty/serial/kgdb_nmi.c | 7 +- drivers/usb/host/fhci.h | 4 +- drivers/usb/serial/cypress_m8.c | 4 +- drivers/usb/serial/io_ti.c | 4 +- drivers/usb/serial/ti_usb_3410_5052.c | 7 +- drivers/usb/serial/usb-serial.c | 2 +- include/linux/kfifo.h | 98 +++++++-------------------- include/linux/rio.h | 1 + include/media/lirc_dev.h | 4 +- include/scsi/libiscsi.h | 4 +- include/scsi/libsrp.h | 1 - kernel/kfifo.c | 32 +-------- mm/memory-failure.c | 3 +- net/dccp/probe.c | 6 +- net/sctp/probe.c | 6 +- samples/kfifo/bytestream-example.c | 8 +- samples/kfifo/dma-example.c | 5 +- samples/kfifo/inttype-example.c | 7 +- samples/kfifo/record-example.c | 6 +- 49 files changed, 195 insertions(+), 231 deletions(-) -- 1.7.7.6 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/5] kfifo: remove unnecessary type check 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu @ 2013-01-08 14:57 ` Yuanhan Liu 2013-01-08 21:51 ` Stefani Seibold 2013-01-08 14:57 ` [PATCH 2/5] libsrp: replace kfifo_init with kfifo_alloc Yuanhan Liu ` (4 subsequent siblings) 5 siblings, 1 reply; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel; +Cc: Yuanhan Liu, Stefani Seibold, Andrew Morton Firstly, this kind of type check doesn't work. It does something similar as following: void * __dummy = NULL; __buf = __dummy; __dummy is defined as void *. Thus it will not trigger warnings as expected. Second, we don't need that kind of check. Since the prototype of __kfifo_out is: unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len) buf is defined as void *, so we don't need do the type check. Remove it. v2: remove ptr and const_ptr, which were used for type checking. LINK: https://lkml.org/lkml/2012/10/25/386 LINK: https://lkml.org/lkml/2012/10/25/584 Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> --- include/linux/kfifo.h | 46 ++++++++++++---------------------------------- 1 files changed, 12 insertions(+), 34 deletions(-) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 10308c6..7a18245 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -63,49 +63,47 @@ struct __kfifo { void *data; }; -#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ +#define __STRUCT_KFIFO_COMMON(datatype, recsize) \ union { \ struct __kfifo kfifo; \ datatype *type; \ char (*rectype)[recsize]; \ - ptrtype *ptr; \ - const ptrtype *ptr_const; \ } -#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ +#define __STRUCT_KFIFO(type, size, recsize) \ { \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + __STRUCT_KFIFO_COMMON(type, recsize); \ type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ } #define STRUCT_KFIFO(type, size) \ - struct __STRUCT_KFIFO(type, size, 0, type) + struct __STRUCT_KFIFO(type, size, 0) -#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ +#define __STRUCT_KFIFO_PTR(type, recsize) \ { \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + __STRUCT_KFIFO_COMMON(type, recsize); \ type buf[0]; \ } #define STRUCT_KFIFO_PTR(type) \ - struct __STRUCT_KFIFO_PTR(type, 0, type) + struct __STRUCT_KFIFO_PTR(type, 0) /* * define compatibility "struct kfifo" for dynamic allocated fifos */ -struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0); #define STRUCT_KFIFO_REC_1(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 1, void) + struct __STRUCT_KFIFO(unsigned char, size, 1) #define STRUCT_KFIFO_REC_2(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 2, void) + struct __STRUCT_KFIFO(unsigned char, size, 2) /* * define kfifo_rec types */ -struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); -struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1); +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2); /* * helper macro to distinguish between real in place fifo where the fifo @@ -390,10 +388,6 @@ __kfifo_int_must_check_helper( \ unsigned int __ret; \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__val))NULL; \ - } \ if (__recsize) \ __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ __recsize); \ @@ -432,8 +426,6 @@ __kfifo_uint_must_check_helper( \ unsigned int __ret; \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))0; \ if (__recsize) \ __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ __recsize); \ @@ -473,8 +465,6 @@ __kfifo_uint_must_check_helper( \ unsigned int __ret; \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))NULL; \ if (__recsize) \ __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ __recsize); \ @@ -512,10 +502,6 @@ __kfifo_uint_must_check_helper( \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__buf))NULL; \ - } \ (__recsize) ?\ __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_in(__kfifo, __buf, __n); \ @@ -565,10 +551,6 @@ __kfifo_uint_must_check_helper( \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy = NULL; \ - __buf = __dummy; \ - } \ (__recsize) ?\ __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_out(__kfifo, __buf, __n); \ @@ -777,10 +759,6 @@ __kfifo_uint_must_check_helper( \ unsigned long __n = (n); \ const size_t __recsize = sizeof(*__tmp->rectype); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ - __buf = __dummy; \ - } \ (__recsize) ? \ __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ __kfifo_out_peek(__kfifo, __buf, __n); \ -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 1/5] kfifo: remove unnecessary type check 2013-01-08 14:57 ` [PATCH 1/5] kfifo: remove unnecessary type check Yuanhan Liu @ 2013-01-08 21:51 ` Stefani Seibold 2013-01-09 2:35 ` Yuanhan Liu 0 siblings, 1 reply; 15+ messages in thread From: Stefani Seibold @ 2013-01-08 21:51 UTC (permalink / raw) To: Yuanhan Liu; +Cc: linux-kernel, Andrew Morton Am Dienstag, den 08.01.2013, 22:57 +0800 schrieb Yuanhan Liu: > Firstly, this kind of type check doesn't work. It does something similar > as following: > void * __dummy = NULL; > __buf = __dummy; > > __dummy is defined as void *. Thus it will not trigger warnings as > expected. > > Second, we don't need that kind of check. Since the prototype > of __kfifo_out is: > unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len) > > buf is defined as void *, so we don't need do the type check. Remove it. > Thats wrong. First the type checking will be used in kfifo_put() and kfifo_in() for const types to check if the passed type of the data can converted to the fifo element type. And it will be used in kfifo_get(), kfifo_peek(), kfifo_out() and kfio_out_peek() to check if the element type of the fifo can be converted to the passed type of the destination. So a big NAK! > v2: remove ptr and const_ptr, which were used for type checking. > > LINK: https://lkml.org/lkml/2012/10/25/386 > LINK: https://lkml.org/lkml/2012/10/25/584 > > Cc: Stefani Seibold <stefani@seibold.net> > Cc: Andrew Morton <akpm@linux-foundation.org> > Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> > --- > include/linux/kfifo.h | 46 ++++++++++++---------------------------------- > 1 files changed, 12 insertions(+), 34 deletions(-) > > diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h > index 10308c6..7a18245 100644 > --- a/include/linux/kfifo.h > +++ b/include/linux/kfifo.h > @@ -63,49 +63,47 @@ struct __kfifo { > void *data; > }; > > -#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ > +#define __STRUCT_KFIFO_COMMON(datatype, recsize) \ > union { \ > struct __kfifo kfifo; \ > datatype *type; \ > char (*rectype)[recsize]; \ > - ptrtype *ptr; \ > - const ptrtype *ptr_const; \ > } > > -#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ > +#define __STRUCT_KFIFO(type, size, recsize) \ > { \ > - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ > + __STRUCT_KFIFO_COMMON(type, recsize); \ > type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ > } > > #define STRUCT_KFIFO(type, size) \ > - struct __STRUCT_KFIFO(type, size, 0, type) > + struct __STRUCT_KFIFO(type, size, 0) > > -#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ > +#define __STRUCT_KFIFO_PTR(type, recsize) \ > { \ > - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ > + __STRUCT_KFIFO_COMMON(type, recsize); \ > type buf[0]; \ > } > > #define STRUCT_KFIFO_PTR(type) \ > - struct __STRUCT_KFIFO_PTR(type, 0, type) > + struct __STRUCT_KFIFO_PTR(type, 0) > > /* > * define compatibility "struct kfifo" for dynamic allocated fifos > */ > -struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); > +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0); > > #define STRUCT_KFIFO_REC_1(size) \ > - struct __STRUCT_KFIFO(unsigned char, size, 1, void) > + struct __STRUCT_KFIFO(unsigned char, size, 1) > > #define STRUCT_KFIFO_REC_2(size) \ > - struct __STRUCT_KFIFO(unsigned char, size, 2, void) > + struct __STRUCT_KFIFO(unsigned char, size, 2) > > /* > * define kfifo_rec types > */ > -struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); > -struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); > +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1); > +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2); > > /* > * helper macro to distinguish between real in place fifo where the fifo > @@ -390,10 +388,6 @@ __kfifo_int_must_check_helper( \ > unsigned int __ret; \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) { \ > - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ > - __dummy = (typeof(__val))NULL; \ > - } \ > if (__recsize) \ > __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ > __recsize); \ > @@ -432,8 +426,6 @@ __kfifo_uint_must_check_helper( \ > unsigned int __ret; \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) \ > - __val = (typeof(__tmp->ptr))0; \ > if (__recsize) \ > __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ > __recsize); \ > @@ -473,8 +465,6 @@ __kfifo_uint_must_check_helper( \ > unsigned int __ret; \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) \ > - __val = (typeof(__tmp->ptr))NULL; \ > if (__recsize) \ > __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ > __recsize); \ > @@ -512,10 +502,6 @@ __kfifo_uint_must_check_helper( \ > unsigned long __n = (n); \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) { \ > - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ > - __dummy = (typeof(__buf))NULL; \ > - } \ > (__recsize) ?\ > __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ > __kfifo_in(__kfifo, __buf, __n); \ > @@ -565,10 +551,6 @@ __kfifo_uint_must_check_helper( \ > unsigned long __n = (n); \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) { \ > - typeof(__tmp->ptr) __dummy = NULL; \ > - __buf = __dummy; \ > - } \ > (__recsize) ?\ > __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ > __kfifo_out(__kfifo, __buf, __n); \ > @@ -777,10 +759,6 @@ __kfifo_uint_must_check_helper( \ > unsigned long __n = (n); \ > const size_t __recsize = sizeof(*__tmp->rectype); \ > struct __kfifo *__kfifo = &__tmp->kfifo; \ > - if (0) { \ > - typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ > - __buf = __dummy; \ > - } \ > (__recsize) ? \ > __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ > __kfifo_out_peek(__kfifo, __buf, __n); \ ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/5] kfifo: remove unnecessary type check 2013-01-08 21:51 ` Stefani Seibold @ 2013-01-09 2:35 ` Yuanhan Liu 2013-01-09 15:29 ` Stefani Seibold 0 siblings, 1 reply; 15+ messages in thread From: Yuanhan Liu @ 2013-01-09 2:35 UTC (permalink / raw) To: Stefani Seibold; +Cc: linux-kernel, Andrew Morton On Tue, Jan 08, 2013 at 10:51:04PM +0100, Stefani Seibold wrote: > Am Dienstag, den 08.01.2013, 22:57 +0800 schrieb Yuanhan Liu: > > Firstly, this kind of type check doesn't work. It does something similar > > as following: > > void * __dummy = NULL; > > __buf = __dummy; > > > > __dummy is defined as void *. Thus it will not trigger warnings as > > expected. > > > > Second, we don't need that kind of check. Since the prototype > > of __kfifo_out is: > > unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len) > > > > buf is defined as void *, so we don't need do the type check. Remove it. > > > > Thats wrong. > > First the type checking will be used in kfifo_put() and kfifo_in() for > const types to check if the passed type of the data can converted to the > fifo element type. Hi Stefani, Yes, I see now. After rechecking the code, I found that this kind of type checking only works for those static defined kifo by DECLARE/DEFINE_KFIFO. As the ptrtype is the same as the data type: /* the 4th argument "type" is "ptrtype" */ #define STRUCT_KFIFO(type, size) struct __STRUCT_KFIFO(type, size, 0, type) #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo While, for those kfifo dynamically allocated, the type checking will not work as expected then as ptrtype is always "void": struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); So, there is no need to do type force convertion like following: arch/arm/plat-omap/mailbox.c: len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); As mq->fifo is dynamically allocated. So, the type checking does work, and I'll drop this patch. Sorry for the noisy. --yliu > And it will be used in kfifo_get(), kfifo_peek(), kfifo_out() and > kfio_out_peek() to check if the element type of the fifo can be > converted to the passed type of the destination. > > So a big NAK! > > > v2: remove ptr and const_ptr, which were used for type checking. > > > > LINK: https://lkml.org/lkml/2012/10/25/386 > > LINK: https://lkml.org/lkml/2012/10/25/584 > > > > Cc: Stefani Seibold <stefani@seibold.net> > > Cc: Andrew Morton <akpm@linux-foundation.org> > > Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> > > --- > > include/linux/kfifo.h | 46 ++++++++++++---------------------------------- > > 1 files changed, 12 insertions(+), 34 deletions(-) > > > > diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h > > index 10308c6..7a18245 100644 > > --- a/include/linux/kfifo.h > > +++ b/include/linux/kfifo.h > > @@ -63,49 +63,47 @@ struct __kfifo { > > void *data; > > }; > > > > -#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ > > +#define __STRUCT_KFIFO_COMMON(datatype, recsize) \ > > union { \ > > struct __kfifo kfifo; \ > > datatype *type; \ > > char (*rectype)[recsize]; \ > > - ptrtype *ptr; \ > > - const ptrtype *ptr_const; \ > > } > > > > -#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ > > +#define __STRUCT_KFIFO(type, size, recsize) \ > > { \ > > - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ > > + __STRUCT_KFIFO_COMMON(type, recsize); \ > > type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ > > } > > > > #define STRUCT_KFIFO(type, size) \ > > - struct __STRUCT_KFIFO(type, size, 0, type) > > + struct __STRUCT_KFIFO(type, size, 0) > > > > -#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ > > +#define __STRUCT_KFIFO_PTR(type, recsize) \ > > { \ > > - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ > > + __STRUCT_KFIFO_COMMON(type, recsize); \ > > type buf[0]; \ > > } > > > > #define STRUCT_KFIFO_PTR(type) \ > > - struct __STRUCT_KFIFO_PTR(type, 0, type) > > + struct __STRUCT_KFIFO_PTR(type, 0) > > > > /* > > * define compatibility "struct kfifo" for dynamic allocated fifos > > */ > > -struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); > > +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0); > > > > #define STRUCT_KFIFO_REC_1(size) \ > > - struct __STRUCT_KFIFO(unsigned char, size, 1, void) > > + struct __STRUCT_KFIFO(unsigned char, size, 1) > > > > #define STRUCT_KFIFO_REC_2(size) \ > > - struct __STRUCT_KFIFO(unsigned char, size, 2, void) > > + struct __STRUCT_KFIFO(unsigned char, size, 2) > > > > /* > > * define kfifo_rec types > > */ > > -struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); > > -struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); > > +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1); > > +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2); > > > > /* > > * helper macro to distinguish between real in place fifo where the fifo > > @@ -390,10 +388,6 @@ __kfifo_int_must_check_helper( \ > > unsigned int __ret; \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) { \ > > - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ > > - __dummy = (typeof(__val))NULL; \ > > - } \ > > if (__recsize) \ > > __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ > > __recsize); \ > > @@ -432,8 +426,6 @@ __kfifo_uint_must_check_helper( \ > > unsigned int __ret; \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) \ > > - __val = (typeof(__tmp->ptr))0; \ > > if (__recsize) \ > > __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ > > __recsize); \ > > @@ -473,8 +465,6 @@ __kfifo_uint_must_check_helper( \ > > unsigned int __ret; \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) \ > > - __val = (typeof(__tmp->ptr))NULL; \ > > if (__recsize) \ > > __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ > > __recsize); \ > > @@ -512,10 +502,6 @@ __kfifo_uint_must_check_helper( \ > > unsigned long __n = (n); \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) { \ > > - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ > > - __dummy = (typeof(__buf))NULL; \ > > - } \ > > (__recsize) ?\ > > __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ > > __kfifo_in(__kfifo, __buf, __n); \ > > @@ -565,10 +551,6 @@ __kfifo_uint_must_check_helper( \ > > unsigned long __n = (n); \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) { \ > > - typeof(__tmp->ptr) __dummy = NULL; \ > > - __buf = __dummy; \ > > - } \ > > (__recsize) ?\ > > __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ > > __kfifo_out(__kfifo, __buf, __n); \ > > @@ -777,10 +759,6 @@ __kfifo_uint_must_check_helper( \ > > unsigned long __n = (n); \ > > const size_t __recsize = sizeof(*__tmp->rectype); \ > > struct __kfifo *__kfifo = &__tmp->kfifo; \ > > - if (0) { \ > > - typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ > > - __buf = __dummy; \ > > - } \ > > (__recsize) ? \ > > __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ > > __kfifo_out_peek(__kfifo, __buf, __n); \ > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/5] kfifo: remove unnecessary type check 2013-01-09 2:35 ` Yuanhan Liu @ 2013-01-09 15:29 ` Stefani Seibold 2013-01-10 7:12 ` Yuanhan Liu 0 siblings, 1 reply; 15+ messages in thread From: Stefani Seibold @ 2013-01-09 15:29 UTC (permalink / raw) To: Yuanhan Liu; +Cc: linux-kernel, Andrew Morton Am Mittwoch, den 09.01.2013, 10:35 +0800 schrieb Yuanhan Liu: > On Tue, Jan 08, 2013 at 10:51:04PM +0100, Stefani Seibold wrote: > > Am Dienstag, den 08.01.2013, 22:57 +0800 schrieb Yuanhan Liu: > > > Firstly, this kind of type check doesn't work. It does something similar > > > as following: > > > void * __dummy = NULL; > > > __buf = __dummy; > > > > > > __dummy is defined as void *. Thus it will not trigger warnings as > > > expected. > > > > > > Second, we don't need that kind of check. Since the prototype > > > of __kfifo_out is: > > > unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len) > > > > > > buf is defined as void *, so we don't need do the type check. Remove it. > > > > > > > Thats wrong. > > > > First the type checking will be used in kfifo_put() and kfifo_in() for > > const types to check if the passed type of the data can converted to the > > fifo element type. > > Hi Stefani, > > Yes, I see now. After rechecking the code, I found that this kind of > type checking only works for those static defined kifo by > DECLARE/DEFINE_KFIFO. As the ptrtype is the same as the data type: > > /* the 4th argument "type" is "ptrtype" */ > #define STRUCT_KFIFO(type, size) struct __STRUCT_KFIFO(type, size, 0, type) > > #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo > > While, for those kfifo dynamically allocated, the type checking will not > work as expected then as ptrtype is always "void": > > struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); > You should avoid using struct kfifo, as you can read in kfifo.h this is only for compatibility reason. If you use the macro DECLARE_KFIFO_PTR(), DECLARE_KFIFO() or DEFINE_KFIFO() instead. Have a look at the examples files in the samples/kfifo directory. - Stefani ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/5] kfifo: remove unnecessary type check 2013-01-09 15:29 ` Stefani Seibold @ 2013-01-10 7:12 ` Yuanhan Liu 0 siblings, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-10 7:12 UTC (permalink / raw) To: Stefani Seibold; +Cc: linux-kernel, Andrew Morton On Wed, Jan 09, 2013 at 04:29:39PM +0100, Stefani Seibold wrote: > Am Mittwoch, den 09.01.2013, 10:35 +0800 schrieb Yuanhan Liu: > > On Tue, Jan 08, 2013 at 10:51:04PM +0100, Stefani Seibold wrote: > > > Am Dienstag, den 08.01.2013, 22:57 +0800 schrieb Yuanhan Liu: > > > > Firstly, this kind of type check doesn't work. It does something similar > > > > as following: > > > > void * __dummy = NULL; > > > > __buf = __dummy; > > > > > > > > __dummy is defined as void *. Thus it will not trigger warnings as > > > > expected. > > > > > > > > Second, we don't need that kind of check. Since the prototype > > > > of __kfifo_out is: > > > > unsigned int __kfifo_out(struct __kfifo *fifo, void *buf, unsigned int len) > > > > > > > > buf is defined as void *, so we don't need do the type check. Remove it. > > > > > > > > > > Thats wrong. > > > > > > First the type checking will be used in kfifo_put() and kfifo_in() for > > > const types to check if the passed type of the data can converted to the > > > fifo element type. > > > > Hi Stefani, > > > > Yes, I see now. After rechecking the code, I found that this kind of > > type checking only works for those static defined kifo by > > DECLARE/DEFINE_KFIFO. As the ptrtype is the same as the data type: > > > > /* the 4th argument "type" is "ptrtype" */ > > #define STRUCT_KFIFO(type, size) struct __STRUCT_KFIFO(type, size, 0, type) > > > > #define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo > > > > While, for those kfifo dynamically allocated, the type checking will not > > work as expected then as ptrtype is always "void": > > > > struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); > > > > You should avoid using struct kfifo, as you can read in kfifo.h this is > only for compatibility reason. Well, the fact is struct kfifo is used far more widely than DECLARE/DEFINE_KFIFO; say above 50 vs less than 10. Thanks. --yliu > > If you use the macro DECLARE_KFIFO_PTR(), DECLARE_KFIFO() or > DEFINE_KFIFO() instead. > > Have a look at the examples files in the samples/kfifo directory. > > - Stefani > ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/5] libsrp: replace kfifo_init with kfifo_alloc 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu 2013-01-08 14:57 ` [PATCH 1/5] kfifo: remove unnecessary type check Yuanhan Liu @ 2013-01-08 14:57 ` Yuanhan Liu 2013-01-08 14:57 ` [PATCH 3/5] libiscsi: " Yuanhan Liu ` (3 subsequent siblings) 5 siblings, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel Cc: Yuanhan Liu, James E.J. Bottomley, Stefani Seibold, Andrew Morton kfifo_init will use a pre-allocated buffer as fifo buffer; the buffer size is determinted at caller side. While, kfifo will maintain a real kfifo buffer size(rounddown power of 2 aligned). So, the two size may not be equal. So, if max is not power of 2, this code will not work. As it assume the kfifo is able to hold max elments, but it is able to hold less than max only. To be safe, we should use kfifo_alloc instead, though it will not address this issue. But a later patch to refactor kfifo_alloc to be a log API will fix it. Cc: James E.J. Bottomley <JBottomley@parallels.com> Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> --- drivers/scsi/libsrp.c | 22 ++++++++++------------ include/scsi/libsrp.h | 1 - 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 0707ecd..63db792 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -50,34 +50,32 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, struct srp_buf **ring) { int i; + int ret; struct iu_entry *iue; - q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL); + q->pool = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL); if (!q->pool) return -ENOMEM; - q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL); - if (!q->items) - goto free_pool; + + ret = kfifo_alloc(&q->queue, max * sizeof(void *), GFP_KERNEL); + if (ret < 0) { + kfree(q->pool); + return ret; + } spin_lock_init(&q->lock); - kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *)); - for (i = 0, iue = q->items; i < max; i++) { + for (i = 0, iue = q->pool; i < max; i++) { kfifo_in(&q->queue, (void *) &iue, sizeof(void *)); iue->sbuf = ring[i]; iue++; } return 0; - - kfree(q->items); -free_pool: - kfree(q->pool); - return -ENOMEM; } static void srp_iu_pool_free(struct srp_queue *q) { - kfree(q->items); + kfifo_free(&q->queue); kfree(q->pool); } diff --git a/include/scsi/libsrp.h b/include/scsi/libsrp.h index f4105c9..999b1e7 100644 --- a/include/scsi/libsrp.h +++ b/include/scsi/libsrp.h @@ -21,7 +21,6 @@ struct srp_buf { struct srp_queue { void *pool; - void *items; struct kfifo queue; spinlock_t lock; }; -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/5] libiscsi: replace kfifo_init with kfifo_alloc 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu 2013-01-08 14:57 ` [PATCH 1/5] kfifo: remove unnecessary type check Yuanhan Liu 2013-01-08 14:57 ` [PATCH 2/5] libsrp: replace kfifo_init with kfifo_alloc Yuanhan Liu @ 2013-01-08 14:57 ` Yuanhan Liu 2013-01-08 14:57 ` [PATCH 4/5] kfifo: remove kfifo_init Yuanhan Liu ` (2 subsequent siblings) 5 siblings, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel Cc: Yuanhan Liu, Mike Christie, James E.J. Bottomley, iscsi list, Stefani Seibold, Andrew Morton kfifo_init will use a pre-allocated buffer as fifo buffer; the buffer size is determinted at caller side. While, kfifo will maintain a real kfifo buffer size(rounddown power of 2 aligned). So, the two size may not be equal. So, if max is not power of 2, this code will not work. As it assume the kfifo is able to hold max elments, but it is able to hold less than max only. To be safe, we should use kfifo_alloc instead, though it will not address this issue. But a later patch to refactor kfifo_alloc to be a log API will fix it. Besides that, I refactored the code a bit with the style used in libsrp.c: allocated items once by kcalloc. Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: James E.J. Bottomley <JBottomley@parallels.com> Cc: iscsi list <open-iscsi@googlegroups.com> Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> --- drivers/scsi/libiscsi.c | 59 ++++++++++++++++++++++++----------------------- include/scsi/libiscsi.h | 4 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 82c3fd4..8e60f1f 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2485,51 +2485,52 @@ EXPORT_SYMBOL_GPL(iscsi_eh_recover_target); int iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) { - int i, num_arrays = 1; - - memset(q, 0, sizeof(*q)); + int i; + int ret; + void *item; - q->max = max; + ret = -ENOMEM; + q->pool = kcalloc(max, item_size, GFP_KERNEL); + if (!q->pool) + goto err_out; - /* If the user passed an items pointer, he wants a copy of - * the array. */ - if (items) - num_arrays++; - q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); - if (q->pool == NULL) - return -ENOMEM; + ret = kfifo_alloc(&q->queue, max * sizeof(void *), GFP_KERNEL); + if (ret < 0) + goto free_pool; - kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*)); - - for (i = 0; i < max; i++) { - q->pool[i] = kzalloc(item_size, GFP_KERNEL); - if (q->pool[i] == NULL) { - q->max = i; - goto enomem; + q->items_ptr = NULL; + /* If the user passed an items pointer, he wants a copy of the array */ + if (items) { + q->items_ptr = kcalloc(max, sizeof(void *), GFP_KERNEL); + if (!q->items_ptr) { + ret = -ENOMEM; + goto free_fifo; } - kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*)); + *items = q->items_ptr; } - if (items) { - *items = q->pool + max; - memcpy(*items, q->pool, max * sizeof(void *)); + for (i = 0, item = q->pool; i < max; i++, item += item_size) { + kfifo_in(&q->queue, &item, sizeof(void *)); + if (q->items_ptr) + q->items_ptr[i] = item; } return 0; -enomem: - iscsi_pool_free(q); - return -ENOMEM; +free_fifo: + kfifo_free(&q->queue); +free_pool: + kfree(q->pool); +err_out: + return ret; } EXPORT_SYMBOL_GPL(iscsi_pool_init); void iscsi_pool_free(struct iscsi_pool *q) { - int i; - - for (i = 0; i < q->max; i++) - kfree(q->pool[i]); kfree(q->pool); + kfree(q->items_ptr); + kfifo_free(&q->queue); } EXPORT_SYMBOL_GPL(iscsi_pool_free); diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 6e33386..c4262c6 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -231,8 +231,8 @@ struct iscsi_conn { struct iscsi_pool { struct kfifo queue; /* FIFO Queue */ - void **pool; /* Pool of elements */ - int max; /* Max number of elements */ + void *pool; /* Pool of elements */ + void **items_ptr; /* element pointers */ }; /* Session's states */ -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/5] kfifo: remove kfifo_init 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu ` (2 preceding siblings ...) 2013-01-08 14:57 ` [PATCH 3/5] libiscsi: " Yuanhan Liu @ 2013-01-08 14:57 ` Yuanhan Liu 2013-01-08 14:57 ` [PATCH 5/5] kfifo: log based kfifo API Yuanhan Liu 2013-01-08 15:03 ` Antw: [PATCH 0/5] kfifo cleanup and " Ulrich Windl 5 siblings, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel; +Cc: Yuanhan Liu, Stefani Seibold, Andrew Morton kfifo_init is buggy, we should never use that. Instead, we should use kfifo_alloc. Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> --- include/linux/kfifo.h | 27 ++------------------------- kernel/kfifo.c | 23 ----------------------- 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 7a18245..4bf984e 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -27,14 +27,14 @@ * * - Modify the declaration of the "struct kfifo *" object into a * in-place "struct kfifo" object - * - Init the in-place object with kfifo_alloc() or kfifo_init() + * - Init the in-place object with kfifo_alloc() * Note: The address of the in-place "struct kfifo" object must be * passed as the first argument to this functions * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get * into kfifo_out * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get * into kfifo_out_spinlocked - * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc + * Note: the spinlock pointer formerly passed to kfifo_alloc * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked * as the last parameter * - The formerly __kfifo_* functions are renamed into kfifo_* @@ -350,26 +350,6 @@ __kfifo_int_must_check_helper( \ }) /** - * kfifo_init - initialize a fifo using a preallocated buffer - * @fifo: the fifo to assign the buffer - * @buffer: the preallocated buffer to be used - * @size: the size of the internal buffer, this have to be a power of 2 - * - * This macro initialize a fifo using a preallocated buffer. - * - * The numer of elements will be rounded-up to a power of 2. - * Return 0 if no error, otherwise an error code. - */ -#define kfifo_init(fifo, buffer, size) \ -({ \ - typeof((fifo) + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __is_kfifo_ptr(__tmp) ? \ - __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ - -EINVAL; \ -}) - -/** * kfifo_put - put data into the fifo * @fifo: address of the fifo to be used * @val: the data to be added @@ -770,9 +750,6 @@ extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, extern void __kfifo_free(struct __kfifo *fifo); -extern int __kfifo_init(struct __kfifo *fifo, void *buffer, - unsigned int size, size_t esize); - extern unsigned int __kfifo_in(struct __kfifo *fifo, const void *buf, unsigned int len); diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 59dcf5b..d07f480 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -78,29 +78,6 @@ void __kfifo_free(struct __kfifo *fifo) } EXPORT_SYMBOL(__kfifo_free); -int __kfifo_init(struct __kfifo *fifo, void *buffer, - unsigned int size, size_t esize) -{ - size /= esize; - - if (!is_power_of_2(size)) - size = rounddown_pow_of_two(size); - - fifo->in = 0; - fifo->out = 0; - fifo->esize = esize; - fifo->data = buffer; - - if (size < 2) { - fifo->mask = 0; - return -EINVAL; - } - fifo->mask = size - 1; - - return 0; -} -EXPORT_SYMBOL(__kfifo_init); - static void kfifo_copy_in(struct __kfifo *fifo, const void *src, unsigned int len, unsigned int off) { -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/5] kfifo: log based kfifo API 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu ` (3 preceding siblings ...) 2013-01-08 14:57 ` [PATCH 4/5] kfifo: remove kfifo_init Yuanhan Liu @ 2013-01-08 14:57 ` Yuanhan Liu 2013-01-08 18:16 ` Dmitry Torokhov 2013-01-08 15:03 ` Antw: [PATCH 0/5] kfifo cleanup and " Ulrich Windl 5 siblings, 1 reply; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 14:57 UTC (permalink / raw) To: linux-kernel Cc: Yuanhan Liu, Stefani Seibold, Andrew Morton, linux-omap, linuxppc-dev, platform-driver-x86, linux-input, linux-iio, linux-rdma, linux-media, linux-mmc, linux-mtd, libertas-dev, linux-wireless, netdev, linux-pci, open-iscsi, linux-scsi, devel, linux-serial, linux-usb, linux-mm, dccp, linux-sctp The current kfifo API take the kfifo size as input, while it rounds _down_ the size to power of 2 at __kfifo_alloc. This may introduce potential issue. Take the code at drivers/hid/hid-logitech-dj.c as example: if (kfifo_alloc(&djrcv_dev->notif_fifo, DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), GFP_KERNEL)) { Where, DJ_MAX_NUMBER_NOTIFICATIONS is 8, and sizeo of(struct dj_report) is 15. Which means it wants to allocate a kfifo buffer which can store 8 dj_report entries at once. The expected kfifo buffer size would be 8 * 15 = 120 then. While, in the end, __kfifo_alloc will turn the size to rounddown_power_of_2(120) = 64, and then allocate a buf with 64 bytes, which I don't think this is the original author want. With the new log API, we can do like following: int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report)); if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, GFP_KERNEL)) { This make sure we will allocate enough kfifo buffer for holding DJ_MAX_NUMBER_NOTIFICATIONS dj_report entries. Cc: Stefani Seibold <stefani@seibold.net> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-omap@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: platform-driver-x86@vger.kernel.org Cc: linux-input@vger.kernel.org Cc: linux-iio@vger.kernel.org Cc: linux-rdma@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: linux-mmc@vger.kernel.org Cc: linux-mtd@lists.infradead.org Cc: libertas-dev@lists.infradead.org Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-pci@vger.kernel.org Cc: open-iscsi@googlegroups.com Cc: linux-scsi@vger.kernel.org Cc: devel@driverdev.osuosl.org Cc: linux-serial@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: linux-mm@kvack.org Cc: dccp@vger.kernel.org Cc: linux-sctp@vger.kernel.org Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com> --- arch/arm/plat-omap/Kconfig | 2 +- arch/arm/plat-omap/mailbox.c | 6 +++- arch/powerpc/sysdev/fsl_rmu.c | 2 +- drivers/char/sonypi.c | 9 ++++--- drivers/hid/hid-logitech-dj.c | 7 +++-- drivers/iio/industrialio-event.c | 2 +- drivers/iio/kfifo_buf.c | 3 +- drivers/infiniband/hw/cxgb3/cxio_resource.c | 8 ++++-- drivers/media/i2c/cx25840/cx25840-ir.c | 9 +++++-- drivers/media/pci/cx23885/cx23888-ir.c | 9 +++++-- drivers/media/pci/meye/meye.c | 6 +--- drivers/media/pci/meye/meye.h | 2 + drivers/media/rc/ir-raw.c | 7 +++-- drivers/memstick/host/r592.h | 2 +- drivers/mmc/card/sdio_uart.c | 4 ++- drivers/mtd/sm_ftl.c | 5 +++- drivers/net/wireless/libertas/main.c | 4 ++- drivers/net/wireless/rt2x00/rt2x00dev.c | 5 +-- drivers/pci/pcie/aer/aerdrv_core.c | 3 +- drivers/platform/x86/fujitsu-laptop.c | 5 ++- drivers/platform/x86/sony-laptop.c | 6 ++-- drivers/rapidio/devices/tsi721.c | 5 ++- drivers/scsi/libiscsi_tcp.c | 6 +++- drivers/staging/omapdrm/omap_plane.c | 5 +++- drivers/tty/n_gsm.c | 4 ++- drivers/tty/nozomi.c | 5 +-- drivers/tty/serial/ifx6x60.c | 2 +- drivers/tty/serial/ifx6x60.h | 3 +- drivers/tty/serial/kgdb_nmi.c | 7 +++-- drivers/usb/host/fhci.h | 4 ++- drivers/usb/serial/cypress_m8.c | 4 +- drivers/usb/serial/io_ti.c | 4 +- drivers/usb/serial/ti_usb_3410_5052.c | 7 +++-- drivers/usb/serial/usb-serial.c | 2 +- include/linux/kfifo.h | 31 +++++++++++++-------------- include/linux/rio.h | 1 + include/media/lirc_dev.h | 4 ++- kernel/kfifo.c | 9 +------ mm/memory-failure.c | 3 +- net/dccp/probe.c | 6 +++- net/sctp/probe.c | 6 +++- samples/kfifo/bytestream-example.c | 8 +++--- samples/kfifo/dma-example.c | 5 ++- samples/kfifo/inttype-example.c | 7 +++-- samples/kfifo/record-example.c | 6 ++-- 45 files changed, 142 insertions(+), 108 deletions(-) diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 665870d..7eda02c 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -124,7 +124,7 @@ config OMAP_MBOX_FWK DSP, IVA1.0 and IVA2 in OMAP1/2/3. config OMAP_MBOX_KFIFO_SIZE - int "Mailbox kfifo default buffer size (bytes)" + int "Mailbox kfifo default buffer size (bytes, should be power of 2. If not, will roundup to power of 2" depends on OMAP_MBOX_FWK default 256 help diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 42377ef..848fa0b 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -30,6 +30,7 @@ #include <linux/err.h> #include <linux/notifier.h> #include <linux/module.h> +#include <linux/log2.h> #include <plat/mailbox.h> @@ -40,7 +41,7 @@ static DEFINE_MUTEX(mbox_configured_lock); static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE; module_param(mbox_kfifo_size, uint, S_IRUGO); -MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)"); +MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes, should be power of 2. If not, will roundup to power of 2)"); /* Mailbox FIFO handle functions */ static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) @@ -218,6 +219,7 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, void (*tasklet)(unsigned long)) { struct omap_mbox_queue *mq; + int mbox_kfifo_size_order = order_base_2(mbox_kfifo_size); mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL); if (!mq) @@ -225,7 +227,7 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, spin_lock_init(&mq->lock); - if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL)) + if (kfifo_alloc(&mq->fifo, mbox_kfifo_size_order, GFP_KERNEL)) goto error; if (work) diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index 14bd522..84d2b8c 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -587,7 +587,7 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw) INIT_WORK(&pw->pw_work, fsl_pw_dpc); spin_lock_init(&pw->pw_fifo_lock); - if (kfifo_alloc(&pw->pw_fifo, RIO_PW_MSG_SIZE * 32, GFP_KERNEL)) { + if (kfifo_alloc(&pw->pw_fifo, RIO_KFIFO_SIZE_ORDER, GFP_KERNEL)) { pr_err("FIFO allocation failed\n"); rc = -ENOMEM; goto err_out_irq; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index d780295..39d8dd7 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -429,7 +429,7 @@ static struct sonypi_eventtypes { { 0 } }; -#define SONYPI_BUF_SIZE 128 +#define SONYPI_KFIFO_SIZE_ORDER 7 /* Correspondance table between sonypi events and input layer events */ static struct { @@ -1316,7 +1316,8 @@ static int sonypi_probe(struct platform_device *dev) "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); spin_lock_init(&sonypi_device.fifo_lock); - error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL); + error = kfifo_alloc(&sonypi_device.fifo, SONYPI_KFIFO_SIZE_ORDER, + GFP_KERNEL); if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); return error; @@ -1395,8 +1396,8 @@ static int sonypi_probe(struct platform_device *dev) } spin_lock_init(&sonypi_device.input_fifo_lock); - error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, - GFP_KERNEL); + error = kfifo_alloc(&sonypi_device.input_fifo, + SONYPI_KFIFO_SIZE_ORDER, GFP_KERNEL); if (error) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); goto err_inpdev_unregister; diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9500f2f..031be77 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -26,6 +26,7 @@ #include <linux/hid.h> #include <linux/module.h> #include <linux/usb.h> +#include <linux/log2.h> #include <asm/unaligned.h> #include "usbhid/usbhid.h" #include "hid-ids.h" @@ -730,6 +731,8 @@ static int logi_dj_probe(struct hid_device *hdev, struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct dj_receiver_dev *djrcv_dev; int retval; + int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * + sizeof(struct dj_report)); if (is_dj_device((struct dj_device *)hdev->driver_data)) return -ENODEV; @@ -757,9 +760,7 @@ static int logi_dj_probe(struct hid_device *hdev, djrcv_dev->hdev = hdev; INIT_WORK(&djrcv_dev->work, delayedwork_callback); spin_lock_init(&djrcv_dev->lock); - if (kfifo_alloc(&djrcv_dev->notif_fifo, - DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), - GFP_KERNEL)) { + if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, GFP_KERNEL)) { dev_err(&hdev->dev, "%s:failed allocating notif_fifo\n", __func__); kfree(djrcv_dev); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 261cae0..9b73680 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -35,7 +35,7 @@ */ struct iio_event_interface { wait_queue_head_t wait; - DECLARE_KFIFO(det_events, struct iio_event_data, 16); + DECLARE_KFIFO(det_events, struct iio_event_data, 4); struct list_head dev_attr_list; unsigned long flags; diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 5bc5c86..d8ba52ff 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -7,6 +7,7 @@ #include <linux/mutex.h> #include <linux/iio/kfifo_buf.h> #include <linux/sched.h> +#include <linux/log2.h> struct iio_kfifo { struct iio_buffer buffer; @@ -23,7 +24,7 @@ static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, return -EINVAL; __iio_update_buffer(&buf->buffer, bytes_per_datum, length); - return __kfifo_alloc((struct __kfifo *)&buf->kf, length, + return __kfifo_alloc((struct __kfifo *)&buf->kf, order_base_2(length), bytes_per_datum, GFP_KERNEL); } diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c index 31f9201..186d05e 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -36,6 +36,7 @@ #include <linux/kfifo.h> #include <linux/spinlock.h> #include <linux/errno.h> +#include <linux/log2.h> #include "cxio_resource.h" #include "cxio_hal.h" @@ -54,8 +55,9 @@ static int __cxio_init_resource_fifo(struct kfifo *fifo, u32 random_bytes; u32 rarray[16]; spin_lock_init(fifo_lock); + int kfifo_size_order = order_base_2(nr * sizeof(u32)); - if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL)) + if (kfifo_alloc(fifo, kfifo_size_order, GFP_KERNEL)) return -ENOMEM; for (i = 0; i < skip_low + skip_high; i++) @@ -111,11 +113,11 @@ static int cxio_init_resource_fifo_random(struct kfifo *fifo, static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p) { u32 i; + int kfifo_size_order = order_base_2(T3_MAX_NUM_QP * sizeof(u32)); spin_lock_init(&rdev_p->rscp->qpid_fifo_lock); - if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32), - GFP_KERNEL)) + if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, kfifo_size_order, GFP_KERNEL)) return -ENOMEM; for (i = 16; i < T3_MAX_NUM_QP; i++) diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index 38ce76e..1da0b6c 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -24,6 +24,7 @@ #include <linux/slab.h> #include <linux/kfifo.h> #include <linux/module.h> +#include <linux/log2.h> #include <media/cx25840.h> #include <media/rc-core.h> @@ -106,8 +107,10 @@ union cx25840_ir_fifo_rec { struct ir_raw_event ir_core_data; }; -#define CX25840_IR_RX_KFIFO_SIZE (256 * sizeof(union cx25840_ir_fifo_rec)) -#define CX25840_IR_TX_KFIFO_SIZE (256 * sizeof(union cx25840_ir_fifo_rec)) +#define CX25840_IR_RX_KFIFO_SIZE_ORDER (order_base_2(256 * sizeof(union cx25840_ir_fifo_rec))) +#define CX25840_IR_RX_KFIFO_SIZE (1<<CX25840_IR_RX_KFIFO_SIZE_ORDER) +#define CX25840_IR_TX_KFIFO_SIZE_ORDER (order_base_2(256 * sizeof(union cx25840_ir_fifo_rec))) +#define CX25840_IR_TX_KFIFO_SIZE (CX25840_IR_TX_KFIFO_SIZE_ORDER) struct cx25840_ir_state { struct i2c_client *c; @@ -1236,7 +1239,7 @@ int cx25840_ir_probe(struct v4l2_subdev *sd) spin_lock_init(&ir_state->rx_kfifo_lock); if (kfifo_alloc(&ir_state->rx_kfifo, - CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) { + CX25840_IR_RX_KFIFO_SIZE_ORDER, GFP_KERNEL)) { kfree(ir_state); return -ENOMEM; } diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index c4bd1e9..4c6e24b 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -23,6 +23,7 @@ #include <linux/kfifo.h> #include <linux/slab.h> +#include <linux/log2.h> #include <media/v4l2-device.h> #include <media/v4l2-chip-ident.h> @@ -125,8 +126,10 @@ union cx23888_ir_fifo_rec { struct ir_raw_event ir_core_data; }; -#define CX23888_IR_RX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec)) -#define CX23888_IR_TX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec)) +#define CX23888_IR_RX_KFIFO_SIZE_ORDER (order_base_2(256 * sizeof(union cx23888_ir_fifo_rec))) +#define CX23888_IR_RX_KFIFO_SIZE (1<<CX23888_IR_RX_KFIFO_SIZE_ORDER) +#define CX23888_IR_TX_KFIFO_SIZE_ORDER (order_base_2(256 * sizeof(union cx23888_ir_fifo_rec))) +#define CX23888_IR_TX_KFIFO_SIZE (1<<CX23888_IR_TX_KFIFO_SIZE_ORDER) struct cx23888_ir_state { struct v4l2_subdev sd; @@ -1213,7 +1216,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev) return -ENOMEM; spin_lock_init(&state->rx_kfifo_lock); - if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE_ORDER, GFP_KERNEL)) return -ENOMEM; state->dev = dev; diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 049e186..3bcde0c 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1759,14 +1759,12 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) } spin_lock_init(&meye.grabq_lock); - if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, - GFP_KERNEL)) { + if (kfifo_alloc(&meye.grabq, MEYE_KFIFO_SIZE_ORDER, GFP_KERNEL)) { v4l2_err(v4l2_dev, "fifo allocation failed\n"); goto outkfifoalloc1; } spin_lock_init(&meye.doneq_lock); - if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, - GFP_KERNEL)) { + if (kfifo_alloc(&meye.doneq, MEYE_KFIFO_SIZE_ORDER, GFP_KERNEL)) { v4l2_err(v4l2_dev, "fifo allocation failed\n"); goto outkfifoalloc2; } diff --git a/drivers/media/pci/meye/meye.h b/drivers/media/pci/meye/meye.h index 4bdeb03..5d3ab4f 100644 --- a/drivers/media/pci/meye/meye.h +++ b/drivers/media/pci/meye/meye.h @@ -260,6 +260,7 @@ /* private API definitions */ #include <linux/meye.h> #include <linux/mutex.h> +#include <linux/log2.h> /* Enable jpg software correction */ @@ -270,6 +271,7 @@ /* Maximum number of buffers */ #define MEYE_MAX_BUFNBRS 32 +#define MEYE_KFIFO_SIZE_ORDER (order_base_2(MEYE_MAX_BUFNBRS * sizeof(int))) /* State of a buffer */ #define MEYE_BUF_UNUSED 0 /* not used */ diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 97dc8d1..e4d1ec8 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -18,6 +18,7 @@ #include <linux/kmod.h> #include <linux/sched.h> #include <linux/freezer.h> +#include <linux/log2.h> #include "rc-core-priv.h" /* Define the max number of pulse/space transitions to buffer */ @@ -252,6 +253,8 @@ int ir_raw_event_register(struct rc_dev *dev) { int rc; struct ir_raw_handler *handler; + int kfifo_size_order = order_base_2(sizeof(struct ir_raw_event) * + MAX_IR_EVENT_SIZE); if (!dev) return -EINVAL; @@ -262,9 +265,7 @@ int ir_raw_event_register(struct rc_dev *dev) dev->raw->dev = dev; dev->raw->enabled_protocols = ~0; - rc = kfifo_alloc(&dev->raw->kfifo, - sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE, - GFP_KERNEL); + rc = kfifo_alloc(&dev->raw->kfifo, kfifo_size_order, GFP_KERNEL); if (rc < 0) goto out; diff --git a/drivers/memstick/host/r592.h b/drivers/memstick/host/r592.h index c5726c1..6fc19f4 100644 --- a/drivers/memstick/host/r592.h +++ b/drivers/memstick/host/r592.h @@ -143,7 +143,7 @@ struct r592_device { struct task_struct *io_thread; bool parallel_mode; - DECLARE_KFIFO(pio_fifo, u8, sizeof(u32)); + DECLARE_KFIFO(pio_fifo, u8, 2); /* DMA area */ int dma_capable; diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index bd57a11..c54a7c5 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -43,12 +43,14 @@ #include <linux/mmc/card.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include <linux/log2.h> #define UART_NR 8 /* Number of UARTs this driver can handle */ #define FIFO_SIZE PAGE_SIZE +#define FIFO_SIZE_ORDER PAGE_SHIFT #define WAKEUP_CHARS 256 struct uart_icount { @@ -93,7 +95,7 @@ static int sdio_uart_add_port(struct sdio_uart_port *port) mutex_init(&port->func_lock); spin_lock_init(&port->write_lock); - if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE_ORDER, GFP_KERNEL)) return -ENOMEM; spin_lock(&sdio_uart_table_lock); diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 8dd6ba5..672ef47 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -17,6 +17,7 @@ #include <linux/bitops.h> #include <linux/slab.h> #include <linux/mtd/nand_ecc.h> +#include <linux/log2.h> #include "nand/sm_common.h" #include "sm_ftl.h" @@ -766,6 +767,7 @@ static int sm_init_zone(struct sm_ftl *ftl, int zone_num) int lba; int i = 0; int len; + int kfifo_size_order; dbg("initializing zone %d", zone_num); @@ -778,7 +780,8 @@ static int sm_init_zone(struct sm_ftl *ftl, int zone_num) /* Allocate memory for free sectors FIFO */ - if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) { + kfifo_size_order = order_base_2(ftl->zone_size * 2); + if (kfifo_alloc(&zone->free_sectors, kfifo_size_order, GFP_KERNEL)) { kfree(zone->lba_to_phys_table); return -ENOMEM; } diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 0c02f04..ea5ddf4 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -25,6 +25,8 @@ #include "cmd.h" #include "mesh.h" +#define KFIFO_SIZE_ORDER 6 + #define DRIVER_RELEASE_VERSION "323.p0" const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION #ifdef DEBUG @@ -914,7 +916,7 @@ static int lbs_init_adapter(struct lbs_private *priv) priv->resp_len[0] = priv->resp_len[1] = 0; /* Create the event FIFO */ - ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); + ret = kfifo_alloc(&priv->event_fifo, KFIFO_SIZE_ORDER, GFP_KERNEL); if (ret) { pr_err("Out of memory allocating event FIFO buffer\n"); goto out; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 44f8b3f..c8f68485 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -979,12 +979,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) * tx_queues * entry_num and round up to the nearest * power of 2. */ - int kfifo_size = - roundup_pow_of_two(rt2x00dev->ops->tx_queues * + int kfifo_size_order = order_base_2(rt2x00dev->ops->tx_queues * rt2x00dev->ops->tx->entry_num * sizeof(u32)); - status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, + status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size_order, GFP_KERNEL); if (status) return status; diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 421bbc5..ec9284a 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -574,7 +574,6 @@ static void handle_error_source(struct pcie_device *aerdev, static void aer_recover_work_func(struct work_struct *work); #define AER_RECOVER_RING_ORDER 4 -#define AER_RECOVER_RING_SIZE (1 << AER_RECOVER_RING_ORDER) struct aer_recover_entry { @@ -585,7 +584,7 @@ struct aer_recover_entry }; static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry, - AER_RECOVER_RING_SIZE); + AER_RECOVER_RING_ORDER); /* * Mutual exclusion for writers of aer_recover_ring, reader side don't * need lock, because there is only one reader and lock is not needed diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index c4c1a54..185bd55 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -66,6 +66,7 @@ #include <linux/backlight.h> #include <linux/input.h> #include <linux/kfifo.h> +#include <linux/log2.h> #include <linux/video_output.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -116,6 +117,7 @@ #define MAX_HOTKEY_RINGBUFFER_SIZE 100 #define RINGBUFFERSIZE 40 +#define KFIFO_SIZE_ORDER (order_base_2(RINGBUFFERSIZE * sizeof(int))) /* Debugging */ #define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": " @@ -825,8 +827,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) /* kfifo */ spin_lock_init(&fujitsu_hotkey->fifo_lock); - error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), - GFP_KERNEL); + error = kfifo_alloc(&fujitsu_hotkey->fifo, KFIFO_SIZE_ORDER, GFP_KERNEL); if (error) { pr_err("kfifo_alloc failed\n"); goto err_stop; diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index daaddec..ee57eac 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -183,7 +183,7 @@ static void sony_nc_rfkill_update(void); /*********** Input Devices ***********/ -#define SONY_LAPTOP_BUF_SIZE 128 +#define SONY_LAPTOP_KFIFO_SIZE_ORDER 7 struct sony_laptop_input_s { atomic_t users; struct input_dev *jog_dev; @@ -447,7 +447,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) /* kfifo */ spin_lock_init(&sony_laptop_input.fifo_lock); error = kfifo_alloc(&sony_laptop_input.fifo, - SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); + SONY_LAPTOP_KFIFO_SIZE_ORDER, GFP_KERNEL); if (error) { pr_err("kfifo_alloc failed\n"); goto err_dec_users; @@ -3752,7 +3752,7 @@ static int sonypi_compat_init(void) spin_lock_init(&sonypi_compat.fifo_lock); error = - kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); + kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_KFIFO_SIZE_ORDER, GFP_KERNEL); if (error) { pr_err("kfifo_alloc failed\n"); return error; diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 6faba40..a731e87 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -32,6 +32,7 @@ #include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/kfifo.h> +#include <linux/log2.h> #include <linux/delay.h> #include "tsi721.h" @@ -970,11 +971,11 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv) */ static int tsi721_port_write_init(struct tsi721_device *priv) { + int kfifo_size_order = order_base_2(TSI721_RIO_PW_MSG_SIZE * 32); priv->pw_discard_count = 0; INIT_WORK(&priv->pw_work, tsi721_pw_dpc); spin_lock_init(&priv->pw_fifo_lock); - if (kfifo_alloc(&priv->pw_fifo, - TSI721_RIO_PW_MSG_SIZE * 32, GFP_KERNEL)) { + if (kfifo_alloc(&priv->pw_fifo, kfifo_size_order, GFP_KERNEL)) { dev_err(&priv->pdev->dev, "PW FIFO allocation failed\n"); return -ENOMEM; } diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 552e8a2..bdb09bf 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -35,6 +35,7 @@ #include <linux/crypto.h> #include <linux/delay.h> #include <linux/kfifo.h> +#include <linux/log2.h> #include <linux/scatterlist.h> #include <linux/module.h> #include <net/tcp.h> @@ -1113,6 +1114,7 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) { int i; int cmd_i; + int kfifo_size_order; /* * initialize per-task: R2T pool and xmit queue @@ -1135,8 +1137,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session) } /* R2T xmit queue */ - if (kfifo_alloc(&tcp_task->r2tqueue, - session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) { + kfifo_size_order = order_base_2(session->max_r2t * 4 * sizeof(void *)); + if (kfifo_alloc(&tcp_task->r2tqueue, kfifo_size_order, GFP_KERNEL)) { iscsi_pool_free(&tcp_task->r2tpool); goto r2t_alloc_fail; } diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 2a8e5ba..40f057f 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -28,6 +28,8 @@ */ #define omap_plane _omap_plane +#define OMAP_KFIFO_SIZE_ORDER 4 + /* * plane funcs */ @@ -508,7 +510,8 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, mutex_init(&omap_plane->unpin_mutex); - ret = kfifo_alloc(&omap_plane->unpin_fifo, 16, GFP_KERNEL); + ret = kfifo_alloc(&omap_plane->unpin_fifo, OMAP_KFIFO_SIZE_ORDER, + GFP_KERNEL); if (ret) { dev_err(dev->dev, "could not allocate unpin FIFO\n"); goto fail; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index dcc0430..b3b1b1c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -66,6 +66,8 @@ static int debug; module_param(debug, int, 0600); +#define KFIFO_SIZE_ORDER 12 + /* Defaults: these are from the specification */ #define T1 10 /* 100mS */ @@ -1636,7 +1638,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) spin_lock_init(&dlci->lock); mutex_init(&dlci->mutex); dlci->fifo = &dlci->_fifo; - if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) { + if (kfifo_alloc(&dlci->_fifo, KFIFO_SIZE_ORDER, GFP_KERNEL) < 0) { kfree(dlci); return NULL; } diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index a0c69ab..8b54da3 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -128,8 +128,7 @@ static int debug; #define NTTY_TTY_MAXMINORS 256 #define NTTY_FIFO_BUFFER_SIZE 8192 -/* Must be power of 2 */ -#define FIFO_BUFFER_SIZE_UL 8192 +#define FIFO_BUFFER_SIZE_ORDER 13 /* Size of tmp send buffer to card */ #define SEND_BUF_MAX 1024 @@ -1428,7 +1427,7 @@ static int nozomi_card_init(struct pci_dev *pdev, } for (i = PORT_MDM; i < MAX_PORT; i++) { - if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL, + if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_ORDER, GFP_KERNEL)) { dev_err(&pdev->dev, "Could not allocate kfifo buffer\n"); diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 675d94a..f80dc2c 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -880,7 +880,7 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) lockdep_set_class_and_subclass(&ifx_dev->fifo_lock, &ifx_spi_key, 0); - if (kfifo_alloc(&ifx_dev->tx_fifo, IFX_SPI_FIFO_SIZE, GFP_KERNEL)) { + if (kfifo_alloc(&ifx_dev->tx_fifo, IFX_SPI_FIFO_SIZE_ORDER, GFP_KERNEL)) { ret = -ENOMEM; goto error_ret; } diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index 4fbddc2..da4fd1c 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h @@ -31,7 +31,8 @@ #define IFX_SPI_MAX_MINORS 1 #define IFX_SPI_TRANSFER_SIZE 2048 -#define IFX_SPI_FIFO_SIZE 4096 +#define IFX_SPI_FIFO_SIZE_ORDER 12 +#define IFX_SPI_FIFO_SIZE (1 << IFX_SPI_FIFO_SIZE_ORDER) #define IFX_SPI_HEADER_OVERHEAD 4 #define IFX_RESET_TIMEOUT msecs_to_jiffies(50) diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 6ac2b79..947dd72 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/hrtimer.h> #include <linux/tick.h> +#include <linux/log2.h> #include <linux/kfifo.h> #include <linux/kgdb.h> #include <linux/kdb.h> @@ -75,13 +76,13 @@ static struct console kgdb_nmi_console = { * This is usually the maximum rate on debug ports. We make fifo large enough * to make copy-pasting to the terminal usable. */ -#define KGDB_NMI_BAUD 115200 -#define KGDB_NMI_FIFO_SIZE roundup_pow_of_two(KGDB_NMI_BAUD / 8 / HZ) +#define KGDB_NMI_BAUD 115200 +#define KGDB_NMI_FIFO_SIZE_ORDER order_base_2(KGDB_NMI_BAUD / 8 / HZ) struct kgdb_nmi_tty_priv { struct tty_port port; struct tasklet_struct tlet; - STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE) fifo; + STRUCT_KFIFO(char, KGDB_NMI_FIFO_SIZE_ORDER) fifo; }; static struct kgdb_nmi_tty_priv *kgdb_nmi_port_to_priv(struct tty_port *port) diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h index 7cc1c32..e4a0ac6 100644 --- a/drivers/usb/host/fhci.h +++ b/drivers/usb/host/fhci.h @@ -24,6 +24,7 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/kfifo.h> +#include <linux/log2.h> #include <linux/io.h> #include <linux/usb.h> #include <linux/usb/hcd.h> @@ -478,7 +479,8 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) /* fifo of pointers */ static inline int cq_new(struct kfifo *fifo, int size) { - return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL); + int kfifo_size_order = order_base_2(size * sizeof(void *)); + return kfifo_alloc(fifo, kfifo_size_order, GFP_KERNEL); } static inline void cq_delete(struct kfifo *kfifo) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index fd8c35f..a4d7cd1 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -54,7 +54,7 @@ static bool unstable_bauds; #define DRIVER_DESC "Cypress USB to Serial Driver" /* write buffer size defines */ -#define CYPRESS_BUF_SIZE 1024 +#define CYPRESS_KFIFO_SIZE_ORDER 10 static const struct usb_device_id id_table_earthmate[] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, @@ -445,7 +445,7 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) priv->comm_is_ok = !0; spin_lock_init(&priv->lock); - if (kfifo_alloc(&priv->write_fifo, CYPRESS_BUF_SIZE, GFP_KERNEL)) { + if (kfifo_alloc(&priv->write_fifo, CYPRESS_KFIFO_SIZE_ORDER, GFP_KERNEL)) { kfree(priv); return -ENOMEM; } diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 58184f3..a19018b 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -64,7 +64,7 @@ #define EDGE_CLOSING_WAIT 4000 /* in .01 sec */ -#define EDGE_OUT_BUF_SIZE 1024 +#define EDGE_KFIFO_SIZE_ORDER 10 /* Product information read from the Edgeport */ @@ -2567,7 +2567,7 @@ static int edge_port_probe(struct usb_serial_port *port) if (!edge_port) return -ENOMEM; - ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, + ret = kfifo_alloc(&edge_port->write_fifo, EDGE_KFIFO_SIZE_ORDER, GFP_KERNEL); if (ret) { kfree(edge_port); diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index f2530d2..777e90a 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -45,7 +45,8 @@ #define TI_FIRMWARE_BUF_SIZE 16284 -#define TI_WRITE_BUF_SIZE 1024 +#define TI_KFIFO_SIZE_ORDER 10 +#define TI_KFIFO_SIZE (1 << TI_KFIFO_SIZE_ORDER) #define TI_TRANSFER_TIMEOUT 2 @@ -434,7 +435,7 @@ static int ti_port_probe(struct usb_serial_port *port) tport->tp_closing_wait = closing_wait; init_waitqueue_head(&tport->tp_msr_wait); init_waitqueue_head(&tport->tp_write_wait); - if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { + if (kfifo_alloc(&tport->write_fifo, TI_KFIFO_SIZE_ORDER, GFP_KERNEL)) { kfree(tport); return -ENOMEM; } @@ -1355,7 +1356,7 @@ static int ti_get_serial_info(struct ti_port *tport, ret_serial.line = port->serial->minor; ret_serial.port = port->number - port->serial->minor; ret_serial.flags = tport->tp_flags; - ret_serial.xmit_fifo_size = TI_WRITE_BUF_SIZE; + ret_serial.xmit_fifo_size = TI_KFIFO_SIZE; ret_serial.baud_base = tport->tp_tdev->td_is_3410 ? 921600 : 460800; ret_serial.closing_wait = tport->tp_closing_wait; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 64bda13..11ca271 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -934,7 +934,7 @@ static int usb_serial_probe(struct usb_interface *interface, for (i = 0; i < num_bulk_out; ++i) { endpoint = bulk_out_endpoint[i]; port = serial->port[i]; - if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&port->write_fifo, PAGE_SHIFT, GFP_KERNEL)) goto probe_error; buffer_size = serial->type->bulk_out_size; if (!buffer_size) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 4bf984e..28dfe98 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -76,8 +76,8 @@ struct __kfifo { type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ } -#define STRUCT_KFIFO(type, size) \ - struct __STRUCT_KFIFO(type, size, 0) +#define STRUCT_KFIFO(type, size_order) \ + struct __STRUCT_KFIFO(type, (1<<(size_order)), 0) #define __STRUCT_KFIFO_PTR(type, recsize) \ { \ @@ -93,11 +93,11 @@ struct __kfifo { */ struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0); -#define STRUCT_KFIFO_REC_1(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 1) +#define STRUCT_KFIFO_REC_1(size_order) \ + struct __STRUCT_KFIFO(unsigned char, (1<<(size_order)), 1) -#define STRUCT_KFIFO_REC_2(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 2) +#define STRUCT_KFIFO_REC_2(size_order) \ + struct __STRUCT_KFIFO(unsigned char, (1<<(size_order)), 2) /* * define kfifo_rec types @@ -123,9 +123,9 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2); * DECLARE_KFIFO - macro to declare a fifo object * @fifo: name of the declared fifo * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 + * @size_order: request 2^size_order fifo elements */ -#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo +#define DECLARE_KFIFO(fifo, type, size_order) STRUCT_KFIFO(type, size_order) fifo /** * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO @@ -146,12 +146,12 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2); * DEFINE_KFIFO - macro to define and initialize a fifo * @fifo: name of the declared fifo datatype * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 + * @size_order: request 2^size_order fifo elements * * Note: the macro can be used for global and local fifo data type variables. */ -#define DEFINE_KFIFO(fifo, type, size) \ - DECLARE_KFIFO(fifo, type, size) = \ +#define DEFINE_KFIFO(fifo, type, size_order) \ + DECLARE_KFIFO(fifo, type, size_order) = \ (typeof(fifo)) { \ { \ { \ @@ -317,22 +317,21 @@ __kfifo_uint_must_check_helper( \ /** * kfifo_alloc - dynamically allocates a new fifo buffer * @fifo: pointer to the fifo - * @size: the number of elements in the fifo, this must be a power of 2 + * @size_order: request 2^size_order fifo elements * @gfp_mask: get_free_pages mask, passed to kmalloc() * * This macro dynamically allocates a new fifo buffer. * - * The numer of elements will be rounded-up to a power of 2. * The fifo will be release with kfifo_free(). * Return 0 if no error, otherwise an error code. */ -#define kfifo_alloc(fifo, size, gfp_mask) \ +#define kfifo_alloc(fifo, size_order, gfp_mask) \ __kfifo_int_must_check_helper( \ ({ \ typeof((fifo) + 1) __tmp = (fifo); \ struct __kfifo *__kfifo = &__tmp->kfifo; \ __is_kfifo_ptr(__tmp) ? \ - __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ + __kfifo_alloc(__kfifo, size_order, sizeof(*__tmp->type), gfp_mask) : \ -EINVAL; \ }) \ ) @@ -745,7 +744,7 @@ __kfifo_uint_must_check_helper( \ }) \ ) -extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, +extern int __kfifo_alloc(struct __kfifo *fifo, int size_order, size_t esize, gfp_t gfp_mask); extern void __kfifo_free(struct __kfifo *fifo); diff --git a/include/linux/rio.h b/include/linux/rio.h index a3e7842..05ff6bb 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -70,6 +70,7 @@ #define RIO_OUTB_MBOX_RESOURCE 2 #define RIO_PW_MSG_SIZE 64 +#define RIO_KFIFO_SIZE_ORDER 11 /* 64 * 32 */ /* * A component tag value (stored in the component tag CSR) is used as device's diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index 168dd0b..7816d39 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h @@ -19,6 +19,7 @@ #include <linux/ioctl.h> #include <linux/poll.h> #include <linux/kfifo.h> +#include <linux/log2.h> #include <media/lirc.h> struct lirc_buffer { @@ -50,12 +51,13 @@ static inline int lirc_buffer_init(struct lirc_buffer *buf, unsigned int size) { int ret; + int kfifo_size_order = order_base_2(size * chunk_size); init_waitqueue_head(&buf->wait_poll); spin_lock_init(&buf->fifo_lock); buf->chunk_size = chunk_size; buf->size = size; - ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); + ret = kfifo_alloc(&buf->fifo, kfifo_size_order, GFP_KERNEL); if (ret == 0) buf->fifo_initialized = 1; diff --git a/kernel/kfifo.c b/kernel/kfifo.c index d07f480..be1c2a0 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -35,15 +35,10 @@ static inline unsigned int kfifo_unused(struct __kfifo *fifo) return (fifo->mask + 1) - (fifo->in - fifo->out); } -int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, +int __kfifo_alloc(struct __kfifo *fifo, int size_order, size_t esize, gfp_t gfp_mask) { - /* - * round down to the next power of 2, since our 'let the indices - * wrap' technique works only in this case. - */ - if (!is_power_of_2(size)) - size = rounddown_pow_of_two(size); + unsigned int size = 1 << size_order; fifo->in = 0; fifo->out = 0; diff --git a/mm/memory-failure.c b/mm/memory-failure.c index c6e4dd3..827bbf3 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1189,7 +1189,6 @@ out: EXPORT_SYMBOL_GPL(memory_failure); #define MEMORY_FAILURE_FIFO_ORDER 4 -#define MEMORY_FAILURE_FIFO_SIZE (1 << MEMORY_FAILURE_FIFO_ORDER) struct memory_failure_entry { unsigned long pfn; @@ -1199,7 +1198,7 @@ struct memory_failure_entry { struct memory_failure_cpu { DECLARE_KFIFO(fifo, struct memory_failure_entry, - MEMORY_FAILURE_FIFO_SIZE); + MEMORY_FAILURE_FIFO_ORDER); spinlock_t lock; struct work_struct work; }; diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 0a8d6eb..0a12fd5 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c @@ -31,6 +31,7 @@ #include <linux/kfifo.h> #include <linux/vmalloc.h> #include <linux/gfp.h> +#include <linux/log2.h> #include <net/net_namespace.h> #include "dccp.h" @@ -166,10 +167,11 @@ static __init int setup_jprobe(void) static __init int dccpprobe_init(void) { int ret = -ENOMEM; + int kfifo_size_order = order_base_2(bufsize); init_waitqueue_head(&dccpw.wait); spin_lock_init(&dccpw.lock); - if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL)) + if (kfifo_alloc(&dccpw.fifo, kfifo_size_order, GFP_KERNEL)) return ret; if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops)) goto err0; @@ -200,7 +202,7 @@ module_exit(dccpprobe_exit); MODULE_PARM_DESC(port, "Port to match (0=all)"); module_param(port, int, 0); -MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); +MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k , should be power of 2. If not, will roundup to power of 2)"); module_param(bufsize, int, 0); MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>"); diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 5f7518d..1736ef4 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/kfifo.h> #include <linux/time.h> +#include <linux/log2.h> #include <net/net_namespace.h> #include <net/sctp/sctp.h> @@ -47,7 +48,7 @@ MODULE_PARM_DESC(port, "Port to match (0=all)"); module_param(port, int, 0); static int bufsize __read_mostly = 64 * 1024; -MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); +MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k, should be power of 2. If not, will roundup to power of 2)"); module_param(bufsize, int, 0); static int full __read_mostly = 1; @@ -182,10 +183,11 @@ static struct jprobe sctp_recv_probe = { static __init int sctpprobe_init(void) { int ret = -ENOMEM; + int kfifo_size_order = order_base_2(bufsize); init_waitqueue_head(&sctpw.wait); spin_lock_init(&sctpw.lock); - if (kfifo_alloc(&sctpw.fifo, bufsize, GFP_KERNEL)) + if (kfifo_alloc(&sctpw.fifo, kfifo_size_order, GFP_KERNEL)) return ret; if (!proc_net_fops_create(&init_net, procname, S_IRUSR, diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c index cfe40ad..eb3a46e 100644 --- a/samples/kfifo/bytestream-example.c +++ b/samples/kfifo/bytestream-example.c @@ -18,7 +18,7 @@ */ /* fifo size in elements (bytes) */ -#define FIFO_SIZE 32 +#define FIFO_SIZE_ORDER 5 /* name of the proc entry */ #define PROC_FIFO "bytestream-fifo" @@ -41,10 +41,10 @@ static DEFINE_MUTEX(write_lock); #ifdef DYNAMIC static struct kfifo test; #else -static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE); +static DECLARE_KFIFO(test, unsigned char, FIFO_SIZE_ORDER); #endif -static const unsigned char expected_result[FIFO_SIZE] = { +static const unsigned char expected_result[1<<FIFO_SIZE_ORDER] = { 3, 4, 5, 6, 7, 8, 9, 0, 1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, @@ -156,7 +156,7 @@ static int __init example_init(void) #ifdef DYNAMIC int ret; - ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL); + ret = kfifo_alloc(&test, FIFO_SIZE_ORDER, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index 0647379..bbc0787 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c @@ -16,7 +16,8 @@ */ /* fifo size in elements (bytes) */ -#define FIFO_SIZE 32 +#define FIFO_SIZE_ORDER 5 +#define FIFO_SIZE (1<< FIFO_SIZE_ORDER) static struct kfifo fifo; @@ -29,7 +30,7 @@ static int __init example_init(void) printk(KERN_INFO "DMA fifo test start\n"); - if (kfifo_alloc(&fifo, FIFO_SIZE, GFP_KERNEL)) { + if (kfifo_alloc(&fifo, FIFO_SIZE_ORDER, GFP_KERNEL)) { printk(KERN_WARNING "error kfifo_alloc\n"); return -ENOMEM; } diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c index 6f8e79e..bed3229 100644 --- a/samples/kfifo/inttype-example.c +++ b/samples/kfifo/inttype-example.c @@ -18,7 +18,8 @@ */ /* fifo size in elements (ints) */ -#define FIFO_SIZE 32 +#define FIFO_SIZE_ORDER 5 +#define FIFO_SIZE (1<< FIFO_SIZE_ORDER) /* name of the proc entry */ #define PROC_FIFO "int-fifo" @@ -41,7 +42,7 @@ static DEFINE_MUTEX(write_lock); #ifdef DYNAMIC static DECLARE_KFIFO_PTR(test, int); #else -static DEFINE_KFIFO(test, int, FIFO_SIZE); +static DEFINE_KFIFO(test, int, FIFO_SIZE_ORDER); #endif static const int expected_result[FIFO_SIZE] = { @@ -149,7 +150,7 @@ static int __init example_init(void) #ifdef DYNAMIC int ret; - ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL); + ret = kfifo_alloc(&test, FIFO_SIZE_ORDER, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c index 2d7529e..2902eae 100644 --- a/samples/kfifo/record-example.c +++ b/samples/kfifo/record-example.c @@ -18,7 +18,7 @@ */ /* fifo size in elements (bytes) */ -#define FIFO_SIZE 128 +#define FIFO_SIZE_ORDER 7 /* name of the proc entry */ #define PROC_FIFO "record-fifo" @@ -50,7 +50,7 @@ static DEFINE_MUTEX(write_lock); struct kfifo_rec_ptr_1 test; #else -typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) mytest; +typedef STRUCT_KFIFO_REC_1(FIFO_SIZE_ORDER) mytest; static mytest test; #endif @@ -163,7 +163,7 @@ static int __init example_init(void) #ifdef DYNAMIC int ret; - ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL); + ret = kfifo_alloc(&test, FIFO_SIZE_ORDER, GFP_KERNEL); if (ret) { printk(KERN_ERR "error kfifo_alloc\n"); return ret; -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 5/5] kfifo: log based kfifo API 2013-01-08 14:57 ` [PATCH 5/5] kfifo: log based kfifo API Yuanhan Liu @ 2013-01-08 18:16 ` Dmitry Torokhov 2013-01-08 21:10 ` Andy Walls 2013-01-09 2:42 ` Yuanhan Liu 0 siblings, 2 replies; 15+ messages in thread From: Dmitry Torokhov @ 2013-01-08 18:16 UTC (permalink / raw) To: Yuanhan Liu Cc: linux-kernel, Stefani Seibold, Andrew Morton, linux-omap, linuxppc-dev, platform-driver-x86, linux-input, linux-iio, linux-rdma, linux-media, linux-mmc, linux-mtd, libertas-dev, linux-wireless, netdev, linux-pci, open-iscsi, linux-scsi, devel, linux-serial, linux-usb, linux-mm, dccp, linux-sctp Hi Yuanhan, On Tue, Jan 08, 2013 at 10:57:53PM +0800, Yuanhan Liu wrote: > The current kfifo API take the kfifo size as input, while it rounds > _down_ the size to power of 2 at __kfifo_alloc. This may introduce > potential issue. > > Take the code at drivers/hid/hid-logitech-dj.c as example: > > if (kfifo_alloc(&djrcv_dev->notif_fifo, > DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), > GFP_KERNEL)) { > > Where, DJ_MAX_NUMBER_NOTIFICATIONS is 8, and sizeo of(struct dj_report) > is 15. > > Which means it wants to allocate a kfifo buffer which can store 8 > dj_report entries at once. The expected kfifo buffer size would be > 8 * 15 = 120 then. While, in the end, __kfifo_alloc will turn the > size to rounddown_power_of_2(120) = 64, and then allocate a buf > with 64 bytes, which I don't think this is the original author want. > > With the new log API, we can do like following: > > int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * > sizeof(struct dj_report)); > > if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, GFP_KERNEL)) { > > This make sure we will allocate enough kfifo buffer for holding > DJ_MAX_NUMBER_NOTIFICATIONS dj_report entries. Why don't you simply change __kfifo_alloc to round the allocation up instead of down? Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 5/5] kfifo: log based kfifo API 2013-01-08 18:16 ` Dmitry Torokhov @ 2013-01-08 21:10 ` Andy Walls 2013-01-09 2:42 ` Yuanhan Liu 1 sibling, 0 replies; 15+ messages in thread From: Andy Walls @ 2013-01-08 21:10 UTC (permalink / raw) To: Dmitry Torokhov, Yuanhan Liu Cc: linux-kernel, Stefani Seibold, Andrew Morton, linux-omap, linuxppc-dev, platform-driver-x86, linux-input, linux-iio, linux-rdma, linux-media, linux-mmc, linux-mtd, libertas-dev, linux-wireless, netdev, linux-pci, open-iscsi, linux-scsi, devel, linux-serial, linux-usb, linux-mm, dccp, linux-sctp Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote: >Hi Yuanhan, > >On Tue, Jan 08, 2013 at 10:57:53PM +0800, Yuanhan Liu wrote: >> The current kfifo API take the kfifo size as input, while it rounds >> _down_ the size to power of 2 at __kfifo_alloc. This may introduce >> potential issue. >> >> Take the code at drivers/hid/hid-logitech-dj.c as example: >> >> if (kfifo_alloc(&djrcv_dev->notif_fifo, >> DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct >dj_report), >> GFP_KERNEL)) { >> >> Where, DJ_MAX_NUMBER_NOTIFICATIONS is 8, and sizeo of(struct >dj_report) >> is 15. >> >> Which means it wants to allocate a kfifo buffer which can store 8 >> dj_report entries at once. The expected kfifo buffer size would be >> 8 * 15 = 120 then. While, in the end, __kfifo_alloc will turn the >> size to rounddown_power_of_2(120) = 64, and then allocate a buf >> with 64 bytes, which I don't think this is the original author want. >> >> With the new log API, we can do like following: >> >> int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * >> sizeof(struct dj_report)); >> >> if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, >GFP_KERNEL)) { >> >> This make sure we will allocate enough kfifo buffer for holding >> DJ_MAX_NUMBER_NOTIFICATIONS dj_report entries. > >Why don't you simply change __kfifo_alloc to round the allocation up >instead of down? > >Thanks. > >-- >Dmitry >-- >To unsubscribe from this list: send the line "unsubscribe linux-media" >in >the body of a message to majordomo@vger.kernel.org >More majordomo info at http://vger.kernel.org/majordomo-info.html Hi Dmitry, I agree. I don't see the benefit in pushing up the change to a kfifo internal decision/problem to many different places in the kernel. Regards, Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 5/5] kfifo: log based kfifo API 2013-01-08 18:16 ` Dmitry Torokhov 2013-01-08 21:10 ` Andy Walls @ 2013-01-09 2:42 ` Yuanhan Liu 1 sibling, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-09 2:42 UTC (permalink / raw) To: Dmitry Torokhov Cc: linux-kernel, Stefani Seibold, Andrew Morton, linux-omap, linuxppc-dev, platform-driver-x86, linux-input, linux-iio, linux-rdma, linux-media, linux-mmc, linux-mtd, libertas-dev, linux-wireless, netdev, linux-pci, open-iscsi, linux-scsi, devel, linux-serial, linux-usb, linux-mm, dccp, linux-sctp On Tue, Jan 08, 2013 at 10:16:46AM -0800, Dmitry Torokhov wrote: > Hi Yuanhan, > > On Tue, Jan 08, 2013 at 10:57:53PM +0800, Yuanhan Liu wrote: > > The current kfifo API take the kfifo size as input, while it rounds > > _down_ the size to power of 2 at __kfifo_alloc. This may introduce > > potential issue. > > > > Take the code at drivers/hid/hid-logitech-dj.c as example: > > > > if (kfifo_alloc(&djrcv_dev->notif_fifo, > > DJ_MAX_NUMBER_NOTIFICATIONS * sizeof(struct dj_report), > > GFP_KERNEL)) { > > > > Where, DJ_MAX_NUMBER_NOTIFICATIONS is 8, and sizeo of(struct dj_report) > > is 15. > > > > Which means it wants to allocate a kfifo buffer which can store 8 > > dj_report entries at once. The expected kfifo buffer size would be > > 8 * 15 = 120 then. While, in the end, __kfifo_alloc will turn the > > size to rounddown_power_of_2(120) = 64, and then allocate a buf > > with 64 bytes, which I don't think this is the original author want. > > > > With the new log API, we can do like following: > > > > int kfifo_size_order = order_base_2(DJ_MAX_NUMBER_NOTIFICATIONS * > > sizeof(struct dj_report)); > > > > if (kfifo_alloc(&djrcv_dev->notif_fifo, kfifo_size_order, GFP_KERNEL)) { > > > > This make sure we will allocate enough kfifo buffer for holding > > DJ_MAX_NUMBER_NOTIFICATIONS dj_report entries. > > Why don't you simply change __kfifo_alloc to round the allocation up > instead of down? Hi Dmitry, Yes, it would be neat and that was my first reaction as well. I then sent out a patch, but it was NACKed by Stefani(the original kfifo author). Here is the link: https://lkml.org/lkml/2012/10/26/144 Then Stefani proposed to change the API to take log of size as input to root fix this kind of issues. And here it is. Thanks. --yliu ^ permalink raw reply [flat|nested] 15+ messages in thread
* Antw: [PATCH 0/5] kfifo cleanup and log based kfifo API 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu ` (4 preceding siblings ...) 2013-01-08 14:57 ` [PATCH 5/5] kfifo: log based kfifo API Yuanhan Liu @ 2013-01-08 15:03 ` Ulrich Windl 2013-01-08 15:29 ` Yuanhan Liu 5 siblings, 1 reply; 15+ messages in thread From: Ulrich Windl @ 2013-01-08 15:03 UTC (permalink / raw) To: Yuanhan Liu, linux-kernel Cc: Mike Christie, iscsi list, Andrew Morton, James E.J. Bottomley, Stefani Seibold >>> Yuanhan Liu <yuanhan.liu@linux.intel.com> schrieb am 08.01.2013 um 15:57 in Nachricht <1357657073-27352-1-git-send-email-yuanhan.liu@linux.intel.com>: [...] > My proposal is to replace kfifo_init with kfifo_alloc, where it > allocate buffer and maintain fifo size inside kfifo. Then we can > remove buggy kfifo_init. [...] Spontaneously I feel that emitting a critical message if the requested size is not a power of two would be a good idea, as well as (in that case) rounding up to the next power of two instead of rounding down seems not too stupid ;-) Sorry, I'm not deeply into recent kernel development. Regards, Ulrich ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Antw: [PATCH 0/5] kfifo cleanup and log based kfifo API 2013-01-08 15:03 ` Antw: [PATCH 0/5] kfifo cleanup and " Ulrich Windl @ 2013-01-08 15:29 ` Yuanhan Liu 0 siblings, 0 replies; 15+ messages in thread From: Yuanhan Liu @ 2013-01-08 15:29 UTC (permalink / raw) To: Ulrich Windl Cc: linux-kernel, Mike Christie, iscsi list, Andrew Morton, James E.J. Bottomley, Stefani Seibold On Tue, Jan 08, 2013 at 04:03:17PM +0100, Ulrich Windl wrote: > >>> Yuanhan Liu <yuanhan.liu@linux.intel.com> schrieb am 08.01.2013 um 15:57 in > Nachricht <1357657073-27352-1-git-send-email-yuanhan.liu@linux.intel.com>: > > [...] > > My proposal is to replace kfifo_init with kfifo_alloc, where it > > allocate buffer and maintain fifo size inside kfifo. Then we can > > remove buggy kfifo_init. > [...] > > Spontaneously I feel that emitting a critical message if the requested size is not a power of two would be a good idea, Hi Ulrich, If we can emit all such critical message at compile time, it would be good then. But we can't, as fifo size is runtime determinated in quite many cases. > as well as (in that case) rounding up to the next power of two instead of rounding down seems not too stupid ;-) There are 2 issues, first, you just can't round the fifo size up to power of 2 for kfifo_init as fifo buffer is allocated outside. And if you do, you may access memory outside the buffer. Second, round up to power of 2 inside kfifo_alloc and DECLARE_KFIFO is simple and should work. But it wastes memory(by allocating more memory) without notifing caller. So, per discussed with Stefani, we better to change the API be log aware to root fix this kind of potential issue. Thanks. --yliu ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2013-01-10 7:11 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-01-08 14:57 [PATCH 0/5] kfifo cleanup and log based kfifo API Yuanhan Liu 2013-01-08 14:57 ` [PATCH 1/5] kfifo: remove unnecessary type check Yuanhan Liu 2013-01-08 21:51 ` Stefani Seibold 2013-01-09 2:35 ` Yuanhan Liu 2013-01-09 15:29 ` Stefani Seibold 2013-01-10 7:12 ` Yuanhan Liu 2013-01-08 14:57 ` [PATCH 2/5] libsrp: replace kfifo_init with kfifo_alloc Yuanhan Liu 2013-01-08 14:57 ` [PATCH 3/5] libiscsi: " Yuanhan Liu 2013-01-08 14:57 ` [PATCH 4/5] kfifo: remove kfifo_init Yuanhan Liu 2013-01-08 14:57 ` [PATCH 5/5] kfifo: log based kfifo API Yuanhan Liu 2013-01-08 18:16 ` Dmitry Torokhov 2013-01-08 21:10 ` Andy Walls 2013-01-09 2:42 ` Yuanhan Liu 2013-01-08 15:03 ` Antw: [PATCH 0/5] kfifo cleanup and " Ulrich Windl 2013-01-08 15:29 ` Yuanhan Liu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).