diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2010-04-12 09:19:07 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-05-19 08:45:43 -0400 |
commit | 7c5e9ed0c84e7d70d887878574590638d5572659 (patch) | |
tree | c929c367c6854f021b787fa99fc56d37f64d9bc0 | |
parent | 1915a712f210f0b63d10bc4f875e8e66aac7a2c4 (diff) |
virtio_ring: remove a level of indirection
We have a single virtqueue_ops implementation,
and it seems unlikely we'll get another one
at this point. So let's remove an unnecessary
level of indirection: it would be very easy to
re-add it if another implementation surfaces.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | drivers/virtio/virtio_ring.c | 36 | ||||
-rw-r--r-- | include/linux/virtio.h | 71 |
2 files changed, 34 insertions, 73 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0f90634bcb85..0717b5b000bb 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -155,11 +155,11 @@ static int vring_add_indirect(struct vring_virtqueue *vq, | |||
155 | return head; | 155 | return head; |
156 | } | 156 | } |
157 | 157 | ||
158 | static int vring_add_buf(struct virtqueue *_vq, | 158 | int virtqueue_add_buf(struct virtqueue *_vq, |
159 | struct scatterlist sg[], | 159 | struct scatterlist sg[], |
160 | unsigned int out, | 160 | unsigned int out, |
161 | unsigned int in, | 161 | unsigned int in, |
162 | void *data) | 162 | void *data) |
163 | { | 163 | { |
164 | struct vring_virtqueue *vq = to_vvq(_vq); | 164 | struct vring_virtqueue *vq = to_vvq(_vq); |
165 | unsigned int i, avail, head, uninitialized_var(prev); | 165 | unsigned int i, avail, head, uninitialized_var(prev); |
@@ -232,8 +232,9 @@ add_head: | |||
232 | return vq->num_free ? vq->vring.num : 0; | 232 | return vq->num_free ? vq->vring.num : 0; |
233 | return vq->num_free; | 233 | return vq->num_free; |
234 | } | 234 | } |
235 | EXPORT_SYMBOL_GPL(virtqueue_add_buf); | ||
235 | 236 | ||
236 | static void vring_kick(struct virtqueue *_vq) | 237 | void virtqueue_kick(struct virtqueue *_vq) |
237 | { | 238 | { |
238 | struct vring_virtqueue *vq = to_vvq(_vq); | 239 | struct vring_virtqueue *vq = to_vvq(_vq); |
239 | START_USE(vq); | 240 | START_USE(vq); |
@@ -253,6 +254,7 @@ static void vring_kick(struct virtqueue *_vq) | |||
253 | 254 | ||
254 | END_USE(vq); | 255 | END_USE(vq); |
255 | } | 256 | } |
257 | EXPORT_SYMBOL_GPL(virtqueue_kick); | ||
256 | 258 | ||
257 | static void detach_buf(struct vring_virtqueue *vq, unsigned int head) | 259 | static void detach_buf(struct vring_virtqueue *vq, unsigned int head) |
258 | { | 260 | { |
@@ -284,7 +286,7 @@ static inline bool more_used(const struct vring_virtqueue *vq) | |||
284 | return vq->last_used_idx != vq->vring.used->idx; | 286 | return vq->last_used_idx != vq->vring.used->idx; |
285 | } | 287 | } |
286 | 288 | ||
287 | static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) | 289 | void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) |
288 | { | 290 | { |
289 | struct vring_virtqueue *vq = to_vvq(_vq); | 291 | struct vring_virtqueue *vq = to_vvq(_vq); |
290 | void *ret; | 292 | void *ret; |
@@ -325,15 +327,17 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) | |||
325 | END_USE(vq); | 327 | END_USE(vq); |
326 | return ret; | 328 | return ret; |
327 | } | 329 | } |
330 | EXPORT_SYMBOL_GPL(virtqueue_get_buf); | ||
328 | 331 | ||
329 | static void vring_disable_cb(struct virtqueue *_vq) | 332 | void virtqueue_disable_cb(struct virtqueue *_vq) |
330 | { | 333 | { |
331 | struct vring_virtqueue *vq = to_vvq(_vq); | 334 | struct vring_virtqueue *vq = to_vvq(_vq); |
332 | 335 | ||
333 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; | 336 | vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; |
334 | } | 337 | } |
338 | EXPORT_SYMBOL_GPL(virtqueue_disable_cb); | ||
335 | 339 | ||
336 | static bool vring_enable_cb(struct virtqueue *_vq) | 340 | bool virtqueue_enable_cb(struct virtqueue *_vq) |
337 | { | 341 | { |
338 | struct vring_virtqueue *vq = to_vvq(_vq); | 342 | struct vring_virtqueue *vq = to_vvq(_vq); |
339 | 343 | ||
@@ -351,8 +355,9 @@ static bool vring_enable_cb(struct virtqueue *_vq) | |||
351 | END_USE(vq); | 355 | END_USE(vq); |
352 | return true; | 356 | return true; |
353 | } | 357 | } |
358 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); | ||
354 | 359 | ||
355 | static void *vring_detach_unused_buf(struct virtqueue *_vq) | 360 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) |
356 | { | 361 | { |
357 | struct vring_virtqueue *vq = to_vvq(_vq); | 362 | struct vring_virtqueue *vq = to_vvq(_vq); |
358 | unsigned int i; | 363 | unsigned int i; |
@@ -375,6 +380,7 @@ static void *vring_detach_unused_buf(struct virtqueue *_vq) | |||
375 | END_USE(vq); | 380 | END_USE(vq); |
376 | return NULL; | 381 | return NULL; |
377 | } | 382 | } |
383 | EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf); | ||
378 | 384 | ||
379 | irqreturn_t vring_interrupt(int irq, void *_vq) | 385 | irqreturn_t vring_interrupt(int irq, void *_vq) |
380 | { | 386 | { |
@@ -396,15 +402,6 @@ irqreturn_t vring_interrupt(int irq, void *_vq) | |||
396 | } | 402 | } |
397 | EXPORT_SYMBOL_GPL(vring_interrupt); | 403 | EXPORT_SYMBOL_GPL(vring_interrupt); |
398 | 404 | ||
399 | static struct virtqueue_ops vring_vq_ops = { | ||
400 | .add_buf = vring_add_buf, | ||
401 | .get_buf = vring_get_buf, | ||
402 | .kick = vring_kick, | ||
403 | .disable_cb = vring_disable_cb, | ||
404 | .enable_cb = vring_enable_cb, | ||
405 | .detach_unused_buf = vring_detach_unused_buf, | ||
406 | }; | ||
407 | |||
408 | struct virtqueue *vring_new_virtqueue(unsigned int num, | 405 | struct virtqueue *vring_new_virtqueue(unsigned int num, |
409 | unsigned int vring_align, | 406 | unsigned int vring_align, |
410 | struct virtio_device *vdev, | 407 | struct virtio_device *vdev, |
@@ -429,7 +426,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
429 | vring_init(&vq->vring, num, pages, vring_align); | 426 | vring_init(&vq->vring, num, pages, vring_align); |
430 | vq->vq.callback = callback; | 427 | vq->vq.callback = callback; |
431 | vq->vq.vdev = vdev; | 428 | vq->vq.vdev = vdev; |
432 | vq->vq.vq_ops = &vring_vq_ops; | ||
433 | vq->vq.name = name; | 429 | vq->vq.name = name; |
434 | vq->notify = notify; | 430 | vq->notify = notify; |
435 | vq->broken = false; | 431 | vq->broken = false; |
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 18ccc686a429..5b0fce0d2aa2 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
@@ -14,7 +14,6 @@ | |||
14 | * @callback: the function to call when buffers are consumed (can be NULL). | 14 | * @callback: the function to call when buffers are consumed (can be NULL). |
15 | * @name: the name of this virtqueue (mainly for debugging) | 15 | * @name: the name of this virtqueue (mainly for debugging) |
16 | * @vdev: the virtio device this queue was created for. | 16 | * @vdev: the virtio device this queue was created for. |
17 | * @vq_ops: the operations for this virtqueue (see below). | ||
18 | * @priv: a pointer for the virtqueue implementation to use. | 17 | * @priv: a pointer for the virtqueue implementation to use. |
19 | */ | 18 | */ |
20 | struct virtqueue { | 19 | struct virtqueue { |
@@ -22,94 +21,60 @@ struct virtqueue { | |||
22 | void (*callback)(struct virtqueue *vq); | 21 | void (*callback)(struct virtqueue *vq); |
23 | const char *name; | 22 | const char *name; |
24 | struct virtio_device *vdev; | 23 | struct virtio_device *vdev; |
25 | struct virtqueue_ops *vq_ops; | ||
26 | void *priv; | 24 | void *priv; |
27 | }; | 25 | }; |
28 | 26 | ||
29 | /** | 27 | /** |
30 | * virtqueue_ops - operations for virtqueue abstraction layer | 28 | * operations for virtqueue |
31 | * @add_buf: expose buffer to other end | 29 | * virtqueue_add_buf: expose buffer to other end |
32 | * vq: the struct virtqueue we're talking about. | 30 | * vq: the struct virtqueue we're talking about. |
33 | * sg: the description of the buffer(s). | 31 | * sg: the description of the buffer(s). |
34 | * out_num: the number of sg readable by other side | 32 | * out_num: the number of sg readable by other side |
35 | * in_num: the number of sg which are writable (after readable ones) | 33 | * in_num: the number of sg which are writable (after readable ones) |
36 | * data: the token identifying the buffer. | 34 | * data: the token identifying the buffer. |
37 | * Returns remaining capacity of queue (sg segments) or a negative error. | 35 | * Returns remaining capacity of queue (sg segments) or a negative error. |
38 | * @kick: update after add_buf | 36 | * virtqueue_kick: update after add_buf |
39 | * vq: the struct virtqueue | 37 | * vq: the struct virtqueue |
40 | * After one or more add_buf calls, invoke this to kick the other side. | 38 | * After one or more add_buf calls, invoke this to kick the other side. |
41 | * @get_buf: get the next used buffer | 39 | * virtqueue_get_buf: get the next used buffer |
42 | * vq: the struct virtqueue we're talking about. | 40 | * vq: the struct virtqueue we're talking about. |
43 | * len: the length written into the buffer | 41 | * len: the length written into the buffer |
44 | * Returns NULL or the "data" token handed to add_buf. | 42 | * Returns NULL or the "data" token handed to add_buf. |
45 | * @disable_cb: disable callbacks | 43 | * virtqueue_disable_cb: disable callbacks |
46 | * vq: the struct virtqueue we're talking about. | 44 | * vq: the struct virtqueue we're talking about. |
47 | * Note that this is not necessarily synchronous, hence unreliable and only | 45 | * Note that this is not necessarily synchronous, hence unreliable and only |
48 | * useful as an optimization. | 46 | * useful as an optimization. |
49 | * @enable_cb: restart callbacks after disable_cb. | 47 | * virtqueue_enable_cb: restart callbacks after disable_cb. |
50 | * vq: the struct virtqueue we're talking about. | 48 | * vq: the struct virtqueue we're talking about. |
51 | * This re-enables callbacks; it returns "false" if there are pending | 49 | * This re-enables callbacks; it returns "false" if there are pending |
52 | * buffers in the queue, to detect a possible race between the driver | 50 | * buffers in the queue, to detect a possible race between the driver |
53 | * checking for more work, and enabling callbacks. | 51 | * checking for more work, and enabling callbacks. |
54 | * @detach_unused_buf: detach first unused buffer | 52 | * virtqueue_detach_unused_buf: detach first unused buffer |
55 | * vq: the struct virtqueue we're talking about. | 53 | * vq: the struct virtqueue we're talking about. |
56 | * Returns NULL or the "data" token handed to add_buf | 54 | * Returns NULL or the "data" token handed to add_buf |
57 | * | 55 | * |
58 | * Locking rules are straightforward: the driver is responsible for | 56 | * Locking rules are straightforward: the driver is responsible for |
59 | * locking. No two operations may be invoked simultaneously, with the exception | 57 | * locking. No two operations may be invoked simultaneously, with the exception |
60 | * of @disable_cb. | 58 | * of virtqueue_disable_cb. |
61 | * | 59 | * |
62 | * All operations can be called in any context. | 60 | * All operations can be called in any context. |
63 | */ | 61 | */ |
64 | struct virtqueue_ops { | ||
65 | int (*add_buf)(struct virtqueue *vq, | ||
66 | struct scatterlist sg[], | ||
67 | unsigned int out_num, | ||
68 | unsigned int in_num, | ||
69 | void *data); | ||
70 | 62 | ||
71 | void (*kick)(struct virtqueue *vq); | 63 | int virtqueue_add_buf(struct virtqueue *vq, |
64 | struct scatterlist sg[], | ||
65 | unsigned int out_num, | ||
66 | unsigned int in_num, | ||
67 | void *data); | ||
72 | 68 | ||
73 | void *(*get_buf)(struct virtqueue *vq, unsigned int *len); | 69 | void virtqueue_kick(struct virtqueue *vq); |
74 | 70 | ||
75 | void (*disable_cb)(struct virtqueue *vq); | 71 | void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); |
76 | bool (*enable_cb)(struct virtqueue *vq); | ||
77 | void *(*detach_unused_buf)(struct virtqueue *vq); | ||
78 | }; | ||
79 | |||
80 | static inline int virtqueue_add_buf(struct virtqueue *vq, | ||
81 | struct scatterlist sg[], | ||
82 | unsigned int out_num, | ||
83 | unsigned int in_num, | ||
84 | void *data) | ||
85 | { | ||
86 | return vq->vq_ops->add_buf(vq, sg, out_num, in_num, data); | ||
87 | } | ||
88 | |||
89 | static inline int void virtqueue_kick(struct virtqueue *vq) | ||
90 | { | ||
91 | return vq->vq_ops->kick(vq); | ||
92 | } | ||
93 | |||
94 | static inline void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len) | ||
95 | { | ||
96 | return vq->vq_ops->get_buf(vq, len); | ||
97 | } | ||
98 | 72 | ||
99 | static inline void virtqueue_disable_cb(struct virtqueue *vq) | 73 | void virtqueue_disable_cb(struct virtqueue *vq); |
100 | { | ||
101 | vq->vq_ops->disable_cb(vq); | ||
102 | } | ||
103 | 74 | ||
104 | static inline bool virtqueue_enable_cb(struct virtqueue *vq) | 75 | bool virtqueue_enable_cb(struct virtqueue *vq); |
105 | { | ||
106 | return vq->vq_ops->enable_cb(vq); | ||
107 | } | ||
108 | 76 | ||
109 | static inline void *virtqueue_detach_unused_buf(struct virtqueue *vq) | 77 | void *virtqueue_detach_unused_buf(struct virtqueue *vq); |
110 | { | ||
111 | return vq->vq_ops->detach_unused_buf(vq); | ||
112 | } | ||
113 | 78 | ||
114 | /** | 79 | /** |
115 | * virtio_device - representation of a device using virtio | 80 | * virtio_device - representation of a device using virtio |