aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/sunrpc/xprt.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c68
1 files changed, 49 insertions, 19 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 970fb00f388c..ce5eb68a9664 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -199,15 +199,12 @@ int xprt_reserve_xprt(struct rpc_task *task)
199 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { 199 if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) {
200 if (task == xprt->snd_task) 200 if (task == xprt->snd_task)
201 return 1; 201 return 1;
202 if (task == NULL)
203 return 0;
204 goto out_sleep; 202 goto out_sleep;
205 } 203 }
206 xprt->snd_task = task; 204 xprt->snd_task = task;
207 if (req) { 205 req->rq_bytes_sent = 0;
208 req->rq_bytes_sent = 0; 206 req->rq_ntrans++;
209 req->rq_ntrans++; 207
210 }
211 return 1; 208 return 1;
212 209
213out_sleep: 210out_sleep:
@@ -215,7 +212,7 @@ out_sleep:
215 task->tk_pid, xprt); 212 task->tk_pid, xprt);
216 task->tk_timeout = 0; 213 task->tk_timeout = 0;
217 task->tk_status = -EAGAIN; 214 task->tk_status = -EAGAIN;
218 if (req && req->rq_ntrans) 215 if (req->rq_ntrans)
219 rpc_sleep_on(&xprt->resend, task, NULL); 216 rpc_sleep_on(&xprt->resend, task, NULL);
220 else 217 else
221 rpc_sleep_on(&xprt->sending, task, NULL); 218 rpc_sleep_on(&xprt->sending, task, NULL);
@@ -757,13 +754,11 @@ static void xprt_connect_status(struct rpc_task *task)
757 */ 754 */
758struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) 755struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
759{ 756{
760 struct list_head *pos; 757 struct rpc_rqst *entry;
761 758
762 list_for_each(pos, &xprt->recv) { 759 list_for_each_entry(entry, &xprt->recv, rq_list)
763 struct rpc_rqst *entry = list_entry(pos, struct rpc_rqst, rq_list);
764 if (entry->rq_xid == xid) 760 if (entry->rq_xid == xid)
765 return entry; 761 return entry;
766 }
767 762
768 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n", 763 dprintk("RPC: xprt_lookup_rqst did not find xid %08x\n",
769 ntohl(xid)); 764 ntohl(xid));
@@ -911,6 +906,7 @@ void xprt_transmit(struct rpc_task *task)
911 } 906 }
912 907
913 dprintk("RPC: %5u xmit complete\n", task->tk_pid); 908 dprintk("RPC: %5u xmit complete\n", task->tk_pid);
909 task->tk_flags |= RPC_TASK_SENT;
914 spin_lock_bh(&xprt->transport_lock); 910 spin_lock_bh(&xprt->transport_lock);
915 911
916 xprt->ops->set_retrans_timeout(task); 912 xprt->ops->set_retrans_timeout(task);
@@ -962,6 +958,38 @@ static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
962 spin_unlock(&xprt->reserve_lock); 958 spin_unlock(&xprt->reserve_lock);
963} 959}
964 960
961struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req)
962{
963 struct rpc_xprt *xprt;
964
965 xprt = kzalloc(size, GFP_KERNEL);
966 if (xprt == NULL)
967 goto out;
968 atomic_set(&xprt->count, 1);
969
970 xprt->max_reqs = max_req;
971 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL);
972 if (xprt->slot == NULL)
973 goto out_free;
974
975 xprt->xprt_net = get_net(net);
976 return xprt;
977
978out_free:
979 kfree(xprt);
980out:
981 return NULL;
982}
983EXPORT_SYMBOL_GPL(xprt_alloc);
984
985void xprt_free(struct rpc_xprt *xprt)
986{
987 put_net(xprt->xprt_net);
988 kfree(xprt->slot);
989 kfree(xprt);
990}
991EXPORT_SYMBOL_GPL(xprt_free);
992
965/** 993/**
966 * xprt_reserve - allocate an RPC request slot 994 * xprt_reserve - allocate an RPC request slot
967 * @task: RPC task requesting a slot allocation 995 * @task: RPC task requesting a slot allocation
@@ -1074,8 +1102,10 @@ found:
1074 -PTR_ERR(xprt)); 1102 -PTR_ERR(xprt));
1075 return xprt; 1103 return xprt;
1076 } 1104 }
1105 if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state))
1106 /* ->setup returned a pre-initialized xprt: */
1107 return xprt;
1077 1108
1078 kref_init(&xprt->kref);
1079 spin_lock_init(&xprt->transport_lock); 1109 spin_lock_init(&xprt->transport_lock);
1080 spin_lock_init(&xprt->reserve_lock); 1110 spin_lock_init(&xprt->reserve_lock);
1081 1111
@@ -1115,13 +1145,11 @@ found:
1115 1145
1116/** 1146/**
1117 * xprt_destroy - destroy an RPC transport, killing off all requests. 1147 * xprt_destroy - destroy an RPC transport, killing off all requests.
1118 * @kref: kref for the transport to destroy 1148 * @xprt: transport to destroy
1119 * 1149 *
1120 */ 1150 */
1121static void xprt_destroy(struct kref *kref) 1151static void xprt_destroy(struct rpc_xprt *xprt)
1122{ 1152{
1123 struct rpc_xprt *xprt = container_of(kref, struct rpc_xprt, kref);
1124
1125 dprintk("RPC: destroying transport %p\n", xprt); 1153 dprintk("RPC: destroying transport %p\n", xprt);
1126 xprt->shutdown = 1; 1154 xprt->shutdown = 1;
1127 del_timer_sync(&xprt->timer); 1155 del_timer_sync(&xprt->timer);
@@ -1145,7 +1173,8 @@ static void xprt_destroy(struct kref *kref)
1145 */ 1173 */
1146void xprt_put(struct rpc_xprt *xprt) 1174void xprt_put(struct rpc_xprt *xprt)
1147{ 1175{
1148 kref_put(&xprt->kref, xprt_destroy); 1176 if (atomic_dec_and_test(&xprt->count))
1177 xprt_destroy(xprt);
1149} 1178}
1150 1179
1151/** 1180/**
@@ -1155,6 +1184,7 @@ void xprt_put(struct rpc_xprt *xprt)
1155 */ 1184 */
1156struct rpc_xprt *xprt_get(struct rpc_xprt *xprt) 1185struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
1157{ 1186{
1158 kref_get(&xprt->kref); 1187 if (atomic_inc_not_zero(&xprt->count))
1159 return xprt; 1188 return xprt;
1189 return NULL;
1160} 1190}