aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-11-22 09:55:48 -0500
committerDavid Howells <dhowells@redhat.com>2006-11-22 09:55:48 -0500
commit65f27f38446e1976cc98fd3004b110fedcddd189 (patch)
tree68f8be93feae31dfa018c22db392a05546b63ee1 /net/sunrpc/xprtsock.c
parent365970a1ea76d81cb1ad2f652acb605f06dae256 (diff)
WorkStruct: Pass the work_struct pointer instead of context data
Pass the work_struct pointer to the work function rather than context data. The work function can use container_of() to work out the data. For the cases where the container of the work_struct may go away the moment the pending bit is cleared, it is made possible to defer the release of the structure by deferring the clearing of the pending bit. To make this work, an extra flag is introduced into the management side of the work_struct. This governs auto-release of the structure upon execution. Ordinarily, the work queue executor would release the work_struct for further scheduling or deallocation by clearing the pending bit prior to jumping to the work function. This means that, unless the driver makes some guarantee itself that the work_struct won't go away, the work function may not access anything else in the work_struct or its container lest they be deallocated.. This is a problem if the auxiliary data is taken away (as done by the last patch). However, if the pending bit is *not* cleared before jumping to the work function, then the work function *may* access the work_struct and its container with no problems. But then the work function must itself release the work_struct by calling work_release(). In most cases, automatic release is fine, so this is the default. Special initiators exist for the non-auto-release case (ending in _NAR). Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 3c7532cd009e..cfe3c15be948 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1060,13 +1060,14 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
1060 1060
1061/** 1061/**
1062 * xs_udp_connect_worker - set up a UDP socket 1062 * xs_udp_connect_worker - set up a UDP socket
1063 * @args: RPC transport to connect 1063 * @work: RPC transport to connect
1064 * 1064 *
1065 * Invoked by a work queue tasklet. 1065 * Invoked by a work queue tasklet.
1066 */ 1066 */
1067static void xs_udp_connect_worker(void *args) 1067static void xs_udp_connect_worker(struct work_struct *work)
1068{ 1068{
1069 struct rpc_xprt *xprt = (struct rpc_xprt *) args; 1069 struct rpc_xprt *xprt =
1070 container_of(work, struct rpc_xprt, connect_worker.work);
1070 struct socket *sock = xprt->sock; 1071 struct socket *sock = xprt->sock;
1071 int err, status = -EIO; 1072 int err, status = -EIO;
1072 1073
@@ -1144,13 +1145,14 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
1144 1145
1145/** 1146/**
1146 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint 1147 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
1147 * @args: RPC transport to connect 1148 * @work: RPC transport to connect
1148 * 1149 *
1149 * Invoked by a work queue tasklet. 1150 * Invoked by a work queue tasklet.
1150 */ 1151 */
1151static void xs_tcp_connect_worker(void *args) 1152static void xs_tcp_connect_worker(struct work_struct *work)
1152{ 1153{
1153 struct rpc_xprt *xprt = (struct rpc_xprt *)args; 1154 struct rpc_xprt *xprt =
1155 container_of(work, struct rpc_xprt, connect_worker.work);
1154 struct socket *sock = xprt->sock; 1156 struct socket *sock = xprt->sock;
1155 int err, status = -EIO; 1157 int err, status = -EIO;
1156 1158
@@ -1375,7 +1377,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1375 /* XXX: header size can vary due to auth type, IPv6, etc. */ 1377 /* XXX: header size can vary due to auth type, IPv6, etc. */
1376 xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); 1378 xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
1377 1379
1378 INIT_DELAYED_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); 1380 INIT_DELAYED_WORK(&xprt->connect_worker, xs_udp_connect_worker);
1379 xprt->bind_timeout = XS_BIND_TO; 1381 xprt->bind_timeout = XS_BIND_TO;
1380 xprt->connect_timeout = XS_UDP_CONN_TO; 1382 xprt->connect_timeout = XS_UDP_CONN_TO;
1381 xprt->reestablish_timeout = XS_UDP_REEST_TO; 1383 xprt->reestablish_timeout = XS_UDP_REEST_TO;
@@ -1420,7 +1422,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1420 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); 1422 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
1421 xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; 1423 xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
1422 1424
1423 INIT_DELAYED_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); 1425 INIT_DELAYED_WORK(&xprt->connect_worker, xs_tcp_connect_worker);
1424 xprt->bind_timeout = XS_BIND_TO; 1426 xprt->bind_timeout = XS_BIND_TO;
1425 xprt->connect_timeout = XS_TCP_CONN_TO; 1427 xprt->connect_timeout = XS_TCP_CONN_TO;
1426 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 1428 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;