diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-11-22 13:21:02 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-12-05 18:30:44 -0500 |
commit | 69d206b5b39e298755b60e8e7056cb240182eb95 (patch) | |
tree | bf36abea6758a4b5d77cb44b53aab6124ce48029 /fs/nfs | |
parent | ac0748359a55faf4618f5f0bd9f9bf967c41d218 (diff) |
NFSv4.1: If slot allocation fails due to OOM, retry more quickly
If the NFSv4.1 session slot allocation fails due to an ENOMEM condition,
then set the task->tk_timeout to 1/4 second to ensure that we do retry
the slot allocation more quickly.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0642e28704de..e9e4d6393f1b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -662,7 +662,7 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, | |||
662 | return slot; | 662 | return slot; |
663 | p = &slot->next; | 663 | p = &slot->next; |
664 | } | 664 | } |
665 | return NULL; | 665 | return ERR_PTR(-ENOMEM); |
666 | } | 666 | } |
667 | 667 | ||
668 | /* | 668 | /* |
@@ -676,7 +676,7 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl, | |||
676 | */ | 676 | */ |
677 | static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) | 677 | static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) |
678 | { | 678 | { |
679 | struct nfs4_slot *ret = NULL; | 679 | struct nfs4_slot *ret = ERR_PTR(-EBUSY); |
680 | u32 slotid; | 680 | u32 slotid; |
681 | 681 | ||
682 | dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n", | 682 | dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n", |
@@ -686,7 +686,7 @@ static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) | |||
686 | if (slotid > tbl->max_slotid) | 686 | if (slotid > tbl->max_slotid) |
687 | goto out; | 687 | goto out; |
688 | ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); | 688 | ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); |
689 | if (ret == NULL) | 689 | if (IS_ERR(ret)) |
690 | goto out; | 690 | goto out; |
691 | __set_bit(slotid, tbl->used_slots); | 691 | __set_bit(slotid, tbl->used_slots); |
692 | if (slotid > tbl->highest_used_slotid || | 692 | if (slotid > tbl->highest_used_slotid || |
@@ -698,7 +698,7 @@ static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) | |||
698 | out: | 698 | out: |
699 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", | 699 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", |
700 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, | 700 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, |
701 | ret ? ret->slot_nr : -1); | 701 | !IS_ERR(ret) ? ret->slot_nr : -1); |
702 | return ret; | 702 | return ret; |
703 | } | 703 | } |
704 | 704 | ||
@@ -727,6 +727,8 @@ int nfs41_setup_sequence(struct nfs4_session *session, | |||
727 | 727 | ||
728 | tbl = &session->fc_slot_table; | 728 | tbl = &session->fc_slot_table; |
729 | 729 | ||
730 | task->tk_timeout = 0; | ||
731 | |||
730 | spin_lock(&tbl->slot_tbl_lock); | 732 | spin_lock(&tbl->slot_tbl_lock); |
731 | if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && | 733 | if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && |
732 | !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { | 734 | !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) { |
@@ -746,7 +748,10 @@ int nfs41_setup_sequence(struct nfs4_session *session, | |||
746 | } | 748 | } |
747 | 749 | ||
748 | slot = nfs4_alloc_slot(tbl); | 750 | slot = nfs4_alloc_slot(tbl); |
749 | if (slot == NULL) { | 751 | if (IS_ERR(slot)) { |
752 | /* If out of memory, try again in 1/4 second */ | ||
753 | if (slot == ERR_PTR(-ENOMEM)) | ||
754 | task->tk_timeout = HZ >> 2; | ||
750 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); | 755 | rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); |
751 | spin_unlock(&tbl->slot_tbl_lock); | 756 | spin_unlock(&tbl->slot_tbl_lock); |
752 | dprintk("<-- %s: no free slots\n", __func__); | 757 | dprintk("<-- %s: no free slots\n", __func__); |
@@ -5778,7 +5783,7 @@ static int nfs4_grow_slot_table(struct nfs4_slot_table *tbl, | |||
5778 | { | 5783 | { |
5779 | if (max_reqs <= tbl->max_slots) | 5784 | if (max_reqs <= tbl->max_slots) |
5780 | return 0; | 5785 | return 0; |
5781 | if (nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS)) | 5786 | if (!IS_ERR(nfs4_find_or_create_slot(tbl, max_reqs - 1, ivalue, GFP_NOFS))) |
5782 | return 0; | 5787 | return 0; |
5783 | return -ENOMEM; | 5788 | return -ENOMEM; |
5784 | } | 5789 | } |