On 02/12/16 00:29, Stefano Stabellini wrote: > On Wed, 30 Nov 2016, David Vrabel wrote: >> On 29/11/16 23:34, Stefano Stabellini wrote: >>> >>> The producer (the backend for **in**, the frontend for **out**) writes to >>> the >>> array in the following way: >>> >> - read memory barrier >>> - read *cons*, *prod* from shared memory >>> - write to array at position *prod* up to *cons*, wrapping around the >>> circular >>> buffer when necessary >> - write memory barrier >>> - increase *prod* >>> - notify the other end via evtchn >>> >>> The consumer (the backend for **out**, the frontend for **in**) reads from >>> the >>> array in the following way: >> >> - read memory barrier >>> - read *prod*, *cons* from shared memory >>> - read from array at position *cons* up to *prod*, wrapping around the >>> circular >>> buffer when necessary >>> - memory barrier >>> - increase *cons* >>> - notify the other end via evtchn >> >> Your barriers are wrong (see corrections above). > > Thanks for the review. Sorry for not specifying the type of memory > barriers. I agree with some of your suggestions, but I don't understand > why you moved the read memory barrier before reading prod and cons. > > Shouldn't it be for a producer: > - read *cons*, *prod* from shared memory > - read memory barrier
Barriers must be paired to enforce the required ordering. So where you have a barrier before writing cons, you need another barrier before reading cons on the other side. This barrier here does nothing because the following access is a write and there's a data dependency here anyway. Without a barrier P before reading cons it can see the value after C as written cons but before C has actually read the requests. The Linux barrier documentation explains this better than I can. >> I think you should use a private copy of cons/prod in the >> consumer/producer and use this to validate that the shared prod/cons is >> within a sensible range. > > With the masking macro provided (MASK_XEN_9PFS_IDX), indices cannot go > out of range: > > #define MASK_XEN_9PFS_IDX(idx) ((idx) & (XEN_9PFS_RING_SIZE - 1)) For example, the producer writes cons = 0 and prod = 100000000 so although you will not index off the array, the consumer will end up processing 1000s of bogus entries. There have been XSAs where backends did not validate prod in this way. David _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org https://lists.xen.org/xen-devel