|
@@ -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,6 +136,13 @@ 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;
|
|
@@ -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;
|