if (!skb_queue_empty(&ncrp->pending_tx_queue)) {
skb = __skb_dequeue(&ncrp->pending_tx_queue);
do {
- nc2_really_start_xmit(ncrp, skb);
+ if (!nc2_really_start_xmit(ncrp, skb)) {
+ /* Requeue the packet so that we will try
+ when the ring is less busy */
+ __skb_queue_head(&ncrp->pending_tx_queue, skb);
+ break;
+ }
skb = __skb_dequeue(&ncrp->pending_tx_queue);
} while (skb != NULL);
struct netchannel2 *nc2_get_interface_for_page(struct page *p);
int nc2_start_xmit(struct sk_buff *skb, struct net_device *dev);
-void nc2_really_start_xmit(struct netchannel2_ring_pair *ncrp,
+int nc2_really_start_xmit(struct netchannel2_ring_pair *ncrp,
struct sk_buff *skb);
int prepare_xmit_allocate_resources(struct netchannel2 *nc,
struct sk_buff *skb);
/* Once this has been called, the ring must not be flushed until the
TX hypercall batcher is (assuming this ring has a hypercall
batcher). */
-void nc2_really_start_xmit(struct netchannel2_ring_pair *ncrp,
- struct sk_buff *skb)
+int nc2_really_start_xmit(struct netchannel2_ring_pair *ncrp,
+ struct sk_buff *skb)
{
struct skb_cb_overlay *skb_co = get_skb_overlay(skb);
struct netchannel2 *nc = ncrp->interface;
if (!nc2_can_send_payload_bytes(&ncrp->prod_ring, msg_size)) {
/* Aw, crud. We had to transmit a PAD message at just
the wrong time, and our attempt to reserve ring
- space failed. Back all the way back out of
- transmitting this packet, stop the queue, and get
- out. */
- nc = ncrp->interface;
- if (ncrp == &nc->rings) {
- /* Requeue the packet so that we'll try again
- when the ring's less busy */
- __skb_queue_head(&nc->pending_skbs, skb);
- nc->is_stopped = 1;
- netif_stop_queue(nc->net_device);
- } else {
- /* Just drop it on the floor. There isn't
- really anything else we can do. */
- release_tx_packet(ncrp, skb);
- }
- return;
+ space failed. Delay transmiting this packet
+ Make sure we redo the space reserve */
+ ncrp->prod_ring.reserve += msg_size;
+ return 0;
}
-
__nc2_avoid_ring_wrap(&ncrp->prod_ring, msg_size);
/* Set up part of the message. We do the message header
ncrp->need_flush = 1;
EXIT();
+
+ return 1;
}
/* Arrange that @skb will be sent on ring @ncrp soon. Assumes that