All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] kfifo: new API v0.4
@ 2009-08-16 20:39 Stefani Seibold
  2009-08-16 20:44 ` [PATCH 1/7] kfifo: move struct kfifo in place Stefani Seibold
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

This is a new generic kernel FIFO implementation.

The current kernel fifo API is not very widely used, because it has to many
constrains. Only 13 files in the current 2.6.31-rc5 used it. FIFO's are
like list's a very basic thing and a kfifo API which handles the most use
case would save a lot of development time and memory resources.

I think this are the reasons why kfifo is not in use:

- The API is to simple, important functions are missing
- A fifo can be only allocated dynamically
- There is a need of a spinlock despite you need it or not
- There is no support for data records inside a fifo

So i decided to extend the kfifo in a more generic way without blowing up
the API to much. The new API has the following benefits:

- Generic usage: For kernel internal use and/or device driver.
- Provide an API for the most use case.
- Slim API: The whole API provides 23 functions.
- Linux style habit.
- DECLARE_KFIFO, DEFINE_KFIFO and INIT_KFIFO Macros
- Direct copy_to_user from the fifo and copy_from_user into the fifo.
- The kfifo itself is an in place member of the using data structure, this save an 
  indirection access and does not waste the kernel allocator. 
- Lockless access: if only one reader and one writer is active on the fifo,
  which is the common use case, no additional locking is necessary.
- Remove spinlock - give the user the freedom of choice what kind of locking to use if 
  one is required.
- Ability to handle records. Three type of records are supported:
  - Variable length records between 0-255 bytes, with a record size field of 1 bytes.
  - Variable length records between 0-65535 bytes, with a record size field of 2 bytes.
  - Fixed size records, which no record size field.
- Preserve memory resource.
- Performance!
- Easy to use!

ChangeLog:

v.0 03.08.2009
 First proposal, post a draft
v.1 04.08.2009
 add kfifo_init()
 kfifo_put() and kfifo_get() restored to the original behavior (but without locking)
 introduce new kfifo_put_rec() and kfifo_put_rec() for FIFO record handling
 kfifo_alloc() does only allocate the FIFO buffer
 kfifo_free() does only release the FIFO buffer
 revert to power of two buffer sizes
v.2 12.08.2009
 simplify record handling
 add new kfifo_reset_out() function
 rename kfifo_put_* into kfifo_in_* to prevent miss-use by non in-kernel-tree drivers
 rename kfifo_get_* into kfifo_out_* to prevent miss-use by non in-kernel-tree drivers
 split it into separated patches
v.3 14.08.2009
 fix documentation
 fix some issues
 refactorized code
 refactorized patches
v.4 16.08.2009
 kfifo_in_rec(): change @from type into a void pointer  
 kfifo_out_rec(): change @to type into a void pointer
 rename internal used KFIFO_INIT() macro into  __kfifo_initializer()
 fix bug in record handling - sorry, i posted an intermediate version
 fix bug in kfifo_in() - sorry, i posted an intermediate version 
 renamed the buffer used by the macros into name##kfifo_buffer (was name##_buffer)
 fix source comments
 cleanup and fix proposal document

The API:
--------

int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 Allocates a new FIFO internal buffer
 The size will be rounded-up to a power of 2.
 The buffer will be release with kfifo_free().
 Return 0 if no error, otherwise the an error code.

 @fifo: the fifo to assign then new buffer
 @size: the size of the internal buffer to be allocated.
 @gfp_mask: get_free_pages mask, passed to kmalloc()


void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 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.


void kfifo_free(struct kfifo *fifo)
 frees a dynamic allocated FIFO
 @fifo: the fifo to be freed.


void kfifo_reset(struct kfifo *fifo)
 removes the entire FIFO contents
 @fifo: the fifo to be emptied.


void kfifo_reset_out(struct kfifo *fifo)
 Skip output FIFO contents
 @fifo: the fifo to be emptied.


unsigned int kfifo_len(struct kfifo *fifo)
 Returns the number of used bytes in the FIFO
 @fifo: the fifo to be used.


unsigned int kfifo_size(struct kfifo *fifo)
 returns the size of the fifo in bytes
 @fifo: the fifo to be used.


kfifo_is_empty(struct kfifo *fifo)
 returns true if the fifo is empty
 @fifo: the fifo to be used.


kfifo_is_full(struct kfifo *fifo)
 Returns true if the fifo is full
 @fifo: the fifo to be used.


unsigned int kfifo_avail(struct kfifo *fifo)
 Returns the number of bytes available in the FIFO
 @fifo: the fifo to be used.


unsigned int kfifo_in(struct kfifo *fifo, unsigned char *from, unsigned int n)
 Puts some data into the FIFO.

 This function copies at most @n bytes from @from into
 the FIFO depending on the free space, and returns the number of
 bytes copied.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.

 @fifo: the fifo to be used.
 @from: the data to be added.
 @n: the length of the data to be added.


unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int n)
 Gets some data from the FIFO.

 This function copies at most @n bytes from the FIFO into
 @to and returns the number of copied bytes.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.

 @fifo: the fifo to be used.
 @to: where the data must be copied.
 @n: the size of the destination buffer.

 
unsigned int kfifo_from_user(struct kfifo *fifo, const void __user *from, unsigned int n)
 Puts some data from user space into the FIFO.

 This function copies at most @n bytes from the @from into the FIFO
 and returns the number of copied bytes.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.

 @fifo: the fifo to be used.
 @from: pointer to the data to be added.
 @n: the length of the data to be added.


unsigned int kfifo_to_user(struct kfifo *fifo, void __user *to, unsigned int n)
 Gets data from the FIFO and write it to user space.

 @fifo: the fifo to be used.
 @to: where the data must be copied.
 @n: the size of the destination buffer.

 This function copies at most @n bytes from the FIFO into @to
 and returns the number of copied bytes.

 Note that with only one concurrent reader and one concurrent writer, you don't
 need extra locking to use these functions.


void kfifo_skip(struct kfifo *fifo, unsigned int len)
 Skip output data
 @fifo: the fifo to be used.
 @len: number of bytes to skip


Functions for simplify porting:
-------------------------------

unsigned int kfifo_in_locked(struct kfifo *fifo,
	const unsigned char *from, unsigned int n, spinlock_t *lock)
 Puts some data into the FIFO using a spinlock for locking
 @fifo: the fifo to be used.
 @from: the data to be added.
 @len: the length of the data to be added.
 @lock: pointer to the spinlock to use for locking.

 This function copies at most @len bytes from the @from buffer into
 the FIFO depending on the free space, and returns the number of
 bytes copied.


unsigned int kfifo_out_locked(struct kfifo *fifo,
	unsigned char *to, unsigned int n, spinlock_t *lock)
 Gets some data from the FIFO using a spinlock for locking
 @fifo: the fifo to be used.
 @to: where the data must be copied.
 @len: the size of the destination buffer.
 @lock: pointer to the spinlock to use for locking.

 This function copies at most @len bytes from the FIFO into the
 @to buffer and returns the number of copied bytes.


These are the functions for handling records:
---------------------------------------------

The functions supports three different kinds of records:

- Fix size records.
  The @recsize parameter is 0 and exactly @len bytes will be copied
- Varible size records with 1 byte length field
  The @recsize parameter is 1 and a record of 0-255 bytes will be copied
- Varible size records with 2 byte length field
  The @recsize parameter is 2 and a record of 0-65535 bytes will be copied


unsigned int kfifo_in_rec(struct kfifo *fifo,
	void *from, unsigned int n, unsigned int recsize)
 Puts some record data into the FIFO.

 This function copies @n bytes from the @from into
 the FIFO and returns the number of bytes which cannot be copied.
 A returned value greater than the @n value means that the record doesn't
 fit into the buffer.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.
 @fifo: the fifo to be used.
 @from: the data to be added.
 @n: the length of the data to be added.
 @recsize: size of record field


unsigned int kfifo_out_rec(struct kfifo *fifo,
	void *to, unsigned int n, unsigned int recsize,
	unsigned int *total)
 Gets some record data from the FIFO.
 
 This function copies at most @n bytes from the @to into
 the FIFO and returns the number of bytes which cannot be copied.

 A returned value greater than the @n value means that the record doesn't
 fit into the @to buffer.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.
 @fifo: the fifo to be used.
 @to: where the data must be copied.
 @n: the size of the destination buffer.
 @recsize: size of record field
 @total: pointer where the total number of to copied bytes should stored


unsigned int kfifo_from_user_rec(struct kfifo *fifo,
	const void __user *from, unsigned int n, unsigned int recsize)
 Puts some data from user space into the FIFO
 
 This function copies @n bytes from the @from into the
 FIFO and returns the number of bytes which cannot be copied. If the 
 returned value is equal or less the @n value, the copy_from_user() functions has 
 failed. Otherwise the record doesn't fit into the buffer.
 
 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.
 @fifo: the fifo to be used.
 @from: pointer to the data to be added.
 @n: the length of the data to be added.
 @recsize: size of record field


unsigned int kfifo_to_user_rec(struct kfifo *fifo,
		void __user *to, unsigned int n, unsigned int recsize,
		unsigned int *total)
 Gets data from the FIFO and write it to user space

 This function copies at most @n bytes from the FIFO into @to.
 In case of an error, the function returns the number of bytes which cannot
 be copied. If the returned value is equal or less the @n value, the
 copy_to_user() functions has failed. Otherwise the record doesn't fit into
 the @to buffer.

 Note that with only one concurrent reader and one concurrent
 writer, you don't need extra locking to use these functions.
 @fifo: the fifo to be used.
 @to: where the data must be copied.
 @n: the size of the destination buffer.
 @recsize: size of record field
 @total: pointer where the total number of to copied bytes should stored


unsigned long kfifo_peek_rec(struct kfifo *fifo, unsigned long recsize)
 Gets the size of the next FIFO record data.

 This function returns the size of the next FIFO record in number of bytes
 @fifo: the fifo to be used.
 @recsize: size of record field


unsigned int kfifo_skip_rec(struct kfifo *fifo,	unsigned int recsize)
 Skip the next output record

 This function skips the next FIFO record

 @fifo: the fifo to be used.
 @recsize: size of record field


Macros defined for kernel FIFO:
-------------------------------

DECLARE_KFIFO(name, size)
 Macro to declare a kfifo and the associated buffer

 Note: the macro can be used inside struct or union declaration

 @name: name of the declared kfifo datatype
 @size: size of the fifo buffer


INIT_KFIFO(name)
 Macro to initialize a with DECLARE_KFIFO declared kfifo
 @name: name of the declared kfifo datatype
 @size: size of the fifo buffer


DEFINE_KFIFO(name, size)
 Macro to define and initialize a kfifo

 Note: the macro can be used for global and local kfifo data type variables

 @name: name of the declared kfifo datatype
 @size: size of the fifo buffer

<End of API Documentation>

One thing is that the new API is not compatible with the old one. I had
a look at the current user of the old kfifo API and it is was easy to adapt it to
the new API. These are the files which currently use the kfifo API:

/usr/src/linux/./drivers/char/nozomi.c
/usr/src/linux/./drivers/char/sonypi.c
/usr/src/linux/./drivers/infiniband/hw/cxgb3/cxio_resource.c
/usr/src/linux/./drivers/media/video/meye.c
/usr/src/linux/./drivers/net/wireless/libertas/main.c
/usr/src/linux/./drivers/platform/x86/fujitsu-laptop.c
/usr/src/linux/./drivers/platform/x86/sony-laptop.c
/usr/src/linux/./drivers/scsi/libiscsi.c
/usr/src/linux/./drivers/scsi/libiscsi_tcp.c
/usr/src/linux/./drivers/scsi/libsrp.c
/usr/src/linux/./drivers/usb/host/fhci.h
/usr/src/linux/./net/dccp/probe.c

The patch is splitted into 7 parts:

 Part 1: move struct kfifo in place
 Part 2: move out spinlock
 Part 3: Cleanup namespace
 Part 4: rename kfifo_put... -> kfifo_in... and kfifo_get... -> kfifo_out...
 Part 5: add DEFINE_KFIFO and friends, add very tiny functions
 Part 6: add kfifo_skip, kfifo_from_user and kfifo_to_user (does some reorg)
 Part 7: add record handling functions (does some reorg)

The patch-set is against kernel 2.6.31-rc5

This is hopefully a version, which is ready for inclusion into the kernel. 
What do you think?

Stefani



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/7] kfifo: move struct kfifo in place
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
@ 2009-08-16 20:44 ` Stefani Seibold
  2009-08-16 20:46 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:44 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

Since most users want to have the kfifo as part of another
object, reorganize the code to allow including struct kfifo
in another data structure. This requires changing the kfifo_alloc
and kfifo_init prototypes so that we pass an existing kfifo
pointer into them. This patch changes the implementation and
all existing users.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 drivers/char/nozomi.c                       |   21 ++++-----
 drivers/char/sonypi.c                       |   40 ++++++++---------
 drivers/infiniband/hw/cxgb3/cxio_hal.h      |    9 ++-
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   60 ++++++++++++-------------
 drivers/media/video/meye.c                  |   48 +++++++++-----------
 drivers/media/video/meye.h                  |    4 -
 drivers/net/wireless/libertas/cmd.c         |    4 -
 drivers/net/wireless/libertas/dev.h         |    3 -
 drivers/net/wireless/libertas/main.c        |   16 +++---
 drivers/platform/x86/fujitsu-laptop.c       |   18 +++----
 drivers/platform/x86/sony-laptop.c          |   46 +++++++++----------
 drivers/scsi/libiscsi.c                     |   22 +++------
 drivers/scsi/libiscsi_tcp.c                 |   29 ++++++------
 drivers/scsi/libsrp.c                       |   12 ++---
 drivers/usb/host/fhci-sched.c               |   10 ++--
 drivers/usb/host/fhci-tds.c                 |   35 +++++++--------
 drivers/usb/host/fhci.h                     |   10 ++--
 include/linux/kfifo.h                       |   11 ++--
 include/scsi/libiscsi.h                     |    3 -
 include/scsi/libiscsi_tcp.h                 |    2 
 include/scsi/libsrp.h                       |    2 
 kernel/kfifo.c                              |   65 ++++++++++++++--------------
 net/dccp/probe.c                            |   20 +++-----
 23 files changed, 236 insertions(+), 254 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/char/nozomi.c linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c
--- linux-2.6.31-rc4-kfifo0/drivers/char/nozomi.c	2009-07-24 20:36:34.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c	2009-08-16 21:25:14.000000000 +0200
@@ -357,7 +357,7 @@
 	u8 update_flow_control;
 	struct ctrl_ul ctrl_ul;
 	struct ctrl_dl ctrl_dl;
-	struct kfifo *fifo_ul;
+	struct kfifo fifo_ul;
 	void __iomem *dl_addr[2];
 	u32 dl_size[2];
 	u8 toggle_dl;
@@ -684,8 +684,8 @@
 		dump_table(dc);
 
 		for (i = PORT_MDM; i < MAX_PORT; i++) {
-			dc->port[i].fifo_ul =
-			    kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
+			kfifo_alloc(&dc->port[i].fifo_ul,
+				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
 			memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
 			memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
 		}
@@ -797,7 +797,7 @@
 	struct tty_struct *tty = tty_port_tty_get(&port->port);
 
 	/* Get data from tty and place in buf for now */
-	size = __kfifo_get(port->fifo_ul, dc->send_buf,
+	size = __kfifo_get(&port->fifo_ul, dc->send_buf,
 			   ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
 
 	if (size == 0) {
@@ -987,11 +987,11 @@
 
 	} else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) {
 
-		if (__kfifo_len(dc->port[port].fifo_ul)) {
+		if (__kfifo_len(&dc->port[port].fifo_ul)) {
 			DBG1("Enable interrupt (0x%04X) on port: %d",
 				enable_ier, port);
 			DBG1("Data in buffer [%d], enable transmit! ",
-				__kfifo_len(dc->port[port].fifo_ul));
+				__kfifo_len(&dc->port[port].fifo_ul));
 			enable_transmit_ul(port, dc);
 		} else {
 			DBG1("No data in buffer...");
@@ -1535,8 +1535,7 @@
 	free_irq(pdev->irq, dc);
 
 	for (i = 0; i < MAX_PORT; i++)
-		if (dc->port[i].fifo_ul)
-			kfifo_free(dc->port[i].fifo_ul);
+		kfifo_free(&dc->port[i].fifo_ul);
 
 	kfree(dc->send_buf);
 
@@ -1672,7 +1671,7 @@
 		goto exit;
 	}
 
-	rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count);
+	rval = __kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count);
 
 	/* notify card */
 	if (unlikely(dc == NULL)) {
@@ -1720,7 +1719,7 @@
 	if (!port->port.count)
 		goto exit;
 
-	room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
+	room = port->fifo_ul.size - __kfifo_len(&port->fifo_ul);
 
 exit:
 	mutex_unlock(&port->tty_sem);
@@ -1877,7 +1876,7 @@
 		goto exit_in_buffer;
 	}
 
-	rval = __kfifo_len(port->fifo_ul);
+	rval = __kfifo_len(&port->fifo_ul);
 
 exit_in_buffer:
 	return rval;
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/char/sonypi.c linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c
--- linux-2.6.31-rc4-kfifo0/drivers/char/sonypi.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c	2009-08-16 21:22:46.000000000 +0200
@@ -486,7 +486,7 @@
 	int camera_power;
 	int bluetooth_power;
 	struct mutex lock;
-	struct kfifo *fifo;
+	struct kfifo fifo;
 	spinlock_t fifo_lock;
 	wait_queue_head_t fifo_proc_list;
 	struct fasync_struct *fifo_async;
@@ -495,7 +495,7 @@
 	struct input_dev *input_jog_dev;
 	struct input_dev *input_key_dev;
 	struct work_struct input_work;
-	struct kfifo *input_fifo;
+	struct kfifo input_fifo;
 	spinlock_t input_fifo_lock;
 } sonypi_device;
 
@@ -776,7 +776,7 @@
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp,
+	while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp,
 			 sizeof(kp)) == sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
@@ -826,7 +826,7 @@
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put(sonypi_device.input_fifo,
+		kfifo_put(&sonypi_device.input_fifo,
 			  (unsigned char *)&kp, sizeof(kp));
 		schedule_work(&sonypi_device.input_work);
 	}
@@ -879,7 +879,7 @@
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -905,7 +905,7 @@
 	mutex_lock(&sonypi_device.lock);
 	/* Flush input queue on first open */
 	if (!sonypi_device.open_count)
-		kfifo_reset(sonypi_device.fifo);
+		kfifo_reset(&sonypi_device.fifo);
 	sonypi_device.open_count++;
 	mutex_unlock(&sonypi_device.lock);
 	unlock_kernel();
@@ -918,17 +918,17 @@
 	ssize_t ret;
 	unsigned char c;
 
-	if ((kfifo_len(sonypi_device.fifo) == 0) &&
+	if ((kfifo_len(&sonypi_device.fifo) == 0) &&
 	    (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
-				       kfifo_len(sonypi_device.fifo) != 0);
+				       kfifo_len(&sonypi_device.fifo) != 0);
 	if (ret)
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -945,7 +945,7 @@
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &sonypi_device.fifo_proc_list, wait);
-	if (kfifo_len(sonypi_device.fifo))
+	if (kfifo_len(&sonypi_device.fifo))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -1312,11 +1312,11 @@
 			"http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
 
 	spin_lock_init(&sonypi_device.fifo_lock);
-	sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
+	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL,
 					 &sonypi_device.fifo_lock);
-	if (IS_ERR(sonypi_device.fifo)) {
+	if (error) {
 		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-		return PTR_ERR(sonypi_device.fifo);
+		return error;
 	}
 
 	init_waitqueue_head(&sonypi_device.fifo_proc_list);
@@ -1392,12 +1392,10 @@
 		}
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
-		sonypi_device.input_fifo =
-			kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-				    &sonypi_device.input_fifo_lock);
-		if (IS_ERR(sonypi_device.input_fifo)) {
+		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
+				GFP_KERNEL, &sonypi_device.input_fifo_lock);
+		if (error) {
 			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-			error = PTR_ERR(sonypi_device.input_fifo);
 			goto err_inpdev_unregister;
 		}
 
@@ -1422,7 +1420,7 @@
 		pci_disable_device(pcidev);
  err_put_pcidev:
 	pci_dev_put(pcidev);
-	kfifo_free(sonypi_device.fifo);
+	kfifo_free(&sonypi_device.fifo);
 
 	return error;
 }
@@ -1437,7 +1435,7 @@
 	if (useinput) {
 		input_unregister_device(sonypi_device.input_key_dev);
 		input_unregister_device(sonypi_device.input_jog_dev);
-		kfifo_free(sonypi_device.input_fifo);
+		kfifo_free(&sonypi_device.input_fifo);
 	}
 
 	misc_deregister(&sonypi_misc_device);
@@ -1450,7 +1448,7 @@
 		pci_dev_put(sonypi_device.dev);
 	}
 
-	kfifo_free(sonypi_device.fifo);
+	kfifo_free(&sonypi_device.fifo);
 
 	return 0;
 }
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/infiniband/hw/cxgb3/cxio_hal.h linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_hal.h
--- linux-2.6.31-rc4-kfifo0/drivers/infiniband/hw/cxgb3/cxio_hal.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_hal.h	2009-08-09 15:40:00.000000000 +0200
@@ -34,6 +34,7 @@
 
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/kfifo.h>
 
 #include "t3_cpl.h"
 #include "t3cdev.h"
@@ -75,13 +76,13 @@
 };
 
 struct cxio_hal_resource {
-	struct kfifo *tpt_fifo;
+	struct kfifo tpt_fifo;
 	spinlock_t tpt_fifo_lock;
-	struct kfifo *qpid_fifo;
+	struct kfifo qpid_fifo;
 	spinlock_t qpid_fifo_lock;
-	struct kfifo *cqid_fifo;
+	struct kfifo cqid_fifo;
 	spinlock_t cqid_fifo_lock;
-	struct kfifo *pdid_fifo;
+	struct kfifo pdid_fifo;
 	spinlock_t pdid_fifo_lock;
 };
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-2.6.31-rc4-kfifo0/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-16 21:20:12.000000000 +0200
@@ -39,12 +39,12 @@
 #include "cxio_resource.h"
 #include "cxio_hal.h"
 
-static struct kfifo *rhdl_fifo;
+static struct kfifo rhdl_fifo;
 static spinlock_t rhdl_fifo_lock;
 
 #define RANDOM_SIZE 16
 
-static int __cxio_init_resource_fifo(struct kfifo **fifo,
+static int __cxio_init_resource_fifo(struct kfifo *fifo,
 				   spinlock_t *fifo_lock,
 				   u32 nr, u32 skip_low,
 				   u32 skip_high,
@@ -55,12 +55,11 @@
 	u32 rarray[16];
 	spin_lock_init(fifo_lock);
 
-	*fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock);
-	if (IS_ERR(*fifo))
+	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		__kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32));
+		__kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32));
 	if (random) {
 		j = 0;
 		random_bytes = random32();
@@ -72,33 +71,33 @@
 				random_bytes = random32();
 			}
 			idx = (random_bytes >> (j * 2)) & 0xF;
-			__kfifo_put(*fifo,
+			__kfifo_put(fifo,
 				(unsigned char *) &rarray[idx],
 				sizeof(u32));
 			rarray[idx] = i;
 			j++;
 		}
 		for (i = 0; i < RANDOM_SIZE; i++)
-			__kfifo_put(*fifo,
+			__kfifo_put(fifo,
 				(unsigned char *) &rarray[i],
 				sizeof(u32));
 	} else
 		for (i = skip_low; i < nr - skip_high; i++)
-			__kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32));
+			__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
 	return 0;
 }
 
-static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock,
+static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock,
 				   u32 nr, u32 skip_low, u32 skip_high)
 {
 	return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
 					  skip_high, 0));
 }
 
-static int cxio_init_resource_fifo_random(struct kfifo **fifo,
+static int cxio_init_resource_fifo_random(struct kfifo *fifo,
 				   spinlock_t * fifo_lock,
 				   u32 nr, u32 skip_low, u32 skip_high)
 {
@@ -113,15 +112,14 @@
 
 	spin_lock_init(&rdev_p->rscp->qpid_fifo_lock);
 
-	rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32),
+	if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32),
 					      GFP_KERNEL,
-					      &rdev_p->rscp->qpid_fifo_lock);
-	if (IS_ERR(rdev_p->rscp->qpid_fifo))
+					      &rdev_p->rscp->qpid_fifo_lock))
 		return -ENOMEM;
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
 		if (!(i & rdev_p->qpmask))
-			__kfifo_put(rdev_p->rscp->qpid_fifo,
+			__kfifo_put(&rdev_p->rscp->qpid_fifo,
 				    (unsigned char *) &i, sizeof(u32));
 	return 0;
 }
@@ -134,7 +132,7 @@
 
 void cxio_hal_destroy_rhdl_resource(void)
 {
-	kfifo_free(rhdl_fifo);
+	kfifo_free(&rhdl_fifo);
 }
 
 /* nr_* must be power of 2 */
@@ -167,11 +165,11 @@
 		goto pdid_err;
 	return 0;
 pdid_err:
-	kfifo_free(rscp->cqid_fifo);
+	kfifo_free(&rscp->cqid_fifo);
 cqid_err:
-	kfifo_free(rscp->qpid_fifo);
+	kfifo_free(&rscp->qpid_fifo);
 qpid_err:
-	kfifo_free(rscp->tpt_fifo);
+	kfifo_free(&rscp->tpt_fifo);
 tpt_err:
 	return -ENOMEM;
 }
@@ -195,17 +193,17 @@
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->tpt_fifo);
+	return cxio_hal_get_resource(&rscp->tpt_fifo);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-	cxio_hal_put_resource(rscp->tpt_fifo, stag);
+	cxio_hal_put_resource(&rscp->tpt_fifo, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-	u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo);
+	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
 	return qpid;
 }
@@ -213,35 +211,35 @@
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
-	cxio_hal_put_resource(rscp->qpid_fifo, qpid);
+	cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->cqid_fifo);
+	return cxio_hal_get_resource(&rscp->cqid_fifo);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-	cxio_hal_put_resource(rscp->cqid_fifo, cqid);
+	cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(rscp->pdid_fifo);
+	return cxio_hal_get_resource(&rscp->pdid_fifo);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-	cxio_hal_put_resource(rscp->pdid_fifo, pdid);
+	cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
 {
-	kfifo_free(rscp->tpt_fifo);
-	kfifo_free(rscp->cqid_fifo);
-	kfifo_free(rscp->qpid_fifo);
-	kfifo_free(rscp->pdid_fifo);
+	kfifo_free(&rscp->tpt_fifo);
+	kfifo_free(&rscp->cqid_fifo);
+	kfifo_free(&rscp->qpid_fifo);
+	kfifo_free(&rscp->pdid_fifo);
 	kfree(rscp);
 }
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/media/video/meye.c linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c
--- linux-2.6.31-rc4-kfifo0/drivers/media/video/meye.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c	2009-08-16 21:14:20.000000000 +0200
@@ -799,7 +799,7 @@
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
+		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
 			      sizeof(int)) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
@@ -810,7 +810,7 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
 		wake_up_interruptible(&meye.proc_list);
 	} else {
 		int size;
@@ -819,7 +819,7 @@
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
+		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
 			      sizeof(int)) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
@@ -830,7 +830,7 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
 		wake_up_interruptible(&meye.proc_list);
 	}
 	mchip_free_frame();
@@ -858,8 +858,8 @@
 
 	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-	kfifo_reset(meye.grabq);
-	kfifo_reset(meye.doneq);
+	kfifo_reset(&meye.grabq);
+	kfifo_reset(&meye.doneq);
 	return 0;
 }
 
@@ -932,7 +932,7 @@
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
+	kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -964,7 +964,7 @@
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
+		kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
 	}
 	*i = meye.grab_buffer[*i].size;
 	mutex_unlock(&meye.lock);
@@ -1451,7 +1451,7 @@
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+	kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -1466,18 +1466,18 @@
 
 	mutex_lock(&meye.lock);
 
-	if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
+	if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
 		mutex_unlock(&meye.lock);
 		return -EAGAIN;
 	}
 
 	if (wait_event_interruptible(meye.proc_list,
-				     kfifo_len(meye.doneq) != 0) < 0) {
+				     kfifo_len(&meye.doneq) != 0) < 0) {
 		mutex_unlock(&meye.lock);
 		return -EINTR;
 	}
 
-	if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
+	if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
 		       sizeof(int))) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
@@ -1528,8 +1528,8 @@
 {
 	mutex_lock(&meye.lock);
 	mchip_hic_stop();
-	kfifo_reset(meye.grabq);
-	kfifo_reset(meye.doneq);
+	kfifo_reset(&meye.grabq);
+	kfifo_reset(&meye.doneq);
 
 	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
@@ -1571,7 +1571,7 @@
 
 	mutex_lock(&meye.lock);
 	poll_wait(file, &meye.proc_list, wait);
-	if (kfifo_len(meye.doneq))
+	if (kfifo_len(&meye.doneq))
 		res = POLLIN | POLLRDNORM;
 	mutex_unlock(&meye.lock);
 	return res;
@@ -1745,16 +1745,14 @@
 	}
 
 	spin_lock_init(&meye.grabq_lock);
-	meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.grabq_lock);
-	if (IS_ERR(meye.grabq)) {
+	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
+				 &meye.grabq_lock)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
 	spin_lock_init(&meye.doneq_lock);
-	meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.doneq_lock);
-	if (IS_ERR(meye.doneq)) {
+	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
+				 &meye.doneq_lock)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc2;
 	}
@@ -1868,9 +1866,9 @@
 outenabledev:
 	sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 outsonypienable:
-	kfifo_free(meye.doneq);
+	kfifo_free(&meye.doneq);
 outkfifoalloc2:
-	kfifo_free(meye.grabq);
+	kfifo_free(&meye.grabq);
 outkfifoalloc1:
 	vfree(meye.grab_temp);
 outvmalloc:
@@ -1901,8 +1899,8 @@
 
 	sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 
-	kfifo_free(meye.doneq);
-	kfifo_free(meye.grabq);
+	kfifo_free(&meye.doneq);
+	kfifo_free(&meye.grabq);
 
 	vfree(meye.grab_temp);
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/media/video/meye.h linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.h
--- linux-2.6.31-rc4-kfifo0/drivers/media/video/meye.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.h	2009-08-09 11:29:50.000000000 +0200
@@ -303,9 +303,9 @@
 	struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
 	int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
 	struct mutex lock;		/* mutex for open/mmap... */
-	struct kfifo *grabq;		/* queue for buffers to be grabbed */
+	struct kfifo grabq;		/* queue for buffers to be grabbed */
 	spinlock_t grabq_lock;		/* lock protecting the queue */
-	struct kfifo *doneq;		/* queue for grabbed buffers */
+	struct kfifo doneq;		/* queue for grabbed buffers */
 	spinlock_t doneq_lock;		/* lock protecting the queue */
 	wait_queue_head_t proc_list;	/* wait queue */
 	struct video_device *video_dev;	/* video device parameters */
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/cmd.c linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/cmd.c
--- linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/cmd.c	2009-07-24 20:36:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/cmd.c	2009-08-11 12:51:53.000000000 +0200
@@ -1862,7 +1862,7 @@
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
 	/* If nothing to do, go back to sleep (?) */
-	if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
+	if (!__kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
 		priv->psstate = PS_STATE_SLEEP;
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1936,7 +1936,7 @@
 	}
 
 	/* Pending events or command responses? */
-	if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
+	if (__kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
 		allowed = 0;
 		lbs_deb_host("pending events or command responses\n");
 	}
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/dev.h linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/dev.h
--- linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/dev.h	2009-07-24 20:36:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/dev.h	2009-08-09 16:07:09.000000000 +0200
@@ -10,6 +10,7 @@
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
+#include <linux/kfifo.h>
 
 #include "defs.h"
 #include "hostcmd.h"
