On Thu, 2014-03-20 at 19:32 +0000, Zoltan Kiss wrote:The backend doesn't see what the guest does with the responses, and that's OK, it's the guest's problem, after netback increased rsp_prod_pvt it doesn't really care. But as soon as the guest start placing new requests after rsp_prod_pvt, or just increasing req_prod so req_prod-rsp_prod_pvt > XEN_NETIF_TX_RING_SIZE, it becomes an issue.
Since the early days TX stops if there isn't enough free pending slots to
consume a maximum sized (slot-wise) packet. Probably the reason for that is to
avoid the case when we don't have enough free pending slot in the ring to finish
the packet. But if we make sure that the pending ring has the same size as the
shared ring, that shouldn't really happen. The frontend can only post packets
which fit the to the free space of the shared ring. If it doesn't, the frontend
has to stop, as it can only increase the req_prod when the whole packet fits
onto the ring.
My only real concern here is that by removing these checks we are
introducing a way for a malicious or buggy guest to trigger misbehaviour
in the backend, leading to e.g. a DoS.
Should we need to some sanity checks which shutdown the ring if
something like this occurs? i.e. if we come to consume a packet and
there is insufficient space on the pending ring we kill the vif.
Yes, it is __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
What's the invariant we are relying on here, is it:
req_prod >= req_cons >= pending_prod >= pending_cons >= rsp_prod >= rsp_cons
?
This patch avoid using this checking, makes sure the 2 ring has the same size,
and remove a checking from the callback. As now we don't stop the NAPI instance
on this condition, we don't have to wake it up if we free pending slots up.
Signed-off-by: Zoltan Kiss <zoltan.kiss@xxxxxxxxxx>
---
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index bef37be..a800a8e 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -81,7 +81,7 @@ struct xenvif_rx_meta {
#define MAX_BUFFER_OFFSET PAGE_SIZE
-#define MAX_PENDING_REQS 256
+#define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE
XEN_NETIF_TX_RING_SIZE is already == 256, right? (Just want to make sure
this is semantically no change).