[ipc/ipcdev.git] / linux / patches / 3.8.0 / omapl138 / 0001-Process-all-available-messages-in-virtqueue-callback.patch
1 From c93a879d9749295d8c56df7395e28fd446e6b9a7 Mon Sep 17 00:00:00 2001
2 From: Robert Tivy <rtivy@ti.com>
3 Date: Fri, 8 Mar 2013 10:17:04 -0800
4 Subject: [PATCH v8 1/7] Process all available messages in virtqueue callback
6 Change virtqueue callback function rpmsg_recv_done() to process all
7 available messages instead of just one message.
9 Signed-off-by: Robert Tivy <rtivy@ti.com>
10 ---
11 drivers/rpmsg/virtio_rpmsg_bus.c | 97 +++++++++++++++++++++++---------------
12 1 file changed, 58 insertions(+), 39 deletions(-)
14 diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
15 index f1e3239..ae92ae7 100644
16 --- a/drivers/rpmsg/virtio_rpmsg_bus.c
17 +++ b/drivers/rpmsg/virtio_rpmsg_bus.c
18 @@ -782,7 +782,7 @@ out:
19 }
20 EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
22 -/* called when an rx buffer is used, and it's time to digest a message */
23 +/* called when an rx buffer is used, and it's time to digest a message(s) */
24 static void rpmsg_recv_done(struct virtqueue *rvq)
25 {
26 struct rpmsg_hdr *msg;
27 @@ -791,6 +791,7 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
28 struct scatterlist sg;
29 struct virtproc_info *vrp = rvq->vdev->priv;
30 struct device *dev = &rvq->vdev->dev;
31 + int added_buf = 0;
32 int err;
34 msg = virtqueue_get_buf(rvq, &len);
35 @@ -799,60 +800,78 @@ static void rpmsg_recv_done(struct virtqueue *rvq)
36 return;
37 }
39 - dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
40 + while (msg) {
41 + dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
42 msg->src, msg->dst, msg->len,
43 msg->flags, msg->reserved);
44 - print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
45 +#ifdef DEBUG_VERBOSE
46 + print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ",
47 + DUMP_PREFIX_NONE, 16, 1,
48 msg, sizeof(*msg) + msg->len, true);
49 +#endif
51 - /*
52 - * We currently use fixed-sized buffers, so trivially sanitize
53 - * the reported payload length.
54 - */
55 - if (len > RPMSG_BUF_SIZE ||
56 - msg->len > (len - sizeof(struct rpmsg_hdr))) {
57 - dev_warn(dev, "inbound msg too big: (%d, %d)\n", len, msg->len);
58 - return;
59 - }
60 + /*
61 + * We currently use fixed-sized buffers, so trivially sanitize
62 + * the reported payload length.
63 + */
64 + if (len > RPMSG_BUF_SIZE ||
65 + msg->len > (len - sizeof(struct rpmsg_hdr))) {
66 + dev_warn(dev, "inbound msg too big: (%d, %d)\n",
67 + len, msg->len);
68 + break;
69 + }
71 - /* use the dst addr to fetch the callback of the appropriate user */
72 - mutex_lock(&vrp->endpoints_lock);
73 + /*
74 + * Use the dst addr to fetch the callback of the appropriate
75 + * user.
76 + */
77 + mutex_lock(&vrp->endpoints_lock);
79 - ept = idr_find(&vrp->endpoints, msg->dst);
80 + ept = idr_find(&vrp->endpoints, msg->dst);
82 - /* let's make sure no one deallocates ept while we use it */
83 - if (ept)
84 - kref_get(&ept->refcount);
85 + /* let's make sure no one deallocates ept while we use it */
86 + if (ept)
87 + kref_get(&ept->refcount);
89 - mutex_unlock(&vrp->endpoints_lock);
90 + mutex_unlock(&vrp->endpoints_lock);
92 - if (ept) {
93 - /* make sure ept->cb doesn't go away while we use it */
94 - mutex_lock(&ept->cb_lock);
95 + if (ept) {
96 + /* make sure ept->cb doesn't go away while we use it */
97 + mutex_lock(&ept->cb_lock);
99 - if (ept->cb)
100 - ept->cb(ept->rpdev, msg->data, msg->len, ept->priv,
101 - msg->src);
102 + if (ept->cb)
103 + ept->cb(ept->rpdev, msg->data, msg->len,
104 + ept->priv, msg->src);
106 - mutex_unlock(&ept->cb_lock);
107 + mutex_unlock(&ept->cb_lock);
109 - /* farewell, ept, we don't need you anymore */
110 - kref_put(&ept->refcount, __ept_release);
111 - } else
112 - dev_warn(dev, "msg received with no recepient\n");
113 + /* farewell, ept, we don't need you anymore */
114 + kref_put(&ept->refcount, __ept_release);
115 + } else
116 + dev_warn(dev, "msg received with no recepient\n");
118 - /* publish the real size of the buffer */
119 - sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
120 + /* publish the real size of the buffer */
121 + sg_init_one(&sg, msg, RPMSG_BUF_SIZE);
123 - /* add the buffer back to the remote processor's virtqueue */
124 - err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
125 - if (err < 0) {
126 - dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
127 - return;
128 + /* add the buffer back to the remote processor's virtqueue */
129 + err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
130 + if (err < 0) {
131 + dev_err(dev, "failed to add a virtqueue buffer: %d\n",
132 + err);
133 + break;
134 + }
135 +
136 + added_buf = 1;
137 +
138 + msg = virtqueue_get_buf(rvq, &len);
139 }
141 - /* tell the remote processor we added another available rx buffer */
142 - virtqueue_kick(vrp->rvq);
143 + if (added_buf)
144 + /*
145 + * Tell the remote processor we added another available rx
146 + * buffer.
147 + */
148 + virtqueue_kick(vrp->rvq);
149 }
151 /*
152 --
153 1.7.9.4