backports: fix kfifo_put()
authorHauke Mehrtens <hauke@hauke-m.de>
Wed, 6 Nov 2013 18:40:43 +0000 (19:40 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 7 Nov 2013 19:15:41 +0000 (20:15 +0100)
kfifo_put() now gets the second parameter by value and not by reference
any more. This replaces the in kernel implementation of kfifo_put()
with a version which is compatible to the in kernel structures but
takes the value and not a reference to the value. We wanted to do this:
 #define kfifo_put(fifo, val) kfifo_put(fifo, &val)

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
backport/backport-include/linux/kfifo.h

index 1850038080713c4ab192b0477e4f34f6856e95dd..379c1cb8ad5852e17da7ea173f59dab6284f30c5 100644 (file)
@@ -5,6 +5,51 @@
 #else
 #include <linux/kfifo-new.h>
 #endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0)
+#undef kfifo_put
+/**
+ * kfifo_put - put data into the fifo
+ * @fifo: address of the fifo to be used
+ * @val: the data to be added
+ *
+ * This macro copies the given value into the fifo.
+ * It returns 0 if the fifo was full. Otherwise it returns the number
+ * processed elements.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these macro.
+ */
+#define        kfifo_put(fifo, val) \
+({ \
+       typeof((fifo) + 1) __tmp = (fifo); \
+       typeof((&val) + 1) __val = (&val); \
+       unsigned int __ret; \
+       const size_t __recsize = sizeof(*__tmp->rectype); \
+       struct __kfifo *__kfifo = &__tmp->kfifo; \
+       if (0) { \
+               typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
+               __dummy = (typeof(__val))NULL; \
+       } \
+       if (__recsize) \
+               __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \
+                       __recsize); \
+       else { \
+               __ret = !kfifo_is_full(__tmp); \
+               if (__ret) { \
+                       (__is_kfifo_ptr(__tmp) ? \
+                       ((typeof(__tmp->type))__kfifo->data) : \
+                       (__tmp->buf) \
+                       )[__kfifo->in & __tmp->kfifo.mask] = \
+                               *(typeof(__tmp->type))__val; \
+                       smp_wmb(); \
+                       __kfifo->in++; \
+               } \
+       } \
+       __ret; \
+})
+#endif
+
 #else
 /*
  * A generic kernel FIFO implementation