fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / kernel / kfifo.c
index 2fbe06a..5d1d907 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/err.h>
 #include <linux/kfifo.h>
 
-/*
+/**
  * kfifo_init - allocates a new FIFO using a preallocated buffer
  * @buffer: the preallocated buffer to be used.
  * @size: the size of the internal buffer, this have to be a power of 2.
@@ -36,7 +36,7 @@
  * struct kfifo with kfree().
  */
 struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
-                        int gfp_mask, spinlock_t *lock)
+                        gfp_t gfp_mask, spinlock_t *lock)
 {
        struct kfifo *fifo;
 
@@ -56,7 +56,7 @@ struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
 }
 EXPORT_SYMBOL(kfifo_init);
 
-/*
+/**
  * kfifo_alloc - allocates a new FIFO and its internal buffer
  * @size: the size of the internal buffer to be allocated.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(kfifo_init);
  *
  * The size will be rounded-up to a power of 2.
  */
-struct kfifo *kfifo_alloc(unsigned int size, int gfp_mask, spinlock_t *lock)
+struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
 {
        unsigned char *buffer;
        struct kfifo *ret;
@@ -91,7 +91,7 @@ struct kfifo *kfifo_alloc(unsigned int size, int gfp_mask, spinlock_t *lock)
 }
 EXPORT_SYMBOL(kfifo_alloc);
 
-/*
+/**
  * kfifo_free - frees the FIFO
  * @fifo: the fifo to be freed.
  */
@@ -102,7 +102,7 @@ void kfifo_free(struct kfifo *fifo)
 }
 EXPORT_SYMBOL(kfifo_free);
 
-/*
+/**
  * __kfifo_put - puts some data into the FIFO, no locking version
  * @fifo: the fifo to be used.
  * @buffer: the data to be added.
@@ -122,6 +122,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
 
        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.
+        */
+
+       smp_mb();
+
        /* 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);
@@ -129,13 +136,20 @@ unsigned int __kfifo_put(struct kfifo *fifo,
        /* then put the rest (if any) at the beginning of the buffer */
        memcpy(fifo->buffer, buffer + l, len - l);
 
+       /*
+        * Ensure that we add the bytes to the kfifo -before-
+        * we update the fifo->in index.
+        */
+
+       smp_wmb();
+
        fifo->in += len;
 
        return len;
 }
 EXPORT_SYMBOL(__kfifo_put);
 
-/*
+/**
  * __kfifo_get - gets some data from the FIFO, no locking version
  * @fifo: the fifo to be used.
  * @buffer: where the data must be copied.
@@ -154,6 +168,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
 
        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();
+
        /* 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);
@@ -161,6 +182,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
        /* then get the rest (if any) from the beginning of the buffer */
        memcpy(buffer + l, fifo->buffer, len - l);
 
+       /*
+        * Ensure that we remove the bytes from the kfifo -before-
+        * we update the fifo->out index.
+        */
+
+       smp_mb();
+
        fifo->out += len;
 
        return len;