summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:49:57 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:49:58 +1100
commit18445c4d501b9ab4336f66ef46b092661ddaf336 (patch)
tree9d23185f207d912942890cf047d1d3200806b401 /drivers
parenta586d4f6016f7139d8c26df0e6927131168d3b5b (diff)
downloadtalos-obmc-linux-18445c4d501b9ab4336f66ef46b092661ddaf336.tar.gz
talos-obmc-linux-18445c4d501b9ab4336f66ef46b092661ddaf336.zip
virtio: explicit enable_cb/disable_cb rather than callback return.
It seems that virtio_net wants to disable callbacks (interrupts) before calling netif_rx_schedule(), so we can't use the return value to do so. Rename "restart" to "cb_enable" and introduce "cb_disable" hook: callback now returns void, rather than a boolean. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/virtio_blk.c3
-rw-r--r--drivers/lguest/lguest_device.c2
-rw-r--r--drivers/net/virtio_net.c15
-rw-r--r--drivers/virtio/virtio_ring.c21
4 files changed, 26 insertions, 15 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 1c63d5b64c20..54a8017ad487 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -36,7 +36,7 @@ struct virtblk_req
struct virtio_blk_inhdr in_hdr;
};
-static bool blk_done(struct virtqueue *vq)
+static void blk_done(struct virtqueue *vq)
{
struct virtio_blk *vblk = vq->vdev->priv;
struct virtblk_req *vbr;
@@ -65,7 +65,6 @@ static bool blk_done(struct virtqueue *vq)
/* In case queue is stopped waiting for more buffers. */
blk_start_queue(vblk->disk->queue);
spin_unlock_irqrestore(&vblk->lock, flags);
- return true;
}
static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 07f57a53658b..ced5b44cebce 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -191,7 +191,7 @@ static void lg_notify(struct virtqueue *vq)
* So we provide devices with a "find virtqueue and set it up" function. */
static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
unsigned index,
- bool (*callback)(struct virtqueue *vq))
+ void (*callback)(struct virtqueue *vq))
{
struct lguest_device *ldev = to_lgdev(vdev);
struct lguest_vq_info *lvq;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4b8138312750..7b0059f0f5d4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -52,13 +52,12 @@ static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
}
-static bool skb_xmit_done(struct virtqueue *rvq)
+static void skb_xmit_done(struct virtqueue *rvq)
{
struct virtnet_info *vi = rvq->vdev->priv;
/* In case we were waiting for output buffers. */
netif_wake_queue(vi->dev);
- return true;
}
static void receive_skb(struct net_device *dev, struct sk_buff *skb,
@@ -161,12 +160,14 @@ static void try_fill_recv(struct virtnet_info *vi)
vi->rvq->vq_ops->kick(vi->rvq);
}
-static bool skb_recv_done(struct virtqueue *rvq)
+static void skb_recv_done(struct virtqueue *rvq)
{
struct virtnet_info *vi = rvq->vdev->priv;
- netif_rx_schedule(vi->dev, &vi->napi);
- /* Suppress further interrupts. */
- return false;
+ /* Schedule NAPI, Suppress further interrupts if successful. */
+ if (netif_rx_schedule_prep(vi->dev, &vi->napi)) {
+ rvq->vq_ops->disable_cb(rvq);
+ __netif_rx_schedule(vi->dev, &vi->napi);
+ }
}
static int virtnet_poll(struct napi_struct *napi, int budget)
@@ -192,7 +193,7 @@ again:
/* Out of packets? */
if (received < budget) {
netif_rx_complete(vi->dev, napi);
- if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq))
+ if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
&& netif_rx_reschedule(vi->dev, napi))
goto again;
}
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 1dc04b6684e6..342bb0363fbe 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -220,7 +220,17 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len)
return ret;
}
-static bool vring_restart(struct virtqueue *_vq)
+static void vring_disable_cb(struct virtqueue *_vq)
+{
+ struct vring_virtqueue *vq = to_vvq(_vq);
+
+ START_USE(vq);
+ BUG_ON(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT);
+ vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+ END_USE(vq);
+}
+
+static bool vring_enable_cb(struct virtqueue *_vq)
{
struct vring_virtqueue *vq = to_vvq(_vq);
@@ -254,8 +264,8 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
return IRQ_HANDLED;
pr_debug("virtqueue callback for %p (%p)\n", vq, vq->vq.callback);
- if (vq->vq.callback && !vq->vq.callback(&vq->vq))
- vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+ if (vq->vq.callback)
+ vq->vq.callback(&vq->vq);
return IRQ_HANDLED;
}
@@ -264,7 +274,8 @@ static struct virtqueue_ops vring_vq_ops = {
.add_buf = vring_add_buf,
.get_buf = vring_get_buf,
.kick = vring_kick,
- .restart = vring_restart,
+ .disable_cb = vring_disable_cb,
+ .enable_cb = vring_enable_cb,
.shutdown = vring_shutdown,
};
@@ -272,7 +283,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
struct virtio_device *vdev,
void *pages,
void (*notify)(struct virtqueue *),
- bool (*callback)(struct virtqueue *))
+ void (*callback)(struct virtqueue *))
{
struct vring_virtqueue *vq;
unsigned int i;
OpenPOWER on IntegriCloud