Merge tag 'nfs-for-5.18-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[linux-2.6-microblaze.git] / net / sunrpc / xprt.c
index 5af484d..515501f 100644 (file)
@@ -1354,17 +1354,6 @@ xprt_request_enqueue_transmit(struct rpc_task *task)
                                INIT_LIST_HEAD(&req->rq_xmit2);
                                goto out;
                        }
-               } else if (RPC_IS_SWAPPER(task)) {
-                       list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
-                               if (pos->rq_cong || pos->rq_bytes_sent)
-                                       continue;
-                               if (RPC_IS_SWAPPER(pos->rq_task))
-                                       continue;
-                               /* Note: req is added _before_ pos */
-                               list_add_tail(&req->rq_xmit, &pos->rq_xmit);
-                               INIT_LIST_HEAD(&req->rq_xmit2);
-                               goto out;
-                       }
                } else if (!req->rq_seqno) {
                        list_for_each_entry(pos, &xprt->xmit_queue, rq_xmit) {
                                if (pos->rq_task->tk_owner != task->tk_owner)
@@ -1503,6 +1492,9 @@ bool xprt_prepare_transmit(struct rpc_task *task)
                return false;
 
        }
+       if (atomic_read(&xprt->swapper))
+               /* This will be clear in __rpc_execute */
+               current->flags |= PF_MEMALLOC;
        return true;
 }
 
@@ -1692,7 +1684,7 @@ static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt)
                goto out;
        ++xprt->num_reqs;
        spin_unlock(&xprt->reserve_lock);
-       req = kzalloc(sizeof(struct rpc_rqst), GFP_NOFS);
+       req = kzalloc(sizeof(*req), rpc_task_gfp_mask());
        spin_lock(&xprt->reserve_lock);
        if (req != NULL)
                goto out;
@@ -2112,7 +2104,14 @@ static void xprt_destroy(struct rpc_xprt *xprt)
         */
        wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE);
 
+       /*
+        * xprt_schedule_autodisconnect() can run after XPRT_LOCKED
+        * is cleared.  We use ->transport_lock to ensure the mod_timer()
+        * can only run *before* del_time_sync(), never after.
+        */
+       spin_lock(&xprt->transport_lock);
        del_timer_sync(&xprt->timer);
+       spin_unlock(&xprt->transport_lock);
 
        /*
         * Destroy sockets etc from the system workqueue so they can