summaryrefslogtreecommitdiff
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-11-01 17:43:20 +0100
committerTakashi Iwai <tiwai@suse.de>2017-11-01 17:43:20 +0100
commita53a0ab8ff725672fcb47bb9a5ef75fce45679d0 (patch)
tree75cdea78f27fdd569d72cea0b7837bbcc8d871f7 /net/sunrpc/xprt.c
parent1f20f9ff57ca23b9f5502fca85ce3977e8496cb1 (diff)
parentb817d936248b9bcee8282e97fb1dda1b03c903fe (diff)
downloadlinux-a53a0ab8ff725672fcb47bb9a5ef75fce45679d0.tar.gz
linux-a53a0ab8ff725672fcb47bb9a5ef75fce45679d0.tar.xz
Merge tag 'asoc-fix-v4.14-rc7' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v4.14 A bunch of fixes here, mostly device specific ones (the biggest one being the revert of the hotword support for rt5514), with a couple of core fixes for potential issues with corrupted or otherwise invalid topology files.
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index e741ec2b4d8e..898485e3ece4 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1333,7 +1333,7 @@ void xprt_release(struct rpc_task *task)
rpc_count_iostats(task, task->tk_client->cl_metrics);
spin_lock(&xprt->recv_lock);
if (!list_empty(&req->rq_list)) {
- list_del(&req->rq_list);
+ list_del_init(&req->rq_list);
xprt_wait_on_pinned_rqst(req);
}
spin_unlock(&xprt->recv_lock);
@@ -1445,6 +1445,23 @@ out:
return xprt;
}
+static void xprt_destroy_cb(struct work_struct *work)
+{
+ struct rpc_xprt *xprt =
+ container_of(work, struct rpc_xprt, task_cleanup);
+
+ rpc_xprt_debugfs_unregister(xprt);
+ rpc_destroy_wait_queue(&xprt->binding);
+ rpc_destroy_wait_queue(&xprt->pending);
+ rpc_destroy_wait_queue(&xprt->sending);
+ rpc_destroy_wait_queue(&xprt->backlog);
+ kfree(xprt->servername);
+ /*
+ * Tear down transport state and free the rpc_xprt
+ */
+ xprt->ops->destroy(xprt);
+}
+
/**
* xprt_destroy - destroy an RPC transport, killing off all requests.
* @xprt: transport to destroy
@@ -1454,22 +1471,19 @@ static void xprt_destroy(struct rpc_xprt *xprt)
{
dprintk("RPC: destroying transport %p\n", xprt);
- /* Exclude transport connect/disconnect handlers */
+ /*
+ * Exclude transport connect/disconnect handlers and autoclose
+ */
wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE);
del_timer_sync(&xprt->timer);
- rpc_xprt_debugfs_unregister(xprt);
- rpc_destroy_wait_queue(&xprt->binding);
- rpc_destroy_wait_queue(&xprt->pending);
- rpc_destroy_wait_queue(&xprt->sending);
- rpc_destroy_wait_queue(&xprt->backlog);
- cancel_work_sync(&xprt->task_cleanup);
- kfree(xprt->servername);
/*
- * Tear down transport state and free the rpc_xprt
+ * Destroy sockets etc from the system workqueue so they can
+ * safely flush receive work running on rpciod.
*/
- xprt->ops->destroy(xprt);
+ INIT_WORK(&xprt->task_cleanup, xprt_destroy_cb);
+ schedule_work(&xprt->task_cleanup);
}
static void xprt_destroy_kref(struct kref *kref)