aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-17 16:57:32 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-17 16:57:32 -0400
commit21de0a955f3af29fa1100d96f66e6adade89e77a (patch)
tree0e829bc99fd3786361f78106f50e3961a5ee209b /net
parent8d9266ffe4332afc5ac9de401ef6f825b3798585 (diff)
SUNRPC: Clean up the slot table allocation
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprt.c64
1 files changed, 37 insertions, 27 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index efb8dc5ab81b..ea7b3c16cddd 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -62,6 +62,7 @@
62/* 62/*
63 * Local functions 63 * Local functions
64 */ 64 */
65static void xprt_init(struct rpc_xprt *xprt, struct net *net);
65static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); 66static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
66static void xprt_connect_status(struct rpc_task *task); 67static void xprt_connect_status(struct rpc_task *task);
67static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); 68static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
@@ -961,25 +962,42 @@ static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
961 spin_unlock(&xprt->reserve_lock); 962 spin_unlock(&xprt->reserve_lock);
962} 963}
963 964
964struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req) 965static void xprt_free_all_slots(struct rpc_xprt *xprt)
966{
967 struct rpc_rqst *req;
968 while (!list_empty(&xprt->free)) {
969 req = list_first_entry(&xprt->free, struct rpc_rqst, rq_list);
970 list_del(&req->rq_list);
971 kfree(req);
972 }
973}
974
975struct rpc_xprt *xprt_alloc(struct net *net, int size, int num_prealloc)
965{ 976{
966 struct rpc_xprt *xprt; 977 struct rpc_xprt *xprt;
978 struct rpc_rqst *req;
979 int i;
967 980
968 xprt = kzalloc(size, GFP_KERNEL); 981 xprt = kzalloc(size, GFP_KERNEL);
969 if (xprt == NULL) 982 if (xprt == NULL)
970 goto out; 983 goto out;
971 atomic_set(&xprt->count, 1);
972 984
973 xprt->max_reqs = max_req; 985 xprt_init(xprt, net);
974 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); 986
975 if (xprt->slot == NULL) 987 for (i = 0; i < num_prealloc; i++) {
988 req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL);
989 if (!req)
990 break;
991 list_add(&req->rq_list, &xprt->free);
992 }
993 if (i < num_prealloc)
976 goto out_free; 994 goto out_free;
995 xprt->max_reqs = num_prealloc;
977 996
978 xprt->xprt_net = get_net(net);
979 return xprt; 997 return xprt;
980 998
981out_free: 999out_free:
982 kfree(xprt); 1000 xprt_free(xprt);
983out: 1001out:
984 return NULL; 1002 return NULL;
985} 1003}
@@ -988,7 +1006,7 @@ EXPORT_SYMBOL_GPL(xprt_alloc);
988void xprt_free(struct rpc_xprt *xprt) 1006void xprt_free(struct rpc_xprt *xprt)
989{ 1007{
990 put_net(xprt->xprt_net); 1008 put_net(xprt->xprt_net);
991 kfree(xprt->slot); 1009 xprt_free_all_slots(xprt);
992 kfree(xprt); 1010 kfree(xprt);
993} 1011}
994EXPORT_SYMBOL_GPL(xprt_free); 1012EXPORT_SYMBOL_GPL(xprt_free);
@@ -1091,9 +1109,9 @@ void xprt_release(struct rpc_task *task)
1091 xprt_free_bc_request(req); 1109 xprt_free_bc_request(req);
1092} 1110}
1093 1111
1094static void xprt_init(struct rpc_xprt *xprt) 1112static void xprt_init(struct rpc_xprt *xprt, struct net *net)
1095{ 1113{
1096 struct rpc_rqst *req; 1114 atomic_set(&xprt->count, 1);
1097 1115
1098 spin_lock_init(&xprt->transport_lock); 1116 spin_lock_init(&xprt->transport_lock);
1099 spin_lock_init(&xprt->reserve_lock); 1117 spin_lock_init(&xprt->reserve_lock);
@@ -1105,12 +1123,6 @@ static void xprt_init(struct rpc_xprt *xprt)
1105 INIT_LIST_HEAD(&xprt->bc_pa_list); 1123 INIT_LIST_HEAD(&xprt->bc_pa_list);
1106#endif /* CONFIG_SUNRPC_BACKCHANNEL */ 1124#endif /* CONFIG_SUNRPC_BACKCHANNEL */
1107 1125
1108 INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
1109 if (xprt_has_timer(xprt))
1110 setup_timer(&xprt->timer, xprt_init_autodisconnect,
1111 (unsigned long)xprt);
1112 else
1113 init_timer(&xprt->timer);
1114 xprt->last_used = jiffies; 1126 xprt->last_used = jiffies;
1115 xprt->cwnd = RPC_INITCWND; 1127 xprt->cwnd = RPC_INITCWND;
1116 xprt->bind_index = 0; 1128 xprt->bind_index = 0;
@@ -1121,12 +1133,9 @@ static void xprt_init(struct rpc_xprt *xprt)
1121 rpc_init_wait_queue(&xprt->resend, "xprt_resend"); 1133 rpc_init_wait_queue(&xprt->resend, "xprt_resend");
1122 rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog"); 1134 rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog");
1123 1135
1124 /* initialize free list */
1125 for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--)
1126 list_add(&req->rq_list, &xprt->free);
1127
1128 xprt_init_xid(xprt); 1136 xprt_init_xid(xprt);
1129 1137
1138 xprt->xprt_net = get_net(net);
1130} 1139}
1131 1140
1132/** 1141/**
@@ -1155,16 +1164,17 @@ found:
1155 if (IS_ERR(xprt)) { 1164 if (IS_ERR(xprt)) {
1156 dprintk("RPC: xprt_create_transport: failed, %ld\n", 1165 dprintk("RPC: xprt_create_transport: failed, %ld\n",
1157 -PTR_ERR(xprt)); 1166 -PTR_ERR(xprt));
1158 return xprt; 1167 goto out;
1159 } 1168 }
1160 if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state)) 1169 INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
1161 /* ->setup returned a pre-initialized xprt: */ 1170 if (xprt_has_timer(xprt))
1162 return xprt; 1171 setup_timer(&xprt->timer, xprt_init_autodisconnect,
1163 1172 (unsigned long)xprt);
1164 xprt_init(xprt); 1173 else
1165 1174 init_timer(&xprt->timer);
1166 dprintk("RPC: created transport %p with %u slots\n", xprt, 1175 dprintk("RPC: created transport %p with %u slots\n", xprt,
1167 xprt->max_reqs); 1176 xprt->max_reqs);
1177out:
1168 return xprt; 1178 return xprt;
1169} 1179}
1170 1180