@@ -194,7 +195,7 @@
 	u32 resp_len[2];
 
 	/* Events sent from hardware to driver */
-	struct kfifo *event_fifo;
+	struct kfifo event_fifo;
 
 	/* nickname */
 	u8 nodename[16];
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/main.c linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c
--- linux-2.6.31-rc4-kfifo0/drivers/net/wireless/libertas/main.c	2009-07-24 20:36:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c	2009-08-16 21:25:46.000000000 +0200
@@ -772,7 +772,7 @@
 			shouldsleep = 1;	/* Can't send a command; one already running */
 		else if (!list_empty(&priv->cmdpendingq))
 			shouldsleep = 0;	/* We have a command to send */
-		else if (__kfifo_len(priv->event_fifo))
+		else if (__kfifo_len(&priv->event_fifo))
 			shouldsleep = 0;	/* We have an event to process */
 		else
 			shouldsleep = 1;	/* No command */
@@ -851,10 +851,10 @@
 
 		/* Process hardware events, e.g. card removed, link lost */
 		spin_lock_irq(&priv->driver_lock);
-		while (__kfifo_len(priv->event_fifo)) {
+		while (__kfifo_len(&priv->event_fifo)) {
 			u32 event;
 
-			__kfifo_get(priv->event_fifo, (unsigned char *) &event,
+			__kfifo_get(&priv->event_fifo, (unsigned char *) &event,
 				sizeof(event));
 			spin_unlock_irq(&priv->driver_lock);
 			lbs_process_event(priv, event);
@@ -1121,10 +1121,9 @@
 	priv->resp_len[0] = priv->resp_len[1] = 0;
 
 	/* Create the event FIFO */
-	priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL);
-	if (IS_ERR(priv->event_fifo)) {
+	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL);
+	if (ret) {
 		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
-		ret = -ENOMEM;
 		goto out;
 	}
 
@@ -1139,8 +1138,7 @@
 	lbs_deb_enter(LBS_DEB_MAIN);
 
 	lbs_free_cmd_buffer(priv);
-	if (priv->event_fifo)
-		kfifo_free(priv->event_fifo);
+	kfifo_free(&priv->event_fifo);
 	del_timer(&priv->command_timer);
 	kfree(priv->networks);
 	priv->networks = NULL;
@@ -1580,7 +1578,7 @@
 	if (priv->psstate == PS_STATE_SLEEP)
 		priv->psstate = PS_STATE_AWAKE;
 
-	__kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32));
+	__kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
 	wake_up_interruptible(&priv->waitq);
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/platform/x86/fujitsu-laptop.c linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c
--- linux-2.6.31-rc4-kfifo0/drivers/platform/x86/fujitsu-laptop.c	2009-08-11 22:46:59.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c	2009-08-16 21:01:06.000000000 +0200
@@ -164,7 +164,7 @@
 	struct input_dev *input;
 	char phys[32];
 	struct platform_device *pf_device;
-	struct kfifo *fifo;
+	struct kfifo fifo;
 	spinlock_t fifo_lock;
 	int rfkill_supported;
 	int rfkill_state;
@@ -833,12 +833,10 @@
 
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
-	fujitsu_hotkey->fifo =
-	    kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
-			&fujitsu_hotkey->fifo_lock);
-	if (IS_ERR(fujitsu_hotkey->fifo)) {
+	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
+			GFP_KERNEL, &fujitsu_hotkey->fifo_lock);
+	if (error) {
 		printk(KERN_ERR "kfifo_alloc failed\n");
-		error = PTR_ERR(fujitsu_hotkey->fifo);
 		goto err_stop;
 	}
 
@@ -942,7 +940,7 @@
 err_free_input_dev:
 	input_free_device(input);
 err_free_fifo:
-	kfifo_free(fujitsu_hotkey->fifo);
+	kfifo_free(&fujitsu_hotkey->fifo);
 err_stop:
 
 	return result;
@@ -959,7 +957,7 @@
 
 	fujitsu_hotkey->acpi_handle = NULL;
 
-	kfifo_free(fujitsu_hotkey->fifo);
+	kfifo_free(&fujitsu_hotkey->fifo);
 
 	return 0;
 }
@@ -1009,7 +1007,7 @@
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put(fujitsu_hotkey->fifo,
+				status = kfifo_put(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
 						   sizeof(keycode));
 				if (status != sizeof(keycode)) {
@@ -1023,7 +1021,7 @@
 			} else if (keycode == 0) {
 				while ((status =
 					kfifo_get
-					(fujitsu_hotkey->fifo, (unsigned char *)
+					(&fujitsu_hotkey->fifo, (unsigned char *)
 					 &keycode_r,
 					 sizeof
 					 (keycode_r))) == sizeof(keycode_r)) {
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/platform/x86/sony-laptop.c linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c
--- linux-2.6.31-rc4-kfifo0/drivers/platform/x86/sony-laptop.c	2009-07-24 20:36:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c	2009-08-16 21:11:55.000000000 +0200
@@ -142,7 +142,7 @@
 	atomic_t		users;
 	struct input_dev	*jog_dev;
 	struct input_dev	*key_dev;
-	struct kfifo		*fifo;
+	struct kfifo		fifo;
 	spinlock_t		fifo_lock;
 	struct workqueue_struct	*wq;
 };
@@ -300,7 +300,7 @@
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp,
+	while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp,
 			 sizeof(kp)) == sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
@@ -362,7 +362,7 @@
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put(sony_laptop_input.fifo,
+		kfifo_put(&sony_laptop_input.fifo,
 			  (unsigned char *)&kp, sizeof(kp));
 
 		if (!work_pending(&sony_laptop_release_key_work))
@@ -385,12 +385,11 @@
 
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
-	sony_laptop_input.fifo =
-		kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
+	error =
+	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
 			    &sony_laptop_input.fifo_lock);
-	if (IS_ERR(sony_laptop_input.fifo)) {
+	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-		error = PTR_ERR(sony_laptop_input.fifo);
 		goto err_dec_users;
 	}
 
@@ -474,7 +473,7 @@
 	destroy_workqueue(sony_laptop_input.wq);
 
 err_free_kfifo:
-	kfifo_free(sony_laptop_input.fifo);
+	kfifo_free(&sony_laptop_input.fifo);
 
 err_dec_users:
 	atomic_dec(&sony_laptop_input.users);
@@ -500,7 +499,7 @@
 	}
 
 	destroy_workqueue(sony_laptop_input.wq);
-	kfifo_free(sony_laptop_input.fifo);
+	kfifo_free(&sony_laptop_input.fifo);
 }
 
 /*********** Platform Device ***********/
@@ -2093,7 +2092,7 @@
 
 struct sonypi_compat_s {
 	struct fasync_struct	*fifo_async;
-	struct kfifo		*fifo;
+	struct kfifo		fifo;
 	spinlock_t		fifo_lock;
 	wait_queue_head_t	fifo_proc_list;
 	atomic_t		open_count;
@@ -2118,12 +2117,12 @@
 	/* Flush input queue on first open */
 	unsigned long flags;
 
-	spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+	spin_lock_irqsave(&sonypi_compat.fifo_lock, flags);
 
 	if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-		__kfifo_reset(sonypi_compat.fifo);
+		__kfifo_reset(&sonypi_compat.fifo);
 
-	spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+	spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags);
 
 	return 0;
 }
@@ -2134,17 +2133,17 @@
 	ssize_t ret;
 	unsigned char c;
 
-	if ((kfifo_len(sonypi_compat.fifo) == 0) &&
+	if ((kfifo_len(&sonypi_compat.fifo) == 0) &&
 	    (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	ret = wait_event_interruptible(sonypi_compat.fifo_proc_list,
-				       kfifo_len(sonypi_compat.fifo) != 0);
+				       kfifo_len(&sonypi_compat.fifo) != 0);
 	if (ret)
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -2161,7 +2160,7 @@
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &sonypi_compat.fifo_proc_list, wait);
-	if (kfifo_len(sonypi_compat.fifo))
+	if (kfifo_len(&sonypi_compat.fifo))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -2323,7 +2322,7 @@
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2333,11 +2332,12 @@
 	int error;
 
 	spin_lock_init(&sonypi_compat.fifo_lock);
-	sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
+	error =
+	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
 					 &sonypi_compat.fifo_lock);
-	if (IS_ERR(sonypi_compat.fifo)) {
+	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-		return PTR_ERR(sonypi_compat.fifo);
+		return error;
 	}
 
 	init_waitqueue_head(&sonypi_compat.fifo_proc_list);
@@ -2356,14 +2356,14 @@
 	return 0;
 
 err_free_kfifo:
-	kfifo_free(sonypi_compat.fifo);
+	kfifo_free(&sonypi_compat.fifo);
 	return error;
 }
 
 static void sonypi_compat_exit(void)
 {
 	misc_deregister(&sonypi_misc_device);
-	kfifo_free(sonypi_compat.fifo);
+	kfifo_free(&sonypi_compat.fifo);
 }
 #else
 static int sonypi_compat_init(void) { return 0; }
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/scsi/libiscsi.c linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c
--- linux-2.6.31-rc4-kfifo0/drivers/scsi/libiscsi.c	2009-07-24 20:36:36.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c	2009-08-16 21:29:03.000000000 +0200
@@ -428,7 +428,7 @@
 	if (conn->login_task == task)
 		return;
 
-	__kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*));
+	__kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*));
 
 	if (sc) {
 		task->sc = NULL;
@@ -614,7 +614,7 @@
 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
 
-		if (!__kfifo_get(session->cmdpool.queue,
+		if (!__kfifo_get(&session->cmdpool.queue,
 				 (void*)&task, sizeof(void*)))
 			return NULL;
 	}
@@ -1376,7 +1376,7 @@
 {
 	struct iscsi_task *task;
 
-	if (!__kfifo_get(conn->session->cmdpool.queue,
+	if (!__kfifo_get(&conn->session->cmdpool.queue,
 			 (void *) &task, sizeof(void *)))
 		return NULL;
 
@@ -2121,12 +2121,7 @@
 	if (q->pool == NULL)
 		return -ENOMEM;
 
-	q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
-			      GFP_KERNEL, NULL);
-	if (IS_ERR(q->queue)) {
-		q->queue = NULL;
-		goto enomem;
-	}
+	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL);
 
 	for (i = 0; i < max; i++) {
 		q->pool[i] = kzalloc(item_size, GFP_KERNEL);
@@ -2134,7 +2129,7 @@
 			q->max = i;
 			goto enomem;
 		}
-		__kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
+		__kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*));
 	}
 
 	if (items) {
@@ -2157,7 +2152,6 @@
 	for (i = 0; i < q->max; i++)
 		kfree(q->pool[i]);
 	kfree(q->pool);
-	kfree(q->queue);
 }
 EXPORT_SYMBOL_GPL(iscsi_pool_free);
 
@@ -2482,7 +2476,7 @@
 
 	/* allocate login_task used for the login/text sequences */
 	spin_lock_bh(&session->lock);
-	if (!__kfifo_get(session->cmdpool.queue,
+	if (!__kfifo_get(&session->cmdpool.queue,
                          (void*)&conn->login_task,
 			 sizeof(void*))) {
 		spin_unlock_bh(&session->lock);
@@ -2502,7 +2496,7 @@
 	return cls_conn;
 
 login_task_data_alloc_fail:
-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+	__kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 login_task_alloc_fail:
 	iscsi_destroy_conn(cls_conn);
@@ -2565,7 +2559,7 @@
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
-	__kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+	__kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/scsi/libiscsi_tcp.c linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c
--- linux-2.6.31-rc4-kfifo0/drivers/scsi/libiscsi_tcp.c	2009-07-24 20:36:36.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c	2009-08-16 21:24:53.000000000 +0200
@@ -445,15 +445,15 @@
 		return;
 
 	/* flush task's r2t queues */
-	while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+	while (__kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
 	}
 
 	r2t = tcp_task->r2t;
 	if (r2t != NULL) {
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		tcp_task->r2t = NULL;
 	}
@@ -541,7 +541,7 @@
 		return 0;
 	}
 
-	rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
+	rc = __kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
@@ -554,7 +554,7 @@
 	if (r2t->data_length == 0) {
 		iscsi_conn_printk(KERN_ERR, conn,
 				  "invalid R2T with zero data len\n");
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -570,7 +570,7 @@
 				  "invalid R2T with data len %u at offset %u "
 				  "and total length %d\n", r2t->data_length,
 				  r2t->data_offset, scsi_out(task->sc)->length);
-		__kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -580,7 +580,7 @@
 	r2t->sent = 0;
 
 	tcp_task->exp_datasn = r2tsn + 1;
-	__kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
+	__kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
 	conn->r2t_pdus_cnt++;
 
 	iscsi_requeue_task(task);
@@ -951,7 +951,7 @@
 		return conn->session->tt->init_pdu(task, 0, task->data_count);
 	}
 
-	BUG_ON(__kfifo_len(tcp_task->r2tqueue));
+	BUG_ON(__kfifo_len(&tcp_task->r2tqueue));
 	tcp_task->exp_datasn = 0;
 
 	/* Prepare PDU, optionally w/ immediate data */
@@ -982,7 +982,7 @@
 			if (r2t->data_length <= r2t->sent) {
 				ISCSI_DBG_TCP(task->conn,
 					      "  done with r2t %p\n", r2t);
-				__kfifo_put(tcp_task->r2tpool.queue,
+				__kfifo_put(&tcp_task->r2tpool.queue,
 					    (void *)&tcp_task->r2t,
 					    sizeof(void *));
 				tcp_task->r2t = r2t = NULL;
@@ -990,7 +990,7 @@
 		}
 
 		if (r2t == NULL) {
-			__kfifo_get(tcp_task->r2tqueue,
+			__kfifo_get(&tcp_task->r2tqueue,
 				    (void *)&tcp_task->r2t, sizeof(void *));
 			r2t = tcp_task->r2t;
 		}
@@ -1127,9 +1127,8 @@
 		}
 
 		/* R2T xmit queue */
-		tcp_task->r2tqueue = kfifo_alloc(
-		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
-		if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) {
+		if (kfifo_alloc(&tcp_task->r2tqueue,
+		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) {
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
@@ -1142,7 +1141,7 @@
 		struct iscsi_task *task = session->cmds[i];
 		struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-		kfifo_free(tcp_task->r2tqueue);
+		kfifo_free(&tcp_task->r2tqueue);
 		iscsi_pool_free(&tcp_task->r2tpool);
 	}
 	return -ENOMEM;
@@ -1157,7 +1156,7 @@
 		struct iscsi_task *task = session->cmds[i];
 		struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-		kfifo_free(tcp_task->r2tqueue);
+		kfifo_free(&tcp_task->r2tqueue);
 		iscsi_pool_free(&tcp_task->r2tpool);
 	}
 }
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/scsi/libsrp.c linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c
--- linux-2.6.31-rc4-kfifo0/drivers/scsi/libsrp.c	2009-07-24 20:36:36.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c	2009-08-16 21:29:13.000000000 +0200
@@ -58,13 +58,11 @@
 		goto free_pool;
 
 	spin_lock_init(&q->lock);
-	q->queue = kfifo_init((void *) q->pool, max * sizeof(void *),
-			      GFP_KERNEL, &q->lock);
-	if (IS_ERR(q->queue))
-		goto free_item;
+	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *),
+			      &q->lock);
 
 	for (i = 0, iue = q->items; i < max; i++) {
-		__kfifo_put(q->queue, (void *) &iue, sizeof(void *));
+		__kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
 		iue->sbuf = ring[i];
 		iue++;
 	}
@@ -166,7 +164,7 @@
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *));
 	if (!iue)
 		return iue;
 	iue->target = target;
@@ -178,7 +176,7 @@
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci.h linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h
--- linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci.h	2009-08-09 15:04:56.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h	2009-08-16 21:25:35.000000000 +0200
@@ -423,9 +423,9 @@
 	struct usb_td __iomem *td_base; /* first TD in the ring */
 	struct usb_td __iomem *conf_td; /* next TD for confirm after transac */
 	struct usb_td __iomem *empty_td;/* next TD for new transaction req. */
-	struct kfifo *empty_frame_Q;  /* Empty frames list to use */
-	struct kfifo *conf_frame_Q;   /* frames passed to TDs,waiting for tx */
-	struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */
+	struct kfifo empty_frame_Q;  /* Empty frames list to use */
+	struct kfifo conf_frame_Q;   /* frames passed to TDs,waiting for tx */
+	struct kfifo dummy_packets_Q;/* dummy packets for the CRC overun */
 
 	bool already_pushed_dummy_bd;
 };
@@ -493,9 +493,9 @@
 }
 
 /* fifo of pointers */
-static inline struct kfifo *cq_new(int size)
+static inline int cq_new(struct kfifo *fifo, int size)
 {
-	return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL);
+	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci-sched.c linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci-sched.c
--- linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci-sched.c	2009-08-09 15:04:51.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci-sched.c	2009-08-09 15:07:58.000000000 +0200
@@ -37,7 +37,7 @@
 	pkt->info = 0;
 	pkt->priv_data = NULL;
 
-	cq_put(usb->ep0->empty_frame_Q, pkt);
+	cq_put(&usb->ep0->empty_frame_Q, pkt);
 }
 
 /* confirm submitted packet */
@@ -57,7 +57,7 @@
 		if ((td->data + td->actual_len) && trans_len)
 			memcpy(td->data + td->actual_len, pkt->data,
 			       trans_len);
-		cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+		cq_put(&usb->ep0->dummy_packets_Q, pkt->data);
 	}
 
 	recycle_frame(usb, pkt);
@@ -213,7 +213,7 @@
 	}
 
 	/* update frame object fields before transmitting */
-	pkt = cq_get(usb->ep0->empty_frame_Q);
+	pkt = cq_get(&usb->ep0->empty_frame_Q);
 	if (!pkt) {
 		fhci_dbg(usb->fhci, "there is no empty frame\n");
 		return -1;
@@ -222,7 +222,7 @@
 
 	pkt->info = 0;
 	if (data == NULL) {
-		data = cq_get(usb->ep0->dummy_packets_Q);
+		data = cq_get(&usb->ep0->dummy_packets_Q);
 		BUG_ON(!data);
 		pkt->info = PKT_DUMMY_PACKET;
 	}
@@ -246,7 +246,7 @@
 		list_del_init(&td->frame_lh);
 		td->status = USB_TD_OK;
 		if (pkt->info & PKT_DUMMY_PACKET)
-			cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+			cq_put(&usb->ep0->dummy_packets_Q, pkt->data);
 		recycle_frame(usb, pkt);
 		usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD);
 		fhci_err(usb->fhci, "host transaction failed\n");
diff -u -N -r linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci-tds.c linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci-tds.c
--- linux-2.6.31-rc4-kfifo0/drivers/usb/host/fhci-tds.c	2009-08-09 15:04:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci-tds.c	2009-08-09 15:11:22.000000000 +0200
@@ -106,33 +106,33 @@
 			cpm_muram_free(cpm_muram_offset(ep->td_base));
 
 		if (ep->conf_frame_Q) {
-			size = cq_howmany(ep->conf_frame_Q);
+			size = cq_howmany(&ep->conf_frame_Q);
 			for (; size; size--) {
-				struct packet *pkt = cq_get(ep->conf_frame_Q);
+				struct packet *pkt = cq_get(&ep->conf_frame_Q);
 
 				kfree(pkt);
 			}
-			cq_delete(ep->conf_frame_Q);
+			cq_delete(&ep->conf_frame_Q);
 		}
 
 		if (ep->empty_frame_Q) {
-			size = cq_howmany(ep->empty_frame_Q);
+			size = cq_howmany(&ep->empty_frame_Q);
 			for (; size; size--) {
-				struct packet *pkt = cq_get(ep->empty_frame_Q);
+				struct packet *pkt = cq_get(&ep->empty_frame_Q);
 
 				kfree(pkt);
 			}
-			cq_delete(ep->empty_frame_Q);
+			cq_delete(&ep->empty_frame_Q);
 		}
 
 		if (ep->dummy_packets_Q) {
-			size = cq_howmany(ep->dummy_packets_Q);
+			size = cq_howmany(&ep->dummy_packets_Q);
 			for (; size; size--) {
-				u8 *buff = cq_get(ep->dummy_packets_Q);
+				u8 *buff = cq_get(&ep->dummy_packets_Q);
 
 				kfree(buff);
 			}
-			cq_delete(ep->dummy_packets_Q);
+			cq_delete(&ep->dummy_packets_Q);
 		}
 
 		kfree(ep);
@@ -175,10 +175,9 @@
 	ep->td_base = cpm_muram_addr(ep_offset);
 
 	/* zero all queue pointers */
-	ep->conf_frame_Q = cq_new(ring_len + 2);
-	ep->empty_frame_Q = cq_new(ring_len + 2);
-	ep->dummy_packets_Q = cq_new(ring_len + 2);
-	if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) {
+	if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
+	    cq_new(&ep->empty_frame_Q, ring_len + 2) ||
+	    cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
 		err_for = "frame_queues";
 		goto err;
 	}
@@ -199,8 +198,8 @@
 			err_for = "buffer";
 			goto err;
 		}
-		cq_put(ep->empty_frame_Q, pkt);
-		cq_put(ep->dummy_packets_Q, buff);
+		cq_put(&ep->empty_frame_Q, pkt);
+		cq_put(&ep->dummy_packets_Q, buff);
 	}
 
 	/* we put the endpoint parameter RAM right behind the TD ring */
@@ -319,7 +318,7 @@
 		if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
 			continue;
 
-		pkt = cq_get(ep->conf_frame_Q);
+		pkt = cq_get(&ep->conf_frame_Q);
 		if (!pkt)
 			fhci_err(usb->fhci, "no frame to confirm\n");
 
@@ -460,9 +459,9 @@
 		out_be16(&td->length, pkt->len);
 
 	/* put the frame to the confirmation queue */
-	cq_put(ep->conf_frame_Q, pkt);
+	cq_put(&ep->conf_frame_Q, pkt);
 
-	if (cq_howmany(ep->conf_frame_Q) == 1)
+	if (cq_howmany(&ep->conf_frame_Q) == 1)
 		out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
 
 	return 0;
diff -u -N -r linux-2.6.31-rc4-kfifo0/include/linux/kfifo.h linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo0/include/linux/kfifo.h	2009-08-14 09:43:52.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h	2009-08-16 22:14:30.000000000 +0200
@@ -1,6 +1,7 @@
 /*
- * A simple kernel FIFO implementation.
+ * A generic kernel FIFO implementation.
  *
+ * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net>
  * Copyright (C) 2004 Stelian Pop <stelian@popies.net>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -32,10 +33,10 @@
 	spinlock_t *lock;	/* protects concurrent modifications */
 };
 
-extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
-				gfp_t gfp_mask, spinlock_t *lock);
-extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask,
-				 spinlock_t *lock);
+extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
+			unsigned int size, spinlock_t *lock);
+extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
+			gfp_t gfp_mask, spinlock_t *lock);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
 				const unsigned char *buffer, unsigned int len);
diff -u -N -r linux-2.6.31-rc4-kfifo0/include/scsi/libiscsi.h linux-2.6.31-rc4-kfifo1/include/scsi/libiscsi.h
--- linux-2.6.31-rc4-kfifo0/include/scsi/libiscsi.h	2009-07-24 20:36:39.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/include/scsi/libiscsi.h	2009-08-09 15:51:58.000000000 +0200
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
+#include <linux/kfifo.h>
 #include <scsi/iscsi_proto.h>
 #include <scsi/iscsi_if.h>
 #include <scsi/scsi_transport_iscsi.h>
@@ -231,7 +232,7 @@
 };
 
 struct iscsi_pool {
-	struct kfifo		*queue;		/* FIFO Queue */
+	struct kfifo		queue;		/* FIFO Queue */
 	void			**pool;		/* Pool of elements */
 	int			max;		/* Max number of elements */
 };
diff -u -N -r linux-2.6.31-rc4-kfifo0/include/scsi/libiscsi_tcp.h linux-2.6.31-rc4-kfifo1/include/scsi/libiscsi_tcp.h
--- linux-2.6.31-rc4-kfifo0/include/scsi/libiscsi_tcp.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/include/scsi/libiscsi_tcp.h	2009-08-09 12:15:46.000000000 +0200
@@ -80,7 +80,7 @@
 	int			data_offset;
 	struct iscsi_r2t_info	*r2t;		/* in progress solict R2T */
 	struct iscsi_pool	r2tpool;
-	struct kfifo		*r2tqueue;
+	struct kfifo		r2tqueue;
 	void			*dd_data;
 };
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/include/scsi/libsrp.h linux-2.6.31-rc4-kfifo1/include/scsi/libsrp.h
--- linux-2.6.31-rc4-kfifo0/include/scsi/libsrp.h	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/include/scsi/libsrp.h	2009-08-09 12:15:39.000000000 +0200
@@ -21,7 +21,7 @@
 struct srp_queue {
 	void *pool;
 	void *items;
-	struct kfifo *queue;
+	struct kfifo queue;
 	spinlock_t lock;
 };
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/kernel/kfifo.c linux-2.6.31-rc4-kfifo1/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo0/kernel/kfifo.c	2009-08-14 09:45:44.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/kernel/kfifo.c	2009-08-16 21:34:51.000000000 +0200
@@ -1,6 +1,7 @@
 /*
- * A simple kernel FIFO implementation.
+ * A generic kernel FIFO implementation.
  *
+ * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net>
  * Copyright (C) 2004 Stelian Pop <stelian@popies.net>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -26,49 +27,51 @@
 #include <linux/kfifo.h>
 #include <linux/log2.h>
 
+static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
+		unsigned int size, spinlock_t *lock)
+{
+	fifo->buffer = buffer;
+	fifo->size = size;
+	fifo->lock = lock;
+
+	kfifo_reset(fifo);
+}
+
 /**
- * kfifo_init - allocates a new FIFO using a preallocated buffer
+ * 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.
- * @gfp_mask: get_free_pages mask, passed to kmalloc()
  * @lock: the lock to be used to protect the fifo buffer
  *
- * Do NOT pass the kfifo to kfifo_free() after use! Simply free the
- * &struct kfifo with kfree().
  */
-struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
-			 gfp_t gfp_mask, spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size,
+			spinlock_t *lock)
 {
-	struct kfifo *fifo;
-
 	/* size must be a power of 2 */
 	BUG_ON(!is_power_of_2(size));
 
-	fifo = kmalloc(sizeof(struct kfifo), gfp_mask);
-	if (!fifo)
-		return ERR_PTR(-ENOMEM);
-
-	fifo->buffer = buffer;
-	fifo->size = size;
-	fifo->in = fifo->out = 0;
-	fifo->lock = lock;
-
-	return fifo;
+	_kfifo_init(fifo, buffer, size, lock);
 }
 EXPORT_SYMBOL(kfifo_init);
 
 /**
- * kfifo_alloc - allocates a new FIFO and its internal buffer
- * @size: the size of the internal buffer to be allocated.
+ * kfifo_alloc - allocates a new FIFO internal buffer
+ * @fifo: the fifo to assign then new buffer
+ * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
  * @lock: the lock to be used to protect the fifo buffer
  *
+ * This function dynamically allocates a new fifo internal buffer
+ *
  * The size will be rounded-up to a power of 2.
+ * The buffer will be release with kfifo_free().
+ * Return 0 if no error, otherwise the an error code
  */
-struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask,
+			spinlock_t *lock)
 {
 	unsigned char *buffer;
-	struct kfifo *ret;
 
 	/*
 	 * round up to the next power of 2, since our 'let the indices
@@ -80,26 +83,24 @@
 	}
 
 	buffer = kmalloc(size, gfp_mask);
-	if (!buffer)
-		return ERR_PTR(-ENOMEM);
-
-	ret = kfifo_init(buffer, size, gfp_mask, lock);
+	if (!buffer) {
+		_kfifo_init(fifo, 0, 0, NULL);
+		return -ENOMEM;
+	}
 
-	if (IS_ERR(ret))
-		kfree(buffer);
+	_kfifo_init(fifo, buffer, size, lock);
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(kfifo_alloc);
 
 /**
- * kfifo_free - frees the FIFO
+ * kfifo_free - frees the FIFO internal buffer
  * @fifo: the fifo to be freed.
  */
 void kfifo_free(struct kfifo *fifo)
 {
 	kfree(fifo->buffer);
-	kfree(fifo);
 }
 EXPORT_SYMBOL(kfifo_free);
 
diff -u -N -r linux-2.6.31-rc4-kfifo0/net/dccp/probe.c linux-2.6.31-rc4-kfifo1/net/dccp/probe.c
--- linux-2.6.31-rc4-kfifo0/net/dccp/probe.c	2009-06-10 05:05:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo1/net/dccp/probe.c	2009-08-16 21:24:04.000000000 +0200
@@ -43,7 +43,7 @@
 static const char procname[] = "dccpprobe";
 
 static struct {
-	struct kfifo	  *fifo;
+	struct kfifo	  fifo;
 	spinlock_t	  lock;
 	wait_queue_head_t wait;
 	struct timespec	  tstart;
@@ -67,7 +67,7 @@
 	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
 	va_end(args);
 
-	kfifo_put(dccpw.fifo, tbuf, len);
+	kfifo_put(&dccpw.fifo, tbuf, len);
 	wake_up(&dccpw.wait);
 }
 
@@ -110,7 +110,7 @@
 
 static int dccpprobe_open(struct inode *inode, struct file *file)
 {
-	kfifo_reset(dccpw.fifo);
+	kfifo_reset(&dccpw.fifo);
 	getnstimeofday(&dccpw.tstart);
 	return 0;
 }
@@ -132,11 +132,11 @@
 		return -ENOMEM;
 
 	error = wait_event_interruptible(dccpw.wait,
-					 __kfifo_len(dccpw.fifo) != 0);
+					 __kfifo_len(&dccpw.fifo) != 0);
 	if (error)
 		goto out_free;
 
-	cnt = kfifo_get(dccpw.fifo, tbuf, len);
+	cnt = kfifo_get(&dccpw.fifo, tbuf, len);
 	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -157,10 +157,8 @@
 
 	init_waitqueue_head(&dccpw.wait);
 	spin_lock_init(&dccpw.lock);
-	dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock);
-	if (IS_ERR(dccpw.fifo))
-		return PTR_ERR(dccpw.fifo);
-
+	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock))
+		return ret;
 	if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
 		goto err0;
 
@@ -173,14 +171,14 @@
 err1:
 	proc_net_remove(&init_net, procname);
 err0:
