[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC] xen/public/ring.h: simplify RING_HAS_UNCONSUMED_REQUESTS()
[CC's clipped] At 17:38 +0100 on 13 Mar (1394728686), Tim Deegan wrote: > [RFC] xen/public/ring.h: simplify RING_HAS_UNCONSUMED_REQUESTS() > > Remove a useless (though harmless) extra check. What shall we do about this? AFAICT, Jan and Paul are in favour of the change; Zoltan is against it. I am wavering. Keir, any opinion? Tim. > Code inspection > --------------- > > Ian Campbell and I looked at this today and can't find any case where > the existing 'rsp' test would be useful. In today's ring.h, > > #define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \ > unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ > unsigned int rsp = RING_SIZE(_r) - \ > ((_r)->req_cons - (_r)->rsp_prod_pvt); \ > req < rsp ? req : rsp; \ > }) > > 'req' is the number of requests that the F/E has published and we have > not yet consumed. 'rsp' is an odd fish, everything _except_ what we > might call requests locally in flight, that is requests we've consumed > but not produced a response for. We could only think of two things we > might be trying to test for here: > > (a) req_cons runs ahead of rsp_prod_pvt, as would be expected from the > way these rings normally work. In that case, as Zoltan pointed > out, rsp must be >= req, for a well-behaved frontend: otherwise > we'd have req_prod > rsp_prod_pvt + RING_SIZE, implying that > req_prod > rsp_cons + RING_SIZE, i.e. the frontend has overrun > the ring. I don't think this even usefully protects against a > malicious/buggy frontend. > > (b) rsp_prod_pvt runs ahead of req_cons, which seems wrong but I'm > told might happen in linux netback? In that case, we might plausibly > want to try to limit RING_HAS_UNCONSUMED_REQUESTS to max of > (req_prod - req_cons) and (req_prod - rsp_prod_pvt), but that's > not what this does. Instead, rsp will underflow to > RING_SIZE + (rsp_prod_pvt - req_cons), which will always be >= req. > > So in both of those cases, 'rsp' is always >= 'req' and is useless. > > > Code archaeology > ---------------- > > In the original ring.h, the test was a boolean, as the name implies. > Cset 99812f40 ([NET] back: Add SG support) extended it to a count in > the obvious manner. Looking at the original (0b788798): > > #define RING_HAS_UNCONSUMED_REQUESTS(_p, _r) \ > ( ((_r)->req_cons != (_r)->sring->req_prod ) && \ > (((_r)->req_cons - (_r)->rsp_prod_pvt) != \ > SRING_SIZE((_p), (_r)->sring)) ) > > it seems to be testing for 'there are unconsumed requests _and_ we > have not got a full ring of consumed-but-not-responded requests'. > This also seems to be effectively harmless: if there are unconsumed > requests, we can't possibly have a ring full of c-b-n-r requests > unless the frontend's request producer has overrun its response > consumer. > > That code was introduced with no callers, but seems to have been > copied from the existing netback code, which switched to use it in > b242b208. All later users of it in the xenolinux trees are either > brand new code or replacing a simple (req_cons - req_prod) test. The > netback code goes back to Keir's original implementation, where it > looked like this, in inverted form (1de448f4): > > /* Work to do? */ > i = netif->tx_req_cons; > if ( (i == netif->tx->req_prod) || > ((i-netif->tx_resp_prod) == NETIF_TX_RING_SIZE) ) > { > netif_put(netif); > continue; > } > > Again, I don't think this test is useful: it's only interesting if > netfront has overrun the ring, but it doesn't reliably detect that. > > So let's remove it. > > Suggested-by: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx> > Signed-off-by: Tim Deegan <tim@xxxxxxx> > Cc: Keir Fraser <keir@xxxxxxx> > Cc: Jan Beulich <JBeulich@xxxxxxxx> > Cc: Ian Campbell <Ian.Campbell@xxxxxxxxxx> > Cc: Wei Liu <wei.liu2@xxxxxxxxxx> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> > Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> > Cc: David Vrabel <david.vrabel@xxxxxxxxxx> > Cc: Alan Somers <alans@xxxxxxxxxxxxxxxx> > Cc: John Suykerbuyk <johns@xxxxxxxxxxxxxxxx> > Cc: Manuel Bouyer <bouyer@xxxxxxxxxx> > Cc: Paul Durrant <Paul.Durrant@xxxxxxxxxx> > Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > > --- > RFC because > - I might well be missing something here; and > - this is a change to a public header that could be in use in any > number of implementations; since the extra test is very cheap, and > seems to be harmess, we might consider leaving it in place. > - I haven't tested it at all yet. > > CC'ing a whole bunch of people whose code might be using this macro. > > diff --git a/xen/include/public/io/ring.h b/xen/include/public/io/ring.h > index 73e13d7..d6e23f1 100644 > --- a/xen/include/public/io/ring.h > +++ b/xen/include/public/io/ring.h > @@ -192,21 +192,8 @@ typedef struct __name##_back_ring __name##_back_ring_t > #define RING_HAS_UNCONSUMED_RESPONSES(_r) \ > ((_r)->sring->rsp_prod - (_r)->rsp_cons) > > -#ifdef __GNUC__ > -#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \ > - unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ > - unsigned int rsp = RING_SIZE(_r) - \ > - ((_r)->req_cons - (_r)->rsp_prod_pvt); \ > - req < rsp ? req : rsp; \ > -}) > -#else > -/* Same as above, but without the nice GCC ({ ... }) syntax. */ > #define RING_HAS_UNCONSUMED_REQUESTS(_r) \ > - ((((_r)->sring->req_prod - (_r)->req_cons) < \ > - (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \ > - ((_r)->sring->req_prod - (_r)->req_cons) : \ > - (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) > -#endif > + ((_r)->sring->req_prod - (_r)->req_cons) > > /* Direct access to individual ring elements, by index. */ > #define RING_GET_REQUEST(_r, _idx) \ > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |