case -ENOTCONN:
        case -EAGAIN:
        case -ETIMEDOUT:
+               if (!(task->tk_flags & RPC_TASK_NO_ROUND_ROBIN) &&
+                   (task->tk_flags & RPC_TASK_MOVEABLE) &&
+                   test_bit(XPRT_REMOVE, &xprt->state)) {
+                       struct rpc_xprt *saved = task->tk_xprt;
+                       struct rpc_xprt_switch *xps;
+
+                       rcu_read_lock();
+                       xps = xprt_switch_get(rcu_dereference(clnt->cl_xpi.xpi_xpswitch));
+                       rcu_read_unlock();
+                       if (xps->xps_nxprts > 1) {
+                               long value;
+
+                               xprt_release(task);
+                               value = atomic_long_dec_return(&xprt->queuelen);
+                               if (value == 0)
+                                       rpc_xprt_switch_remove_xprt(xps, saved);
+                               xprt_put(saved);
+                               task->tk_xprt = NULL;
+                               task->tk_action = call_start;
+                       }
+                       xprt_switch_put(xps);
+                       if (!task->tk_xprt)
+                               return;
+               }
                goto out_retry;
        case -ENOBUFS:
                rpc_delay(task, HZ >> 2);
 
        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
        ssize_t ret;
        int locked, connected, connecting, close_wait, bound, binding,
-           closing, congested, cwnd_wait, write_space, offline;
+           closing, congested, cwnd_wait, write_space, offline, remove;
 
        if (!xprt)
                return 0;
                cwnd_wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
                write_space = test_bit(XPRT_WRITE_SPACE, &xprt->state);
                offline = test_bit(XPRT_OFFLINE, &xprt->state);
+               remove = test_bit(XPRT_REMOVE, &xprt->state);
 
-               ret = sprintf(buf, "state=%s %s %s %s %s %s %s %s %s %s %s\n",
+               ret = sprintf(buf, "state=%s %s %s %s %s %s %s %s %s %s %s %s\n",
                              locked ? "LOCKED" : "",
                              connected ? "CONNECTED" : "",
                              connecting ? "CONNECTING" : "",
                              congested ? "CONGESTED" : "",
                              cwnd_wait ? "CWND_WAIT" : "",
                              write_space ? "WRITE_SPACE" : "",
-                             offline ? "OFFLINE" : "");
+                             offline ? "OFFLINE" : "",
+                             remove ? "REMOVE" : "");
        }
 
        xprt_put(xprt);
                                           const char *buf, size_t count)
 {
        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
-       int offline = 0, online = 0;
+       int offline = 0, online = 0, remove = 0;
        struct rpc_xprt_switch *xps = rpc_sysfs_xprt_kobj_get_xprt_switch(kobj);
 
        if (!xprt)
                offline = 1;
        else if (!strncmp(buf, "online", 6))
                online = 1;
+       else if (!strncmp(buf, "remove", 6))
+               remove = 1;
        else
                return -EINVAL;
 
                spin_lock(&xps->xps_lock);
                xps->xps_nactive++;
                spin_unlock(&xps->xps_lock);
+       } else if (remove) {
+               if (test_bit(XPRT_OFFLINE, &xprt->state)) {
+                       set_bit(XPRT_REMOVE, &xprt->state);
+                       xprt_force_disconnect(xprt);
+                       if (test_bit(XPRT_CONNECTED, &xprt->state)) {
+                               if (!xprt->sending.qlen &&
+                                   !xprt->pending.qlen &&
+                                   !xprt->backlog.qlen &&
+                                   !atomic_long_read(&xprt->queuelen))
+                                       rpc_xprt_switch_remove_xprt(xps, xprt);
+                       }
+               } else {
+                       count = -EINVAL;
+               }
        }
 
 release_tasks: