diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-31 13:53:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-31 13:53:34 -0400 |
commit | 8164c5719b864da3bcfee97ad8af8cfd7ee5ad8c (patch) | |
tree | 2259ef4e7a709c9edc2417adacf3da97c6075a47 | |
parent | 27a03b1a71b9adfa7f4ef3f61452fb3bc5b195b1 (diff) | |
parent | d10e0cc113c9e1b64b5c6e3db37b5c839794f3df (diff) |
Merge tag 'for-linus-5.2b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen fixes from Juergen Gross:
"One minor cleanup patch and a fix for handling of live migration when
running as Xen guest"
* tag 'for-linus-5.2b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
xenbus: Avoid deadlock during suspend due to open transactions
xen/pvcalls: Remove set but not used variable
-rw-r--r-- | drivers/xen/pvcalls-front.c | 4 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus.h | 3 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_dev_frontend.c | 18 | ||||
-rw-r--r-- | drivers/xen/xenbus/xenbus_xs.c | 7 |
4 files changed, 26 insertions, 6 deletions
diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index c75549928656..57592a6b5c9e 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c | |||
@@ -531,7 +531,6 @@ out: | |||
531 | int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, | 531 | int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, |
532 | size_t len) | 532 | size_t len) |
533 | { | 533 | { |
534 | struct pvcalls_bedata *bedata; | ||
535 | struct sock_mapping *map; | 534 | struct sock_mapping *map; |
536 | int sent, tot_sent = 0; | 535 | int sent, tot_sent = 0; |
537 | int count = 0, flags; | 536 | int count = 0, flags; |
@@ -543,7 +542,6 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg, | |||
543 | map = pvcalls_enter_sock(sock); | 542 | map = pvcalls_enter_sock(sock); |
544 | if (IS_ERR(map)) | 543 | if (IS_ERR(map)) |
545 | return PTR_ERR(map); | 544 | return PTR_ERR(map); |
546 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | ||
547 | 545 | ||
548 | mutex_lock(&map->active.out_mutex); | 546 | mutex_lock(&map->active.out_mutex); |
549 | if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { | 547 | if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) { |
@@ -626,7 +624,6 @@ out: | |||
626 | int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | 624 | int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, |
627 | int flags) | 625 | int flags) |
628 | { | 626 | { |
629 | struct pvcalls_bedata *bedata; | ||
630 | int ret; | 627 | int ret; |
631 | struct sock_mapping *map; | 628 | struct sock_mapping *map; |
632 | 629 | ||
@@ -636,7 +633,6 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
636 | map = pvcalls_enter_sock(sock); | 633 | map = pvcalls_enter_sock(sock); |
637 | if (IS_ERR(map)) | 634 | if (IS_ERR(map)) |
638 | return PTR_ERR(map); | 635 | return PTR_ERR(map); |
639 | bedata = dev_get_drvdata(&pvcalls_front_dev->dev); | ||
640 | 636 | ||
641 | mutex_lock(&map->active.in_mutex); | 637 | mutex_lock(&map->active.in_mutex); |
642 | if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) | 638 | if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER)) |
diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h index 092981171df1..d75a2385b37c 100644 --- a/drivers/xen/xenbus/xenbus.h +++ b/drivers/xen/xenbus/xenbus.h | |||
@@ -83,6 +83,7 @@ struct xb_req_data { | |||
83 | int num_vecs; | 83 | int num_vecs; |
84 | int err; | 84 | int err; |
85 | enum xb_req_state state; | 85 | enum xb_req_state state; |
86 | bool user_req; | ||
86 | void (*cb)(struct xb_req_data *); | 87 | void (*cb)(struct xb_req_data *); |
87 | void *par; | 88 | void *par; |
88 | }; | 89 | }; |
@@ -133,4 +134,6 @@ void xenbus_ring_ops_init(void); | |||
133 | int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par); | 134 | int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par); |
134 | void xenbus_dev_queue_reply(struct xb_req_data *req); | 135 | void xenbus_dev_queue_reply(struct xb_req_data *req); |
135 | 136 | ||
137 | extern unsigned int xb_dev_generation_id; | ||
138 | |||
136 | #endif | 139 | #endif |
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index faf452d0edf0..08adc590f631 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c | |||
@@ -62,6 +62,8 @@ | |||
62 | 62 | ||
63 | #include "xenbus.h" | 63 | #include "xenbus.h" |
64 | 64 | ||
65 | unsigned int xb_dev_generation_id; | ||
66 | |||
65 | /* | 67 | /* |
66 | * An element of a list of outstanding transactions, for which we're | 68 | * An element of a list of outstanding transactions, for which we're |
67 | * still waiting a reply. | 69 | * still waiting a reply. |
@@ -69,6 +71,7 @@ | |||
69 | struct xenbus_transaction_holder { | 71 | struct xenbus_transaction_holder { |
70 | struct list_head list; | 72 | struct list_head list; |
71 | struct xenbus_transaction handle; | 73 | struct xenbus_transaction handle; |
74 | unsigned int generation_id; | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | /* | 77 | /* |
@@ -441,6 +444,7 @@ static int xenbus_write_transaction(unsigned msg_type, | |||
441 | rc = -ENOMEM; | 444 | rc = -ENOMEM; |
442 | goto out; | 445 | goto out; |
443 | } | 446 | } |
447 | trans->generation_id = xb_dev_generation_id; | ||
444 | list_add(&trans->list, &u->transactions); | 448 | list_add(&trans->list, &u->transactions); |
445 | } else if (msg->hdr.tx_id != 0 && | 449 | } else if (msg->hdr.tx_id != 0 && |
446 | !xenbus_get_transaction(u, msg->hdr.tx_id)) | 450 | !xenbus_get_transaction(u, msg->hdr.tx_id)) |
@@ -449,6 +453,20 @@ static int xenbus_write_transaction(unsigned msg_type, | |||
449 | !(msg->hdr.len == 2 && | 453 | !(msg->hdr.len == 2 && |
450 | (!strcmp(msg->body, "T") || !strcmp(msg->body, "F")))) | 454 | (!strcmp(msg->body, "T") || !strcmp(msg->body, "F")))) |
451 | return xenbus_command_reply(u, XS_ERROR, "EINVAL"); | 455 | return xenbus_command_reply(u, XS_ERROR, "EINVAL"); |
456 | else if (msg_type == XS_TRANSACTION_END) { | ||
457 | trans = xenbus_get_transaction(u, msg->hdr.tx_id); | ||
458 | if (trans && trans->generation_id != xb_dev_generation_id) { | ||
459 | list_del(&trans->list); | ||
460 | kfree(trans); | ||
461 | if (!strcmp(msg->body, "T")) | ||
462 | return xenbus_command_reply(u, XS_ERROR, | ||
463 | "EAGAIN"); | ||
464 | else | ||
465 | return xenbus_command_reply(u, | ||
466 | XS_TRANSACTION_END, | ||
467 | "OK"); | ||
468 | } | ||
469 | } | ||
452 | 470 | ||
453 | rc = xenbus_dev_request_and_reply(&msg->hdr, u); | 471 | rc = xenbus_dev_request_and_reply(&msg->hdr, u); |
454 | if (rc && trans) { | 472 | if (rc && trans) { |
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 49a3874ae6bb..ddc18da61834 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
@@ -105,6 +105,7 @@ static void xs_suspend_enter(void) | |||
105 | 105 | ||
106 | static void xs_suspend_exit(void) | 106 | static void xs_suspend_exit(void) |
107 | { | 107 | { |
108 | xb_dev_generation_id++; | ||
108 | spin_lock(&xs_state_lock); | 109 | spin_lock(&xs_state_lock); |
109 | xs_suspend_active--; | 110 | xs_suspend_active--; |
110 | spin_unlock(&xs_state_lock); | 111 | spin_unlock(&xs_state_lock); |
@@ -125,7 +126,7 @@ static uint32_t xs_request_enter(struct xb_req_data *req) | |||
125 | spin_lock(&xs_state_lock); | 126 | spin_lock(&xs_state_lock); |
126 | } | 127 | } |
127 | 128 | ||
128 | if (req->type == XS_TRANSACTION_START) | 129 | if (req->type == XS_TRANSACTION_START && !req->user_req) |
129 | xs_state_users++; | 130 | xs_state_users++; |
130 | xs_state_users++; | 131 | xs_state_users++; |
131 | rq_id = xs_request_id++; | 132 | rq_id = xs_request_id++; |
@@ -140,7 +141,7 @@ void xs_request_exit(struct xb_req_data *req) | |||
140 | spin_lock(&xs_state_lock); | 141 | spin_lock(&xs_state_lock); |
141 | xs_state_users--; | 142 | xs_state_users--; |
142 | if ((req->type == XS_TRANSACTION_START && req->msg.type == XS_ERROR) || | 143 | if ((req->type == XS_TRANSACTION_START && req->msg.type == XS_ERROR) || |
143 | (req->type == XS_TRANSACTION_END && | 144 | (req->type == XS_TRANSACTION_END && !req->user_req && |
144 | !WARN_ON_ONCE(req->msg.type == XS_ERROR && | 145 | !WARN_ON_ONCE(req->msg.type == XS_ERROR && |
145 | !strcmp(req->body, "ENOENT")))) | 146 | !strcmp(req->body, "ENOENT")))) |
146 | xs_state_users--; | 147 | xs_state_users--; |
@@ -286,6 +287,7 @@ int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par) | |||
286 | req->num_vecs = 1; | 287 | req->num_vecs = 1; |
287 | req->cb = xenbus_dev_queue_reply; | 288 | req->cb = xenbus_dev_queue_reply; |
288 | req->par = par; | 289 | req->par = par; |
290 | req->user_req = true; | ||
289 | 291 | ||
290 | xs_send(req, msg); | 292 | xs_send(req, msg); |
291 | 293 | ||
@@ -313,6 +315,7 @@ static void *xs_talkv(struct xenbus_transaction t, | |||
313 | req->vec = iovec; | 315 | req->vec = iovec; |
314 | req->num_vecs = num_vecs; | 316 | req->num_vecs = num_vecs; |
315 | req->cb = xs_wake_up; | 317 | req->cb = xs_wake_up; |
318 | req->user_req = false; | ||
316 | 319 | ||
317 | msg.req_id = 0; | 320 | msg.req_id = 0; |
318 | msg.tx_id = t.id; | 321 | msg.tx_id = t.id; |