Merge tag 'for-linus-5.2b-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 May 2019 17:53:34 +0000 (10:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 May 2019 17:53:34 +0000 (10:53 -0700)
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

drivers/xen/pvcalls-front.c
drivers/xen/xenbus/xenbus.h
drivers/xen/xenbus/xenbus_dev_frontend.c
drivers/xen/xenbus/xenbus_xs.c

index c755499..57592a6 100644 (file)
@@ -531,7 +531,6 @@ out:
 int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg,
                          size_t len)
 {
-       struct pvcalls_bedata *bedata;
        struct sock_mapping *map;
        int sent, tot_sent = 0;
        int count = 0, flags;
@@ -543,7 +542,6 @@ int pvcalls_front_sendmsg(struct socket *sock, struct msghdr *msg,
        map = pvcalls_enter_sock(sock);
        if (IS_ERR(map))
                return PTR_ERR(map);
-       bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
        mutex_lock(&map->active.out_mutex);
        if ((flags & MSG_DONTWAIT) && !pvcalls_front_write_todo(map)) {
@@ -626,7 +624,6 @@ out:
 int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
                     int flags)
 {
-       struct pvcalls_bedata *bedata;
        int ret;
        struct sock_mapping *map;
 
@@ -636,7 +633,6 @@ int pvcalls_front_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
        map = pvcalls_enter_sock(sock);
        if (IS_ERR(map))
                return PTR_ERR(map);
-       bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
 
        mutex_lock(&map->active.in_mutex);
        if (len > XEN_FLEX_RING_SIZE(PVCALLS_RING_ORDER))
index 0929811..d75a238 100644 (file)
@@ -83,6 +83,7 @@ struct xb_req_data {
        int num_vecs;
        int err;
        enum xb_req_state state;
+       bool user_req;
        void (*cb)(struct xb_req_data *);
        void *par;
 };
@@ -133,4 +134,6 @@ void xenbus_ring_ops_init(void);
 int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par);
 void xenbus_dev_queue_reply(struct xb_req_data *req);
 
+extern unsigned int xb_dev_generation_id;
+
 #endif
index faf452d..08adc59 100644 (file)
@@ -62,6 +62,8 @@
 
 #include "xenbus.h"
 
+unsigned int xb_dev_generation_id;
+
 /*
  * An element of a list of outstanding transactions, for which we're
  * still waiting a reply.
@@ -69,6 +71,7 @@
 struct xenbus_transaction_holder {
        struct list_head list;
        struct xenbus_transaction handle;
+       unsigned int generation_id;
 };
 
 /*
@@ -441,6 +444,7 @@ static int xenbus_write_transaction(unsigned msg_type,
                        rc = -ENOMEM;
                        goto out;
                }
+               trans->generation_id = xb_dev_generation_id;
                list_add(&trans->list, &u->transactions);
        } else if (msg->hdr.tx_id != 0 &&
                   !xenbus_get_transaction(u, msg->hdr.tx_id))
@@ -449,6 +453,20 @@ static int xenbus_write_transaction(unsigned msg_type,
                 !(msg->hdr.len == 2 &&
                   (!strcmp(msg->body, "T") || !strcmp(msg->body, "F"))))
                return xenbus_command_reply(u, XS_ERROR, "EINVAL");
+       else if (msg_type == XS_TRANSACTION_END) {
+               trans = xenbus_get_transaction(u, msg->hdr.tx_id);
+               if (trans && trans->generation_id != xb_dev_generation_id) {
+                       list_del(&trans->list);
+                       kfree(trans);
+                       if (!strcmp(msg->body, "T"))
+                               return xenbus_command_reply(u, XS_ERROR,
+                                                           "EAGAIN");
+                       else
+                               return xenbus_command_reply(u,
+                                                           XS_TRANSACTION_END,
+                                                           "OK");
+               }
+       }
 
        rc = xenbus_dev_request_and_reply(&msg->hdr, u);
        if (rc && trans) {
index 49a3874..ddc18da 100644 (file)
@@ -105,6 +105,7 @@ static void xs_suspend_enter(void)
 
 static void xs_suspend_exit(void)
 {
+       xb_dev_generation_id++;
        spin_lock(&xs_state_lock);
        xs_suspend_active--;
        spin_unlock(&xs_state_lock);
@@ -125,7 +126,7 @@ static uint32_t xs_request_enter(struct xb_req_data *req)
                spin_lock(&xs_state_lock);
        }
 
-       if (req->type == XS_TRANSACTION_START)
+       if (req->type == XS_TRANSACTION_START && !req->user_req)
                xs_state_users++;
        xs_state_users++;
        rq_id = xs_request_id++;
@@ -140,7 +141,7 @@ void xs_request_exit(struct xb_req_data *req)
        spin_lock(&xs_state_lock);
        xs_state_users--;
        if ((req->type == XS_TRANSACTION_START && req->msg.type == XS_ERROR) ||
-           (req->type == XS_TRANSACTION_END &&
+           (req->type == XS_TRANSACTION_END && !req->user_req &&
             !WARN_ON_ONCE(req->msg.type == XS_ERROR &&
                           !strcmp(req->body, "ENOENT"))))
                xs_state_users--;
@@ -286,6 +287,7 @@ int xenbus_dev_request_and_reply(struct xsd_sockmsg *msg, void *par)
        req->num_vecs = 1;
        req->cb = xenbus_dev_queue_reply;
        req->par = par;
+       req->user_req = true;
 
        xs_send(req, msg);
 
@@ -313,6 +315,7 @@ static void *xs_talkv(struct xenbus_transaction t,
        req->vec = iovec;
        req->num_vecs = num_vecs;
        req->cb = xs_wake_up;
+       req->user_req = false;
 
        msg.req_id = 0;
        msg.tx_id = t.id;