aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/kfifo.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 64ab045c3d9d..5d1d907378a2 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -122,6 +122,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
122 122
123 len = min(len, fifo->size - fifo->in + fifo->out); 123 len = min(len, fifo->size - fifo->in + fifo->out);
124 124
125 /*
126 * Ensure that we sample the fifo->out index -before- we
127 * start putting bytes into the kfifo.
128 */
129
130 smp_mb();
131
125 /* first put the data starting from fifo->in to buffer end */ 132 /* first put the data starting from fifo->in to buffer end */
126 l = min(len, fifo->size - (fifo->in & (fifo->size - 1))); 133 l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
127 memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l); 134 memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
@@ -129,6 +136,13 @@ unsigned int __kfifo_put(struct kfifo *fifo,
129 /* then put the rest (if any) at the beginning of the buffer */ 136 /* then put the rest (if any) at the beginning of the buffer */
130 memcpy(fifo->buffer, buffer + l, len - l); 137 memcpy(fifo->buffer, buffer + l, len - l);
131 138
139 /*
140 * Ensure that we add the bytes to the kfifo -before-
141 * we update the fifo->in index.
142 */
143
144 smp_wmb();
145
132 fifo->in += len; 146 fifo->in += len;
133 147
134 return len; 148 return len;
@@ -154,6 +168,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
154 168
155 len = min(len, fifo->in - fifo->out); 169 len = min(len, fifo->in - fifo->out);
156 170
171 /*
172 * Ensure that we sample the fifo->in index -before- we
173 * start removing bytes from the kfifo.
174 */
175
176 smp_rmb();
177
157 /* first get the data from fifo->out until the end of the buffer */ 178 /* first get the data from fifo->out until the end of the buffer */
158 l = min(len, fifo->size - (fifo->out & (fifo->size - 1))); 179 l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
159 memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l); 180 memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
@@ -161,6 +182,13 @@ unsigned int __kfifo_get(struct kfifo *fifo,
161 /* then get the rest (if any) from the beginning of the buffer */ 182 /* then get the rest (if any) from the beginning of the buffer */
162 memcpy(buffer + l, fifo->buffer, len - l); 183 memcpy(buffer + l, fifo->buffer, len - l);
163 184
185 /*
186 * Ensure that we remove the bytes from the kfifo -before-
187 * we update the fifo->out index.
188 */
189
190 smp_mb();
191
164 fifo->out += len; 192 fifo->out += len;
165 193
166 return len; 194 return len;