-	kfifo_free(dccpw.fifo);
+	kfifo_free(&dccpw.fifo);
 	return ret;
 }
 module_init(dccpprobe_init);
 
 static __exit void dccpprobe_exit(void)
 {
-	kfifo_free(dccpw.fifo);
+	kfifo_free(&dccpw.fifo);
 	proc_net_remove(&init_net, procname);
 	unregister_jprobe(&dccp_send_probe);
 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
  2009-08-16 20:44 ` [PATCH 1/7] kfifo: move struct kfifo in place Stefani Seibold
@ 2009-08-16 20:46 ` Stefani Seibold
  2009-08-16 22:58   ` Alan Cox
  2009-08-16 20:50 ` [PATCH 3/7] kfifo: cleanup namespace Stefani Seibold
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

Move the pointer to the spinlock out of struct kfifo. Most
users in tree do not actually use a spinlock, so the few
exceptions now have to call kfifo_{get,put}_locked, which takes
an extra argument to a spinlock.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 drivers/char/nozomi.c                       |    2 
 drivers/char/sonypi.c                       |   21 ++++---
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   36 +++++++------
 drivers/media/video/meye.c                  |   35 +++++++-----
 drivers/net/wireless/libertas/main.c        |    2 
 drivers/platform/x86/fujitsu-laptop.c       |   18 +++---
 drivers/platform/x86/sony-laptop.c          |   22 ++++----
 drivers/scsi/libiscsi.c                     |    2 
 drivers/scsi/libiscsi_tcp.c                 |    2 
 drivers/scsi/libsrp.c                       |    9 +--
 drivers/usb/host/fhci.h                     |    2 
 include/linux/kfifo.h                       |   76 ++++++++++++----------------
 kernel/kfifo.c                              |   17 ++----
 net/dccp/probe.c                            |    6 +-
 14 files changed, 126 insertions(+), 124 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c
--- linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c	2009-08-16 21:25:14.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c	2009-08-11 12:46:56.000000000 +0200
@@ -685,7 +685,7 @@
 
 		for (i = PORT_MDM; i < MAX_PORT; i++) {
 			kfifo_alloc(&dc->port[i].fifo_ul,
-				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
+				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC);
 			memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
 			memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c linux-2.6.31-rc4-kfifo2/drivers/char/sonypi.c
--- linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c	2009-08-16 21:22:46.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/char/sonypi.c	2009-08-11 12:56:44.000000000 +0200
@@ -776,8 +776,9 @@
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+			 sizeof(kp), &sonypi_device.input_fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -826,8 +827,9 @@
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put(&sonypi_device.input_fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sonypi_device.input_fifo,
+			(unsigned char *)&kp, sizeof(kp),
+			&sonypi_device.input_fifo_lock);
 		schedule_work(&sonypi_device.input_work);
 	}
 }
@@ -879,7 +881,8 @@
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_device.fifo_lock);
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -928,7 +931,8 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c),
+				 &sonypi_device.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -1312,8 +1316,7 @@
 			"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,
-					 &sonypi_device.fifo_lock);
+	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 		return error;
@@ -1393,7 +1396,7 @@
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
 		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
-				GFP_KERNEL, &sonypi_device.input_fifo_lock);
+				GFP_KERNEL);
 		if (error) {
 			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 			goto err_inpdev_unregister;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-16 21:20:12.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 12:47:57.000000000 +0200
@@ -55,7 +55,7 @@
 	u32 rarray[16];
 	spin_lock_init(fifo_lock);
 
-	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
+	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
@@ -86,7 +86,8 @@
 			__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_get_locked(fifo, (unsigned char *) &entry,
+				sizeof(u32), fifo_lock);
 	return 0;
 }
 
@@ -113,8 +114,7 @@
 	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,
-					      &rdev_p->rscp->qpid_fifo_lock))
+					      GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
@@ -177,33 +177,37 @@
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
 	u32 entry;
-	if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+	if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
 		return entry;
 	else
 		return 0;	/* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+		u32 entry)
 {
-	BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+	BUG_ON(
+	kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+	== 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->tpt_fifo);
+	return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-	cxio_hal_put_resource(&rscp->tpt_fifo, stag);
+	cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
+	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+			&rscp->qpid_fifo_lock);
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
 	return qpid;
 }
@@ -211,27 +215,27 @@
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
-	cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
+	cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->cqid_fifo);
+	return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-	cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
+	cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->pdid_fifo);
+	return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-	cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
+	cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c linux-2.6.31-rc4-kfifo2/drivers/media/video/meye.c
--- linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c	2009-08-16 21:14:20.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/media/video/meye.c	2009-08-09 11:40:34.000000000 +0200
@@ -799,8 +799,8 @@
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
 		}
@@ -810,7 +810,8 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	} else {
 		int size;
@@ -819,8 +820,8 @@
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
 		}
@@ -830,7 +831,8 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	}
 	mchip_free_frame();
@@ -932,7 +934,8 @@
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+			 &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -964,7 +967,8 @@
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
+		kfifo_get_locked(&meye.doneq, (unsigned char *)&unused,
+				sizeof(int), &meye.doneq_lock);
 	}
 	*i = meye.grab_buffer[*i].size;
 	mutex_unlock(&meye.lock);
@@ -1451,7 +1455,8 @@
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index,
+			sizeof(int), &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -1477,8 +1482,8 @@
 		return -EINTR;
 	}
 
-	if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
-		       sizeof(int))) {
+	if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr,
+		       sizeof(int), &meye.doneq_lock)) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
 	}
@@ -1745,14 +1750,14 @@
 	}
 
 	spin_lock_init(&meye.grabq_lock);
-	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.grabq_lock)) {
+	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
 	spin_lock_init(&meye.doneq_lock);
-	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.doneq_lock)) {
+	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc2;
 	}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c
--- linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c	2009-08-16 21:25:46.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c	2009-08-11 12:45:53.000000000 +0200
@@ -1121,7 +1121,7 @@
 	priv->resp_len[0] = priv->resp_len[1] = 0;
 
 	/* Create the event FIFO */
-	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL);
+	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
 	if (ret) {
 		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
 		goto out;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c linux-2.6.31-rc4-kfifo2/drivers/platform/x86/fujitsu-laptop.c
--- linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c	2009-08-16 21:01:06.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/platform/x86/fujitsu-laptop.c	2009-08-11 22:46:08.000000000 +0200
@@ -834,7 +834,7 @@
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
 	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
-			GFP_KERNEL, &fujitsu_hotkey->fifo_lock);
+			GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "kfifo_alloc failed\n");
 		goto err_stop;
@@ -1007,9 +1007,10 @@
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put(&fujitsu_hotkey->fifo,
+				status = kfifo_put_locked(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
-						   sizeof(keycode));
+						   sizeof(keycode),
+						   &fujitsu_hotkey->fifo_lock);
 				if (status != sizeof(keycode)) {
 					vdbg_printk(FUJLAPTOP_DBG_WARN,
 					    "Could not push keycode [0x%x]\n",
@@ -1020,11 +1021,12 @@
 				}
 			} else if (keycode == 0) {
 				while ((status =
-					kfifo_get
-					(&fujitsu_hotkey->fifo, (unsigned char *)
-					 &keycode_r,
-					 sizeof
-					 (keycode_r))) == sizeof(keycode_r)) {
+					kfifo_get_locked(
+					 &fujitsu_hotkey->fifo,
+					 (unsigned char *) &keycode_r,
+					 sizeof(keycode_r),
+					 &fujitsu_hotkey->fifo_lock))
+					 == sizeof(keycode_r)) {
 					input_report_key(input, keycode_r, 0);
 					input_sync(input);
 					vdbg_printk(FUJLAPTOP_DBG_TRACE,
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c
--- linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c	2009-08-16 21:11:55.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c	2009-08-11 12:49:23.000000000 +0200
@@ -300,8 +300,9 @@
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+			sizeof(kp), &sony_laptop_input.fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -362,8 +363,9 @@
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put(&sony_laptop_input.fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sony_laptop_input.fifo,
+			  (unsigned char *)&kp, sizeof(kp),
+			  &sony_laptop_input.fifo_lock);
 
 		if (!work_pending(&sony_laptop_release_key_work))
 			queue_work(sony_laptop_input.wq,
@@ -386,8 +388,7 @@
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
 	error =
-	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-			    &sony_laptop_input.fifo_lock);
+	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		goto err_dec_users;
@@ -2143,7 +2144,8 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c),
+			  &sonypi_compat.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -2322,7 +2324,8 @@
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_compat.fifo_lock);
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2333,8 +2336,7 @@
 
 	spin_lock_init(&sonypi_compat.fifo_lock);
 	error =
-	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-					 &sonypi_compat.fifo_lock);
+	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		return error;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c	2009-08-16 21:29:03.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c	2009-08-09 16:15:00.000000000 +0200
@@ -2121,7 +2121,7 @@
 	if (q->pool == NULL)
 		return -ENOMEM;
 
-	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL);
+	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
 	for (i = 0; i < max; i++) {
 		q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c	2009-08-16 21:24:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:11.000000000 +0200
@@ -1128,7 +1128,7 @@
 
 		/* R2T xmit queue */
 		if (kfifo_alloc(&tcp_task->r2tqueue,
-		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) {
+		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c	2009-08-16 21:29:13.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c	2009-08-09 16:18:53.000000000 +0200
@@ -58,8 +58,7 @@
 		goto free_pool;
 
 	spin_lock_init(&q->lock);
-	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *),
-			      &q->lock);
+	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
 		__kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
@@ -164,7 +163,8 @@
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_get_locked(&target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &target->iu_queue.lock);
 	if (!iue)
 		return iue;
 	iue->target = target;
@@ -176,7 +176,8 @@
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h
--- linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h	2009-08-16 21:25:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h	2009-08-11 12:46:08.000000000 +0200
@@ -495,7 +495,7 @@
 /* fifo of pointers */
 static inline int cq_new(struct kfifo *fifo, int size)
 {
-	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL);
+	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
diff -u -N -r linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h	2009-08-16 22:14:30.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h	2009-08-16 22:18:26.000000000 +0200
@@ -30,13 +30,12 @@
 	unsigned int size;	/* the size of the allocated buffer */
 	unsigned int in;	/* data is added at offset (in % size) */
 	unsigned int out;	/* data is extracted from off. (out % size) */
-	spinlock_t *lock;	/* protects concurrent modifications */
 };
 
 extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-			unsigned int size, spinlock_t *lock);
+			unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
-			gfp_t gfp_mask, spinlock_t *lock);
+			gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
 				const unsigned char *buffer, unsigned int len);
@@ -58,58 +57,67 @@
  */
 static inline void kfifo_reset(struct kfifo *fifo)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
 	__kfifo_reset(fifo);
+}
+
+/**
+ * __kfifo_len - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline unsigned int __kfifo_len(struct kfifo *fifo)
+{
+	register unsigned int	out;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	out = fifo->out;
+	smp_rmb();
+	return fifo->in - out;
 }
 
 /**
- * kfifo_put - puts some data into the FIFO
+ * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
+ * @from: the data to be added.
  * @len: the length of the data to be added.
+ * @lock: pointer to the spinlock to use for locking.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline unsigned int kfifo_put(struct kfifo *fifo,
-				const unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
+		const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_put(fifo, buffer, len);
+	ret = __kfifo_put(fifo, from, n);
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * kfifo_get - gets some data from the FIFO
+ * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
+ * @to: where the data must be copied.
  * @len: the size of the destination buffer.
+ * @lock: pointer to the spinlock to use for locking.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  */
-static inline unsigned int kfifo_get(struct kfifo *fifo,
-				     unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
+	unsigned char *to, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_get(fifo, buffer, len);
+	ret = __kfifo_get(fifo, to, n);
 
 	/*
 	 * optimization: if the FIFO is empty, set the indices to 0
@@ -118,36 +126,18 @@
 	if (fifo->in == fifo->out)
 		fifo->in = fifo->out = 0;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO, no locking version
- * @fifo: the fifo to be used.
- */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
-{
-	return fifo->in - fifo->out;
-}
-
-/**
  * kfifo_len - returns the number of bytes available in the FIFO
  * @fifo: the fifo to be used.
  */
 static inline unsigned int kfifo_len(struct kfifo *fifo)
 {
-	unsigned long flags;
-	unsigned int ret;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
-	ret = __kfifo_len(fifo);
-
-	spin_unlock_irqrestore(fifo->lock, flags);
-
-	return ret;
+	return __kfifo_len(fifo);
 }
 
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo1/kernel/kfifo.c linux-2.6.31-rc4-kfifo2/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo1/kernel/kfifo.c	2009-08-16 21:34:51.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/kernel/kfifo.c	2009-08-16 22:08:37.000000000 +0200
@@ -28,11 +28,10 @@
 #include <linux/log2.h>
 
 static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-		unsigned int size, spinlock_t *lock)
+		unsigned int size)
 {
 	fifo->buffer = buffer;
 	fifo->size = size;
-	fifo->lock = lock;
 
 	kfifo_reset(fifo);
 }
@@ -42,16 +41,14 @@
  * @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.
- * @lock: the lock to be used to protect the fifo buffer
  *
  */
-void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size,
-			spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 {
 	/* size must be a power of 2 */
 	BUG_ON(!is_power_of_2(size));
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 }
 EXPORT_SYMBOL(kfifo_init);
 
@@ -60,7 +57,6 @@
  * @fifo: the fifo to assign then new buffer
  * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
  *
  * This function dynamically allocates a new fifo internal buffer
  *
@@ -68,8 +64,7 @@
  * The buffer will be release with kfifo_free().
  * Return 0 if no error, otherwise the an error code
  */
-int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask,
-			spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 {
 	unsigned char *buffer;
 
@@ -84,11 +79,11 @@
 
 	buffer = kmalloc(size, gfp_mask);
 	if (!buffer) {
-		_kfifo_init(fifo, 0, 0, NULL);
+		_kfifo_init(fifo, 0, 0);
 		return -ENOMEM;
 	}
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 
 	return 0;
 }
diff -u -N -r linux-2.6.31-rc4-kfifo1/net/dccp/probe.c linux-2.6.31-rc4-kfifo2/net/dccp/probe.c
--- linux-2.6.31-rc4-kfifo1/net/dccp/probe.c	2009-08-16 21:24:04.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/net/dccp/probe.c	2009-08-11 12:50:28.000000000 +0200
@@ -67,7 +67,7 @@
 	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
 	va_end(args);
 
-	kfifo_put(&dccpw.fifo, tbuf, len);
+	kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	wake_up(&dccpw.wait);
 }
 
@@ -136,7 +136,7 @@
 	if (error)
 		goto out_free;
 
-	cnt = kfifo_get(&dccpw.fifo, tbuf, len);
+	cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -157,7 +157,7 @@
 
 	init_waitqueue_head(&dccpw.wait);
 	spin_lock_init(&dccpw.lock);
-	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock))
+	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL))
 		return ret;
 	if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
 		goto err0;



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 3/7] kfifo: cleanup namespace
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
  2009-08-16 20:44 ` [PATCH 1/7] kfifo: move struct kfifo in place Stefani Seibold
  2009-08-16 20:46 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
@ 2009-08-16 20:50 ` Stefani Seibold
  2009-08-16 20:53 ` [PATCH 4/7] kfifo: rename kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out Stefani Seibold
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:50 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

change name of __kfifo_* functions to kfifo_*, because 
the prefix __kfifo should be reserved for internal functions.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 drivers/char/nozomi.c                       |   12 +++++-----
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   10 ++++----
 drivers/net/wireless/libertas/cmd.c         |    4 +--
 drivers/net/wireless/libertas/main.c        |    8 +++----
 drivers/platform/x86/sony-laptop.c          |    2 -
 drivers/scsi/libiscsi.c                     |   14 ++++++------
 drivers/scsi/libiscsi_tcp.c                 |   20 ++++++++---------
 drivers/scsi/libsrp.c                       |    2 -
 drivers/usb/host/fhci.h                     |    6 ++---
 include/linux/kfifo.h                       |   32 ++++++----------------------
 kernel/kfifo.c                              |   12 +++++-----
 net/dccp/probe.c                            |    2 -
 12 files changed, 53 insertions(+), 71 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c linux-2.6.31-rc4-kfifo3/drivers/char/nozomi.c
--- linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c	2009-08-11 12:46:56.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/char/nozomi.c	2009-08-11 13:14:26.000000000 +0200
@@ -797,7 +797,7 @@
 	struct tty_struct *tty = tty_port_tty_get(&port->port);
 
 	/* Get data from tty and place in buf for now */
-	size = __kfifo_get(&port->fifo_ul, dc->send_buf,
+	size = kfifo_get(&port->fifo_ul, dc->send_buf,
 			   ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
 
 	if (size == 0) {
@@ -987,11 +987,11 @@
 
 	} else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) {
 
-		if (__kfifo_len(&dc->port[port].fifo_ul)) {
+		if (kfifo_len(&dc->port[port].fifo_ul)) {
 			DBG1("Enable interrupt (0x%04X) on port: %d",
 				enable_ier, port);
 			DBG1("Data in buffer [%d], enable transmit! ",
-				__kfifo_len(&dc->port[port].fifo_ul));
+				kfifo_len(&dc->port[port].fifo_ul));
 			enable_transmit_ul(port, dc);
 		} else {
 			DBG1("No data in buffer...");
@@ -1671,7 +1671,7 @@
 		goto exit;
 	}
 
-	rval = __kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count);
+	rval = kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count);
 
 	/* notify card */
 	if (unlikely(dc == NULL)) {
@@ -1719,7 +1719,7 @@
 	if (!port->port.count)
 		goto exit;
 
-	room = port->fifo_ul.size - __kfifo_len(&port->fifo_ul);
+	room = port->fifo_ul.size - kfifo_len(&port->fifo_ul);
 
 exit:
 	mutex_unlock(&port->tty_sem);
@@ -1876,7 +1876,7 @@
 		goto exit_in_buffer;
 	}
 
-	rval = __kfifo_len(&port->fifo_ul);
+	rval = kfifo_len(&port->fifo_ul);
 
 exit_in_buffer:
 	return rval;
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-2.6.31-rc4-kfifo3/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 12:47:57.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 13:14:18.000000000 +0200
@@ -59,7 +59,7 @@
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		__kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32));
 	if (random) {
 		j = 0;
 		random_bytes = random32();
@@ -71,19 +71,19 @@
 				random_bytes = random32();
 			}
 			idx = (random_bytes >> (j * 2)) & 0xF;
-			__kfifo_put(fifo,
+			kfifo_put(fifo,
 				(unsigned char *) &rarray[idx],
 				sizeof(u32));
 			rarray[idx] = i;
 			j++;
 		}
 		for (i = 0; i < RANDOM_SIZE; i++)
-			__kfifo_put(fifo,
+			kfifo_put(fifo,
 				(unsigned char *) &rarray[i],
 				sizeof(u32));
 	} else
 		for (i = skip_low; i < nr - skip_high; i++)
-			__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
+			kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
 		kfifo_get_locked(fifo, (unsigned char *) &entry,
@@ -119,7 +119,7 @@
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
 		if (!(i & rdev_p->qpmask))
-			__kfifo_put(&rdev_p->rscp->qpid_fifo,
+			kfifo_put(&rdev_p->rscp->qpid_fifo,
 				    (unsigned char *) &i, sizeof(u32));
 	return 0;
 }
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/cmd.c linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/cmd.c
--- linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/cmd.c	2009-08-11 12:51:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/cmd.c	2009-08-11 13:14:45.000000000 +0200
@@ -1862,7 +1862,7 @@
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
 	/* If nothing to do, go back to sleep (?) */
-	if (!__kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
+	if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
 		priv->psstate = PS_STATE_SLEEP;
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1936,7 +1936,7 @@
 	}
 
 	/* Pending events or command responses? */
-	if (__kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
+	if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
 		allowed = 0;
 		lbs_deb_host("pending events or command responses\n");
 	}
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/main.c
--- linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c	2009-08-11 12:45:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/main.c	2009-08-11 13:14:41.000000000 +0200
@@ -772,7 +772,7 @@
 			shouldsleep = 1;	/* Can't send a command; one already running */
 		else if (!list_empty(&priv->cmdpendingq))
 			shouldsleep = 0;	/* We have a command to send */
-		else if (__kfifo_len(&priv->event_fifo))
+		else if (kfifo_len(&priv->event_fifo))
 			shouldsleep = 0;	/* We have an event to process */
 		else
 			shouldsleep = 1;	/* No command */
@@ -851,10 +851,10 @@
 
 		/* Process hardware events, e.g. card removed, link lost */
 		spin_lock_irq(&priv->driver_lock);
-		while (__kfifo_len(&priv->event_fifo)) {
+		while (kfifo_len(&priv->event_fifo)) {
 			u32 event;
 
-			__kfifo_get(&priv->event_fifo, (unsigned char *) &event,
+			kfifo_get(&priv->event_fifo, (unsigned char *) &event,
 				sizeof(event));
 			spin_unlock_irq(&priv->driver_lock);
 			lbs_process_event(priv, event);
@@ -1578,7 +1578,7 @@
 	if (priv->psstate == PS_STATE_SLEEP)
 		priv->psstate = PS_STATE_AWAKE;
 
-	__kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
+	kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
 	wake_up_interruptible(&priv->waitq);
 
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c linux-2.6.31-rc4-kfifo3/drivers/platform/x86/sony-laptop.c
--- linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c	2009-08-11 12:49:23.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/platform/x86/sony-laptop.c	2009-08-11 13:13:24.000000000 +0200
@@ -2121,7 +2121,7 @@
 	spin_lock_irqsave(&sonypi_compat.fifo_lock, flags);
 
 	if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-		__kfifo_reset(&sonypi_compat.fifo);
+		kfifo_reset(&sonypi_compat.fifo);
 
 	spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags);
 
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi.c
--- linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c	2009-08-09 16:15:00.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi.c	2009-08-11 13:13:43.000000000 +0200
@@ -428,7 +428,7 @@
 	if (conn->login_task == task)
 		return;
 
-	__kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*));
+	kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*));
 
 	if (sc) {
 		task->sc = NULL;
@@ -614,7 +614,7 @@
 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
 
-		if (!__kfifo_get(&session->cmdpool.queue,
+		if (!kfifo_get(&session->cmdpool.queue,
 				 (void*)&task, sizeof(void*)))
 			return NULL;
 	}
@@ -1376,7 +1376,7 @@
 {
 	struct iscsi_task *task;
 
-	if (!__kfifo_get(&conn->session->cmdpool.queue,
+	if (!kfifo_get(&conn->session->cmdpool.queue,
 			 (void *) &task, sizeof(void *)))
 		return NULL;
 
@@ -2129,7 +2129,7 @@
 			q->max = i;
 			goto enomem;
 		}
-		__kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*));
+		kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*));
 	}
 
 	if (items) {
@@ -2476,7 +2476,7 @@
 
 	/* allocate login_task used for the login/text sequences */
 	spin_lock_bh(&session->lock);
-	if (!__kfifo_get(&session->cmdpool.queue,
+	if (!kfifo_get(&session->cmdpool.queue,
                          (void*)&conn->login_task,
 			 sizeof(void*))) {
 		spin_unlock_bh(&session->lock);
@@ -2496,7 +2496,7 @@
 	return cls_conn;
 
 login_task_data_alloc_fail:
-	__kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 login_task_alloc_fail:
 	iscsi_destroy_conn(cls_conn);
@@ -2559,7 +2559,7 @@
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
-	__kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi_tcp.c
--- linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:11.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:20.000000000 +0200
@@ -445,15 +445,15 @@
 		return;
 
 	/* flush task's r2t queues */
-	while (__kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
-		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+	while (kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
 	}
 
 	r2t = tcp_task->r2t;
 	if (r2t != NULL) {
-		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		tcp_task->r2t = NULL;
 	}
@@ -541,7 +541,7 @@
 		return 0;
 	}
 
-	rc = __kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
+	rc = kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
@@ -554,7 +554,7 @@
 	if (r2t->data_length == 0) {
 		iscsi_conn_printk(KERN_ERR, conn,
 				  "invalid R2T with zero data len\n");
-		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -570,7 +570,7 @@
 				  "invalid R2T with data len %u at offset %u "
 				  "and total length %d\n", r2t->data_length,
 				  r2t->data_offset, scsi_out(task->sc)->length);
-		__kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -580,7 +580,7 @@
 	r2t->sent = 0;
 
 	tcp_task->exp_datasn = r2tsn + 1;
-	__kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
+	kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
 	conn->r2t_pdus_cnt++;
 
 	iscsi_requeue_task(task);
@@ -951,7 +951,7 @@
 		return conn->session->tt->init_pdu(task, 0, task->data_count);
 	}
 
-	BUG_ON(__kfifo_len(&tcp_task->r2tqueue));
+	BUG_ON(kfifo_len(&tcp_task->r2tqueue));
 	tcp_task->exp_datasn = 0;
 
 	/* Prepare PDU, optionally w/ immediate data */
@@ -982,7 +982,7 @@
 			if (r2t->data_length <= r2t->sent) {
 				ISCSI_DBG_TCP(task->conn,
 					      "  done with r2t %p\n", r2t);
-				__kfifo_put(&tcp_task->r2tpool.queue,
+				kfifo_put(&tcp_task->r2tpool.queue,
 					    (void *)&tcp_task->r2t,
 					    sizeof(void *));
 				tcp_task->r2t = r2t = NULL;
@@ -990,7 +990,7 @@
 		}
 
 		if (r2t == NULL) {
-			__kfifo_get(&tcp_task->r2tqueue,
+			kfifo_get(&tcp_task->r2tqueue,
 				    (void *)&tcp_task->r2t, sizeof(void *));
 			r2t = tcp_task->r2t;
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c linux-2.6.31-rc4-kfifo3/drivers/scsi/libsrp.c
--- linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c	2009-08-09 16:18:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/scsi/libsrp.c	2009-08-11 13:14:12.000000000 +0200
@@ -61,7 +61,7 @@
 	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
-		__kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
+		kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
 		iue->sbuf = ring[i];
 		iue++;
 	}
diff -u -N -r linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h linux-2.6.31-rc4-kfifo3/drivers/usb/host/fhci.h
--- linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h	2009-08-11 12:46:08.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/drivers/usb/host/fhci.h	2009-08-11 13:14:36.000000000 +0200
@@ -505,19 +505,19 @@
 
 static inline unsigned int cq_howmany(struct kfifo *kfifo)
 {
-	return __kfifo_len(kfifo) / sizeof(void *);
+	return kfifo_len(kfifo) / sizeof(void *);
 }
 
 static inline int cq_put(struct kfifo *kfifo, void *p)
 {
-	return __kfifo_put(kfifo, (void *)&p, sizeof(p));
+	return kfifo_put(kfifo, (void *)&p, sizeof(p));
 }
 
 static inline void *cq_get(struct kfifo *kfifo)
 {
 	void *p = NULL;
 
-	__kfifo_get(kfifo, (void *)&p, sizeof(p));
+	kfifo_get(kfifo, (void *)&p, sizeof(p));
 	return p;
 }
 
diff -u -N -r linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h linux-2.6.31-rc4-kfifo3/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h	2009-08-16 22:18:26.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/include/linux/kfifo.h	2009-08-16 22:15:37.000000000 +0200
@@ -37,34 +37,25 @@
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
 			gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
-extern unsigned int __kfifo_put(struct kfifo *fifo,
+extern unsigned int kfifo_put(struct kfifo *fifo,
 				const unsigned char *buffer, unsigned int len);
-extern unsigned int __kfifo_get(struct kfifo *fifo,
+extern unsigned int kfifo_get(struct kfifo *fifo,
 				unsigned char *buffer, unsigned int len);
 
 /**
- * __kfifo_reset - removes the entire FIFO contents, no locking version
- * @fifo: the fifo to be emptied.
- */
-static inline void __kfifo_reset(struct kfifo *fifo)
-{
-	fifo->in = fifo->out = 0;
-}
-
-/**
  * kfifo_reset - removes the entire FIFO contents
  * @fifo: the fifo to be emptied.
  */
 static inline void kfifo_reset(struct kfifo *fifo)
 {
-	__kfifo_reset(fifo);
+	fifo->in = fifo->out = 0;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO
+ * kfifo_len - returns the number of used bytes in the FIFO
  * @fifo: the fifo to be used.
  */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
+static inline unsigned int kfifo_len(struct kfifo *fifo)
 {
 	register unsigned int	out;
 
@@ -92,7 +83,7 @@
 
 	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_put(fifo, from, n);
+	ret = kfifo_put(fifo, from, n);
 
 	spin_unlock_irqrestore(lock, flags);
 
@@ -117,7 +108,7 @@
 
 	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_get(fifo, to, n);
+	ret = kfifo_get(fifo, to, n);
 
 	/*
 	 * optimization: if the FIFO is empty, set the indices to 0
@@ -131,13 +122,4 @@
 	return ret;
 }
 
-/**
- * kfifo_len - returns the number of bytes available in the FIFO
- * @fifo: the fifo to be used.
- */
-static inline unsigned int kfifo_len(struct kfifo *fifo)
-{
-	return __kfifo_len(fifo);
-}
-
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo2/kernel/kfifo.c linux-2.6.31-rc4-kfifo3/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo2/kernel/kfifo.c	2009-08-16 22:08:37.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/kernel/kfifo.c	2009-08-16 22:08:48.000000000 +0200
@@ -100,7 +100,7 @@
 EXPORT_SYMBOL(kfifo_free);
 
 /**
- * __kfifo_put - puts some data into the FIFO, no locking version
+ * kfifo_put - puts some data into the FIFO, no locking version
  * @fifo: the fifo to be used.
  * @buffer: the data to be added.
  * @len: the length of the data to be added.
@@ -112,7 +112,7 @@
  * Note that with only one concurrent reader and one concurrent
  * writer, you don't need extra locking to use these functions.
  */
-unsigned int __kfifo_put(struct kfifo *fifo,
+unsigned int kfifo_put(struct kfifo *fifo,
 			const unsigned char *buffer, unsigned int len)
 {
 	unsigned int l;
@@ -144,10 +144,10 @@
 
 	return len;
 }
-EXPORT_SYMBOL(__kfifo_put);
+EXPORT_SYMBOL(kfifo_put);
 
 /**
- * __kfifo_get - gets some data from the FIFO, no locking version
+ * kfifo_get - gets some data from the FIFO, no locking version
  * @fifo: the fifo to be used.
  * @buffer: where the data must be copied.
  * @len: the size of the destination buffer.
@@ -158,7 +158,7 @@
  * Note that with only one concurrent reader and one concurrent
  * writer, you don't need extra locking to use these functions.
  */
-unsigned int __kfifo_get(struct kfifo *fifo,
+unsigned int kfifo_get(struct kfifo *fifo,
 			 unsigned char *buffer, unsigned int len)
 {
 	unsigned int l;
@@ -190,4 +190,4 @@
 
 	return len;
 }
-EXPORT_SYMBOL(__kfifo_get);
+EXPORT_SYMBOL(kfifo_get);
diff -u -N -r linux-2.6.31-rc4-kfifo2/net/dccp/probe.c linux-2.6.31-rc4-kfifo3/net/dccp/probe.c
--- linux-2.6.31-rc4-kfifo2/net/dccp/probe.c	2009-08-11 12:50:28.000000000 +0200
+++ linux-2.6.31-rc4-kfifo3/net/dccp/probe.c	2009-08-11 13:15:34.000000000 +0200
@@ -132,7 +132,7 @@
 		return -ENOMEM;
 
 	error = wait_event_interruptible(dccpw.wait,
-					 __kfifo_len(&dccpw.fifo) != 0);
+					 kfifo_len(&dccpw.fifo) != 0);
 	if (error)
 		goto out_free;
 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 4/7] kfifo: rename kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out...
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (2 preceding siblings ...)
  2009-08-16 20:50 ` [PATCH 3/7] kfifo: cleanup namespace Stefani Seibold
@ 2009-08-16 20:53 ` Stefani Seibold
  2009-08-16 20:57 ` [PATCH 5/7] kfifo: add DEFINE_KFIFO and friends, add very tiny functions Stefani Seibold
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

rename kfifo_put... into kfifo_in... to prevent miss use of old non in kernel-tree drivers
ditto for kfifo_get... -> kfifo_out...

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 drivers/char/nozomi.c                       |    4 +--
 drivers/char/sonypi.c                       |    8 +++----
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   16 +++++++-------
 drivers/media/video/meye.c                  |   16 +++++++-------
 drivers/net/wireless/libertas/main.c        |    4 +--
 drivers/platform/x86/fujitsu-laptop.c       |    4 +--
 drivers/platform/x86/sony-laptop.c          |    8 +++----
 drivers/scsi/libiscsi.c                     |   14 ++++++------
 drivers/scsi/libiscsi_tcp.c                 |   18 +++++++--------
 drivers/scsi/libsrp.c                       |    6 ++---
 drivers/usb/host/fhci.h                     |    4 +--
 include/linux/kfifo.h                       |   20 ++++++++---------
 kernel/kfifo.c                              |   32 ++++++++++++++--------------
 net/dccp/probe.c                            |    4 +--
 14 files changed, 79 insertions(+), 79 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/char/nozomi.c linux-2.6.31-rc4-kfifo4/drivers/char/nozomi.c
