aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vhost/net.c')
-rw-r--r--drivers/vhost/net.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index df5b6b971f26..d219070fed3d 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -98,7 +98,8 @@ static void tx_poll_start(struct vhost_net *net, struct socket *sock)
98static void handle_tx(struct vhost_net *net) 98static void handle_tx(struct vhost_net *net)
99{ 99{
100 struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX]; 100 struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_TX];
101 unsigned head, out, in, s; 101 unsigned out, in, s;
102 int head;
102 struct msghdr msg = { 103 struct msghdr msg = {
103 .msg_name = NULL, 104 .msg_name = NULL,
104 .msg_namelen = 0, 105 .msg_namelen = 0,
@@ -135,6 +136,9 @@ static void handle_tx(struct vhost_net *net)
135 ARRAY_SIZE(vq->iov), 136 ARRAY_SIZE(vq->iov),
136 &out, &in, 137 &out, &in,
137 NULL, NULL); 138 NULL, NULL);
139 /* On error, stop handling until the next kick. */
140 if (unlikely(head < 0))
141 break;
138 /* Nothing new? Wait for eventfd to tell us they refilled. */ 142 /* Nothing new? Wait for eventfd to tell us they refilled. */
139 if (head == vq->num) { 143 if (head == vq->num) {
140 wmem = atomic_read(&sock->sk->sk_wmem_alloc); 144 wmem = atomic_read(&sock->sk->sk_wmem_alloc);
@@ -173,8 +177,8 @@ static void handle_tx(struct vhost_net *net)
173 break; 177 break;
174 } 178 }
175 if (err != len) 179 if (err != len)
176 pr_err("Truncated TX packet: " 180 pr_debug("Truncated TX packet: "
177 " len %d != %zd\n", err, len); 181 " len %d != %zd\n", err, len);
178 vhost_add_used_and_signal(&net->dev, vq, head, 0); 182 vhost_add_used_and_signal(&net->dev, vq, head, 0);
179 total_len += len; 183 total_len += len;
180 if (unlikely(total_len >= VHOST_NET_WEIGHT)) { 184 if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
@@ -192,7 +196,8 @@ static void handle_tx(struct vhost_net *net)
192static void handle_rx(struct vhost_net *net) 196static void handle_rx(struct vhost_net *net)
193{ 197{
194 struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX]; 198 struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
195 unsigned head, out, in, log, s; 199 unsigned out, in, log, s;
200 int head;
196 struct vhost_log *vq_log; 201 struct vhost_log *vq_log;
197 struct msghdr msg = { 202 struct msghdr msg = {
198 .msg_name = NULL, 203 .msg_name = NULL,
@@ -228,6 +233,9 @@ static void handle_rx(struct vhost_net *net)
228 ARRAY_SIZE(vq->iov), 233 ARRAY_SIZE(vq->iov),
229 &out, &in, 234 &out, &in,
230 vq_log, &log); 235 vq_log, &log);
236 /* On error, stop handling until the next kick. */
237 if (unlikely(head < 0))
238 break;
231 /* OK, now we need to know about added descriptors. */ 239 /* OK, now we need to know about added descriptors. */
232 if (head == vq->num) { 240 if (head == vq->num) {
233 if (unlikely(vhost_enable_notify(vq))) { 241 if (unlikely(vhost_enable_notify(vq))) {
@@ -267,8 +275,8 @@ static void handle_rx(struct vhost_net *net)
267 } 275 }
268 /* TODO: Should check and handle checksum. */ 276 /* TODO: Should check and handle checksum. */
269 if (err > len) { 277 if (err > len) {
270 pr_err("Discarded truncated rx packet: " 278 pr_debug("Discarded truncated rx packet: "
271 " len %d > %zd\n", err, len); 279 " len %d > %zd\n", err, len);
272 vhost_discard_vq_desc(vq); 280 vhost_discard_vq_desc(vq);
273 continue; 281 continue;
274 } 282 }
@@ -526,11 +534,16 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
526 rcu_assign_pointer(vq->private_data, sock); 534 rcu_assign_pointer(vq->private_data, sock);
527 vhost_net_enable_vq(n, vq); 535 vhost_net_enable_vq(n, vq);
528done: 536done:
537 mutex_unlock(&vq->mutex);
538
529 if (oldsock) { 539 if (oldsock) {
530 vhost_net_flush_vq(n, index); 540 vhost_net_flush_vq(n, index);
531 fput(oldsock->file); 541 fput(oldsock->file);
532 } 542 }
533 543
544 mutex_unlock(&n->dev.mutex);
545 return 0;
546
534err_vq: 547err_vq:
535 mutex_unlock(&vq->mutex); 548 mutex_unlock(&vq->mutex);
536err: 549err: