Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
This commit is contained in:
@@ -281,6 +281,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
|
||||
{
|
||||
RING_IDX req_prod = queue->rx.req_prod_pvt;
|
||||
int notify;
|
||||
int err = 0;
|
||||
|
||||
if (unlikely(!netif_carrier_ok(queue->info->netdev)))
|
||||
return;
|
||||
@@ -295,8 +296,10 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
|
||||
struct xen_netif_rx_request *req;
|
||||
|
||||
skb = xennet_alloc_one_rx_buffer(queue);
|
||||
if (!skb)
|
||||
if (!skb) {
|
||||
err = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
id = xennet_rxidx(req_prod);
|
||||
|
||||
@@ -320,8 +323,13 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
|
||||
|
||||
queue->rx.req_prod_pvt = req_prod;
|
||||
|
||||
/* Not enough requests? Try again later. */
|
||||
if (req_prod - queue->rx.sring->req_prod < NET_RX_SLOTS_MIN) {
|
||||
/* Try again later if there are not enough requests or skb allocation
|
||||
* failed.
|
||||
* Enough requests is quantified as the sum of newly created slots and
|
||||
* the unconsumed slots at the backend.
|
||||
*/
|
||||
if (req_prod - queue->rx.rsp_cons < NET_RX_SLOTS_MIN ||
|
||||
unlikely(err)) {
|
||||
mod_timer(&queue->rx_refill_timer, jiffies + (HZ/10));
|
||||
return;
|
||||
}
|
||||
@@ -1377,6 +1385,8 @@ static void xennet_disconnect_backend(struct netfront_info *info)
|
||||
for (i = 0; i < num_queues && info->queues; ++i) {
|
||||
struct netfront_queue *queue = &info->queues[i];
|
||||
|
||||
del_timer_sync(&queue->rx_refill_timer);
|
||||
|
||||
if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
|
||||
unbind_from_irqhandler(queue->tx_irq, queue);
|
||||
if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
|
||||
@@ -1731,7 +1741,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
|
||||
|
||||
if (netif_running(info->netdev))
|
||||
napi_disable(&queue->napi);
|
||||
del_timer_sync(&queue->rx_refill_timer);
|
||||
netif_napi_del(&queue->napi);
|
||||
}
|
||||
|
||||
@@ -1820,27 +1829,19 @@ static int talk_to_netback(struct xenbus_device *dev,
|
||||
xennet_destroy_queues(info);
|
||||
|
||||
err = xennet_create_queues(info, &num_queues);
|
||||
if (err < 0)
|
||||
goto destroy_ring;
|
||||
if (err < 0) {
|
||||
xenbus_dev_fatal(dev, err, "creating queues");
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create shared ring, alloc event channel -- for each queue */
|
||||
for (i = 0; i < num_queues; ++i) {
|
||||
queue = &info->queues[i];
|
||||
err = setup_netfront(dev, queue, feature_split_evtchn);
|
||||
if (err) {
|
||||
/* setup_netfront() will tidy up the current
|
||||
* queue on error, but we need to clean up
|
||||
* those already allocated.
|
||||
*/
|
||||
if (i > 0) {
|
||||
rtnl_lock();
|
||||
netif_set_real_num_tx_queues(info->netdev, i);
|
||||
rtnl_unlock();
|
||||
goto destroy_ring;
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
goto destroy_ring;
|
||||
}
|
||||
|
||||
again:
|
||||
@@ -1930,9 +1931,10 @@ abort_transaction_no_dev_fatal:
|
||||
xenbus_transaction_end(xbt, 1);
|
||||
destroy_ring:
|
||||
xennet_disconnect_backend(info);
|
||||
kfree(info->queues);
|
||||
info->queues = NULL;
|
||||
xennet_destroy_queues(info);
|
||||
out:
|
||||
unregister_netdev(info->netdev);
|
||||
xennet_free_netdev(info->netdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user