--- linux-2.6.31-rc4-kfifo3/drivers/char/nozomi.c	2009-08-11 13:14:26.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/char/nozomi.c	2009-08-11 13:26:07.000000000 +0200
@@ -797,7 +797,7 @@
 	struct tty_struct *tty = tty_port_tty_get(&port->port);
 
 	/* Get data from tty and place in buf for now */
-	size = kfifo_get(&port->fifo_ul, dc->send_buf,
+	size = kfifo_out(&port->fifo_ul, dc->send_buf,
 			   ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
 
 	if (size == 0) {
@@ -1671,7 +1671,7 @@
 		goto exit;
 	}
 
-	rval = kfifo_put(&port->fifo_ul, (unsigned char *)buffer, count);
+	rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
 
 	/* notify card */
 	if (unlikely(dc == NULL)) {
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/char/sonypi.c linux-2.6.31-rc4-kfifo4/drivers/char/sonypi.c
--- linux-2.6.31-rc4-kfifo3/drivers/char/sonypi.c	2009-08-11 12:56:44.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/char/sonypi.c	2009-08-11 13:26:11.000000000 +0200
@@ -776,7 +776,7 @@
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+	while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
 			 sizeof(kp), &sonypi_device.input_fifo_lock)
 			== sizeof(kp)) {
 		msleep(10);
@@ -827,7 +827,7 @@
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put_locked(&sonypi_device.input_fifo,
+		kfifo_in_locked(&sonypi_device.input_fifo,
 			(unsigned char *)&kp, sizeof(kp),
 			&sonypi_device.input_fifo_lock);
 		schedule_work(&sonypi_device.input_work);
@@ -881,7 +881,7 @@
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event,
+	kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
 			sizeof(event), &sonypi_device.fifo_lock);
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
@@ -931,7 +931,7 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c),
+	       (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
 				 &sonypi_device.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-2.6.31-rc4-kfifo4/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-2.6.31-rc4-kfifo3/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 13:14:18.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 13:26:03.000000000 +0200
@@ -59,7 +59,7 @@
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32));
 	if (random) {
 		j = 0;
 		random_bytes = random32();
@@ -71,22 +71,22 @@
 				random_bytes = random32();
 			}
 			idx = (random_bytes >> (j * 2)) & 0xF;
-			kfifo_put(fifo,
+			kfifo_in(fifo,
 				(unsigned char *) &rarray[idx],
 				sizeof(u32));
 			rarray[idx] = i;
 			j++;
 		}
 		for (i = 0; i < RANDOM_SIZE; i++)
-			kfifo_put(fifo,
+			kfifo_in(fifo,
 				(unsigned char *) &rarray[i],
 				sizeof(u32));
 	} else
 		for (i = skip_low; i < nr - skip_high; i++)
-			kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
+			kfifo_in(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get_locked(fifo, (unsigned char *) &entry,
+		kfifo_out_locked(fifo, (unsigned char *) &entry,
 				sizeof(u32), fifo_lock);
 	return 0;
 }
@@ -119,7 +119,7 @@
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
 		if (!(i & rdev_p->qpmask))
-			kfifo_put(&rdev_p->rscp->qpid_fifo,
+			kfifo_in(&rdev_p->rscp->qpid_fifo,
 				    (unsigned char *) &i, sizeof(u32));
 	return 0;
 }
@@ -180,7 +180,7 @@
 static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
 	u32 entry;
-	if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
+	if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
 		return entry;
 	else
 		return 0;	/* fifo emptry */
@@ -190,7 +190,7 @@
 		u32 entry)
 {
 	BUG_ON(
-	kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+	kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
 	== 0);
 }
 
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/media/video/meye.c linux-2.6.31-rc4-kfifo4/drivers/media/video/meye.c
--- linux-2.6.31-rc4-kfifo3/drivers/media/video/meye.c	2009-08-09 11:40:34.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/media/video/meye.c	2009-08-11 13:25:56.000000000 +0200
@@ -799,7 +799,7 @@
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+		if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
 			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
@@ -810,7 +810,7 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+		kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
 				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	} else {
@@ -820,7 +820,7 @@
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+		if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
 			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
@@ -831,7 +831,7 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+		kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
 				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	}
@@ -934,7 +934,7 @@
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+	kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
 			 &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
@@ -967,7 +967,7 @@
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get_locked(&meye.doneq, (unsigned char *)&unused,
+		kfifo_out_locked(&meye.doneq, (unsigned char *)&unused,
 				sizeof(int), &meye.doneq_lock);
 	}
 	*i = meye.grab_buffer[*i].size;
@@ -1455,7 +1455,7 @@
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index,
+	kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index,
 			sizeof(int), &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
@@ -1482,7 +1482,7 @@
 		return -EINTR;
 	}
 
-	if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr,
+	if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr,
 		       sizeof(int), &meye.doneq_lock)) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/main.c linux-2.6.31-rc4-kfifo4/drivers/net/wireless/libertas/main.c
--- linux-2.6.31-rc4-kfifo3/drivers/net/wireless/libertas/main.c	2009-08-11 13:14:41.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/net/wireless/libertas/main.c	2009-08-11 13:26:16.000000000 +0200
@@ -854,7 +854,7 @@
 		while (kfifo_len(&priv->event_fifo)) {
 			u32 event;
 
-			kfifo_get(&priv->event_fifo, (unsigned char *) &event,
+			kfifo_out(&priv->event_fifo, (unsigned char *) &event,
 				sizeof(event));
 			spin_unlock_irq(&priv->driver_lock);
 			lbs_process_event(priv, event);
@@ -1578,7 +1578,7 @@
 	if (priv->psstate == PS_STATE_SLEEP)
 		priv->psstate = PS_STATE_AWAKE;
 
-	kfifo_put(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
+	kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
 	wake_up_interruptible(&priv->waitq);
 
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/platform/x86/fujitsu-laptop.c linux-2.6.31-rc4-kfifo4/drivers/platform/x86/fujitsu-laptop.c
--- linux-2.6.31-rc4-kfifo3/drivers/platform/x86/fujitsu-laptop.c	2009-08-11 22:47:25.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/platform/x86/fujitsu-laptop.c	2009-08-11 22:47:40.000000000 +0200
@@ -1007,7 +1007,7 @@
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put_locked(&fujitsu_hotkey->fifo,
+				status = kfifo_in_locked(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
 						   sizeof(keycode),
 						   &fujitsu_hotkey->fifo_lock);
@@ -1021,7 +1021,7 @@
 				}
 			} else if (keycode == 0) {
 				while ((status =
-					kfifo_get_locked(
+					kfifo_out_locked(
 					 &fujitsu_hotkey->fifo,
 					 (unsigned char *) &keycode_r,
 					 sizeof(keycode_r),
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/platform/x86/sony-laptop.c linux-2.6.31-rc4-kfifo4/drivers/platform/x86/sony-laptop.c
--- linux-2.6.31-rc4-kfifo3/drivers/platform/x86/sony-laptop.c	2009-08-11 13:13:24.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/platform/x86/sony-laptop.c	2009-08-11 13:25:37.000000000 +0200
@@ -300,7 +300,7 @@
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+	while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
 			sizeof(kp), &sony_laptop_input.fifo_lock)
 			== sizeof(kp)) {
 		msleep(10);
@@ -363,7 +363,7 @@
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put_locked(&sony_laptop_input.fifo,
+		kfifo_in_locked(&sony_laptop_input.fifo,
 			  (unsigned char *)&kp, sizeof(kp),
 			  &sony_laptop_input.fifo_lock);
 
@@ -2144,7 +2144,7 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c),
+	       (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c),
 			  &sonypi_compat.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
@@ -2324,7 +2324,7 @@
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+	kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event,
 			sizeof(event), &sonypi_compat.fifo_lock);
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi.c linux-2.6.31-rc4-kfifo4/drivers/scsi/libiscsi.c
--- linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi.c	2009-08-11 13:13:43.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/scsi/libiscsi.c	2009-08-11 13:25:42.000000000 +0200
@@ -428,7 +428,7 @@
 	if (conn->login_task == task)
 		return;
 
-	kfifo_put(&session->cmdpool.queue, (void*)&task, sizeof(void*));
+	kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*));
 
 	if (sc) {
 		task->sc = NULL;
@@ -614,7 +614,7 @@
 		BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
 		BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
 
-		if (!kfifo_get(&session->cmdpool.queue,
+		if (!kfifo_out(&session->cmdpool.queue,
 				 (void*)&task, sizeof(void*)))
 			return NULL;
 	}
@@ -1376,7 +1376,7 @@
 {
 	struct iscsi_task *task;
 
-	if (!kfifo_get(&conn->session->cmdpool.queue,
+	if (!kfifo_out(&conn->session->cmdpool.queue,
 			 (void *) &task, sizeof(void *)))
 		return NULL;
 
@@ -2129,7 +2129,7 @@
 			q->max = i;
 			goto enomem;
 		}
-		kfifo_put(&q->queue, (void*)&q->pool[i], sizeof(void*));
+		kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*));
 	}
 
 	if (items) {
@@ -2476,7 +2476,7 @@
 
 	/* allocate login_task used for the login/text sequences */
 	spin_lock_bh(&session->lock);
-	if (!kfifo_get(&session->cmdpool.queue,
+	if (!kfifo_out(&session->cmdpool.queue,
                          (void*)&conn->login_task,
 			 sizeof(void*))) {
 		spin_unlock_bh(&session->lock);
@@ -2496,7 +2496,7 @@
 	return cls_conn;
 
 login_task_data_alloc_fail:
-	kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 login_task_alloc_fail:
 	iscsi_destroy_conn(cls_conn);
@@ -2559,7 +2559,7 @@
 	free_pages((unsigned long) conn->data,
 		   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
 	kfree(conn->persistent_address);
-	kfifo_put(&session->cmdpool.queue, (void*)&conn->login_task,
+	kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
 		    sizeof(void*));
 	if (session->leadconn == conn)
 		session->leadconn = NULL;
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi_tcp.c linux-2.6.31-rc4-kfifo4/drivers/scsi/libiscsi_tcp.c
--- linux-2.6.31-rc4-kfifo3/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:20.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:29.000000000 +0200
@@ -445,15 +445,15 @@
 		return;
 
 	/* flush task's r2t queues */
-	while (kfifo_get(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
-		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+	while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
 	}
 
 	r2t = tcp_task->r2t;
 	if (r2t != NULL) {
-		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		tcp_task->r2t = NULL;
 	}
@@ -541,7 +541,7 @@
 		return 0;
 	}
 
-	rc = kfifo_get(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
+	rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
@@ -554,7 +554,7 @@
 	if (r2t->data_length == 0) {
 		iscsi_conn_printk(KERN_ERR, conn,
 				  "invalid R2T with zero data len\n");
-		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -570,7 +570,7 @@
 				  "invalid R2T with data len %u at offset %u "
 				  "and total length %d\n", r2t->data_length,
 				  r2t->data_offset, scsi_out(task->sc)->length);
-		kfifo_put(&tcp_task->r2tpool.queue, (void*)&r2t,
+		kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 	}
@@ -580,7 +580,7 @@
 	r2t->sent = 0;
 
 	tcp_task->exp_datasn = r2tsn + 1;
-	kfifo_put(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
+	kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
 	conn->r2t_pdus_cnt++;
 
 	iscsi_requeue_task(task);
@@ -982,7 +982,7 @@
 			if (r2t->data_length <= r2t->sent) {
 				ISCSI_DBG_TCP(task->conn,
 					      "  done with r2t %p\n", r2t);
-				kfifo_put(&tcp_task->r2tpool.queue,
+				kfifo_in(&tcp_task->r2tpool.queue,
 					    (void *)&tcp_task->r2t,
 					    sizeof(void *));
 				tcp_task->r2t = r2t = NULL;
@@ -990,7 +990,7 @@
 		}
 
 		if (r2t == NULL) {
-			kfifo_get(&tcp_task->r2tqueue,
+			kfifo_out(&tcp_task->r2tqueue,
 				    (void *)&tcp_task->r2t, sizeof(void *));
 			r2t = tcp_task->r2t;
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/scsi/libsrp.c linux-2.6.31-rc4-kfifo4/drivers/scsi/libsrp.c
--- linux-2.6.31-rc4-kfifo3/drivers/scsi/libsrp.c	2009-08-11 13:14:12.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/scsi/libsrp.c	2009-08-11 13:25:50.000000000 +0200
@@ -61,7 +61,7 @@
 	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
-		kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
+		kfifo_in(&q->queue, (void *) &iue, sizeof(void *));
 		iue->sbuf = ring[i];
 		iue++;
 	}
@@ -163,7 +163,7 @@
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get_locked(&target->iu_queue.queue, (void *) &iue,
+	kfifo_out_locked(&target->iu_queue.queue, (void *) &iue,
 			sizeof(void *), &target->iu_queue.lock);
 	if (!iue)
 		return iue;
@@ -176,7 +176,7 @@
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue,
+	kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue,
 			sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
diff -u -N -r linux-2.6.31-rc4-kfifo3/drivers/usb/host/fhci.h linux-2.6.31-rc4-kfifo4/drivers/usb/host/fhci.h
--- linux-2.6.31-rc4-kfifo3/drivers/usb/host/fhci.h	2009-08-11 13:14:36.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/drivers/usb/host/fhci.h	2009-08-11 13:26:13.000000000 +0200
@@ -510,14 +510,14 @@
 
 static inline int cq_put(struct kfifo *kfifo, void *p)
 {
-	return kfifo_put(kfifo, (void *)&p, sizeof(p));
+	return kfifo_in(kfifo, (void *)&p, sizeof(p));
 }
 
 static inline void *cq_get(struct kfifo *kfifo)
 {
 	void *p = NULL;
 
-	kfifo_get(kfifo, (void *)&p, sizeof(p));
+	kfifo_out(kfifo, (void *)&p, sizeof(p));
 	return p;
 }
 
diff -u -N -r linux-2.6.31-rc4-kfifo3/include/linux/kfifo.h linux-2.6.31-rc4-kfifo4/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo3/include/linux/kfifo.h	2009-08-16 22:15:37.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/include/linux/kfifo.h	2009-08-16 22:16:13.000000000 +0200
@@ -37,10 +37,10 @@
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
 			gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
-extern unsigned int kfifo_put(struct kfifo *fifo,
-				const unsigned char *buffer, unsigned int len);
-extern unsigned int kfifo_get(struct kfifo *fifo,
-				unsigned char *buffer, unsigned int len);
+extern __must_check unsigned int kfifo_in(struct kfifo *fifo,
+				const unsigned char *from, unsigned int len);
+extern __must_check unsigned int kfifo_out(struct kfifo *fifo,
+				unsigned char *to, unsigned int len);
 
 /**
  * kfifo_reset - removes the entire FIFO contents
@@ -65,7 +65,7 @@
 }
 
 /**
- * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
+ * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
  * @from: the data to be added.
  * @len: the length of the data to be added.
@@ -75,7 +75,7 @@
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
+static inline __must_check unsigned int kfifo_in_locked(struct kfifo *fifo,
 		const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
@@ -83,7 +83,7 @@
 
 	spin_lock_irqsave(lock, flags);
 
-	ret = kfifo_put(fifo, from, n);
+	ret = kfifo_in(fifo, from, n);
 
 	spin_unlock_irqrestore(lock, flags);
 
@@ -91,7 +91,7 @@
 }
 
 /**
- * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
+ * kfifo_out_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
  * @to: where the data must be copied.
  * @len: the size of the destination buffer.
@@ -100,7 +100,7 @@
  * This function copies at most @len bytes from the FIFO into the
  * @to buffer and returns the number of copied bytes.
  */
-static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
+static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo,
 	unsigned char *to, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
@@ -108,7 +108,7 @@
 
 	spin_lock_irqsave(lock, flags);
 
-	ret = kfifo_get(fifo, to, n);
+	ret = kfifo_out(fifo, to, n);
 
 	/*
 	 * optimization: if the FIFO is empty, set the indices to 0
diff -u -N -r linux-2.6.31-rc4-kfifo3/kernel/kfifo.c linux-2.6.31-rc4-kfifo4/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo3/kernel/kfifo.c	2009-08-16 22:08:48.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/kernel/kfifo.c	2009-08-16 22:08:56.000000000 +0200
@@ -100,20 +100,20 @@
 EXPORT_SYMBOL(kfifo_free);
 
 /**
- * kfifo_put - puts some data into the FIFO, no locking version
+ * kfifo_in - puts some data into the FIFO
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
+ * @from: the data to be added.
  * @len: the length of the data to be added.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  *
  * Note that with only one concurrent reader and one concurrent
  * writer, you don't need extra locking to use these functions.
  */
-unsigned int kfifo_put(struct kfifo *fifo,
-			const unsigned char *buffer, unsigned int len)
+unsigned int kfifo_in(struct kfifo *fifo,
+			const unsigned char *from, unsigned int len)
 {
 	unsigned int l;
 
@@ -128,10 +128,10 @@
 
 	/* first put the data starting from fifo->in to buffer end */
 	l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
-	memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
+	memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), from, l);
 
 	/* then put the rest (if any) at the beginning of the buffer */
-	memcpy(fifo->buffer, buffer + l, len - l);
+	memcpy(fifo->buffer, from + l, len - l);
 
 	/*
 	 * Ensure that we add the bytes to the kfifo -before-
@@ -144,22 +144,22 @@
 
 	return len;
 }
-EXPORT_SYMBOL(kfifo_put);
+EXPORT_SYMBOL(kfifo_in);
 
 /**
- * kfifo_get - gets some data from the FIFO, no locking version
+ * kfifo_out - gets some data from the FIFO
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
+ * @to: where the data must be copied.
  * @len: the size of the destination buffer.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  *
  * Note that with only one concurrent reader and one concurrent
  * writer, you don't need extra locking to use these functions.
  */
-unsigned int kfifo_get(struct kfifo *fifo,
-			 unsigned char *buffer, unsigned int len)
+unsigned int kfifo_out(struct kfifo *fifo,
+			 unsigned char *to, unsigned int len)
 {
 	unsigned int l;
 
@@ -174,10 +174,10 @@
 
 	/* first get the data from fifo->out until the end of the buffer */
 	l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
-	memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
+	memcpy(to, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
 
 	/* then get the rest (if any) from the beginning of the buffer */
-	memcpy(buffer + l, fifo->buffer, len - l);
+	memcpy(to + l, fifo->buffer, len - l);
 
 	/*
 	 * Ensure that we remove the bytes from the kfifo -before-
@@ -190,4 +190,4 @@
 
 	return len;
 }
-EXPORT_SYMBOL(kfifo_get);
+EXPORT_SYMBOL(kfifo_out);
diff -u -N -r linux-2.6.31-rc4-kfifo3/net/dccp/probe.c linux-2.6.31-rc4-kfifo4/net/dccp/probe.c
--- linux-2.6.31-rc4-kfifo3/net/dccp/probe.c	2009-08-11 13:15:34.000000000 +0200
+++ linux-2.6.31-rc4-kfifo4/net/dccp/probe.c	2009-08-11 13:26:33.000000000 +0200
@@ -67,7 +67,7 @@
 	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
 	va_end(args);
 
-	kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
+	kfifo_in_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	wake_up(&dccpw.wait);
 }
 
@@ -136,7 +136,7 @@
 	if (error)
 		goto out_free;
 
-	cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
+	cnt = kfifo_out_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 5/7] kfifo: add DEFINE_KFIFO and friends, add very tiny functions
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (3 preceding siblings ...)
  2009-08-16 20:53 ` [PATCH 4/7] kfifo: rename kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out Stefani Seibold
@ 2009-08-16 20:57 ` Stefani Seibold
  2009-08-16 21:00 ` [PATCH 6/7] kfifo: add kfifo_skip, kfifo_from_user and kfifo_to_user Stefani Seibold
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 20:57 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

 Add DECLARE_KFIFO - macro to declare a kfifo and the associated buffer inside a struct
 Add INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO
 Add DEFINE_KFIFO - macro to define and initialize a kfifo as a global or local object
 Add kfifo_size() - returns the size of the fifo in bytes
 Add kfifo_is_empty() - returns true if the fifo is empty
 Add kfifo_is_full() - returns true if the fifo is full
 Add kfifo_avail() - returns the number of bytes available in the FIFO
 Do some code cleanup

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 kfifo.h |   85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 2 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo4/include/linux/kfifo.h linux-2.6.31-rc4-kfifo5/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo4/include/linux/kfifo.h	2009-08-16 22:16:13.000000000 +0200
+++ linux-2.6.31-rc4-kfifo5/include/linux/kfifo.h	2009-08-16 22:16:43.000000000 +0200
@@ -32,6 +32,51 @@
 	unsigned int out;	/* data is extracted from off. (out % size) */
 };
 
+/*
+ * Macros for declaration and initialization of the kfifo datatype
+ */
+
+#define __kfifo_initializer(s, b) \
+	(struct kfifo) { \
+		.size	= s, \
+		.in	= 0, \
+		.out	= 0, \
+		.buffer = b \
+	}
+
+/**
+ * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ *
+ * Note: the macro can be used inside struct or union declaration
+ */
+#define DECLARE_KFIFO(name, size) \
+union { \
+	struct kfifo name; \
+	unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \
+}
+
+/**
+ * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ */
+#define INIT_KFIFO(name) \
+	name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
+				sizeof(struct kfifo), name##kfifo_buffer)
+
+/**
+ * DEFINE_KFIFO - macro to define and initialize a kfifo
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ *
+ * Note: the macro can be used for global and local kfifo data type variables
+ */
+#define DEFINE_KFIFO(name, size) \
+	unsigned char name##kfifo_buffer[size]; \
+	struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer)
+
 extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
 			unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
@@ -52,6 +97,15 @@
 }
 
 /**
+ * kfifo_size - returns the size of the fifo in bytes
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check unsigned int kfifo_size(struct kfifo *fifo)
+{
+	return fifo->size;
+}
+
+/**
  * kfifo_len - returns the number of used bytes in the FIFO
  * @fifo: the fifo to be used.
  */
@@ -65,6 +119,33 @@
 }
 
 /**
+ * kfifo_is_empty - returns true if the fifo is empty
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check int kfifo_is_empty(struct kfifo *fifo)
+{
+	return fifo->in == fifo->out;
+}
+
+/**
+ * kfifo_is_full - returns true if the fifo is full
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check int kfifo_is_full(struct kfifo *fifo)
+{
+	return kfifo_len(fifo) == kfifo_size(fifo);
+}
+
+/**
+ * kfifo_avail - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo)
+{
+	return kfifo_size(fifo) - kfifo_len(fifo);
+}
+
+/**
  * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
  * @from: the data to be added.
@@ -114,8 +195,8 @@
 	 * optimization: if the FIFO is empty, set the indices to 0
 	 * so we don't wrap the next time
 	 */
-	if (fifo->in == fifo->out)
-		fifo->in = fifo->out = 0;
+	if (kfifo_is_empty(fifo))
+		kfifo_reset(fifo);
 
 	spin_unlock_irqrestore(lock, flags);
 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 6/7] kfifo: add kfifo_skip, kfifo_from_user and kfifo_to_user
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (4 preceding siblings ...)
  2009-08-16 20:57 ` [PATCH 5/7] kfifo: add DEFINE_KFIFO and friends, add very tiny functions Stefani Seibold
@ 2009-08-16 21:00 ` Stefani Seibold
  2009-08-16 21:03 ` [PATCH 0/7] kfifo: add record handling functions Stefani Seibold
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 21:00 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

 Add kfifo_reset_out() to lockless save discard the fifo output
 Add kfifo_skip() to skip a number of output bytes
 Add kfifo_from_user() to copy user space data into the fifo
 Add kfifo_to_user() to copy fifo data to user space

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 include/linux/kfifo.h |   47 ++++++++++++++++
 kernel/kfifo.c        |  139 ++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 170 insertions(+), 16 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo5/include/linux/kfifo.h linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo5/include/linux/kfifo.h	2009-08-16 22:16:43.000000000 +0200
+++ linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h	2009-08-16 22:17:08.000000000 +0200
@@ -97,6 +97,16 @@
 }
 
 /**
+ * kfifo_reset_out - skip FIFO contents
+ * @fifo: the fifo to be emptied.
+ */
+static inline void kfifo_reset_out(struct kfifo *fifo)
+{
+	smp_mb();
+	fifo->out = fifo->in;
+}
+
+/**
  * kfifo_size - returns the size of the fifo in bytes
  * @fifo: the fifo to be used.
  */
@@ -203,4 +213,41 @@
 	return ret;
 }
 
+extern void kfifo_skip(struct kfifo *fifo, unsigned int len);
+
+extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo,
+	const void __user *from, unsigned int n);
+
+extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo,
+	void __user *to, unsigned int n);
+
+/**
+ * __kfifo_add_out internal helper function for updating the out offset
+ */
+static inline void __kfifo_add_out(struct kfifo *fifo,
+				unsigned int off)
+{
+	smp_mb();
+	fifo->out += off;
+}
+
+/**
+ * __kfifo_add_in internal helper function for updating the in offset
+ */
+static inline void __kfifo_add_in(struct kfifo *fifo,
+				unsigned int off)
+{
+	smp_wmb();
+	fifo->in += off;
+}
+
+/**
+ * __kfifo_off internal helper function for calculating the index of a
+ * given offeset
+ */
+static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off)
+{
+	return off & (fifo->size - 1);
+}
+
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo5/kernel/kfifo.c linux-2.6.31-rc4-kfifo6/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo5/kernel/kfifo.c	2009-08-16 22:09:05.000000000 +0200
+++ linux-2.6.31-rc4-kfifo6/kernel/kfifo.c	2009-08-16 22:09:13.000000000 +0200
@@ -26,6 +26,7 @@
 #include <linux/err.h>
 #include <linux/kfifo.h>
 #include <linux/log2.h>
+#include <linux/uaccess.h>
 
 static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
 		unsigned int size)
@@ -100,6 +101,21 @@
 EXPORT_SYMBOL(kfifo_free);
 
 /**
+ * kfifo_skip - skip output data
+ * @fifo: the fifo to be used.
+ * @len: number of bytes to skip
+ */
+void kfifo_skip(struct kfifo *fifo, unsigned int len)
+{
+	if (len < kfifo_len(fifo)) {
+		__kfifo_add_out(fifo, len);
+		return;
+	}
+	kfifo_reset_out(fifo);
+}
+EXPORT_SYMBOL(kfifo_skip);
+
+/**
  * kfifo_in - puts some data into the FIFO
  * @fifo: the fifo to be used.
  * @from: the data to be added.
@@ -115,6 +131,7 @@
 unsigned int kfifo_in(struct kfifo *fifo,
 			const unsigned char *from, unsigned int len)
 {
+	unsigned int off;
 	unsigned int l;
 
 	len = min(len, fifo->size - fifo->in + fifo->out);
@@ -126,21 +143,16 @@
 
 	smp_mb();
 
+	off = __kfifo_off(fifo, fifo->in);
+
 	/* first put the data starting from fifo->in to buffer end */
-	l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
-	memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), from, l);
+	l = min(len, fifo->size - off);
+	memcpy(fifo->buffer + off, from, l);
 
 	/* then put the rest (if any) at the beginning of the buffer */
 	memcpy(fifo->buffer, from + l, len - l);
 
-	/*
-	 * Ensure that we add the bytes to the kfifo -before-
-	 * we update the fifo->in index.
-	 */
-
-	smp_wmb();
-
-	fifo->in += len;
+	__kfifo_add_in(fifo, len);
 
 	return len;
 }
@@ -161,6 +173,7 @@
 unsigned int kfifo_out(struct kfifo *fifo,
 			 unsigned char *to, unsigned int len)
 {
+	unsigned int off;
 	unsigned int l;
 
 	len = min(len, fifo->in - fifo->out);
@@ -172,22 +185,116 @@
 
 	smp_rmb();
 
+	off = __kfifo_off(fifo, fifo->out);
+
 	/* first get the data from fifo->out until the end of the buffer */
-	l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
-	memcpy(to, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
+	l = min(len, fifo->size - off);
+	memcpy(to, fifo->buffer + off, l);
 
 	/* then get the rest (if any) from the beginning of the buffer */
 	memcpy(to + l, fifo->buffer, len - l);
 
+	__kfifo_add_out(fifo, len);
+
+	return len;
+}
+EXPORT_SYMBOL(kfifo_out);
+
+/**
+ * kfifo_from_user - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from into the
+ * FIFO depending and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_from_user(struct kfifo *fifo,
+	const void __user *from, unsigned int len)
+{
+	unsigned int off;
+	unsigned int l;
+	int ret;
+
+	len = min(len, fifo->size - fifo->in + fifo->out);
+
 	/*
-	 * Ensure that we remove the bytes from the kfifo -before-
-	 * we update the fifo->out index.
+	 * Ensure that we sample the fifo->out index -before- we
+	 * start putting bytes into the kfifo.
 	 */
 
 	smp_mb();
 
-	fifo->out += len;
+	off = __kfifo_off(fifo, fifo->in);
+
+	/* first put the data starting from fifo->in to buffer end */
+	l = min(len, fifo->size - off);
+	ret = copy_from_user(fifo->buffer + off, from, l);
+
+	if (unlikely(ret))
+		return l - ret;
+
+	/* then put the rest (if any) at the beginning of the buffer */
+	ret = copy_from_user(fifo->buffer, from + l, len - l);
+
+	if (unlikely(ret))
+		return len - ret;
+
+	__kfifo_add_in(fifo, len);
 
 	return len;
 }
-EXPORT_SYMBOL(kfifo_out);
+EXPORT_SYMBOL(kfifo_from_user);
+
+/**
+ * kfifo_to_user - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_to_user(struct kfifo *fifo,
+	void __user *to, unsigned int len)
+{
+	unsigned int off;
+	unsigned int l;
+	int ret;
+
+	len = min(len, fifo->in - fifo->out);
+
+	/*
+	 * Ensure that we sample the fifo->in index -before- we
+	 * start removing bytes from the kfifo.
+	 */
+
+	smp_rmb();
+
+	off = __kfifo_off(fifo, fifo->out);
+
+	/* first get the data from fifo->out until the end of the buffer */
+	l = min(len, fifo->size - off);
+	ret = copy_to_user(to, fifo->buffer + off, l);
+
+	if (unlikely(ret))
+		return l - ret;
+
+	/* then get the rest (if any) from the beginning of the buffer */
+	ret = copy_to_user(to + l, fifo->buffer, len - l);
+
+	if (unlikely(ret))
+		return len - ret;
+
+	__kfifo_add_out(fifo, len);
+
+	return len;
+}
+EXPORT_SYMBOL(kfifo_to_user);
+



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 0/7] kfifo: add record handling functions
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (5 preceding siblings ...)
  2009-08-16 21:00 ` [PATCH 6/7] kfifo: add kfifo_skip, kfifo_from_user and kfifo_to_user Stefani Seibold
@ 2009-08-16 21:03 ` Stefani Seibold
  2009-08-16 21:04 ` [PATCH 7/7] " Stefani Seibold
  2009-08-16 21:08 ` [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 21:03 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

 Add kfifo_in_rec() - puts some record data into the FIFO
 Add kfifo_out_rec() - gets some record data from the FIFO
 Add kfifo_from_user_rec() - puts some data from user space into the FIFO
 Add kfifo_to_user_rec() - gets data from the FIFO and write it to user space
 Add kfifo_peek_rec() - gets the size of the next FIFO record field
 Add kfifo_skip_rec() - skip the next fifo out record

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 include/linux/kfifo.h |  318 ++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/kfifo.c        |  292 +++++++++++++++++++++++++++++++--------------
 2 files changed, 519 insertions(+), 91 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h	2009-08-16 22:17:08.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h	2009-08-16 22:17:22.000000000 +0200
@@ -250,4 +250,322 @@
 	return off & (fifo->size - 1);
 }
 
+/**
+ * __kfifo_peek_n internal helper function for determinate the length of
+ * the next record in the fifo
+ */
+static inline unsigned int __kfifo_peek_n(struct kfifo *fifo,
+				unsigned int recsize)
+{
+#define	__KFIFO_GET(fifo, off, shift) \
+	((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift))
+
+	unsigned int l;
+
+	l = __KFIFO_GET(fifo, 0, 0);
+
+	if (--recsize)
+		l |= __KFIFO_GET(fifo, 1, 8);
+
+	return l;
+}
+
+/**
+ * __kfifo_poke_n internal helper function for storing the length of
+ * the next record into the fifo
+ */
+static inline void __kfifo_poke_n(struct kfifo *fifo,
+			unsigned int recsize, unsigned int n)
+{
+#define	__KFIFO_PUT(fifo, off, val, shift) \
+		( \
+		(fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \
+		(unsigned char)((val) >> (shift)) \
+		)
+
+	__KFIFO_PUT(fifo, 0, n, 0);
+
+	if (--recsize)
+		__KFIFO_PUT(fifo, 1, n, 8);
+}
+
+/**
+ * __kfifo_in_... internal functions for put date into the fifo
+ * do not call it directly, use kfifo_in_rec() instead
+ */
+extern unsigned int __kfifo_in_n(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_in_generic(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_in_rec(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize)
+{
+	unsigned int ret;
+
+	ret = __kfifo_in_n(fifo, from, n, recsize);
+
+	if (likely(ret == 0)) {
+		if (recsize)
+			__kfifo_poke_n(fifo, recsize, n);
+		__kfifo_add_in(fifo, n + recsize);
+	}
+	return ret;
+}
+
+/**
+ * kfifo_in_rec - puts some record data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the FIFO and returns
+ * the number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo,
+	void *from, unsigned int n, unsigned int recsize)
+{
+	if (!__builtin_constant_p(recsize))
+		return __kfifo_in_generic(fifo, from, n, recsize);
+
+	return __kfifo_in_rec(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_out_... internal functions for get date from the fifo
+ * do not call it directly, use kfifo_out_rec() instead
+ */
+extern unsigned int __kfifo_out_n(struct kfifo *fifo,
+	void *to, unsigned int reclen, unsigned int recsize);
+
+extern unsigned int __kfifo_out_generic(struct kfifo *fifo,
+	void *to, unsigned int n,
+	unsigned int recsize, unsigned int *total);
+
+static inline unsigned int __kfifo_out_rec(struct kfifo *fifo,
+	void *to, unsigned int n, unsigned int recsize,
+	unsigned int *total)
+{
+	unsigned int l;
+
+	if (!recsize) {
+		l = n;
+		if (total)
+			*total = l;
+	} else {
+		l = __kfifo_peek_n(fifo, recsize);
+		if (total)
+			*total = l;
+		if (n < l)
+			return l;
+	}
+
+	return __kfifo_out_n(fifo, to, l, recsize);
+}
+
+/**
+ * kfifo_out_rec - gets some record data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to @to and returns the
+ * number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo,
+	void *to, unsigned int n, unsigned int recsize,
+	unsigned int *total)
+
+{
+	if (!__builtin_constant_p(recsize))
+		return __kfifo_out_generic(fifo, to, n, recsize, total);
+
+	return __kfifo_out_rec(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_from_user_... internal functions for transfer from user space into
+ * the fifo. do not call it directly, use kfifo_from_user_rec() instead
+ */
+extern unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize)
+{
+	unsigned int ret;
+
+	ret = __kfifo_from_user_n(fifo, from, n, recsize);
+
+	if (likely(ret == 0)) {
+		if (recsize)
+			__kfifo_poke_n(fifo, recsize, n);
+		__kfifo_add_in(fifo, n + recsize);
+	}
+	return ret;
+}
+
+/**
+ * kfifo_from_user_rec - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the
+ * FIFO and returns the number of bytes which cannot be copied.
+ *
+ * If the returned value is equal or less the @n value, the copy_from_user()
+ * functions has failed. Otherwise the record doesn't fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize))
+		return __kfifo_from_user_rec(fifo, from, n, recsize);
+	return __kfifo_from_user_generic(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_to_user_... internal functions for transfer fifo data into user space
+ * do not call it directly, use kfifo_to_user_rec() instead
+ */
+extern unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+	void __user *to, unsigned int n, unsigned int reclen,
+	unsigned int recsize);
+
+extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+	void __user *to, unsigned int n, unsigned int recsize,
+	unsigned int *total);
+
+static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo,
+	void __user *to, unsigned int n,
+	unsigned int recsize, unsigned int *total)
+{
+	unsigned int l;
+
+	if (!recsize) {
+		l = n;
+		if (total)
+			*total = l;
+	} else {
+		l = __kfifo_peek_n(fifo, recsize);
+		if (total)
+			*total = l;
+		if (n < l)
+			return l;
+	}
+
+	return __kfifo_to_user_n(fifo, to, n, l, recsize);
+}
+
+/**
+ * kfifo_to_user_rec - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to the @to.
+ * In case of an error, the function returns the number of bytes which cannot
+ * be copied.
+ * If the returned value is equal or less the @n value, the copy_to_user()
+ * functions has failed. Otherwise the record doesn't fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo,
+		void __user *to, unsigned int n, unsigned int recsize,
+		unsigned int *total)
+{
+	if (__builtin_constant_p(recsize))
+		return __kfifo_to_user_rec(fifo, to, n, recsize, total);
+	return __kfifo_to_user_generic(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_peek_... internal functions for peek into the next fifo record
+ * do not call it directly, use kfifo_peek_rec() instead
+ */
+extern unsigned int __kfifo_peek_generic(struct kfifo *fifo,
+				unsigned int recsize);
+
+/**
+ * kfifo_peek_rec - gets the size of the next FIFO record data
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function returns the size of the next FIFO record in number of bytes
+ */
+static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize)) {
+		if (!recsize)
+			return kfifo_len(fifo);
+		return __kfifo_peek_n(fifo, recsize);
+	}
+	return __kfifo_peek_generic(fifo, recsize);
+}
+
+/**
+ * __kfifo_skip_... internal functions for skip the next fifo record
+ * do not call it directly, use kfifo_skip_rec() instead
+ */
+extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize);
+
+static inline void __kfifo_skip_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	unsigned int l;
+
+	if (recsize) {
+		l = __kfifo_peek_n(fifo, recsize);
+
+		if (l + recsize <= kfifo_len(fifo)) {
+			__kfifo_add_out(fifo, l + recsize);
+			return;
+		}
+	}
+	kfifo_reset_out(fifo);
+}
+
+/**
+ * kfifo_skip_rec - skip the next fifo out record
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function skips the next FIFO record
+ */
+static inline void kfifo_skip_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize))
+		__kfifo_skip_rec(fifo, recsize);
+	else
+		__kfifo_skip_generic(fifo, recsize);
+}
+
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo6/kernel/kfifo.c linux-2.6.31-rc4-kfifo7/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo6/kernel/kfifo.c	2009-08-16 22:09:13.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/kernel/kfifo.c	2009-08-16 22:09:21.000000000 +0200
@@ -115,27 +115,11 @@
 }
 EXPORT_SYMBOL(kfifo_skip);
 
-/**
- * kfifo_in - puts some data into the FIFO
- * @fifo: the fifo to be used.
- * @from: the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from buffer into
- * the FIFO depending on the free space, and returns the number of
- * bytes copied.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_in(struct kfifo *fifo,
-			const unsigned char *from, unsigned int len)
+static inline void __kfifo_in_data(struct kfifo *fifo,
+		const void *from, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 
-	len = min(len, fifo->size - fifo->in + fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->out index -before- we
 	 * start putting bytes into the kfifo.
@@ -143,7 +127,7 @@
 
 	smp_mb();
 
-	off = __kfifo_off(fifo, fifo->in);
+	off = __kfifo_off(fifo, fifo->in + off);
 
 	/* first put the data starting from fifo->in to buffer end */
 	l = min(len, fifo->size - off);
@@ -151,33 +135,13 @@
 
 	/* then put the rest (if any) at the beginning of the buffer */
 	memcpy(fifo->buffer, from + l, len - l);
-
-	__kfifo_add_in(fifo, len);
-
-	return len;
 }
-EXPORT_SYMBOL(kfifo_in);
 
-/**
- * kfifo_out - gets some data from the FIFO
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_out(struct kfifo *fifo,
-			 unsigned char *to, unsigned int len)
+static inline void __kfifo_out_data(struct kfifo *fifo,
+		void *to, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 
-	len = min(len, fifo->in - fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->in index -before- we
 	 * start removing bytes from the kfifo.
@@ -185,7 +149,7 @@
 
 	smp_rmb();
 
-	off = __kfifo_off(fifo, fifo->out);
+	off = __kfifo_off(fifo, fifo->out + off);
 
 	/* first get the data from fifo->out until the end of the buffer */
 	l = min(len, fifo->size - off);
@@ -193,34 +157,14 @@
 
 	/* then get the rest (if any) from the beginning of the buffer */
 	memcpy(to + l, fifo->buffer, len - l);
-
-	__kfifo_add_out(fifo, len);
-
-	return len;
 }
-EXPORT_SYMBOL(kfifo_out);
 
-/**
- * kfifo_from_user - puts some data from user space into the FIFO
- * @fifo: the fifo to be used.
- * @from: pointer to the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from into the
- * FIFO depending and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_from_user(struct kfifo *fifo,
-	const void __user *from, unsigned int len)
+static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo,
+	 const void __user *from, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 	int ret;
 
-	len = min(len, fifo->size - fifo->in + fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->out index -before- we
 	 * start putting bytes into the kfifo.
@@ -228,48 +172,30 @@
 
 	smp_mb();
 
-	off = __kfifo_off(fifo, fifo->in);
+	off = __kfifo_off(fifo, fifo->in + off);
 
 	/* first put the data starting from fifo->in to buffer end */
 	l = min(len, fifo->size - off);
 	ret = copy_from_user(fifo->buffer + off, from, l);
 
 	if (unlikely(ret))
-		return l - ret;
+		return ret + len - l;
 
 	/* then put the rest (if any) at the beginning of the buffer */
 	ret = copy_from_user(fifo->buffer, from + l, len - l);
 
 	if (unlikely(ret))
-		return len - ret;
-
-	__kfifo_add_in(fifo, len);
+		return ret;
 
-	return len;
+	return 0;
 }
-EXPORT_SYMBOL(kfifo_from_user);
 
-/**
- * kfifo_to_user - gets data from the FIFO and write it to user space
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_to_user(struct kfifo *fifo,
-	void __user *to, unsigned int len)
+static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo,
+		void __user *to, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 	int ret;
 
-	len = min(len, fifo->in - fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->in index -before- we
 	 * start removing bytes from the kfifo.
@@ -277,24 +203,208 @@
 
 	smp_rmb();
 
-	off = __kfifo_off(fifo, fifo->out);
+	off = __kfifo_off(fifo, fifo->out + off);
 
 	/* first get the data from fifo->out until the end of the buffer */
 	l = min(len, fifo->size - off);
 	ret = copy_to_user(to, fifo->buffer + off, l);
 
 	if (unlikely(ret))
-		return l - ret;
+		return ret + len - l;
 
 	/* then get the rest (if any) from the beginning of the buffer */
 	ret = copy_to_user(to + l, fifo->buffer, len - l);
 
 	if (unlikely(ret))
-		return len - ret;
+		return ret;
+
+	return 0;
+}
+
+unsigned int __kfifo_in_n(struct kfifo *fifo,
+	const void *from, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_avail(fifo) < len + recsize)
+		return len + 1;
+
+	__kfifo_in_data(fifo, from, len, recsize);
+	return 0;
+}
+EXPORT_SYMBOL(__kfifo_in_n);
 
+/**
+ * kfifo_in - puts some data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from buffer into
+ * the FIFO depending on the free space, and returns the number of
+ * bytes copied.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from,
+				unsigned int len)
+{
+	len = min(kfifo_avail(fifo), len);
+
+	__kfifo_in_data(fifo, from, len, 0);
+	__kfifo_add_in(fifo, len);
+	return len;
+}
+EXPORT_SYMBOL(kfifo_in);
+
+unsigned int __kfifo_in_generic(struct kfifo *fifo,
+	const void *from, unsigned int len, unsigned int recsize)
+{
+	return __kfifo_in_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_in_generic);
+
+unsigned int __kfifo_out_n(struct kfifo *fifo,
+	void *to, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_len(fifo) < len + recsize)
+		return len;
+
+	__kfifo_out_data(fifo, to, len, recsize);
+	__kfifo_add_out(fifo, len + recsize);
+	return 0;
+}
+EXPORT_SYMBOL(__kfifo_out_n);
+
+/**
+ * kfifo_out - gets some data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len)
+{
+	len = min(kfifo_len(fifo), len);
+
+	__kfifo_out_data(fifo, to, len, 0);
 	__kfifo_add_out(fifo, len);
 
 	return len;
 }
+EXPORT_SYMBOL(kfifo_out);
+
+unsigned int __kfifo_out_generic(struct kfifo *fifo,
+	void *to, unsigned int len, unsigned int recsize,
+	unsigned int *total)
+{
+	return __kfifo_out_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_out_generic);
+
+unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+	const void __user *from, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_avail(fifo) < len + recsize)
+		return len + 1;
+
+	return __kfifo_from_user_data(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_n);
+
+/**
+ * kfifo_from_user - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from into the
+ * FIFO depending and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_from_user(struct kfifo *fifo,
+	const void __user *from, unsigned int len)
+{
+	len = min(kfifo_avail(fifo), len);
+	len -= __kfifo_from_user_data(fifo, from, len, 0);
+	__kfifo_add_in(fifo, len);
+	return len;
+}
+EXPORT_SYMBOL(kfifo_from_user);
+
+unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+	const void __user *from, unsigned int len, unsigned int recsize)
+{
+	return __kfifo_from_user_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_generic);
+
+unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+	void __user *to, unsigned int len, unsigned int reclen,
+	unsigned int recsize)
+{
+	unsigned int ret;
+
+	if (kfifo_len(fifo) < reclen + recsize)
+		return len;
+
+	ret = __kfifo_to_user_data(fifo, to, reclen, recsize);
+
+	if (likely(ret == 0))
+		__kfifo_add_out(fifo, reclen + recsize);
+
+	return ret;
+}
+EXPORT_SYMBOL(__kfifo_to_user_n);
+
+/**
+ * kfifo_to_user - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_to_user(struct kfifo *fifo,
+	void __user *to, unsigned int len)
+{
+	len = min(kfifo_len(fifo), len);
+	len -= __kfifo_to_user_data(fifo, to, len, 0);
+	__kfifo_add_out(fifo, len);
+	return len;
+}
 EXPORT_SYMBOL(kfifo_to_user);
 
+unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+	void __user *to, unsigned int len, unsigned int recsize,
+	unsigned int *total)
+{
+	return __kfifo_to_user_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_to_user_generic);
+
+unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize)
+{
+	if (recsize == 0)
+		return kfifo_avail(fifo);
+
+	return __kfifo_peek_n(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_peek_generic);
+
+void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize)
+{
+	__kfifo_skip_rec(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_skip_generic);
+



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 7/7] kfifo: add record handling functions
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (6 preceding siblings ...)
  2009-08-16 21:03 ` [PATCH 0/7] kfifo: add record handling functions Stefani Seibold
@ 2009-08-16 21:04 ` Stefani Seibold
  2009-08-16 21:08 ` [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 21:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

 Add kfifo_in_rec() - puts some record data into the FIFO
 Add kfifo_out_rec() - gets some record data from the FIFO
 Add kfifo_from_user_rec() - puts some data from user space into the FIFO
 Add kfifo_to_user_rec() - gets data from the FIFO and write it to user space
 Add kfifo_peek_rec() - gets the size of the next FIFO record field
 Add kfifo_skip_rec() - skip the next fifo out record

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 include/linux/kfifo.h |  318 ++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/kfifo.c        |  292 +++++++++++++++++++++++++++++++--------------
 2 files changed, 519 insertions(+), 91 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h	2009-08-16 22:17:08.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h	2009-08-16 22:17:22.000000000 +0200
@@ -250,4 +250,322 @@
 	return off & (fifo->size - 1);
 }
 
+/**
+ * __kfifo_peek_n internal helper function for determinate the length of
+ * the next record in the fifo
+ */
+static inline unsigned int __kfifo_peek_n(struct kfifo *fifo,
+				unsigned int recsize)
+{
+#define	__KFIFO_GET(fifo, off, shift) \
+	((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift))
+
+	unsigned int l;
+
+	l = __KFIFO_GET(fifo, 0, 0);
+
+	if (--recsize)
+		l |= __KFIFO_GET(fifo, 1, 8);
+
+	return l;
+}
+
+/**
+ * __kfifo_poke_n internal helper function for storing the length of
+ * the next record into the fifo
+ */
+static inline void __kfifo_poke_n(struct kfifo *fifo,
+			unsigned int recsize, unsigned int n)
+{
+#define	__KFIFO_PUT(fifo, off, val, shift) \
+		( \
+		(fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \
+		(unsigned char)((val) >> (shift)) \
+		)
+
+	__KFIFO_PUT(fifo, 0, n, 0);
+
+	if (--recsize)
+		__KFIFO_PUT(fifo, 1, n, 8);
+}
+
+/**
+ * __kfifo_in_... internal functions for put date into the fifo
+ * do not call it directly, use kfifo_in_rec() instead
+ */
+extern unsigned int __kfifo_in_n(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_in_generic(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_in_rec(struct kfifo *fifo,
+	const void *from, unsigned int n, unsigned int recsize)
+{
+	unsigned int ret;
+
+	ret = __kfifo_in_n(fifo, from, n, recsize);
+
+	if (likely(ret == 0)) {
+		if (recsize)
+			__kfifo_poke_n(fifo, recsize, n);
+		__kfifo_add_in(fifo, n + recsize);
+	}
+	return ret;
+}
+
+/**
+ * kfifo_in_rec - puts some record data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the FIFO and returns
+ * the number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo,
+	void *from, unsigned int n, unsigned int recsize)
+{
+	if (!__builtin_constant_p(recsize))
+		return __kfifo_in_generic(fifo, from, n, recsize);
+
+	return __kfifo_in_rec(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_out_... internal functions for get date from the fifo
+ * do not call it directly, use kfifo_out_rec() instead
+ */
+extern unsigned int __kfifo_out_n(struct kfifo *fifo,
+	void *to, unsigned int reclen, unsigned int recsize);
+
+extern unsigned int __kfifo_out_generic(struct kfifo *fifo,
+	void *to, unsigned int n,
+	unsigned int recsize, unsigned int *total);
+
+static inline unsigned int __kfifo_out_rec(struct kfifo *fifo,
+	void *to, unsigned int n, unsigned int recsize,
+	unsigned int *total)
+{
+	unsigned int l;
+
+	if (!recsize) {
+		l = n;
+		if (total)
+			*total = l;
+	} else {
+		l = __kfifo_peek_n(fifo, recsize);
+		if (total)
+			*total = l;
+		if (n < l)
+			return l;
+	}
+
+	return __kfifo_out_n(fifo, to, l, recsize);
+}
+
+/**
+ * kfifo_out_rec - gets some record data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to @to and returns the
+ * number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo,
+	void *to, unsigned int n, unsigned int recsize,
+	unsigned int *total)
+
+{
+	if (!__builtin_constant_p(recsize))
+		return __kfifo_out_generic(fifo, to, n, recsize, total);
+
+	return __kfifo_out_rec(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_from_user_... internal functions for transfer from user space into
+ * the fifo. do not call it directly, use kfifo_from_user_rec() instead
+ */
+extern unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize)
+{
+	unsigned int ret;
+
+	ret = __kfifo_from_user_n(fifo, from, n, recsize);
+
+	if (likely(ret == 0)) {
+		if (recsize)
+			__kfifo_poke_n(fifo, recsize, n);
+		__kfifo_add_in(fifo, n + recsize);
+	}
+	return ret;
+}
+
+/**
+ * kfifo_from_user_rec - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the
+ * FIFO and returns the number of bytes which cannot be copied.
+ *
+ * If the returned value is equal or less the @n value, the copy_from_user()
+ * functions has failed. Otherwise the record doesn't fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo,
+	const void __user *from, unsigned int n, unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize))
+		return __kfifo_from_user_rec(fifo, from, n, recsize);
+	return __kfifo_from_user_generic(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_to_user_... internal functions for transfer fifo data into user space
+ * do not call it directly, use kfifo_to_user_rec() instead
+ */
+extern unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+	void __user *to, unsigned int n, unsigned int reclen,
+	unsigned int recsize);
+
+extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+	void __user *to, unsigned int n, unsigned int recsize,
+	unsigned int *total);
+
+static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo,
+	void __user *to, unsigned int n,
+	unsigned int recsize, unsigned int *total)
+{
+	unsigned int l;
+
+	if (!recsize) {
+		l = n;
+		if (total)
+			*total = l;
+	} else {
+		l = __kfifo_peek_n(fifo, recsize);
+		if (total)
+			*total = l;
+		if (n < l)
+			return l;
+	}
+
+	return __kfifo_to_user_n(fifo, to, n, l, recsize);
+}
+
+/**
+ * kfifo_to_user_rec - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to the @to.
+ * In case of an error, the function returns the number of bytes which cannot
+ * be copied.
+ * If the returned value is equal or less the @n value, the copy_to_user()
+ * functions has failed. Otherwise the record doesn't fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo,
+		void __user *to, unsigned int n, unsigned int recsize,
+		unsigned int *total)
+{
+	if (__builtin_constant_p(recsize))
+		return __kfifo_to_user_rec(fifo, to, n, recsize, total);
+	return __kfifo_to_user_generic(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_peek_... internal functions for peek into the next fifo record
+ * do not call it directly, use kfifo_peek_rec() instead
+ */
+extern unsigned int __kfifo_peek_generic(struct kfifo *fifo,
+				unsigned int recsize);
+
+/**
+ * kfifo_peek_rec - gets the size of the next FIFO record data
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function returns the size of the next FIFO record in number of bytes
+ */
+static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize)) {
+		if (!recsize)
+			return kfifo_len(fifo);
+		return __kfifo_peek_n(fifo, recsize);
+	}
+	return __kfifo_peek_generic(fifo, recsize);
+}
+
+/**
+ * __kfifo_skip_... internal functions for skip the next fifo record
+ * do not call it directly, use kfifo_skip_rec() instead
+ */
+extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize);
+
+static inline void __kfifo_skip_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	unsigned int l;
+
+	if (recsize) {
+		l = __kfifo_peek_n(fifo, recsize);
+
+		if (l + recsize <= kfifo_len(fifo)) {
+			__kfifo_add_out(fifo, l + recsize);
+			return;
+		}
+	}
+	kfifo_reset_out(fifo);
+}
+
+/**
+ * kfifo_skip_rec - skip the next fifo out record
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function skips the next FIFO record
+ */
+static inline void kfifo_skip_rec(struct kfifo *fifo,
+	unsigned int recsize)
+{
+	if (__builtin_constant_p(recsize))
+		__kfifo_skip_rec(fifo, recsize);
+	else
+		__kfifo_skip_generic(fifo, recsize);
+}
+
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo6/kernel/kfifo.c linux-2.6.31-rc4-kfifo7/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo6/kernel/kfifo.c	2009-08-16 22:09:13.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/kernel/kfifo.c	2009-08-16 22:09:21.000000000 +0200
@@ -115,27 +115,11 @@
 }
 EXPORT_SYMBOL(kfifo_skip);
 
-/**
- * kfifo_in - puts some data into the FIFO
- * @fifo: the fifo to be used.
- * @from: the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from buffer into
- * the FIFO depending on the free space, and returns the number of
- * bytes copied.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_in(struct kfifo *fifo,
-			const unsigned char *from, unsigned int len)
+static inline void __kfifo_in_data(struct kfifo *fifo,
+		const void *from, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 
-	len = min(len, fifo->size - fifo->in + fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->out index -before- we
 	 * start putting bytes into the kfifo.
@@ -143,7 +127,7 @@
 
 	smp_mb();
 
-	off = __kfifo_off(fifo, fifo->in);
+	off = __kfifo_off(fifo, fifo->in + off);
 
 	/* first put the data starting from fifo->in to buffer end */
 	l = min(len, fifo->size - off);
@@ -151,33 +135,13 @@
 
 	/* then put the rest (if any) at the beginning of the buffer */
 	memcpy(fifo->buffer, from + l, len - l);
-
-	__kfifo_add_in(fifo, len);
-
-	return len;
 }
-EXPORT_SYMBOL(kfifo_in);
 
-/**
- * kfifo_out - gets some data from the FIFO
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_out(struct kfifo *fifo,
-			 unsigned char *to, unsigned int len)
+static inline void __kfifo_out_data(struct kfifo *fifo,
+		void *to, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 
-	len = min(len, fifo->in - fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->in index -before- we
 	 * start removing bytes from the kfifo.
@@ -185,7 +149,7 @@
 
 	smp_rmb();
 
-	off = __kfifo_off(fifo, fifo->out);
+	off = __kfifo_off(fifo, fifo->out + off);
 
 	/* first get the data from fifo->out until the end of the buffer */
 	l = min(len, fifo->size - off);
@@ -193,34 +157,14 @@
 
 	/* then get the rest (if any) from the beginning of the buffer */
 	memcpy(to + l, fifo->buffer, len - l);
-
-	__kfifo_add_out(fifo, len);
-
-	return len;
 }
-EXPORT_SYMBOL(kfifo_out);
 
-/**
- * kfifo_from_user - puts some data from user space into the FIFO
- * @fifo: the fifo to be used.
- * @from: pointer to the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from into the
- * FIFO depending and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_from_user(struct kfifo *fifo,
-	const void __user *from, unsigned int len)
+static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo,
+	 const void __user *from, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 	int ret;
 
-	len = min(len, fifo->size - fifo->in + fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->out index -before- we
 	 * start putting bytes into the kfifo.
@@ -228,48 +172,30 @@
 
 	smp_mb();
 
-	off = __kfifo_off(fifo, fifo->in);
+	off = __kfifo_off(fifo, fifo->in + off);
 
 	/* first put the data starting from fifo->in to buffer end */
 	l = min(len, fifo->size - off);
 	ret = copy_from_user(fifo->buffer + off, from, l);
 
 	if (unlikely(ret))
-		return l - ret;
+		return ret + len - l;
 
 	/* then put the rest (if any) at the beginning of the buffer */
 	ret = copy_from_user(fifo->buffer, from + l, len - l);
 
 	if (unlikely(ret))
-		return len - ret;
-
-	__kfifo_add_in(fifo, len);
+		return ret;
 
-	return len;
+	return 0;
 }
