summaryrefslogtreecommitdiff
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-10-01 14:52:40 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-01 14:52:40 -0300
commitaaf675f53a7176475f69595827248c8b2556ea8c (patch)
tree0cb744dec714328c9f89bf85553fb7195107e5d4 /net/sunrpc/xprt.c
parent347c4e95845fad1853c0e3da6603a44c5d6122b3 (diff)
parenta0d271cbfed1dd50278c6b06bead3d00ba0a88f9 (diff)
Merge tag 'v3.6' into staging/for_v3.7
Linux 3.6 * tag 'v3.6': (562 commits) Linux 3.6 vfs: dcache: fix deadlock in tree traversal mtdchar: fix offset overflow detection thp: avoid VM_BUG_ON page_count(page) false positives in __collapse_huge_page_copy iommu/amd: Fix wrong assumption in iommu-group specific code netdev: octeon: fix return value check in octeon_mgmt_init_phy() ALSA: snd-usb: fix next_packet_size calls for pause case inetpeer: fix token initialization qlcnic: Fix scheduling while atomic bug bnx2: Clean up remaining iounmap trivial select_parent documentation fix net: phy: smsc: Implement PHY config_init for LAN87xx smsc75xx: fix resume after device reset um: Preinclude include/linux/kern_levels.h um: Fix IPC on um netdev: pasemi: fix return value check in pasemi_mac_phy_init() team: fix return value check l2tp: fix return value check USB: Fix race condition when removing host controllers USB: ohci-at91: fix null pointer in ohci_hcd_at91_overcurrent_irq ...
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index a5a402a7d21f..5d7f61d7559c 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -969,11 +969,11 @@ static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
return false;
}
-static void xprt_alloc_slot(struct rpc_task *task)
+void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req;
+ spin_lock(&xprt->reserve_lock);
if (!list_empty(&xprt->free)) {
req = list_entry(xprt->free.next, struct rpc_rqst, rq_list);
list_del(&req->rq_list);
@@ -994,12 +994,29 @@ static void xprt_alloc_slot(struct rpc_task *task)
default:
task->tk_status = -EAGAIN;
}
+ spin_unlock(&xprt->reserve_lock);
return;
out_init_req:
task->tk_status = 0;
task->tk_rqstp = req;
xprt_request_init(task, xprt);
+ spin_unlock(&xprt->reserve_lock);
+}
+EXPORT_SYMBOL_GPL(xprt_alloc_slot);
+
+void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)
+{
+ /* Note: grabbing the xprt_lock_write() ensures that we throttle
+ * new slot allocation if the transport is congested (i.e. when
+ * reconnecting a stream transport or when out of socket write
+ * buffer space).
+ */
+ if (xprt_lock_write(xprt, task)) {
+ xprt_alloc_slot(xprt, task);
+ xprt_release_write(xprt, task);
+ }
}
+EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot);
static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
{
@@ -1083,20 +1100,9 @@ void xprt_reserve(struct rpc_task *task)
if (task->tk_rqstp != NULL)
return;
- /* Note: grabbing the xprt_lock_write() here is not strictly needed,
- * but ensures that we throttle new slot allocation if the transport
- * is congested (e.g. if reconnecting or if we're out of socket
- * write buffer space).
- */
task->tk_timeout = 0;
task->tk_status = -EAGAIN;
- if (!xprt_lock_write(xprt, task))
- return;
-
- spin_lock(&xprt->reserve_lock);
- xprt_alloc_slot(task);
- spin_unlock(&xprt->reserve_lock);
- xprt_release_write(xprt, task);
+ xprt->ops->alloc_slot(xprt, task);
}
static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)