On Wed, 16 Apr 2014, Oliver Neukum wrote:

> Hi,
> 
> I am looking at memory ordering and a question hit me.
> I was looking at the kfifo code. kfifo_put() has a barrier:
> 
>                       )[__kfifo->in & __tmp->kfifo.mask] = \
>                               (typeof(*__tmp->type))__val; \
>                       smp_wmb(); \
>                       __kfifo->in++; \
> 
> Looking at kfifo_get() 
> 
>               __ret = !kfifo_is_empty(__tmp); \
>               if (__ret) { \
>                       *(typeof(__tmp->type))__val = \
>                               (__is_kfifo_ptr(__tmp) ? \
> 
> A thought struck me. There is no corresponding barrier. I cannot
> help myself, but I think there needs to be a smp_read_barrier_depends()
> between reading kfifo->in (in kfifo_is empty) and reading val.
> What do you think?

I think you are right.

In addition, the following code in kfifo_get() does this:

                        *(typeof(__tmp->type))__val = \
                                (__is_kfifo_ptr(__tmp) ? \
                                ((typeof(__tmp->type))__kfifo->data) : \
                                (__tmp->buf) \
                                )[__kfifo->out & __tmp->kfifo.mask]; \
                        smp_wmb(); \
                        __kfifo->out++; \

It looks like the smp_wmb() should really be smp_mb(), because it 
separates the _read_ for val from the _write_ of kfifo->out.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to