-EXPORT_SYMBOL(kfifo_from_user);
 
-/**
- * kfifo_to_user - gets data from the FIFO and write it to user space
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_to_user(struct kfifo *fifo,
-	void __user *to, unsigned int len)
+static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo,
+		void __user *to, unsigned int len, unsigned int off)
 {
-	unsigned int off;
 	unsigned int l;
 	int ret;
 
-	len = min(len, fifo->in - fifo->out);
-
 	/*
 	 * Ensure that we sample the fifo->in index -before- we
 	 * start removing bytes from the kfifo.
@@ -277,24 +203,208 @@
 
 	smp_rmb();
 
-	off = __kfifo_off(fifo, fifo->out);
+	off = __kfifo_off(fifo, fifo->out + off);
 
 	/* first get the data from fifo->out until the end of the buffer */
 	l = min(len, fifo->size - off);
 	ret = copy_to_user(to, fifo->buffer + off, l);
 
 	if (unlikely(ret))
-		return l - ret;
+		return ret + len - l;
 
 	/* then get the rest (if any) from the beginning of the buffer */
 	ret = copy_to_user(to + l, fifo->buffer, len - l);
 
 	if (unlikely(ret))
-		return len - ret;
+		return ret;
+
+	return 0;
+}
+
+unsigned int __kfifo_in_n(struct kfifo *fifo,
+	const void *from, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_avail(fifo) < len + recsize)
+		return len + 1;
+
+	__kfifo_in_data(fifo, from, len, recsize);
+	return 0;
+}
+EXPORT_SYMBOL(__kfifo_in_n);
 
