diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2009-12-15 00:27:56 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-15 13:55:18 -0500 |
commit | 689cf5c15baf603a8041565ff0bd0d65d1634fd7 (patch) | |
tree | 83fc6e666f0c099486cfcdb41b40c02d9fa163b7 | |
parent | cf3b01b54880debb01ea7d471123da5887a7c2cb (diff) |
nfs: enforce FIFO ordering of operations trying to acquire slot
Signed-off-by: Alexandros Batsakis <batsakis@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 22 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 18 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 1 |
3 files changed, 35 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index acd698baf8eb..02513da9a016 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -346,8 +346,12 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) | |||
346 | */ | 346 | */ |
347 | static void nfs41_check_drain_session_complete(struct nfs4_session *ses) | 347 | static void nfs41_check_drain_session_complete(struct nfs4_session *ses) |
348 | { | 348 | { |
349 | struct rpc_task *task; | ||
350 | |||
349 | if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) { | 351 | if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) { |
350 | rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq); | 352 | task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq); |
353 | if (task) | ||
354 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | ||
351 | return; | 355 | return; |
352 | } | 356 | } |
353 | 357 | ||
@@ -483,6 +487,14 @@ static int nfs41_setup_sequence(struct nfs4_session *session, | |||
483 | return -EAGAIN; | 487 | return -EAGAIN; |
484 | } | 488 | } |
485 | 489 | ||
490 | if (!rpc_queue_empty(&tbl->slot_tbl_waitq) && | ||
491 | !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { | ||
492 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); | ||
493 | spin_unlock(&tbl->slot_tbl_lock); | ||
494 | dprintk("%s enforce FIFO order\n", __func__); | ||
495 | return -EAGAIN; | ||
496 | } | ||
497 | |||
486 | slotid = nfs4_find_slot(tbl); | 498 | slotid = nfs4_find_slot(tbl); |
487 | if (slotid == NFS4_MAX_SLOT_TABLE) { | 499 | if (slotid == NFS4_MAX_SLOT_TABLE) { |
488 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); | 500 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); |
@@ -492,6 +504,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session, | |||
492 | } | 504 | } |
493 | spin_unlock(&tbl->slot_tbl_lock); | 505 | spin_unlock(&tbl->slot_tbl_lock); |
494 | 506 | ||
507 | rpc_task_set_priority(task, RPC_PRIORITY_NORMAL); | ||
495 | slot = tbl->slots + slotid; | 508 | slot = tbl->slots + slotid; |
496 | args->sa_session = session; | 509 | args->sa_session = session; |
497 | args->sa_slotid = slotid; | 510 | args->sa_slotid = slotid; |
@@ -4401,11 +4414,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task, | |||
4401 | (struct nfs4_get_lease_time_data *)calldata; | 4414 | (struct nfs4_get_lease_time_data *)calldata; |
4402 | 4415 | ||
4403 | dprintk("--> %s\n", __func__); | 4416 | dprintk("--> %s\n", __func__); |
4417 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | ||
4404 | /* just setup sequence, do not trigger session recovery | 4418 | /* just setup sequence, do not trigger session recovery |
4405 | since we're invoked within one */ | 4419 | since we're invoked within one */ |
4406 | ret = nfs41_setup_sequence(data->clp->cl_session, | 4420 | ret = nfs41_setup_sequence(data->clp->cl_session, |
4407 | &data->args->la_seq_args, | 4421 | &data->args->la_seq_args, |
4408 | &data->res->lr_seq_res, 0, task); | 4422 | &data->res->lr_seq_res, 0, task); |
4409 | 4423 | ||
4410 | BUG_ON(ret == -EAGAIN); | 4424 | BUG_ON(ret == -EAGAIN); |
4411 | rpc_call_start(task); | 4425 | rpc_call_start(task); |
@@ -4625,7 +4639,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) | |||
4625 | tbl = &session->fc_slot_table; | 4639 | tbl = &session->fc_slot_table; |
4626 | tbl->highest_used_slotid = -1; | 4640 | tbl->highest_used_slotid = -1; |
4627 | spin_lock_init(&tbl->slot_tbl_lock); | 4641 | spin_lock_init(&tbl->slot_tbl_lock); |
4628 | rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); | 4642 | rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); |
4629 | 4643 | ||
4630 | tbl = &session->bc_slot_table; | 4644 | tbl = &session->bc_slot_table; |
4631 | tbl->highest_used_slotid = -1; | 4645 | tbl->highest_used_slotid = -1; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e76427e6346f..0e45075836b2 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -138,8 +138,22 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp) | |||
138 | static void nfs41_end_drain_session(struct nfs_client *clp, | 138 | static void nfs41_end_drain_session(struct nfs_client *clp, |
139 | struct nfs4_session *ses) | 139 | struct nfs4_session *ses) |
140 | { | 140 | { |
141 | if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) | 141 | int max_slots; |
142 | rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq); | 142 | |
143 | if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) { | ||
144 | spin_lock(&ses->fc_slot_table.slot_tbl_lock); | ||
145 | max_slots = ses->fc_slot_table.max_slots; | ||
146 | while (max_slots--) { | ||
147 | struct rpc_task *task; | ||
148 | |||
149 | task = rpc_wake_up_next(&ses->fc_slot_table. | ||
150 | slot_tbl_waitq); | ||
151 | if (!task) | ||
152 | break; | ||
153 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | ||
154 | } | ||
155 | spin_unlock(&ses->fc_slot_table.slot_tbl_lock); | ||
156 | } | ||
143 | } | 157 | } |
144 | 158 | ||
145 | static int nfs41_begin_drain_session(struct nfs_client *clp, | 159 | static int nfs41_begin_drain_session(struct nfs_client *clp, |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 89ea8e69ec78..aae6907fd546 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -210,6 +210,7 @@ void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qnam | |||
210 | { | 210 | { |
211 | __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); | 211 | __rpc_init_priority_wait_queue(queue, qname, RPC_NR_PRIORITY); |
212 | } | 212 | } |
213 | EXPORT_SYMBOL_GPL(rpc_init_priority_wait_queue); | ||
213 | 214 | ||
214 | void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) | 215 | void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) |
215 | { | 216 | { |