Skip to content

Commit

Permalink
virtio: populate network rings in the probe routine, not open
Browse files Browse the repository at this point in the history
Since we want to reset the device to remove them, this is simpler
(device is reset for us on driver remove).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
Rusty Russell committed Feb 4, 2008
1 parent 34a4857 commit b3369c1
Showing 1 changed file with 25 additions and 19 deletions.
44 changes: 25 additions & 19 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,35 +282,16 @@ static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);

try_fill_recv(vi);

/* If we didn't even get one input buffer, we're useless. */
if (vi->num == 0)
return -ENOMEM;

napi_enable(&vi->napi);
return 0;
}

static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
struct sk_buff *skb;

napi_disable(&vi->napi);

/* networking core has neutered skb_xmit_done/skb_recv_done, so don't
* worry about races vs. get(). */
vi->rvq->vq_ops->shutdown(vi->rvq);
while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
kfree_skb(skb);
vi->num--;
}
vi->svq->vq_ops->shutdown(vi->svq);
while ((skb = __skb_dequeue(&vi->send)) != NULL)
kfree_skb(skb);

BUG_ON(vi->num != 0);
return 0;
}

Expand Down Expand Up @@ -379,10 +360,22 @@ static int virtnet_probe(struct virtio_device *vdev)
pr_debug("virtio_net: registering device failed\n");
goto free_send;
}

/* Last of all, set up some receive buffers. */
try_fill_recv(vi);

/* If we didn't even get one input buffer, we're useless. */
if (vi->num == 0) {
err = -ENOMEM;
goto unregister;
}

pr_debug("virtnet: registered device %s\n", dev->name);
vdev->priv = vi;
return 0;

unregister:
unregister_netdev(dev);
free_send:
vdev->config->del_vq(vi->svq);
free_recv:
Expand All @@ -395,6 +388,19 @@ static int virtnet_probe(struct virtio_device *vdev)
static void virtnet_remove(struct virtio_device *vdev)
{
struct virtnet_info *vi = vdev->priv;
struct sk_buff *skb;

/* Free our skbs in send and recv queues, if any. */
vi->rvq->vq_ops->shutdown(vi->rvq);
while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
kfree_skb(skb);
vi->num--;
}
vi->svq->vq_ops->shutdown(vi->svq);
while ((skb = __skb_dequeue(&vi->send)) != NULL)
kfree_skb(skb);

BUG_ON(vi->num != 0);

vdev->config->del_vq(vi->svq);
vdev->config->del_vq(vi->rvq);
Expand Down

0 comments on commit b3369c1

Please sign in to comment.