+/**
+ * kfifo_in - puts some data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from buffer into
+ * the FIFO depending on the free space, and returns the number of
+ * bytes copied.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from,
+				unsigned int len)
+{
+	len = min(kfifo_avail(fifo), len);
+
+	__kfifo_in_data(fifo, from, len, 0);
+	__kfifo_add_in(fifo, len);
+	return len;
+}
+EXPORT_SYMBOL(kfifo_in);
+
+unsigned int __kfifo_in_generic(struct kfifo *fifo,
+	const void *from, unsigned int len, unsigned int recsize)
+{
+	return __kfifo_in_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_in_generic);
+
+unsigned int __kfifo_out_n(struct kfifo *fifo,
+	void *to, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_len(fifo) < len + recsize)
+		return len;
+
+	__kfifo_out_data(fifo, to, len, recsize);
+	__kfifo_add_out(fifo, len + recsize);
+	return 0;
+}
+EXPORT_SYMBOL(__kfifo_out_n);
+
+/**
+ * kfifo_out - gets some data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len)
+{
+	len = min(kfifo_len(fifo), len);
+
+	__kfifo_out_data(fifo, to, len, 0);
 	__kfifo_add_out(fifo, len);
 
 	return len;
 }
+EXPORT_SYMBOL(kfifo_out);
+
+unsigned int __kfifo_out_generic(struct kfifo *fifo,
+	void *to, unsigned int len, unsigned int recsize,
+	unsigned int *total)
+{
+	return __kfifo_out_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_out_generic);
+
+unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+	const void __user *from, unsigned int len, unsigned int recsize)
+{
+	if (kfifo_avail(fifo) < len + recsize)
+		return len + 1;
+
+	return __kfifo_from_user_data(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_n);
+
+/**
+ * kfifo_from_user - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from into the
+ * FIFO depending and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_from_user(struct kfifo *fifo,
+	const void __user *from, unsigned int len)
+{
+	len = min(kfifo_avail(fifo), len);
+	len -= __kfifo_from_user_data(fifo, from, len, 0);
+	__kfifo_add_in(fifo, len);
+	return len;
+}
+EXPORT_SYMBOL(kfifo_from_user);
+
+unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+	const void __user *from, unsigned int len, unsigned int recsize)
+{
+	return __kfifo_from_user_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_generic);
+
+unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+	void __user *to, unsigned int len, unsigned int reclen,
+	unsigned int recsize)
+{
+	unsigned int ret;
+
+	if (kfifo_len(fifo) < reclen + recsize)
+		return len;
+
+	ret = __kfifo_to_user_data(fifo, to, reclen, recsize);
+
+	if (likely(ret == 0))
+		__kfifo_add_out(fifo, reclen + recsize);
+
+	return ret;
+}
+EXPORT_SYMBOL(__kfifo_to_user_n);
+
+/**
+ * kfifo_to_user - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_to_user(struct kfifo *fifo,
+	void __user *to, unsigned int len)
+{
+	len = min(kfifo_len(fifo), len);
+	len -= __kfifo_to_user_data(fifo, to, len, 0);
+	__kfifo_add_out(fifo, len);
+	return len;
+}
 EXPORT_SYMBOL(kfifo_to_user);
 
+unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+	void __user *to, unsigned int len, unsigned int recsize,
+	unsigned int *total)
+{
+	return __kfifo_to_user_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_to_user_generic);
+
+unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize)
+{
+	if (recsize == 0)
+		return kfifo_avail(fifo);
+
+	return __kfifo_peek_n(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_peek_generic);
+
+void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize)
+{
+	__kfifo_skip_rec(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_skip_generic);
+



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 0/7] kfifo: new API v0.4
  2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
                   ` (7 preceding siblings ...)
  2009-08-16 21:04 ` [PATCH 7/7] " Stefani Seibold
@ 2009-08-16 21:08 ` Stefani Seibold
  8 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-16 21:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

Message
[PATCH 0/7] kfifo: add record handling functions
should be
[PATCH 7/7] kfifo: add record handling functions

So i send it again..

I am sorry,
Stefani



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-16 20:46 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
@ 2009-08-16 22:58   ` Alan Cox
  2009-08-16 23:34     ` Andrew Morton
  0 siblings, 1 reply; 31+ messages in thread
From: Alan Cox @ 2009-08-16 22:58 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, Andrew Morton, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

On Sun, 16 Aug 2009 22:46:30 +0200
Stefani Seibold <stefani@seibold.net> wrote:

> Move the pointer to the spinlock out of struct kfifo. Most
> users in tree do not actually use a spinlock, so the few
> exceptions now have to call kfifo_{get,put}_locked, which takes
> an extra argument to a spinlock.

NAK this one for the moment

We are about to set fifo loose through all the USB and some other
char/serial drivers all of which will use the spinlock facility.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-16 22:58   ` Alan Cox
@ 2009-08-16 23:34     ` Andrew Morton
  2009-08-17  6:48       ` Alan Cox
  0 siblings, 1 reply; 31+ messages in thread
From: Andrew Morton @ 2009-08-16 23:34 UTC (permalink / raw)
  To: Alan Cox
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

On Sun, 16 Aug 2009 23:58:43 +0100 Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> On Sun, 16 Aug 2009 22:46:30 +0200
> Stefani Seibold <stefani@seibold.net> wrote:
> 
> > Move the pointer to the spinlock out of struct kfifo. Most
> > users in tree do not actually use a spinlock, so the few
> > exceptions now have to call kfifo_{get,put}_locked, which takes
> > an extra argument to a spinlock.
> 
> NAK this one for the moment
> 
> We are about to set fifo loose through all the USB and some other
> char/serial drivers all of which will use the spinlock facility.

That sounds like a good reason for applying this patch first.

kfifo has no business assuming that the caller wants to use
spin_lock() locking.

If we want to add wrapper helpers around kfifo to reduce code
duplication in callers, and if one of those wrapper helpers provides
spinlock-based locking then fine.

But the happens-to-use-spin_lock functions shouldn't be called
kfifo_get(), because that steals namespace from the unlocked functions,
and makes the naming for the happens-to-use-mutex_lock functions look
weird.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-16 23:34     ` Andrew Morton
@ 2009-08-17  6:48       ` Alan Cox
  2009-08-17  7:36         ` Andrew Morton
  2009-08-17  7:46         ` Stefani Seibold
  0 siblings, 2 replies; 31+ messages in thread
From: Alan Cox @ 2009-08-17  6:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> kfifo has no business assuming that the caller wants to use
> spin_lock() locking.
> 
> If we want to add wrapper helpers around kfifo to reduce code
> duplication in callers, and if one of those wrapper helpers provides
> spinlock-based locking then fine.

Those wrappers happen to be called kfifo_get and kfifo_put

> But the happens-to-use-spin_lock functions shouldn't be called
> kfifo_get(), because that steals namespace from the unlocked functions,
> and makes the naming for the happens-to-use-mutex_lock functions look
> weird.

All over the kernel unlocked function versions have a leading _ name.
It's the kernel convention.

The other thing I must say I dislike about these patches is the
gratuitious 'let's rename all the functions' approach it takes. The kfifo
API is documented, used and random API of the year type changes mess
stuff up and cause unneeded churn.

The implementation itself is a really really nice idea.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  6:48       ` Alan Cox
@ 2009-08-17  7:36         ` Andrew Morton
  2009-08-17  8:08           ` Alan Cox
  2009-08-17  7:46         ` Stefani Seibold
  1 sibling, 1 reply; 31+ messages in thread
From: Andrew Morton @ 2009-08-17  7:36 UTC (permalink / raw)
  To: Alan Cox
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

On Mon, 17 Aug 2009 07:48:20 +0100 Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> > kfifo has no business assuming that the caller wants to use
> > spin_lock() locking.
> > 
> > If we want to add wrapper helpers around kfifo to reduce code
> > duplication in callers, and if one of those wrapper helpers provides
> > spinlock-based locking then fine.
> 
> Those wrappers happen to be called kfifo_get and kfifo_put

Those names are wrong.

They're wrong because they are the spinlock-specific variant.  What are
we going to call the mutex_lock-specific variant?

> > But the happens-to-use-spin_lock functions shouldn't be called
> > kfifo_get(), because that steals namespace from the unlocked functions,
> > and makes the naming for the happens-to-use-mutex_lock functions look
> > weird.
> 
> All over the kernel unlocked function versions have a leading _ name.
> It's the kernel convention.

tisn't.  radix-tree, rbrtee, idr, list_head, prio_tree, flex_array -
none of them use that convention.

> The other thing I must say I dislike about these patches is the
> gratuitious 'let's rename all the functions' approach it takes. The kfifo
> API is documented, used and random API of the year type changes mess
> stuff up and cause unneeded churn.

It fixes naming mistakes.  Long-term it is the correct thing to do. 
Best to do it now before we get more callers.


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  6:48       ` Alan Cox
  2009-08-17  7:36         ` Andrew Morton
@ 2009-08-17  7:46         ` Stefani Seibold
  2009-08-17  8:15           ` Alan Cox
  2009-08-17  9:52           ` Andi Kleen
  1 sibling, 2 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  7:46 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 07:48 +0100 schrieb Alan Cox:
> > kfifo has no business assuming that the caller wants to use
> > spin_lock() locking.
> > 
> > If we want to add wrapper helpers around kfifo to reduce code
> > duplication in callers, and if one of those wrapper helpers provides
> > spinlock-based locking then fine.
> 
> Those wrappers happen to be called kfifo_get and kfifo_put
> 
> > But the happens-to-use-spin_lock functions shouldn't be called
> > kfifo_get(), because that steals namespace from the unlocked functions,
> > and makes the naming for the happens-to-use-mutex_lock functions look
> > weird.
> 
> All over the kernel unlocked function versions have a leading _ name.
> It's the kernel convention.

Thats is not true in every case. Have a look at list.h - That was the
pattern i have implemented the new kfifo API.

> 
> The other thing I must say I dislike about these patches is the
> gratuitious 'let's rename all the functions' approach it takes. The kfifo
> API is documented, used and random API of the year type changes mess
> stuff up and cause unneeded churn.

First: Non of my eight linux kernel developer books does mention this
API. The only place is the in-kernel documentation and the man pages of
the "kernel hackers manual".

The main reason to do this was to design a cleaner interface. Because
there are very few users of this API, i thought it is a good time and
chance to do this.

My first draft version does also not renamed this functions, but there
was some concerns about the new functionality without modification the
function names.

Also the remove of the spinlock made is necessary to rename the
functions for preventing miss-use by out-of-kernel-tree drivers.

I think the break is not so hard if you believe. All you have to do is
to replace or kfifo_get() into kfifo_out_locked() and kfifo_put() into
kfifo_in_locked() if you really need the old behavior.

The thing is that we get no progress without changes.

> 
> The implementation itself is a really really nice idea.
> 
> 

Thanks for the flowers ;-)



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  7:36         ` Andrew Morton
@ 2009-08-17  8:08           ` Alan Cox
  2009-08-17  8:14             ` Stefani Seibold
  2009-08-17  8:21             ` Andrew Morton
  0 siblings, 2 replies; 31+ messages in thread
From: Alan Cox @ 2009-08-17  8:08 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> > Those wrappers happen to be called kfifo_get and kfifo_put
> 
> Those names are wrong.

We've had them for years

> They're wrong because they are the spinlock-specific variant.  What are
> we going to call the mutex_lock-specific variant?

There isn't one.

> 
> > > But the happens-to-use-spin_lock functions shouldn't be called
> > > kfifo_get(), because that steals namespace from the unlocked functions,
> > > and makes the naming for the happens-to-use-mutex_lock functions look
> > > weird.
> > 
> > All over the kernel unlocked function versions have a leading _ name.
> > It's the kernel convention.
> 
> tisn't.  radix-tree, rbrtee, idr, list_head, prio_tree, flex_array -
> none of them use that convention.

Some random "10 second grep" examples, and this is also used more
generally for the "without extra goo" variant of things

__set_special_pids
__sysrq_put_key_op
__sysrq_get_key_op
__handle_sysrq
__audit_getname
__audit_inode
__audit_node_child

and the without extra goo use includes such minor classics
__get_user
__put_user

the kernel contains lots and lots of

__foo()

foo()
{
	spin_lock(bar);
	__foo()
	spin_unlock(bar)
}

> > The other thing I must say I dislike about these patches is the
> > gratuitious 'let's rename all the functions' approach it takes. The kfifo
> > API is documented, used and random API of the year type changes mess
> > stuff up and cause unneeded churn.
> 
> It fixes naming mistakes.  Long-term it is the correct thing to do. 
> Best to do it now before we get more callers.

Why don't we fix all the really dumb naming mistakes then - things like
the chrdev interfaces ? Massive churn, massive confusion. Patches are
always being rejected (and rightfully so) for causing such messes.

And remember: its very hard to fix existing API documentation and books.
It's doubly dangerous (and IMHO a complete no-no) to change the API of an
interface if you don't change it such that old code will not reliably get
a compile time failure.

Alan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:08           ` Alan Cox
@ 2009-08-17  8:14             ` Stefani Seibold
  2009-08-17  8:21             ` Andrew Morton
  1 sibling, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  8:14 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 09:08 +0100 schrieb Alan Cox:
> > > Those wrappers happen to be called kfifo_get and kfifo_put
> > 
> > Those names are wrong.
> 
> We've had them for years
> 
> > They're wrong because they are the spinlock-specific variant.  What are
> > we going to call the mutex_lock-specific variant?
> 
> There isn't one.
> 
> > 
> > > > But the happens-to-use-spin_lock functions shouldn't be called
> > > > kfifo_get(), because that steals namespace from the unlocked functions,
> > > > and makes the naming for the happens-to-use-mutex_lock functions look
> > > > weird.
> > > 
> > > All over the kernel unlocked function versions have a leading _ name.
> > > It's the kernel convention.
> > 
> > tisn't.  radix-tree, rbrtee, idr, list_head, prio_tree, flex_array -
> > none of them use that convention.
> 
> Some random "10 second grep" examples, and this is also used more
> generally for the "without extra goo" variant of things
> 
> __set_special_pids
> __sysrq_put_key_op
> __sysrq_get_key_op
> __handle_sysrq
> __audit_getname
> __audit_inode
> __audit_node_child
> 
> and the without extra goo use includes such minor classics
> __get_user
> __put_user
> 
> the kernel contains lots and lots of
> 
> __foo()
> 
> foo()
> {
> 	spin_lock(bar);
> 	__foo()
> 	spin_unlock(bar)
> }
> 
> > > The other thing I must say I dislike about these patches is the
> > > gratuitious 'let's rename all the functions' approach it takes. The kfifo
> > > API is documented, used and random API of the year type changes mess
> > > stuff up and cause unneeded churn.
> > 
> > It fixes naming mistakes.  Long-term it is the correct thing to do. 
> > Best to do it now before we get more callers.
> 
> Why don't we fix all the really dumb naming mistakes then - things like
> the chrdev interfaces ? Massive churn, massive confusion. Patches are
> always being rejected (and rightfully so) for causing such messes.
> 
> And remember: its very hard to fix existing API documentation and books.
> It's doubly dangerous (and IMHO a complete no-no) to change the API of an
> interface if you don't change it such that old code will not reliably get
> a compile time failure.
> 

As mention: i have no book which describes this interface.

To get reliably a compile time failure was the reason to change the
function names.

> Alan

Stefani



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  7:46         ` Stefani Seibold
@ 2009-08-17  8:15           ` Alan Cox
  2009-08-17  8:28             ` Stefani Seibold
  2009-08-17  9:52           ` Andi Kleen
  1 sibling, 1 reply; 31+ messages in thread
From: Alan Cox @ 2009-08-17  8:15 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> > All over the kernel unlocked function versions have a leading _ name.
> > It's the kernel convention.
> 
> Thats is not true in every case. Have a look at list.h - That was the
> pattern i have implemented the new kfifo API.

Of course it isn't true in every case. Show me a *single* kernel
convention that is. It's also not true in no cases. foo_locked isn't used
much at all.

> The main reason to do this was to design a cleaner interface. Because
> there are very few users of this API, i thought it is a good time and
> chance to do this.
> 
> My first draft version does also not renamed this functions, but there
> was some concerns about the new functionality without modification the
> function names.
> 
> Also the remove of the spinlock made is necessary to rename the
> functions for preventing miss-use by out-of-kernel-tree drivers.

So if you didn't remove the spinlock you wouldn't have to change the API
and patch all the drivers.
 
> I think the break is not so hard if you believe. All you have to do is
> to replace or kfifo_get() into kfifo_out_locked() and kfifo_put() into
> kfifo_in_locked() if you really need the old behavior.

Which is very long winded. If you want longwinded and without breaking
stuff you can use

foo_unlocked() or unlocked_foo()

which do occur in the kernel (eg ioctl) when we want people to be
specifically aware of it although according to grep a little less often
than foo_locked() [discounting foo_is_locked which is general tests]


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:08           ` Alan Cox
  2009-08-17  8:14             ` Stefani Seibold
@ 2009-08-17  8:21             ` Andrew Morton
  2009-08-17  8:48               ` Alan Cox
  1 sibling, 1 reply; 31+ messages in thread
From: Andrew Morton @ 2009-08-17  8:21 UTC (permalink / raw)
  To: Alan Cox
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

On Mon, 17 Aug 2009 09:08:29 +0100 Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> > > Those wrappers happen to be called kfifo_get and kfifo_put
> > 
> > Those names are wrong.
> 
> We've had them for years

So?  It's been wrong for years.  This is a chance to fix it.

> > They're wrong because they are the spinlock-specific variant.  What are
> > we going to call the mutex_lock-specific variant?
> 
> There isn't one.

Oh come on.

> > 
> > > > But the happens-to-use-spin_lock functions shouldn't be called
> > > > kfifo_get(), because that steals namespace from the unlocked functions,
> > > > and makes the naming for the happens-to-use-mutex_lock functions look
> > > > weird.
> > > 
> > > All over the kernel unlocked function versions have a leading _ name.
> > > It's the kernel convention.
> > 
> > tisn't.  radix-tree, rbrtee, idr, list_head, prio_tree, flex_array -
> > none of them use that convention.
> 
> Some random "10 second grep" examples, and this is also used more
> generally for the "without extra goo" variant of things
> 
> __set_special_pids
> __sysrq_put_key_op
> __sysrq_get_key_op
> __handle_sysrq
> __audit_getname
> __audit_inode
> __audit_node_child
> 
> and the without extra goo use includes such minor classics
> __get_user
> __put_user
> 
> the kernel contains lots and lots of
> 
> __foo()
> 
> foo()
> {
> 	spin_lock(bar);
> 	__foo()
> 	spin_unlock(bar)
> }

None of those functions are part of general container libraries.  All
the ones I mentioned _are_ part of general container libraries.

Plus, as I've said enty en times and keep getting ignored: the current
naming is wrong.  The generic kfifo_get() should not be assuming that
the caller wants spinlock-based locking.

> > > The other thing I must say I dislike about these patches is the
> > > gratuitious 'let's rename all the functions' approach it takes. The kfifo
> > > API is documented, used and random API of the year type changes mess
> > > stuff up and cause unneeded churn.
> > 
> > It fixes naming mistakes.  Long-term it is the correct thing to do. 
> > Best to do it now before we get more callers.
> 
> Why don't we fix all the really dumb naming mistakes then - things like
> the chrdev interfaces ? Massive churn, massive confusion. Patches are
> always being rejected (and rightfully so) for causing such messes.

These patches don't make a mess.  Stefani has already fixed all callers
in a small number of patches.

> And remember: its very hard to fix existing API documentation and books.
> It's doubly dangerous (and IMHO a complete no-no) to change the API of an
> interface if you don't change it such that old code will not reliably get
> a compile time failure.

The patchet will cause unmigrated code to fail to build, won't it?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:15           ` Alan Cox
@ 2009-08-17  8:28             ` Stefani Seibold
  2009-08-17  8:53               ` Alan Cox
  0 siblings, 1 reply; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  8:28 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 09:15 +0100 schrieb Alan Cox:
> > > All over the kernel unlocked function versions have a leading _ name.
> > > It's the kernel convention.
> > 
> > Thats is not true in every case. Have a look at list.h - That was the
> > pattern i have implemented the new kfifo API.
> 
> Of course it isn't true in every case. Show me a *single* kernel
> convention that is. It's also not true in no cases. foo_locked isn't used
> much at all.
> 
> > The main reason to do this was to design a cleaner interface. Because
> > there are very few users of this API, i thought it is a good time and
> > chance to do this.
> > 
> > My first draft version does also not renamed this functions, but there
> > was some concerns about the new functionality without modification the
> > function names.
> > 
> > Also the remove of the spinlock made is necessary to rename the
> > functions for preventing miss-use by out-of-kernel-tree drivers.
> 
> So if you didn't remove the spinlock you wouldn't have to change the API
> and patch all the drivers.
>  

No. The kfifo struct in place does made it also necessary to patch all
this drivers. 

And the spinlock is in most cases useless, because the API works fine if
only one reader and one writer is using the fifo. This is the common
case.

> > I think the break is not so hard if you believe. All you have to do is
> > to replace or kfifo_get() into kfifo_out_locked() and kfifo_put() into
> > kfifo_in_locked() if you really need the old behavior.
> 
> Which is very long winded. If you want longwinded and without breaking
> stuff you can use
> 
> foo_unlocked() or unlocked_foo()
> 
> which do occur in the kernel (eg ioctl) when we want people to be
> specifically aware of it although according to grep a little less often
> than foo_locked() [discounting foo_is_locked which is general tests]
> 

If you like it is very easy to add a compatibility layer, which restores
the old function names. But for what, only for very few users who
depends on it? This will only waste the name space.
  


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:21             ` Andrew Morton
@ 2009-08-17  8:48               ` Alan Cox
  2009-08-17  9:22                 ` Stefani Seibold
  0 siblings, 1 reply; 31+ messages in thread
From: Alan Cox @ 2009-08-17  8:48 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Stefani Seibold, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

I simply pasted randomly from the regexp output. The __ semantic for the
less sanity checking/unlocked/non synchronizing version of an API is all
over the kernel. Not suprisingly as it seems to be a Linusism looking at
some of the old patch sets.

> > And remember: its very hard to fix existing API documentation and
books.
> > It's doubly dangerous (and IMHO a complete no-no) to change the API of an
> > interface if you don't change it such that old code will not reliably get
> > a compile time failure.
> 
> The patchet will cause unmigrated code to fail to build, won't it?

Yes but it won't fix the API docs.

So I still disagree with you. Adding _locked to the API end doesn't solve
any problems

You asked about mutexes but is get_locked() mutex locked, semaphore
locked, spinlocked, rwlocked ? So it doesn't do what you say.

What it does do is make the code more verbose, wider, more likely to go
over 80 columns and more typing.

Anyway I've made my point. I still think you are wrong on this one Andrew
but I think we have to simply continue to disagree.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:28             ` Stefani Seibold
@ 2009-08-17  8:53               ` Alan Cox
  2009-08-17  9:26                 ` Stefani Seibold
  0 siblings, 1 reply; 31+ messages in thread
From: Alan Cox @ 2009-08-17  8:53 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> And the spinlock is in most cases useless, because the API works fine if
> only one reader and one writer is using the fifo. This is the common
> case.

That is one good argument for fixing the naming. The USB serial code
probably can be persuaded to use the  single reader/writer assumption as
well.

> If you like it is very easy to add a compatibility layer, which restores
> the old function names. But for what, only for very few users who
> depends on it? This will only waste the name space.

Ooh the tragedy, we are short many things but namespace strangely is not
one of them. Especially when the names all start kfifo_ and __kfifo_, a
namespace much in demand by other code.

I'd rather have the old names, or the new names than some kind of gunge
middle layer of both. Either choice is better.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:48               ` Alan Cox
@ 2009-08-17  9:22                 ` Stefani Seibold
  0 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  9:22 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 09:48 +0100 schrieb Alan Cox:
> What it does do is make the code more verbose, wider, more likely to
> go
> over 80 columns and more typing.

I don't think so, because kfifo_*_locked() is only there for a
simplified porting. New user will not normally not use it.

Stefani


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  8:53               ` Alan Cox
@ 2009-08-17  9:26                 ` Stefani Seibold
  2009-08-17  9:51                   ` Alan Cox
  0 siblings, 1 reply; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  9:26 UTC (permalink / raw)
  To: Alan Cox
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 09:53 +0100 schrieb Alan Cox:
> > And the spinlock is in most cases useless, because the API works fine if
> > only one reader and one writer is using the fifo. This is the common
> > case.
> 
> That is one good argument for fixing the naming. The USB serial code
> probably can be persuaded to use the  single reader/writer assumption as
> well.
> 
> > If you like it is very easy to add a compatibility layer, which restores
> > the old function names. But for what, only for very few users who
> > depends on it? This will only waste the name space.
> 
> Ooh the tragedy, we are short many things but namespace strangely is not
> one of them. Especially when the names all start kfifo_ and __kfifo_, a
> namespace much in demand by other code.
> 
> I'd rather have the old names, or the new names than some kind of gunge
> middle layer of both. Either choice is better.

The question is: what do you expect? Should i provide a compat layer?
Should i retiring my work? 

Give me a solution for this dilemma. I see at this point no way if you
insist for the spinlock to design a clean interface.

Stefani


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  9:26                 ` Stefani Seibold
@ 2009-08-17  9:51                   ` Alan Cox
  0 siblings, 0 replies; 31+ messages in thread
From: Alan Cox @ 2009-08-17  9:51 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> The question is: what do you expect? Should i provide a compat layer?
> Should i retiring my work? 

Do what you think is right.

> Give me a solution for this dilemma. I see at this point no way if you
> insist for the spinlock to design a clean interface.

Then I won't insist.

Alan


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  7:46         ` Stefani Seibold
  2009-08-17  8:15           ` Alan Cox
@ 2009-08-17  9:52           ` Andi Kleen
  2009-08-17  9:56             ` Stefani Seibold
  1 sibling, 1 reply; 31+ messages in thread
From: Andi Kleen @ 2009-08-17  9:52 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: Alan Cox, Andrew Morton, linux-kernel, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

> I think the break is not so hard if you believe. All you have to do is
> to replace or kfifo_get() into kfifo_out_locked() and kfifo_put() into
> kfifo_in_locked() if you really need the old behavior.
> 
> The thing is that we get no progress without changes.

One thing that would be good to ensure is that old unconverted code
gets a clear compile time error, just in case some out of tree
code uses it. Bonus points also for having a short comment in kfifo.h that 
explains how to do the conversion.

Other than that I would be all for getting rid of embedded spinlocks
completely.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-17  9:52           ` Andi Kleen
@ 2009-08-17  9:56             ` Stefani Seibold
  0 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-17  9:56 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Alan Cox, Andrew Morton, linux-kernel, Arnd Bergmann,
	Amerigo Wang, Joe Perches

Am Montag, den 17.08.2009, 11:52 +0200 schrieb Andi Kleen:
> > I think the break is not so hard if you believe. All you have to do is
> > to replace or kfifo_get() into kfifo_out_locked() and kfifo_put() into
> > kfifo_in_locked() if you really need the old behavior.
> > 
> > The thing is that we get no progress without changes.
> 
> One thing that would be good to ensure is that old unconverted code
> gets a clear compile time error, just in case some out of tree
> code uses it. 

This is already done.

> Bonus points also for having a short comment in kfifo.h that 
> explains how to do the conversion.
> 

I can do this on a maintainance patch.

> Other than that I would be all for getting rid of embedded spinlocks
> completely.
> 
> -Andi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-11-20  8:15 [PATCH 0/7] kfifo: new API v0.7 Stefani Seibold
@ 2009-11-20  8:20 ` Stefani Seibold
  0 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-11-20  8:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang,
	Joe Perches, Roger Quadros, Greg Kroah-Hartman,
	Mauro Carvalho Chehab

Move the pointer to the spinlock out of struct kfifo. Most
users in tree do not actually use a spinlock, so the few
exceptions now have to call kfifo_{get,put}_locked, which takes
an extra argument to a spinlock.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/char/nozomi.c                       |    2 
 drivers/char/sonypi.c                       |   21 ++++---
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   36 +++++++-----
 drivers/media/video/meye.c                  |   35 +++++++-----
 drivers/net/wireless/libertas/main.c        |    2 
 drivers/platform/x86/fujitsu-laptop.c       |   18 +++---
 drivers/platform/x86/sony-laptop.c          |   22 ++++---
 drivers/scsi/libiscsi.c                     |    2 
 drivers/scsi/libiscsi_tcp.c                 |    2 
 drivers/scsi/libsrp.c                       |    9 +--
 drivers/usb/host/fhci.h                     |    2 
 drivers/usb/serial/generic.c                |    4 -
 drivers/usb/serial/usb-serial.c             |    3 -
 include/linux/kfifo.h                       |   80 ++++++++++++----------------
 kernel/kfifo.c                              |   17 ++---
 net/dccp/probe.c                            |    6 +-
 16 files changed, 131 insertions(+), 130 deletions(-)

diff -u -N -r -p kfifo1/drivers/char/nozomi.c kfifo2/drivers/char/nozomi.c
--- kfifo1/drivers/char/nozomi.c	2009-10-19 20:39:24.367550786 +0200
+++ kfifo2/drivers/char/nozomi.c	2009-10-19 20:58:34.000000000 +0200
@@ -686,7 +686,7 @@ static int nozomi_read_config_table(stru
 
 		for (i = PORT_MDM; i < MAX_PORT; i++) {
 			kfifo_alloc(&dc->port[i].fifo_ul,
-				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
+				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC);
 			memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
 			memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
 		}
diff -u -N -r -p kfifo1/drivers/char/sonypi.c kfifo2/drivers/char/sonypi.c
--- kfifo1/drivers/char/sonypi.c	2009-10-19 20:39:24.462844882 +0200
+++ kfifo2/drivers/char/sonypi.c	2009-10-19 20:58:34.000000000 +0200
@@ -777,8 +777,9 @@ static void input_keyrelease(struct work
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+			 sizeof(kp), &sonypi_device.input_fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put(&sonypi_device.input_fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sonypi_device.input_fifo,
+			(unsigned char *)&kp, sizeof(kp),
+			&sonypi_device.input_fifo_lock);
 		schedule_work(&sonypi_device.input_work);
 	}
 }
@@ -880,7 +882,8 @@ found:
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_device.fifo_lock);
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -929,7 +932,8 @@ static ssize_t sonypi_misc_read(struct f
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c),
+				 &sonypi_device.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -1313,8 +1317,7 @@ static int __devinit sonypi_probe(struct
 			"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,
-					 &sonypi_device.fifo_lock);
+	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 		return error;
@@ -1394,7 +1397,7 @@ static int __devinit sonypi_probe(struct
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
 		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
-				GFP_KERNEL, &sonypi_device.input_fifo_lock);
+				GFP_KERNEL);
 		if (error) {
 			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 			goto err_inpdev_unregister;
diff -u -N -r -p kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-10-19 20:58:34.000000000 +0200
@@ -55,7 +55,7 @@ static int __cxio_init_resource_fifo(str
 	u32 rarray[16];
 	spin_lock_init(fifo_lock);
 
-	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
+	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
@@ -86,7 +86,8 @@ static int __cxio_init_resource_fifo(str
 			__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_get_locked(fifo, (unsigned char *) &entry,
+				sizeof(u32), fifo_lock);
 	return 0;
 }
 
@@ -113,8 +114,7 @@ static int cxio_init_qpid_fifo(struct cx
 	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,
-					      &rdev_p->rscp->qpid_fifo_lock))
+					      GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
@@ -177,33 +177,37 @@ tpt_err:
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
 	u32 entry;
-	if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+	if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
 		return entry;
 	else
 		return 0;	/* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+		u32 entry)
 {
-	BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+	BUG_ON(
+	kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+	== 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->tpt_fifo);
+	return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-	cxio_hal_put_resource(&rscp->tpt_fifo, stag);
+	cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
+	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+			&rscp->qpid_fifo_lock);
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
 	return qpid;
 }
@@ -211,27 +215,27 @@ u32 cxio_hal_get_qpid(struct cxio_hal_re
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
-	cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
+	cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->cqid_fifo);
+	return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-	cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
+	cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->pdid_fifo);
+	return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-	cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
+	cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
diff -u -N -r -p kfifo1/drivers/media/video/meye.c kfifo2/drivers/media/video/meye.c
--- kfifo1/drivers/media/video/meye.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/media/video/meye.c	2009-10-19 20:58:34.000000000 +0200
@@ -800,8 +800,8 @@ again:
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
 		}
@@ -811,7 +811,8 @@ again:
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	} else {
 		int size;
@@ -820,8 +821,8 @@ again:
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
 		}
@@ -831,7 +832,8 @@ again:
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	}
 	mchip_free_frame();
@@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb)
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+			 &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -965,7 +968,8 @@ static int meyeioc_sync(struct file *fil
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
+		kfifo_get_locked(&meye.doneq, (unsigned char *)&unused,
+				sizeof(int), &meye.doneq_lock);
 	}
 	*i = meye.grab_buffer[*i].size;
 	mutex_unlock(&meye.lock);
@@ -1452,7 +1456,8 @@ static int vidioc_qbuf(struct file *file
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index,
+			sizeof(int), &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -1478,8 +1483,8 @@ static int vidioc_dqbuf(struct file *fil
 		return -EINTR;
 	}
 
-	if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
-		       sizeof(int))) {
+	if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr,
+		       sizeof(int), &meye.doneq_lock)) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
 	}
@@ -1746,14 +1751,14 @@ static int __devinit meye_probe(struct p
 	}
 
 	spin_lock_init(&meye.grabq_lock);
-	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.grabq_lock)) {
+	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
 	spin_lock_init(&meye.doneq_lock);
-	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.doneq_lock)) {
+	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc2;
 	}
diff -u -N -r -p kfifo1/drivers/net/wireless/libertas/main.c kfifo2/drivers/net/wireless/libertas/main.c
--- kfifo1/drivers/net/wireless/libertas/main.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/net/wireless/libertas/main.c	2009-10-19 20:58:34.000000000 +0200
@@ -1121,7 +1121,7 @@ static int lbs_init_adapter(struct lbs_p
 	priv->resp_len[0] = priv->resp_len[1] = 0;
 
 	/* Create the event FIFO */
-	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL);
+	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
 	if (ret) {
 		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
 		goto out;
diff -u -N -r -p kfifo1/drivers/platform/x86/fujitsu-laptop.c kfifo2/drivers/platform/x86/fujitsu-laptop.c
--- kfifo1/drivers/platform/x86/fujitsu-laptop.c	2009-10-19 20:39:24.111587921 +0200
+++ kfifo2/drivers/platform/x86/fujitsu-laptop.c	2009-10-19 20:58:34.000000000 +0200
@@ -825,7 +825,7 @@ static int acpi_fujitsu_hotkey_add(struc
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
 	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
-			GFP_KERNEL, &fujitsu_hotkey->fifo_lock);
+			GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "kfifo_alloc failed\n");
 		goto err_stop;
