xenbus: Avoid deadlock during suspend due to open transactions
[platform/kernel/linux-starfive.git] / drivers / xen / xenbus / xenbus_xs.c
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;