@@ -1006,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(s
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put(&fujitsu_hotkey->fifo,
+				status = kfifo_put_locked(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
-						   sizeof(keycode));
+						   sizeof(keycode),
+						   &fujitsu_hotkey->fifo_lock);
 				if (status != sizeof(keycode)) {
 					vdbg_printk(FUJLAPTOP_DBG_WARN,
 					    "Could not push keycode [0x%x]\n",
@@ -1019,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(s
 				}
 			} else if (keycode == 0) {
 				while ((status =
-					kfifo_get
-					(&fujitsu_hotkey->fifo, (unsigned char *)
-					 &keycode_r,
-					 sizeof
-					 (keycode_r))) == sizeof(keycode_r)) {
+					kfifo_get_locked(
+					 &fujitsu_hotkey->fifo,
+					 (unsigned char *) &keycode_r,
+					 sizeof(keycode_r),
+					 &fujitsu_hotkey->fifo_lock))
+					 == sizeof(keycode_r)) {
 					input_report_key(input, keycode_r, 0);
 					input_sync(input);
 					vdbg_printk(FUJLAPTOP_DBG_TRACE,
diff -u -N -r -p kfifo1/drivers/platform/x86/sony-laptop.c kfifo2/drivers/platform/x86/sony-laptop.c
--- kfifo1/drivers/platform/x86/sony-laptop.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/platform/x86/sony-laptop.c	2009-10-19 20:58:34.482782781 +0200
@@ -300,8 +300,9 @@ static void do_sony_laptop_release_key(s
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+			sizeof(kp), &sony_laptop_input.fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -362,8 +363,9 @@ static void sony_laptop_report_input_eve
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put(&sony_laptop_input.fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sony_laptop_input.fifo,
+			  (unsigned char *)&kp, sizeof(kp),
+			  &sony_laptop_input.fifo_lock);
 
 		if (!work_pending(&sony_laptop_release_key_work))
 			queue_work(sony_laptop_input.wq,
@@ -386,8 +388,7 @@ static int sony_laptop_setup_input(struc
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
 	error =
-	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-			    &sony_laptop_input.fifo_lock);
+	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		goto err_dec_users;
@@ -2129,7 +2130,8 @@ static ssize_t sonypi_misc_read(struct f
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c),
+			  &sonypi_compat.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -2308,7 +2310,8 @@ static struct miscdevice sonypi_misc_dev
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_compat.fifo_lock);
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2319,8 +2322,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,
-					 &sonypi_compat.fifo_lock);
+	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		return error;
diff -u -N -r -p kfifo1/drivers/scsi/libiscsi.c kfifo2/drivers/scsi/libiscsi.c
--- kfifo1/drivers/scsi/libiscsi.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libiscsi.c	2009-10-19 20:58:34.000000000 +0200
@@ -2252,7 +2252,7 @@ iscsi_pool_init(struct iscsi_pool *q, in
 	if (q->pool == NULL)
 		return -ENOMEM;
 
-	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL);
+	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
 	for (i = 0; i < max; i++) {
 		q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff -u -N -r -p kfifo1/drivers/scsi/libiscsi_tcp.c kfifo2/drivers/scsi/libiscsi_tcp.c
--- kfifo1/drivers/scsi/libiscsi_tcp.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libiscsi_tcp.c	2009-10-19 20:58:34.863588144 +0200
@@ -1128,7 +1128,7 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi
 
 		/* R2T xmit queue */
 		if (kfifo_alloc(&tcp_task->r2tqueue,
-		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) {
+		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
diff -u -N -r -p kfifo1/drivers/scsi/libsrp.c kfifo2/drivers/scsi/libsrp.c
--- kfifo1/drivers/scsi/libsrp.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libsrp.c	2009-10-19 20:58:34.419253835 +0200
@@ -58,8 +58,7 @@ static int srp_iu_pool_alloc(struct srp_
 		goto free_pool;
 
 	spin_lock_init(&q->lock);
-	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *),
-			      &q->lock);
+	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
 		__kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
@@ -165,7 +164,8 @@ struct iu_entry *srp_iu_get(struct srp_t
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_get_locked(&target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &target->iu_queue.lock);
 	if (!iue)
 		return iue;
 	iue->target = target;
@@ -177,7 +177,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get);
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -u -N -r -p kfifo1/drivers/usb/host/fhci.h kfifo2/drivers/usb/host/fhci.h
--- kfifo1/drivers/usb/host/fhci.h	2009-10-19 20:39:24.022212548 +0200
+++ kfifo2/drivers/usb/host/fhci.h	2009-10-19 20:58:34.893303070 +0200
@@ -495,7 +495,7 @@ static inline struct usb_hcd *fhci_to_hc
 /* fifo of pointers */
 static inline int cq_new(struct kfifo *fifo, int size)
 {
-	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL);
+	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
diff -u -N -r -p kfifo1/drivers/usb/serial/generic.c kfifo2/drivers/usb/serial/generic.c
--- kfifo1/drivers/usb/serial/generic.c	2009-10-19 21:00:10.423587193 +0200
+++ kfifo2/drivers/usb/serial/generic.c	2009-10-19 20:58:34.197586887 +0200
@@ -285,7 +285,7 @@ static int usb_serial_generic_write_star
 		return 0;
 
 	data = port->write_urb->transfer_buffer;
-	count = kfifo_get(port->write_fifo, data, port->bulk_out_size);
+	count = kfifo_get_locked(port->write_fifo, data, port->bulk_out_size, &port->lock);
 	usb_serial_debug_data(debug, &port->dev, __func__, count, data);
 
 	/* set up our urb */
@@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_
 		return usb_serial_multi_urb_write(tty, port,
 						  buf, count);
 
-	count = kfifo_put(port->write_fifo, buf, count);
+	count = kfifo_put_locked(port->write_fifo, buf, count, &port->lock);
 	result = usb_serial_generic_write_start(port);
 
 	if (result >= 0)
diff -u -N -r -p kfifo1/drivers/usb/serial/usb-serial.c kfifo2/drivers/usb/serial/usb-serial.c
--- kfifo1/drivers/usb/serial/usb-serial.c	2009-10-19 20:39:24.969443191 +0200
+++ kfifo2/drivers/usb/serial/usb-serial.c	2009-10-19 20:58:34.175586396 +0200
@@ -966,8 +966,7 @@ int usb_serial_probe(struct usb_interfac
 			dev_err(&interface->dev, "No free urbs available\n");
 			goto probe_error;
 		}
-		if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL,
-			&port->lock))
+		if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL))
 			goto probe_error;
 		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
 		port->bulk_out_size = buffer_size;
diff -u -N -r -p kfifo1/include/linux/kfifo.h kfifo2/include/linux/kfifo.h
--- kfifo1/include/linux/kfifo.h	2009-10-19 20:39:24.361587054 +0200
+++ kfifo2/include/linux/kfifo.h	2009-11-19 20:53:21.526214294 +0100
@@ -30,13 +30,12 @@ struct kfifo {
 	unsigned int size;	/* the size of the allocated buffer */
 	unsigned int in;	/* data is added at offset (in % size) */
 	unsigned int out;	/* data is extracted from off. (out % size) */
-	spinlock_t *lock;	/* protects concurrent modifications */
 };
 
 extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-			unsigned int size, spinlock_t *lock);
+			unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
-			gfp_t gfp_mask, spinlock_t *lock);
+			gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
 				const unsigned char *buffer, unsigned int len);
@@ -58,58 +57,67 @@ static inline void __kfifo_reset(struct 
  */
 static inline void kfifo_reset(struct kfifo *fifo)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
 	__kfifo_reset(fifo);
+}
+
+/**
+ * __kfifo_len - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline unsigned int __kfifo_len(struct kfifo *fifo)
+{
+	register unsigned int	out;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	out = fifo->out;
+	smp_rmb();
+	return fifo->in - out;
 }
 
 /**
- * kfifo_put - puts some data into the FIFO
+ * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
- * @len: the length of the data to be added.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @lock: pointer to the spinlock to use for locking.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline unsigned int kfifo_put(struct kfifo *fifo,
-				const unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
+		const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_put(fifo, buffer, len);
+	ret = __kfifo_put(fifo, from, n);
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * kfifo_get - gets some data from the FIFO
+ * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
- * @len: the size of the destination buffer.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @lock: pointer to the spinlock to use for locking.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  */
-static inline unsigned int kfifo_get(struct kfifo *fifo,
-				     unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
+	unsigned char *to, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_get(fifo, buffer, len);
+	ret = __kfifo_get(fifo, to, n);
 
 	/*
 	 * optimization: if the FIFO is empty, set the indices to 0
@@ -118,36 +126,18 @@ static inline unsigned int kfifo_get(str
 	if (fifo->in == fifo->out)
 		fifo->in = fifo->out = 0;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO, no locking version
- * @fifo: the fifo to be used.
- */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
-{
-	return fifo->in - fifo->out;
-}
-
-/**
  * kfifo_len - returns the number of bytes available in the FIFO
  * @fifo: the fifo to be used.
  */
 static inline unsigned int kfifo_len(struct kfifo *fifo)
 {
-	unsigned long flags;
-	unsigned int ret;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
-	ret = __kfifo_len(fifo);
-
-	spin_unlock_irqrestore(fifo->lock, flags);
-
-	return ret;
+	return __kfifo_len(fifo);
 }
 
 #endif
diff -u -N -r -p kfifo1/kernel/kfifo.c kfifo2/kernel/kfifo.c
--- kfifo1/kernel/kfifo.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/kernel/kfifo.c	2009-10-19 20:58:34.000000000 +0200
@@ -28,11 +28,10 @@
 #include <linux/log2.h>
 
 static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-		unsigned int size, spinlock_t *lock)
+		unsigned int size)
 {
 	fifo->buffer = buffer;
 	fifo->size = size;
-	fifo->lock = lock;
 
 	kfifo_reset(fifo);
 }
@@ -42,16 +41,14 @@ static void _kfifo_init(struct kfifo *fi
  * @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.
- * @lock: the lock to be used to protect the fifo buffer
  *
  */
-void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size,
-			spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 {
 	/* size must be a power of 2 */
 	BUG_ON(!is_power_of_2(size));
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 }
 EXPORT_SYMBOL(kfifo_init);
 
@@ -60,7 +57,6 @@ EXPORT_SYMBOL(kfifo_init);
  * @fifo: the fifo to assign then new buffer
  * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
  *
  * This function dynamically allocates a new fifo internal buffer
  *
@@ -68,8 +64,7 @@ EXPORT_SYMBOL(kfifo_init);
  * The buffer will be release with kfifo_free().
  * Return 0 if no error, otherwise the an error code
  */
-int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask,
-			spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 {
 	unsigned char *buffer;
 
@@ -84,11 +79,11 @@ int kfifo_alloc(struct kfifo *fifo, unsi
 
 	buffer = kmalloc(size, gfp_mask);
 	if (!buffer) {
-		_kfifo_init(fifo, 0, 0, NULL);
+		_kfifo_init(fifo, 0, 0);
 		return -ENOMEM;
 	}
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 
 	return 0;
 }
diff -u -N -r -p kfifo1/net/dccp/probe.c kfifo2/net/dccp/probe.c
--- kfifo1/net/dccp/probe.c	2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/net/dccp/probe.c	2009-10-19 20:58:34.000000000 +0200
@@ -67,7 +67,7 @@ static void printl(const char *fmt, ...)
 	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
 	va_end(args);
 
-	kfifo_put(&dccpw.fifo, tbuf, len);
+	kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	wake_up(&dccpw.wait);
 }
 
@@ -136,7 +136,7 @@ static ssize_t dccpprobe_read(struct fil
 	if (error)
 		goto out_free;
 
-	cnt = kfifo_get(&dccpw.fifo, tbuf, len);
+	cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -157,7 +157,7 @@ static __init int dccpprobe_init(void)
 
 	init_waitqueue_head(&dccpw.wait);
 	spin_lock_init(&dccpw.lock);
-	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock))
+	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL))
 		return ret;
 	if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
 		goto err0;



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-11-16 11:58 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
@ 2009-11-17 11:44   ` Roger Quadros
  0 siblings, 0 replies; 31+ messages in thread
From: Roger Quadros @ 2009-11-17 11:44 UTC (permalink / raw)
  To: Stefani Seibold
  Cc: linux-kernel, Andrew Morton, Arnd Bergmann, Andi Kleen,
	Amerigo Wang, Joe Perches

Hi Stefani,

 minor typo.

> diff -u -N -r kfifo1/include/linux/kfifo.h kfifo2/include/linux/kfifo.h
> --- kfifo1/include/linux/kfifo.h        2009-10-19 20:39:24.000000000 +0200
> +++ kfifo2/include/linux/kfifo.h        2009-10-19 20:58:34.000000000 +0200
> @@ -30,13 +30,12 @@
>        unsigned int size;      /* the size of the allocated buffer */
>        unsigned int in;        /* data is added at offset (in % size) */
>        unsigned int out;       /* data is extracted from off. (out % size) */
> -       spinlock_t *lock;       /* protects concurrent modifications */
>  };
>
>  extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
> -                       unsigned int size, spinlock_t *lock);
> +                       unsigned int size);
>  extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
> -                       gfp_t gfp_mask, spinlock_t *lock);
> +                       gfp_t gfp_mask);
>  extern void kfifo_free(struct kfifo *fifo);
>  extern unsigned int __kfifo_put(struct kfifo *fifo,
>                                const unsigned char *buffer, unsigned int len);
> @@ -58,58 +57,67 @@
>  */
>  static inline void kfifo_reset(struct kfifo *fifo)
>  {
> -       unsigned long flags;
> -
> -       spin_lock_irqsave(fifo->lock, flags);
> -
>        __kfifo_reset(fifo);
> +}
> +
> +/**
> + * __kfifo_len - returns the number of bytes available in the FIFO
> + * @fifo: the fifo to be used.
> + */
> +static inline unsigned int __kfifo_len(struct kfifo *fifo)
> +{
> +       register unsigned int   out;
>
> -       spin_unlock_irqrestore(fifo->lock, flags);
> +       out = fifo->out;
> +       smp_rmb();
> +       return fifo->in - out;
>  }
>
>  /**
> - * kfifo_put - puts some data into the FIFO
> + * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
>  * @fifo: the fifo to be used.
> - * @buffer: the data to be added.
> + * @from: the data to be added.
>  * @len: the length of the data to be added.

should be @n:

> + * @lock: pointer to the spinlock to use for locking.
>  *
> - * This function copies at most @len bytes from the @buffer into
> + * This function copies at most @len bytes from the @from buffer into
>  * the FIFO depending on the free space, and returns the number of
>  * bytes copied.
>  */
> -static inline unsigned int kfifo_put(struct kfifo *fifo,
> -                               const unsigned char *buffer, unsigned int len)
> +static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
> +               const unsigned char *from, unsigned int n, spinlock_t *lock)
>  {
>        unsigned long flags;
>        unsigned int ret;
>
> -       spin_lock_irqsave(fifo->lock, flags);
> +       spin_lock_irqsave(lock, flags);
>
> -       ret = __kfifo_put(fifo, buffer, len);
> +       ret = __kfifo_put(fifo, from, n);
>
> -       spin_unlock_irqrestore(fifo->lock, flags);
> +       spin_unlock_irqrestore(lock, flags);
>
>        return ret;
>  }
>
>  /**
> - * kfifo_get - gets some data from the FIFO
> + * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
>  * @fifo: the fifo to be used.
> - * @buffer: where the data must be copied.
> + * @to: where the data must be copied.
>  * @len: the size of the destination buffer.

should be @n

> + * @lock: pointer to the spinlock to use for locking.
>  *
>  * This function copies at most @len bytes from the FIFO into the
> - * @buffer and returns the number of copied bytes.
> + * @to buffer and returns the number of copied bytes.
>  */
> -static inline unsigned int kfifo_get(struct kfifo *fifo,
> -                                    unsigned char *buffer, unsigned int len)
> +static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
> +       unsigned char *to, unsigned int n, spinlock_t *lock)
>  {
>        unsigned long flags;
>        unsigned int ret;
>
> -       spin_lock_irqsave(fifo->lock, flags);
> +       spin_lock_irqsave(lock, flags);
>
> -       ret = __kfifo_get(fifo, buffer, len);
> +       ret = __kfifo_get(fifo, to, n);
>
>        /*
>         * optimization: if the FIFO is empty, set the indices to 0
> @@ -118,36 +126,18 @@
>        if (fifo->in == fifo->out)
>                fifo->in = fifo->out = 0;
>
> -       spin_unlock_irqrestore(fifo->lock, flags);
> +       spin_unlock_irqrestore(lock, flags);
>
>        return ret;
>  }

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-11-16 11:50 [PATCH 0/7] kfifo: new API v0.6 Stefani Seibold
@ 2009-11-16 11:58 ` Stefani Seibold
  2009-11-17 11:44   ` Roger Quadros
  0 siblings, 1 reply; 31+ messages in thread
From: Stefani Seibold @ 2009-11-16 11:58 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

Move the pointer to the spinlock out of struct kfifo. Most
users in tree do not actually use a spinlock, so the few
exceptions now have to call kfifo_{get,put}_locked, which takes
an extra argument to a spinlock.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/char/nozomi.c                       |    2 
 drivers/char/sonypi.c                       |   21 ++++---
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   36 +++++++------
 drivers/media/video/meye.c                  |   35 +++++++-----
 drivers/net/wireless/libertas/main.c        |    2 
 drivers/platform/x86/fujitsu-laptop.c       |   18 +++---
 drivers/platform/x86/sony-laptop.c          |   22 ++++----
 drivers/scsi/libiscsi.c                     |    2 
 drivers/scsi/libiscsi_tcp.c                 |    2 
 drivers/scsi/libsrp.c                       |    9 +--
 drivers/usb/host/fhci.h                     |    2 
 drivers/usb/serial/generic.c                |    4 -
 drivers/usb/serial/usb-serial.c             |    3 -
 include/linux/kfifo.h                       |   76 ++++++++++++----------------
 kernel/kfifo.c                              |   17 ++----
 net/dccp/probe.c                            |    6 +-
 16 files changed, 129 insertions(+), 128 deletions(-)

diff -u -N -r kfifo1/drivers/char/nozomi.c kfifo2/drivers/char/nozomi.c
--- kfifo1/drivers/char/nozomi.c        2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/char/nozomi.c        2009-10-19 20:58:34.000000000 +0200
@@ -686,7 +686,7 @@
 
                for (i = PORT_MDM; i < MAX_PORT; i++) {
                        kfifo_alloc(&dc->port[i].fifo_ul,
-                               FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
+                               FIFO_BUFFER_SIZE_UL, GFP_ATOMIC);
                        memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
                        memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
                }
diff -u -N -r kfifo1/drivers/char/sonypi.c kfifo2/drivers/char/sonypi.c
--- kfifo1/drivers/char/sonypi.c        2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/char/sonypi.c        2009-10-19 20:58:34.000000000 +0200
@@ -777,8 +777,9 @@
 {
        struct sonypi_keypress kp;
 
-       while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp,
-                        sizeof(kp)) == sizeof(kp)) {
+       while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+                        sizeof(kp), &sonypi_device.input_fifo_lock)
+                       == sizeof(kp)) {
                msleep(10);
                input_report_key(kp.dev, kp.key, 0);
                input_sync(kp.dev);
@@ -827,8 +828,9 @@
        if (kp.dev) {
                input_report_key(kp.dev, kp.key, 1);
                input_sync(kp.dev);
-               kfifo_put(&sonypi_device.input_fifo,
-                         (unsigned char *)&kp, sizeof(kp));
+               kfifo_put_locked(&sonypi_device.input_fifo,
+                       (unsigned char *)&kp, sizeof(kp),
+                       &sonypi_device.input_fifo_lock);
                schedule_work(&sonypi_device.input_work);
        }
 }
@@ -880,7 +882,8 @@
                acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-       kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+       kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event,
+                       sizeof(event), &sonypi_device.fifo_lock);
        kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
        wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -929,7 +932,8 @@
                return ret;
 
        while (ret < count &&
-              (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+              (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c),
+                                &sonypi_device.fifo_lock) == sizeof(c))) {
                if (put_user(c, buf++))
                        return -EFAULT;
                ret++;
@@ -1313,8 +1317,7 @@
                        "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,
-                                        &sonypi_device.fifo_lock);
+       error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
        if (error) {
                printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
                return error;
@@ -1394,7 +1397,7 @@
 
                spin_lock_init(&sonypi_device.input_fifo_lock);
                error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
-                               GFP_KERNEL, &sonypi_device.input_fifo_lock);
+                               GFP_KERNEL);
                if (error) {
                        printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
                        goto err_inpdev_unregister;
diff -u -N -r kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c  2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c  2009-10-19 20:58:34.000000000 +0200
@@ -55,7 +55,7 @@
        u32 rarray[16];
        spin_lock_init(fifo_lock);
 
-       if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
+       if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
                return -ENOMEM;
 
        for (i = 0; i < skip_low + skip_high; i++)
@@ -86,7 +86,8 @@
                        __kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
        for (i = 0; i < skip_low + skip_high; i++)
-               kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
+               kfifo_get_locked(fifo, (unsigned char *) &entry,
+                               sizeof(u32), fifo_lock);
        return 0;
 }
 
@@ -113,8 +114,7 @@
        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,
-                                             &rdev_p->rscp->qpid_fifo_lock))
+                                             GFP_KERNEL))
                return -ENOMEM;
 
        for (i = 16; i < T3_MAX_NUM_QP; i++)
@@ -177,33 +177,37 @@
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
        u32 entry;
-       if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+       if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
                return entry;
        else
                return 0;       /* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+               u32 entry)
 {
-       BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+       BUG_ON(
+       kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+       == 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(&rscp->tpt_fifo);
+       return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-       cxio_hal_put_resource(&rscp->tpt_fifo, stag);
+       cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-       u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
+       u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+                       &rscp->qpid_fifo_lock);
        PDBG("%s qpid 0x%x\n", __func__, qpid);
        return qpid;
 }
@@ -211,27 +215,27 @@
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
        PDBG("%s qpid 0x%x\n", __func__, qpid);
-       cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
+       cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(&rscp->cqid_fifo);
+       return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-       cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
+       cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(&rscp->pdid_fifo);
+       return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-       cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
+       cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
diff -u -N -r kfifo1/drivers/media/video/meye.c kfifo2/drivers/media/video/meye.c
--- kfifo1/drivers/media/video/meye.c   2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/media/video/meye.c   2009-10-19 20:58:34.000000000 +0200
@@ -800,8 +800,8 @@
                return IRQ_HANDLED;
 
        if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-               if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-                             sizeof(int)) != sizeof(int)) {
+               if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+                             sizeof(int), &meye.grabq_lock) != sizeof(int)) {
                        mchip_free_frame();
                        return IRQ_HANDLED;
                }
@@ -811,7 +811,8 @@
                meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
                do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
                meye.grab_buffer[reqnr].sequence = sequence++;
-               kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+               kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+                               sizeof(int), &meye.doneq_lock);
                wake_up_interruptible(&meye.proc_list);
        } else {
                int size;
@@ -820,8 +821,8 @@
                        mchip_free_frame();
                        goto again;
                }
-               if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-                             sizeof(int)) != sizeof(int)) {
+               if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+                             sizeof(int), &meye.grabq_lock) != sizeof(int)) {
                        mchip_free_frame();
                        goto again;
                }
@@ -831,7 +832,8 @@
                meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
                do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
                meye.grab_buffer[reqnr].sequence = sequence++;
-               kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+               kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+                               sizeof(int), &meye.doneq_lock);
                wake_up_interruptible(&meye.proc_list);
        }
        mchip_free_frame();
@@ -933,7 +935,8 @@
                mchip_cont_compression_start();
 
        meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-       kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
+       kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+                        &meye.grabq_lock);
        mutex_unlock(&meye.lock);
 
        return 0;
@@ -965,7 +968,8 @@
                /* fall through */
        case MEYE_BUF_DONE:
                meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-               kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
+               kfifo_get_locked(&meye.doneq, (unsigned char *)&unused,
+                               sizeof(int), &meye.doneq_lock);
        }
        *i = meye.grab_buffer[*i].size;
        mutex_unlock(&meye.lock);
@@ -1452,7 +1456,8 @@
        buf->flags |= V4L2_BUF_FLAG_QUEUED;
        buf->flags &= ~V4L2_BUF_FLAG_DONE;
        meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-       kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+       kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index,
+                       sizeof(int), &meye.grabq_lock);
        mutex_unlock(&meye.lock);
 
        return 0;
@@ -1478,8 +1483,8 @@
                return -EINTR;
        }
 
-       if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
-                      sizeof(int))) {
+       if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr,
+                      sizeof(int), &meye.doneq_lock)) {
                mutex_unlock(&meye.lock);
                return -EBUSY;
        }
@@ -1746,14 +1751,14 @@
        }
 
        spin_lock_init(&meye.grabq_lock);
-       if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-                                &meye.grabq_lock)) {
+       if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+                               GFP_KERNEL)) {
                printk(KERN_ERR "meye: fifo allocation failed\n");
                goto outkfifoalloc1;
        }
        spin_lock_init(&meye.doneq_lock);
-       if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-                                &meye.doneq_lock)) {
+       if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+                               GFP_KERNEL)) {
                printk(KERN_ERR "meye: fifo allocation failed\n");
                goto outkfifoalloc2;
        }
diff -u -N -r kfifo1/drivers/net/wireless/libertas/main.c kfifo2/drivers/net/wireless/libertas/main.c
--- kfifo1/drivers/net/wireless/libertas/main.c 2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/net/wireless/libertas/main.c 2009-10-19 20:58:34.000000000 +0200
@@ -1121,7 +1121,7 @@
        priv->resp_len[0] = priv->resp_len[1] = 0;
 
        /* Create the event FIFO */
-       ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL);
+       ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
        if (ret) {
                lbs_pr_err("Out of memory allocating event FIFO buffer\n");
                goto out;
diff -u -N -r kfifo1/drivers/platform/x86/fujitsu-laptop.c kfifo2/drivers/platform/x86/fujitsu-laptop.c
--- kfifo1/drivers/platform/x86/fujitsu-laptop.c        2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/platform/x86/fujitsu-laptop.c        2009-10-19 20:58:34.000000000 +0200
@@ -825,7 +825,7 @@
        /* kfifo */
        spin_lock_init(&fujitsu_hotkey->fifo_lock);
        error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
-                       GFP_KERNEL, &fujitsu_hotkey->fifo_lock);
+                       GFP_KERNEL);
        if (error) {
                printk(KERN_ERR "kfifo_alloc failed\n");
                goto err_stop;
@@ -1006,9 +1006,10 @@
                                vdbg_printk(FUJLAPTOP_DBG_TRACE,
                                        "Push keycode into ringbuffer [%d]\n",
                                        keycode);
-                               status = kfifo_put(&fujitsu_hotkey->fifo,
+                               status = kfifo_put_locked(&fujitsu_hotkey->fifo,
                                                   (unsigned char *)&keycode,
-                                                  sizeof(keycode));
+                                                  sizeof(keycode),
+                                                  &fujitsu_hotkey->fifo_lock);
                                if (status != sizeof(keycode)) {
                                        vdbg_printk(FUJLAPTOP_DBG_WARN,
                                            "Could not push keycode [0x%x]\n",
@@ -1019,11 +1020,12 @@
                                }
                        } else if (keycode == 0) {
                                while ((status =
-                                       kfifo_get
-                                       (&fujitsu_hotkey->fifo, (unsigned char *)
-                                        &keycode_r,
-                                        sizeof
-                                        (keycode_r))) == sizeof(keycode_r)) {
+                                       kfifo_get_locked(
+                                        &fujitsu_hotkey->fifo,
+                                        (unsigned char *) &keycode_r,
+                                        sizeof(keycode_r),
+                                        &fujitsu_hotkey->fifo_lock))
+                                        == sizeof(keycode_r)) {
                                        input_report_key(input, keycode_r, 0);
                                        input_sync(input);
                                        vdbg_printk(FUJLAPTOP_DBG_TRACE,
diff -u -N -r kfifo1/drivers/platform/x86/sony-laptop.c kfifo2/drivers/platform/x86/sony-laptop.c
--- kfifo1/drivers/platform/x86/sony-laptop.c   2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/platform/x86/sony-laptop.c   2009-10-19 20:58:34.000000000 +0200
@@ -300,8 +300,9 @@
 {
        struct sony_laptop_keypress kp;
 
-       while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp,
-                        sizeof(kp)) == sizeof(kp)) {
+       while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+                       sizeof(kp), &sony_laptop_input.fifo_lock)
+                       == sizeof(kp)) {
                msleep(10);
                input_report_key(kp.dev, kp.key, 0);
                input_sync(kp.dev);
@@ -362,8 +363,9 @@
                /* we emit the scancode so we can always remap the key */
                input_event(kp.dev, EV_MSC, MSC_SCAN, event);
                input_sync(kp.dev);
-               kfifo_put(&sony_laptop_input.fifo,
-                         (unsigned char *)&kp, sizeof(kp));
+               kfifo_put_locked(&sony_laptop_input.fifo,
+                         (unsigned char *)&kp, sizeof(kp),
+                         &sony_laptop_input.fifo_lock);
 
                if (!work_pending(&sony_laptop_release_key_work))
                        queue_work(sony_laptop_input.wq,
@@ -386,8 +388,7 @@
        /* kfifo */
        spin_lock_init(&sony_laptop_input.fifo_lock);
        error =
-        kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-                           &sony_laptop_input.fifo_lock);
+        kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
        if (error) {
                printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
                goto err_dec_users;
@@ -2129,7 +2130,8 @@
                return ret;
 
        while (ret < count &&
-              (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+              (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c),
+                         &sonypi_compat.fifo_lock) == sizeof(c))) {
                if (put_user(c, buf++))
                        return -EFAULT;
                ret++;
@@ -2308,7 +2310,8 @@
 
 static void sonypi_compat_report_event(u8 event)
 {
-       kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+       kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+                       sizeof(event), &sonypi_compat.fifo_lock);
        kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
        wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2319,8 +2322,7 @@
 
        spin_lock_init(&sonypi_compat.fifo_lock);
        error =
-        kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-                                        &sonypi_compat.fifo_lock);
+        kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
        if (error) {
                printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
                return error;
diff -u -N -r kfifo1/drivers/scsi/libiscsi.c kfifo2/drivers/scsi/libiscsi.c
--- kfifo1/drivers/scsi/libiscsi.c      2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libiscsi.c      2009-10-19 20:58:34.000000000 +0200
@@ -2252,7 +2252,7 @@
        if (q->pool == NULL)
                return -ENOMEM;
 
-       kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL);
+       kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
        for (i = 0; i < max; i++) {
                q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff -u -N -r kfifo1/drivers/scsi/libiscsi_tcp.c kfifo2/drivers/scsi/libiscsi_tcp.c
--- kfifo1/drivers/scsi/libiscsi_tcp.c  2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libiscsi_tcp.c  2009-10-19 20:58:34.000000000 +0200
@@ -1128,7 +1128,7 @@
 
                /* R2T xmit queue */
                if (kfifo_alloc(&tcp_task->r2tqueue,
-                     session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) {
+                     session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
                        iscsi_pool_free(&tcp_task->r2tpool);
                        goto r2t_alloc_fail;
                }
diff -u -N -r kfifo1/drivers/scsi/libsrp.c kfifo2/drivers/scsi/libsrp.c
--- kfifo1/drivers/scsi/libsrp.c        2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/scsi/libsrp.c        2009-10-19 20:58:34.000000000 +0200
@@ -58,8 +58,7 @@
                goto free_pool;
 
        spin_lock_init(&q->lock);
-       kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *),
-                             &q->lock);
+       kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
        for (i = 0, iue = q->items; i < max; i++) {
                __kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
@@ -165,7 +164,8 @@
 {
        struct iu_entry *iue = NULL;
 
-       kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *));
+       kfifo_get_locked(&target->iu_queue.queue, (void *) &iue,
+                       sizeof(void *), &target->iu_queue.lock);
        if (!iue)
                return iue;
        iue->target = target;
@@ -177,7 +177,8 @@
 
 void srp_iu_put(struct iu_entry *iue)
 {
-       kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+       kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue,
+                       sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -u -N -r kfifo1/drivers/usb/host/fhci.h kfifo2/drivers/usb/host/fhci.h
--- kfifo1/drivers/usb/host/fhci.h      2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/usb/host/fhci.h      2009-10-19 20:58:34.000000000 +0200
@@ -495,7 +495,7 @@
 /* fifo of pointers */
 static inline int cq_new(struct kfifo *fifo, int size)
 {
-       return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL);
+       return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
diff -u -N -r kfifo1/drivers/usb/serial/generic.c kfifo2/drivers/usb/serial/generic.c
--- kfifo1/drivers/usb/serial/generic.c 2009-10-19 21:00:10.000000000 +0200
+++ kfifo2/drivers/usb/serial/generic.c 2009-10-19 20:58:34.000000000 +0200
@@ -285,7 +285,7 @@
                return 0;
 
        data = port->write_urb->transfer_buffer;
-       count = kfifo_get(port->write_fifo, data, port->bulk_out_size);
+       count = kfifo_get_locked(port->write_fifo, data, port->bulk_out_size, &port->lock);
        usb_serial_debug_data(debug, &port->dev, __func__, count, data);
 
        /* set up our urb */
@@ -345,7 +345,7 @@
                return usb_serial_multi_urb_write(tty, port,
                                                  buf, count);
 
-       count = kfifo_put(port->write_fifo, buf, count);
+       count = kfifo_put_locked(port->write_fifo, buf, count, &port->lock);
        result = usb_serial_generic_write_start(port);
 
        if (result >= 0)
diff -u -N -r kfifo1/drivers/usb/serial/usb-serial.c kfifo2/drivers/usb/serial/usb-serial.c
--- kfifo1/drivers/usb/serial/usb-serial.c      2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/drivers/usb/serial/usb-serial.c      2009-10-19 20:58:34.000000000 +0200
@@ -966,8 +966,7 @@
                        dev_err(&interface->dev, "No free urbs available\n");
                        goto probe_error;
                }
-               if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL,
-                       &port->lock))
+               if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL))
                        goto probe_error;
                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                port->bulk_out_size = buffer_size;
diff -u -N -r kfifo1/include/linux/kfifo.h kfifo2/include/linux/kfifo.h
--- kfifo1/include/linux/kfifo.h        2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/include/linux/kfifo.h        2009-10-19 20:58:34.000000000 +0200
@@ -30,13 +30,12 @@
        unsigned int size;      /* the size of the allocated buffer */
        unsigned int in;        /* data is added at offset (in % size) */
        unsigned int out;       /* data is extracted from off. (out % size) */
-       spinlock_t *lock;       /* protects concurrent modifications */
 };
 
 extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-                       unsigned int size, spinlock_t *lock);
+                       unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
-                       gfp_t gfp_mask, spinlock_t *lock);
+                       gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
                                const unsigned char *buffer, unsigned int len);
@@ -58,58 +57,67 @@
  */
 static inline void kfifo_reset(struct kfifo *fifo)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(fifo->lock, flags);
-
        __kfifo_reset(fifo);
+}
+
+/**
+ * __kfifo_len - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline unsigned int __kfifo_len(struct kfifo *fifo)
+{
+       register unsigned int   out;
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       out = fifo->out;
+       smp_rmb();
+       return fifo->in - out;
 }
 
 /**
- * kfifo_put - puts some data into the FIFO
+ * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
+ * @from: the data to be added.
  * @len: the length of the data to be added.
+ * @lock: pointer to the spinlock to use for locking.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline unsigned int kfifo_put(struct kfifo *fifo,
-                               const unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
+               const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
        unsigned long flags;
        unsigned int ret;
 
-       spin_lock_irqsave(fifo->lock, flags);
+       spin_lock_irqsave(lock, flags);
 
-       ret = __kfifo_put(fifo, buffer, len);
+       ret = __kfifo_put(fifo, from, n);
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       spin_unlock_irqrestore(lock, flags);
 
        return ret;
 }
 
 /**
- * kfifo_get - gets some data from the FIFO
+ * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
+ * @to: where the data must be copied.
  * @len: the size of the destination buffer.
+ * @lock: pointer to the spinlock to use for locking.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  */
-static inline unsigned int kfifo_get(struct kfifo *fifo,
-                                    unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
+       unsigned char *to, unsigned int n, spinlock_t *lock)
 {
        unsigned long flags;
        unsigned int ret;
 
-       spin_lock_irqsave(fifo->lock, flags);
+       spin_lock_irqsave(lock, flags);
 
-       ret = __kfifo_get(fifo, buffer, len);
+       ret = __kfifo_get(fifo, to, n);
 
        /*
         * optimization: if the FIFO is empty, set the indices to 0
@@ -118,36 +126,18 @@
        if (fifo->in == fifo->out)
                fifo->in = fifo->out = 0;
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       spin_unlock_irqrestore(lock, flags);
 
        return ret;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO, no locking version
- * @fifo: the fifo to be used.
- */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
-{
-       return fifo->in - fifo->out;
-}
-
-/**
  * kfifo_len - returns the number of bytes available in the FIFO
  * @fifo: the fifo to be used.
  */
 static inline unsigned int kfifo_len(struct kfifo *fifo)
 {
-       unsigned long flags;
-       unsigned int ret;
-
-       spin_lock_irqsave(fifo->lock, flags);
-
-       ret = __kfifo_len(fifo);
-
-       spin_unlock_irqrestore(fifo->lock, flags);
-
-       return ret;
+       return __kfifo_len(fifo);
 }
 
 #endif
diff -u -N -r kfifo1/kernel/kfifo.c kfifo2/kernel/kfifo.c
--- kfifo1/kernel/kfifo.c       2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/kernel/kfifo.c       2009-10-19 20:58:34.000000000 +0200
@@ -28,11 +28,10 @@
 #include <linux/log2.h>
 
 static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-               unsigned int size, spinlock_t *lock)
+               unsigned int size)
 {
        fifo->buffer = buffer;
        fifo->size = size;
-       fifo->lock = lock;
 
        kfifo_reset(fifo);
 }
@@ -42,16 +41,14 @@
  * @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.
- * @lock: the lock to be used to protect the fifo buffer
  *
  */
-void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size,
-                       spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 {
        /* size must be a power of 2 */
        BUG_ON(!is_power_of_2(size));
 
-       _kfifo_init(fifo, buffer, size, lock);
+       _kfifo_init(fifo, buffer, size);
 }
 EXPORT_SYMBOL(kfifo_init);
 
@@ -60,7 +57,6 @@
  * @fifo: the fifo to assign then new buffer
  * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
  *
  * This function dynamically allocates a new fifo internal buffer
  *
@@ -68,8 +64,7 @@
  * The buffer will be release with kfifo_free().
  * Return 0 if no error, otherwise the an error code
  */
-int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask,
-                       spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 {
        unsigned char *buffer;
 
@@ -84,11 +79,11 @@
 
        buffer = kmalloc(size, gfp_mask);
        if (!buffer) {
-               _kfifo_init(fifo, 0, 0, NULL);
+               _kfifo_init(fifo, 0, 0);
                return -ENOMEM;
        }
 
-       _kfifo_init(fifo, buffer, size, lock);
+       _kfifo_init(fifo, buffer, size);
 
        return 0;
 }
diff -u -N -r kfifo1/net/dccp/probe.c kfifo2/net/dccp/probe.c
--- kfifo1/net/dccp/probe.c     2009-10-19 20:39:24.000000000 +0200
+++ kfifo2/net/dccp/probe.c     2009-10-19 20:58:34.000000000 +0200
@@ -67,7 +67,7 @@
        len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
        va_end(args);
 
-       kfifo_put(&dccpw.fifo, tbuf, len);
+       kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
        wake_up(&dccpw.wait);
 }
 
@@ -136,7 +136,7 @@
        if (error)
                goto out_free;
 
-       cnt = kfifo_get(&dccpw.fifo, tbuf, len);
+       cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
        error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -157,7 +157,7 @@
 
        init_waitqueue_head(&dccpw.wait);
        spin_lock_init(&dccpw.lock);
-       if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock))
+       if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL))
                return ret;
        if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
                goto err0;



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/7] kfifo: move out spinlock
  2009-08-19 20:49 [PATCH 0/7] kfifo: new API v0.5 Stefani Seibold
@ 2009-08-19 20:53 ` Stefani Seibold
  0 siblings, 0 replies; 31+ messages in thread
From: Stefani Seibold @ 2009-08-19 20:53 UTC (permalink / raw)
  To: linux-kernel
  Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang, Joe Perches

Move the pointer to the spinlock out of struct kfifo. Most
users in tree do not actually use a spinlock, so the few
exceptions now have to call kfifo_{get,put}_locked, which takes
an extra argument to a spinlock.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
---
 drivers/char/nozomi.c                       |    2 
 drivers/char/sonypi.c                       |   21 ++++---
 drivers/infiniband/hw/cxgb3/cxio_resource.c |   36 +++++++------
 drivers/media/video/meye.c                  |   35 +++++++-----
 drivers/net/wireless/libertas/main.c        |    2 
 drivers/platform/x86/fujitsu-laptop.c       |   18 +++---
 drivers/platform/x86/sony-laptop.c          |   22 ++++----
 drivers/scsi/libiscsi.c                     |    2 
 drivers/scsi/libiscsi_tcp.c                 |    2 
 drivers/scsi/libsrp.c                       |    9 +--
 drivers/usb/host/fhci.h                     |    2 
 include/linux/kfifo.h                       |   76 ++++++++++++----------------
 kernel/kfifo.c                              |   17 ++----
 net/dccp/probe.c                            |    6 +-
 14 files changed, 126 insertions(+), 124 deletions(-)

diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c
--- linux-2.6.31-rc4-kfifo1/drivers/char/nozomi.c	2009-08-16 21:25:14.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/char/nozomi.c	2009-08-11 12:46:56.000000000 +0200
@@ -685,7 +685,7 @@
 
 		for (i = PORT_MDM; i < MAX_PORT; i++) {
 			kfifo_alloc(&dc->port[i].fifo_ul,
-				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
+				FIFO_BUFFER_SIZE_UL, GFP_ATOMIC);
 			memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
 			memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c linux-2.6.31-rc4-kfifo2/drivers/char/sonypi.c
--- linux-2.6.31-rc4-kfifo1/drivers/char/sonypi.c	2009-08-16 21:22:46.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/char/sonypi.c	2009-08-11 12:56:44.000000000 +0200
@@ -776,8 +776,9 @@
 {
 	struct sonypi_keypress kp;
 
-	while (kfifo_get(&sonypi_device.input_fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+			 sizeof(kp), &sonypi_device.input_fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -826,8 +827,9 @@
 	if (kp.dev) {
 		input_report_key(kp.dev, kp.key, 1);
 		input_sync(kp.dev);
-		kfifo_put(&sonypi_device.input_fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sonypi_device.input_fifo,
+			(unsigned char *)&kp, sizeof(kp),
+			&sonypi_device.input_fifo_lock);
 		schedule_work(&sonypi_device.input_work);
 	}
 }
@@ -879,7 +881,8 @@
 		acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-	kfifo_put(&sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_device.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_device.fifo_lock);
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -928,7 +931,8 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_device.fifo, &c, sizeof(c),
+				 &sonypi_device.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -1312,8 +1316,7 @@
 			"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,
-					 &sonypi_device.fifo_lock);
+	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 		return error;
@@ -1393,7 +1396,7 @@
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
 		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
-				GFP_KERNEL, &sonypi_device.input_fifo_lock);
+				GFP_KERNEL);
 		if (error) {
 			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
 			goto err_inpdev_unregister;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c
--- linux-2.6.31-rc4-kfifo1/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-16 21:20:12.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/infiniband/hw/cxgb3/cxio_resource.c	2009-08-11 12:47:57.000000000 +0200
@@ -55,7 +55,7 @@
 	u32 rarray[16];
 	spin_lock_init(fifo_lock);
 
-	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL, fifo_lock))
+	if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 0; i < skip_low + skip_high; i++)
@@ -86,7 +86,8 @@
 			__kfifo_put(fifo, (unsigned char *) &i, sizeof(u32));
 
 	for (i = 0; i < skip_low + skip_high; i++)
-		kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32));
+		kfifo_get_locked(fifo, (unsigned char *) &entry,
+				sizeof(u32), fifo_lock);
 	return 0;
 }
 
@@ -113,8 +114,7 @@
 	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,
-					      &rdev_p->rscp->qpid_fifo_lock))
+					      GFP_KERNEL))
 		return -ENOMEM;
 
 	for (i = 16; i < T3_MAX_NUM_QP; i++)
@@ -177,33 +177,37 @@
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
 	u32 entry;
-	if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+	if (kfifo_get_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
 		return entry;
 	else
 		return 0;	/* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+		u32 entry)
 {
-	BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+	BUG_ON(
+	kfifo_put_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+	== 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->tpt_fifo);
+	return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-	cxio_hal_put_resource(&rscp->tpt_fifo, stag);
+	cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo);
+	u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+			&rscp->qpid_fifo_lock);
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
 	return qpid;
 }
@@ -211,27 +215,27 @@
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
 	PDBG("%s qpid 0x%x\n", __func__, qpid);
-	cxio_hal_put_resource(&rscp->qpid_fifo, qpid);
+	cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->cqid_fifo);
+	return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-	cxio_hal_put_resource(&rscp->cqid_fifo, cqid);
+	cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-	return cxio_hal_get_resource(&rscp->pdid_fifo);
+	return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-	cxio_hal_put_resource(&rscp->pdid_fifo, pdid);
+	cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c linux-2.6.31-rc4-kfifo2/drivers/media/video/meye.c
--- linux-2.6.31-rc4-kfifo1/drivers/media/video/meye.c	2009-08-16 21:14:20.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/media/video/meye.c	2009-08-09 11:40:34.000000000 +0200
@@ -799,8 +799,8 @@
 		return IRQ_HANDLED;
 
 	if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			return IRQ_HANDLED;
 		}
@@ -810,7 +810,8 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	} else {
 		int size;
@@ -819,8 +820,8 @@
 			mchip_free_frame();
 			goto again;
 		}
-		if (kfifo_get(&meye.grabq, (unsigned char *)&reqnr,
-			      sizeof(int)) != sizeof(int)) {
+		if (kfifo_get_locked(&meye.grabq, (unsigned char *)&reqnr,
+			      sizeof(int), &meye.grabq_lock) != sizeof(int)) {
 			mchip_free_frame();
 			goto again;
 		}
@@ -830,7 +831,8 @@
 		meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
 		do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
 		meye.grab_buffer[reqnr].sequence = sequence++;
-		kfifo_put(&meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+		kfifo_put_locked(&meye.doneq, (unsigned char *)&reqnr,
+				sizeof(int), &meye.doneq_lock);
 		wake_up_interruptible(&meye.proc_list);
 	}
 	mchip_free_frame();
@@ -932,7 +934,8 @@
 		mchip_cont_compression_start();
 
 	meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)nb, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+			 &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -964,7 +967,8 @@
 		/* fall through */
 	case MEYE_BUF_DONE:
 		meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-		kfifo_get(&meye.doneq, (unsigned char *)&unused, sizeof(int));
+		kfifo_get_locked(&meye.doneq, (unsigned char *)&unused,
+				sizeof(int), &meye.doneq_lock);
 	}
 	*i = meye.grab_buffer[*i].size;
 	mutex_unlock(&meye.lock);
@@ -1451,7 +1455,8 @@
 	buf->flags |= V4L2_BUF_FLAG_QUEUED;
 	buf->flags &= ~V4L2_BUF_FLAG_DONE;
 	meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-	kfifo_put(&meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+	kfifo_put_locked(&meye.grabq, (unsigned char *)&buf->index,
+			sizeof(int), &meye.grabq_lock);
 	mutex_unlock(&meye.lock);
 
 	return 0;
@@ -1477,8 +1482,8 @@
 		return -EINTR;
 	}
 
-	if (!kfifo_get(&meye.doneq, (unsigned char *)&reqnr,
-		       sizeof(int))) {
+	if (!kfifo_get_locked(&meye.doneq, (unsigned char *)&reqnr,
+		       sizeof(int), &meye.doneq_lock)) {
 		mutex_unlock(&meye.lock);
 		return -EBUSY;
 	}
@@ -1745,14 +1750,14 @@
 	}
 
 	spin_lock_init(&meye.grabq_lock);
-	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.grabq_lock)) {
+	if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc1;
 	}
 	spin_lock_init(&meye.doneq_lock);
-	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-				 &meye.doneq_lock)) {
+	if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+				GFP_KERNEL)) {
 		printk(KERN_ERR "meye: fifo allocation failed\n");
 		goto outkfifoalloc2;
 	}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c
--- linux-2.6.31-rc4-kfifo1/drivers/net/wireless/libertas/main.c	2009-08-16 21:25:46.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/net/wireless/libertas/main.c	2009-08-11 12:45:53.000000000 +0200
@@ -1121,7 +1121,7 @@
 	priv->resp_len[0] = priv->resp_len[1] = 0;
 
 	/* Create the event FIFO */
-	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL, NULL);
+	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
 	if (ret) {
 		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
 		goto out;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c linux-2.6.31-rc4-kfifo2/drivers/platform/x86/fujitsu-laptop.c
--- linux-2.6.31-rc4-kfifo1/drivers/platform/x86/fujitsu-laptop.c	2009-08-16 21:01:06.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/platform/x86/fujitsu-laptop.c	2009-08-11 22:46:08.000000000 +0200
@@ -834,7 +834,7 @@
 	/* kfifo */
 	spin_lock_init(&fujitsu_hotkey->fifo_lock);
 	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
-			GFP_KERNEL, &fujitsu_hotkey->fifo_lock);
+			GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR "kfifo_alloc failed\n");
 		goto err_stop;
@@ -1007,9 +1007,10 @@
 				vdbg_printk(FUJLAPTOP_DBG_TRACE,
 					"Push keycode into ringbuffer [%d]\n",
 					keycode);
-				status = kfifo_put(&fujitsu_hotkey->fifo,
+				status = kfifo_put_locked(&fujitsu_hotkey->fifo,
 						   (unsigned char *)&keycode,
-						   sizeof(keycode));
+						   sizeof(keycode),
+						   &fujitsu_hotkey->fifo_lock);
 				if (status != sizeof(keycode)) {
 					vdbg_printk(FUJLAPTOP_DBG_WARN,
 					    "Could not push keycode [0x%x]\n",
@@ -1020,11 +1021,12 @@
 				}
 			} else if (keycode == 0) {
 				while ((status =
-					kfifo_get
-					(&fujitsu_hotkey->fifo, (unsigned char *)
-					 &keycode_r,
-					 sizeof
-					 (keycode_r))) == sizeof(keycode_r)) {
+					kfifo_get_locked(
+					 &fujitsu_hotkey->fifo,
+					 (unsigned char *) &keycode_r,
+					 sizeof(keycode_r),
+					 &fujitsu_hotkey->fifo_lock))
+					 == sizeof(keycode_r)) {
 					input_report_key(input, keycode_r, 0);
 					input_sync(input);
 					vdbg_printk(FUJLAPTOP_DBG_TRACE,
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c
--- linux-2.6.31-rc4-kfifo1/drivers/platform/x86/sony-laptop.c	2009-08-16 21:11:55.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/platform/x86/sony-laptop.c	2009-08-11 12:49:23.000000000 +0200
@@ -300,8 +300,9 @@
 {
 	struct sony_laptop_keypress kp;
 
-	while (kfifo_get(&sony_laptop_input.fifo, (unsigned char *)&kp,
-			 sizeof(kp)) == sizeof(kp)) {
+	while (kfifo_get_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+			sizeof(kp), &sony_laptop_input.fifo_lock)
+			== sizeof(kp)) {
 		msleep(10);
 		input_report_key(kp.dev, kp.key, 0);
 		input_sync(kp.dev);
@@ -362,8 +363,9 @@
 		/* we emit the scancode so we can always remap the key */
 		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
-		kfifo_put(&sony_laptop_input.fifo,
-			  (unsigned char *)&kp, sizeof(kp));
+		kfifo_put_locked(&sony_laptop_input.fifo,
+			  (unsigned char *)&kp, sizeof(kp),
+			  &sony_laptop_input.fifo_lock);
 
 		if (!work_pending(&sony_laptop_release_key_work))
 			queue_work(sony_laptop_input.wq,
@@ -386,8 +388,7 @@
 	/* kfifo */
 	spin_lock_init(&sony_laptop_input.fifo_lock);
 	error =
-	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-			    &sony_laptop_input.fifo_lock);
+	 kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		goto err_dec_users;
@@ -2143,7 +2144,8 @@
 		return ret;
 
 	while (ret < count &&
-	       (kfifo_get(&sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+	       (kfifo_get_locked(&sonypi_compat.fifo, &c, sizeof(c),
+			  &sonypi_compat.fifo_lock) == sizeof(c))) {
 		if (put_user(c, buf++))
 			return -EFAULT;
 		ret++;
@@ -2322,7 +2324,8 @@
 
 static void sonypi_compat_report_event(u8 event)
 {
-	kfifo_put(&sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+	kfifo_put_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+			sizeof(event), &sonypi_compat.fifo_lock);
 	kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2333,8 +2336,7 @@
 
 	spin_lock_init(&sonypi_compat.fifo_lock);
 	error =
-	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-					 &sonypi_compat.fifo_lock);
+	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
 		printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
 		return error;
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi.c	2009-08-16 21:29:03.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi.c	2009-08-09 16:15:00.000000000 +0200
@@ -2121,7 +2121,7 @@
 	if (q->pool == NULL)
 		return -ENOMEM;
 
-	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*), NULL);
+	kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
 	for (i = 0; i < max; i++) {
 		q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libiscsi_tcp.c	2009-08-16 21:24:53.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libiscsi_tcp.c	2009-08-11 22:41:11.000000000 +0200
@@ -1128,7 +1128,7 @@
 
 		/* R2T xmit queue */
 		if (kfifo_alloc(&tcp_task->r2tqueue,
-		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL)) {
+		      session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
 			iscsi_pool_free(&tcp_task->r2tpool);
 			goto r2t_alloc_fail;
 		}
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c
--- linux-2.6.31-rc4-kfifo1/drivers/scsi/libsrp.c	2009-08-16 21:29:13.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/scsi/libsrp.c	2009-08-09 16:18:53.000000000 +0200
@@ -58,8 +58,7 @@
 		goto free_pool;
 
 	spin_lock_init(&q->lock);
-	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *),
-			      &q->lock);
+	kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
 	for (i = 0, iue = q->items; i < max; i++) {
 		__kfifo_put(&q->queue, (void *) &iue, sizeof(void *));
@@ -164,7 +163,8 @@
 {
 	struct iu_entry *iue = NULL;
 
-	kfifo_get(&target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_get_locked(&target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &target->iu_queue.lock);
 	if (!iue)
 		return iue;
 	iue->target = target;
@@ -176,7 +176,8 @@
 
 void srp_iu_put(struct iu_entry *iue)
 {
-	kfifo_put(&iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+	kfifo_put_locked(&iue->target->iu_queue.queue, (void *) &iue,
+			sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
diff -u -N -r linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h
--- linux-2.6.31-rc4-kfifo1/drivers/usb/host/fhci.h	2009-08-16 21:25:35.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/drivers/usb/host/fhci.h	2009-08-11 12:46:08.000000000 +0200
@@ -495,7 +495,7 @@
 /* fifo of pointers */
 static inline int cq_new(struct kfifo *fifo, int size)
 {
-	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL, NULL);
+	return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
diff -u -N -r linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo1/include/linux/kfifo.h	2009-08-16 22:14:30.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/include/linux/kfifo.h	2009-08-16 22:18:26.000000000 +0200
@@ -30,13 +30,12 @@
 	unsigned int size;	/* the size of the allocated buffer */
 	unsigned int in;	/* data is added at offset (in % size) */
 	unsigned int out;	/* data is extracted from off. (out % size) */
-	spinlock_t *lock;	/* protects concurrent modifications */
 };
 
 extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-			unsigned int size, spinlock_t *lock);
+			unsigned int size);
 extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
-			gfp_t gfp_mask, spinlock_t *lock);
+			gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
 				const unsigned char *buffer, unsigned int len);
@@ -58,58 +57,67 @@
  */
 static inline void kfifo_reset(struct kfifo *fifo)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
 	__kfifo_reset(fifo);
+}
+
+/**
+ * __kfifo_len - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline unsigned int __kfifo_len(struct kfifo *fifo)
+{
+	register unsigned int	out;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	out = fifo->out;
+	smp_rmb();
+	return fifo->in - out;
 }
 
 /**
- * kfifo_put - puts some data into the FIFO
+ * kfifo_put_locked - puts some data into the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
+ * @from: the data to be added.
  * @len: the length of the data to be added.
+ * @lock: pointer to the spinlock to use for locking.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline unsigned int kfifo_put(struct kfifo *fifo,
-				const unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_put_locked(struct kfifo *fifo,
+		const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_put(fifo, buffer, len);
+	ret = __kfifo_put(fifo, from, n);
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * kfifo_get - gets some data from the FIFO
+ * kfifo_get_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
+ * @to: where the data must be copied.
  * @len: the size of the destination buffer.
+ * @lock: pointer to the spinlock to use for locking.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  */
-static inline unsigned int kfifo_get(struct kfifo *fifo,
-				     unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_get_locked(struct kfifo *fifo,
+	unsigned char *to, unsigned int n, spinlock_t *lock)
 {
 	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(fifo->lock, flags);
+	spin_lock_irqsave(lock, flags);
 
-	ret = __kfifo_get(fifo, buffer, len);
+	ret = __kfifo_get(fifo, to, n);
 
 	/*
 	 * optimization: if the FIFO is empty, set the indices to 0
@@ -118,36 +126,18 @@
 	if (fifo->in == fifo->out)
 		fifo->in = fifo->out = 0;
 
-	spin_unlock_irqrestore(fifo->lock, flags);
+	spin_unlock_irqrestore(lock, flags);
 
 	return ret;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO, no locking version
- * @fifo: the fifo to be used.
- */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
-{
-	return fifo->in - fifo->out;
-}
-
-/**
  * kfifo_len - returns the number of bytes available in the FIFO
  * @fifo: the fifo to be used.
  */
 static inline unsigned int kfifo_len(struct kfifo *fifo)
 {
-	unsigned long flags;
-	unsigned int ret;
-
-	spin_lock_irqsave(fifo->lock, flags);
-
-	ret = __kfifo_len(fifo);
-
-	spin_unlock_irqrestore(fifo->lock, flags);
-
-	return ret;
+	return __kfifo_len(fifo);
 }
 
 #endif
diff -u -N -r linux-2.6.31-rc4-kfifo1/kernel/kfifo.c linux-2.6.31-rc4-kfifo2/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo1/kernel/kfifo.c	2009-08-16 21:34:51.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/kernel/kfifo.c	2009-08-16 22:08:37.000000000 +0200
@@ -28,11 +28,10 @@
 #include <linux/log2.h>
 
 static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
-		unsigned int size, spinlock_t *lock)
+		unsigned int size)
 {
 	fifo->buffer = buffer;
 	fifo->size = size;
-	fifo->lock = lock;
 
 	kfifo_reset(fifo);
 }
@@ -42,16 +41,14 @@
  * @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.
- * @lock: the lock to be used to protect the fifo buffer
  *
  */
-void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size,
-			spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 {
 	/* size must be a power of 2 */
 	BUG_ON(!is_power_of_2(size));
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 }
 EXPORT_SYMBOL(kfifo_init);
 
@@ -60,7 +57,6 @@
  * @fifo: the fifo to assign then new buffer
  * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
  *
  * This function dynamically allocates a new fifo internal buffer
  *
@@ -68,8 +64,7 @@
  * The buffer will be release with kfifo_free().
  * Return 0 if no error, otherwise the an error code
  */
-int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask,
-			spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 {
 	unsigned char *buffer;
 
@@ -84,11 +79,11 @@
 
 	buffer = kmalloc(size, gfp_mask);
 	if (!buffer) {
-		_kfifo_init(fifo, 0, 0, NULL);
+		_kfifo_init(fifo, 0, 0);
 		return -ENOMEM;
 	}
 
-	_kfifo_init(fifo, buffer, size, lock);
+	_kfifo_init(fifo, buffer, size);
 
 	return 0;
 }
diff -u -N -r linux-2.6.31-rc4-kfifo1/net/dccp/probe.c linux-2.6.31-rc4-kfifo2/net/dccp/probe.c
--- linux-2.6.31-rc4-kfifo1/net/dccp/probe.c	2009-08-16 21:24:04.000000000 +0200
+++ linux-2.6.31-rc4-kfifo2/net/dccp/probe.c	2009-08-11 12:50:28.000000000 +0200
@@ -67,7 +67,7 @@
 	len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
 	va_end(args);
 
-	kfifo_put(&dccpw.fifo, tbuf, len);
+	kfifo_put_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	wake_up(&dccpw.wait);
 }
 
@@ -136,7 +136,7 @@
 	if (error)
 		goto out_free;
 
-	cnt = kfifo_get(&dccpw.fifo, tbuf, len);
+	cnt = kfifo_get_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
 	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -157,7 +157,7 @@
 
 	init_waitqueue_head(&dccpw.wait);
 	spin_lock_init(&dccpw.lock);
-	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL, &dccpw.lock))
+	if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL))
 		return ret;
 	if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
 		goto err0;



^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2009-11-20  8:21 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-16 20:39 [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
2009-08-16 20:44 ` [PATCH 1/7] kfifo: move struct kfifo in place Stefani Seibold
2009-08-16 20:46 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
2009-08-16 22:58   ` Alan Cox
2009-08-16 23:34     ` Andrew Morton
2009-08-17  6:48       ` Alan Cox
2009-08-17  7:36         ` Andrew Morton
2009-08-17  8:08           ` Alan Cox
2009-08-17  8:14             ` Stefani Seibold
2009-08-17  8:21             ` Andrew Morton
2009-08-17  8:48               ` Alan Cox
2009-08-17  9:22                 ` Stefani Seibold
2009-08-17  7:46         ` Stefani Seibold
2009-08-17  8:15           ` Alan Cox
2009-08-17  8:28             ` Stefani Seibold
2009-08-17  8:53               ` Alan Cox
2009-08-17  9:26                 ` Stefani Seibold
2009-08-17  9:51                   ` Alan Cox
2009-08-17  9:52           ` Andi Kleen
2009-08-17  9:56             ` Stefani Seibold
2009-08-16 20:50 ` [PATCH 3/7] kfifo: cleanup namespace Stefani Seibold
2009-08-16 20:53 ` [PATCH 4/7] kfifo: rename kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out Stefani Seibold
2009-08-16 20:57 ` [PATCH 5/7] kfifo: add DEFINE_KFIFO and friends, add very tiny functions Stefani Seibold
2009-08-16 21:00 ` [PATCH 6/7] kfifo: add kfifo_skip, kfifo_from_user and kfifo_to_user Stefani Seibold
2009-08-16 21:03 ` [PATCH 0/7] kfifo: add record handling functions Stefani Seibold
2009-08-16 21:04 ` [PATCH 7/7] " Stefani Seibold
2009-08-16 21:08 ` [PATCH 0/7] kfifo: new API v0.4 Stefani Seibold
2009-08-19 20:49 [PATCH 0/7] kfifo: new API v0.5 Stefani Seibold
2009-08-19 20:53 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
2009-11-16 11:50 [PATCH 0/7] kfifo: new API v0.6 Stefani Seibold
2009-11-16 11:58 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold
2009-11-17 11:44   ` Roger Quadros
2009-11-20  8:15 [PATCH 0/7] kfifo: new API v0.7 Stefani Seibold
2009-11-20  8:20 ` [PATCH 2/7] kfifo: move out spinlock Stefani Seibold

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.