Commit 45d43c29 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.1: Convert slotid from u8 to u32

It is perfectly legal to negotiate up to 2^32-1 slots in the protocol,
and with 10GigE, we are already seeing that 255 slots is far too limiting.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 17347d03
...@@ -38,7 +38,7 @@ enum nfs4_callback_opnum { ...@@ -38,7 +38,7 @@ enum nfs4_callback_opnum {
struct cb_process_state { struct cb_process_state {
__be32 drc_status; __be32 drc_status;
struct nfs_client *clp; struct nfs_client *clp;
int slotid; u32 slotid;
struct net *net; struct net *net;
}; };
......
...@@ -759,14 +759,14 @@ static void nfs4_callback_free_slot(struct nfs4_session *session) ...@@ -759,14 +759,14 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
* Let the state manager know callback processing done. * Let the state manager know callback processing done.
* A single slot, so highest used slotid is either 0 or -1 * A single slot, so highest used slotid is either 0 or -1
*/ */
tbl->highest_used_slotid = -1; tbl->highest_used_slotid = NFS4_NO_SLOT;
nfs4_check_drain_bc_complete(session); nfs4_check_drain_bc_complete(session);
spin_unlock(&tbl->slot_tbl_lock); spin_unlock(&tbl->slot_tbl_lock);
} }
static void nfs4_cb_free_slot(struct cb_process_state *cps) static void nfs4_cb_free_slot(struct cb_process_state *cps)
{ {
if (cps->slotid != -1) if (cps->slotid != NFS4_NO_SLOT)
nfs4_callback_free_slot(cps->clp->cl_session); nfs4_callback_free_slot(cps->clp->cl_session);
} }
...@@ -860,7 +860,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r ...@@ -860,7 +860,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
struct cb_process_state cps = { struct cb_process_state cps = {
.drc_status = 0, .drc_status = 0,
.clp = NULL, .clp = NULL,
.slotid = -1, .slotid = NFS4_NO_SLOT,
.net = rqstp->rq_xprt->xpt_net, .net = rqstp->rq_xprt->xpt_net,
}; };
unsigned int nops = 0; unsigned int nops = 0;
......
...@@ -360,16 +360,14 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp ...@@ -360,16 +360,14 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
* When updating highest_used_slotid there may be "holes" in the bitmap * When updating highest_used_slotid there may be "holes" in the bitmap
* so we need to scan down from highest_used_slotid to 0 looking for the now * so we need to scan down from highest_used_slotid to 0 looking for the now
* highest slotid in use. * highest slotid in use.
* If none found, highest_used_slotid is set to -1. * If none found, highest_used_slotid is set to NFS4_NO_SLOT.
* *
* Must be called while holding tbl->slot_tbl_lock * Must be called while holding tbl->slot_tbl_lock
*/ */
static void static void
nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) nfs4_free_slot(struct nfs4_slot_table *tbl, u32 slotid)
{ {
int slotid = free_slotid; BUG_ON(slotid >= NFS4_MAX_SLOT_TABLE);
BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE);
/* clear used bit in bitmap */ /* clear used bit in bitmap */
__clear_bit(slotid, tbl->used_slots); __clear_bit(slotid, tbl->used_slots);
...@@ -379,10 +377,10 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) ...@@ -379,10 +377,10 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
if (slotid < tbl->max_slots) if (slotid < tbl->max_slots)
tbl->highest_used_slotid = slotid; tbl->highest_used_slotid = slotid;
else else
tbl->highest_used_slotid = -1; tbl->highest_used_slotid = NFS4_NO_SLOT;
} }
dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
free_slotid, tbl->highest_used_slotid); slotid, tbl->highest_used_slotid);
} }
bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy) bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
...@@ -402,7 +400,7 @@ static void nfs4_check_drain_fc_complete(struct nfs4_session *ses) ...@@ -402,7 +400,7 @@ static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
return; return;
} }
if (ses->fc_slot_table.highest_used_slotid != -1) if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
return; return;
dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__); dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
...@@ -415,7 +413,7 @@ static void nfs4_check_drain_fc_complete(struct nfs4_session *ses) ...@@ -415,7 +413,7 @@ static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
void nfs4_check_drain_bc_complete(struct nfs4_session *ses) void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
{ {
if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) || if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
ses->bc_slot_table.highest_used_slotid != -1) ses->bc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
return; return;
dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__); dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
complete(&ses->bc_slot_table.complete); complete(&ses->bc_slot_table.complete);
...@@ -510,25 +508,25 @@ static int nfs4_sequence_done(struct rpc_task *task, ...@@ -510,25 +508,25 @@ static int nfs4_sequence_done(struct rpc_task *task,
* nfs4_find_slot looks for an unset bit in the used_slots bitmap. * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
* If found, we mark the slot as used, update the highest_used_slotid, * If found, we mark the slot as used, update the highest_used_slotid,
* and respectively set up the sequence operation args. * and respectively set up the sequence operation args.
* The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise. * The slot number is returned if found, or NFS4_NO_SLOT otherwise.
* *
* Note: must be called with under the slot_tbl_lock. * Note: must be called with under the slot_tbl_lock.
*/ */
static u8 static u32
nfs4_find_slot(struct nfs4_slot_table *tbl) nfs4_find_slot(struct nfs4_slot_table *tbl)
{ {
int slotid; u32 slotid;
u8 ret_id = NFS4_MAX_SLOT_TABLE; u32 ret_id = NFS4_NO_SLOT;
BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n", dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
__func__, tbl->used_slots[0], tbl->highest_used_slotid, __func__, tbl->used_slots[0], tbl->highest_used_slotid,
tbl->max_slots); tbl->max_slots);
slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots); slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
if (slotid >= tbl->max_slots) if (slotid >= tbl->max_slots)
goto out; goto out;
__set_bit(slotid, tbl->used_slots); __set_bit(slotid, tbl->used_slots);
if (slotid > tbl->highest_used_slotid) if (slotid > tbl->highest_used_slotid ||
tbl->highest_used_slotid == NFS4_NO_SLOT)
tbl->highest_used_slotid = slotid; tbl->highest_used_slotid = slotid;
ret_id = slotid; ret_id = slotid;
out: out:
...@@ -555,7 +553,7 @@ int nfs41_setup_sequence(struct nfs4_session *session, ...@@ -555,7 +553,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
{ {
struct nfs4_slot *slot; struct nfs4_slot *slot;
struct nfs4_slot_table *tbl; struct nfs4_slot_table *tbl;
u8 slotid; u32 slotid;
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
/* slot already allocated? */ /* slot already allocated? */
...@@ -583,7 +581,7 @@ int nfs41_setup_sequence(struct nfs4_session *session, ...@@ -583,7 +581,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
} }
slotid = nfs4_find_slot(tbl); slotid = nfs4_find_slot(tbl);
if (slotid == NFS4_MAX_SLOT_TABLE) { if (slotid == NFS4_NO_SLOT) {
rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
spin_unlock(&tbl->slot_tbl_lock); spin_unlock(&tbl->slot_tbl_lock);
dprintk("<-- %s: no free slots\n", __func__); dprintk("<-- %s: no free slots\n", __func__);
...@@ -5144,7 +5142,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, ...@@ -5144,7 +5142,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
spin_lock(&tbl->slot_tbl_lock); spin_lock(&tbl->slot_tbl_lock);
tbl->max_slots = max_slots; tbl->max_slots = max_slots;
tbl->slots = slot; tbl->slots = slot;
tbl->highest_used_slotid = -1; /* no slot is currently used */ tbl->highest_used_slotid = NFS4_NO_SLOT; /* no slot is currently used */
spin_unlock(&tbl->slot_tbl_lock); spin_unlock(&tbl->slot_tbl_lock);
dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
tbl, tbl->slots, tbl->max_slots); tbl, tbl->slots, tbl->max_slots);
...@@ -5196,13 +5194,13 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) ...@@ -5196,13 +5194,13 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
return NULL; return NULL;
tbl = &session->fc_slot_table; tbl = &session->fc_slot_table;
tbl->highest_used_slotid = -1; tbl->highest_used_slotid = NFS4_NO_SLOT;
spin_lock_init(&tbl->slot_tbl_lock); spin_lock_init(&tbl->slot_tbl_lock);
rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
init_completion(&tbl->complete); init_completion(&tbl->complete);
tbl = &session->bc_slot_table; tbl = &session->bc_slot_table;
tbl->highest_used_slotid = -1; tbl->highest_used_slotid = NFS4_NO_SLOT;
spin_lock_init(&tbl->slot_tbl_lock); spin_lock_init(&tbl->slot_tbl_lock);
rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
init_completion(&tbl->complete); init_completion(&tbl->complete);
......
...@@ -191,6 +191,7 @@ struct nfs_server { ...@@ -191,6 +191,7 @@ struct nfs_server {
/* maximum number of slots to use */ /* maximum number of slots to use */
#define NFS4_MAX_SLOT_TABLE (128U) #define NFS4_MAX_SLOT_TABLE (128U)
#define NFS4_NO_SLOT ((u32)-1)
#if defined(CONFIG_NFS_V4) #if defined(CONFIG_NFS_V4)
...@@ -201,10 +202,10 @@ struct nfs4_slot_table { ...@@ -201,10 +202,10 @@ struct nfs4_slot_table {
unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */ unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
spinlock_t slot_tbl_lock; spinlock_t slot_tbl_lock;
struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */ struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
int max_slots; /* # slots in table */ u32 max_slots; /* # slots in table */
int highest_used_slotid; /* sent to server on each SEQ. u32 highest_used_slotid; /* sent to server on each SEQ.
* op for dynamic resizing */ * op for dynamic resizing */
int target_max_slots; /* Set by CB_RECALL_SLOT as u32 target_max_slots; /* Set by CB_RECALL_SLOT as
* the new max_slots */ * the new max_slots */
struct completion complete; struct completion complete;
}; };
......
...@@ -181,7 +181,7 @@ struct nfs4_slot { ...@@ -181,7 +181,7 @@ struct nfs4_slot {
struct nfs4_sequence_args { struct nfs4_sequence_args {
struct nfs4_session *sa_session; struct nfs4_session *sa_session;
u8 sa_slotid; u32 sa_slotid;
u8 sa_cache_this; u8 sa_cache_this;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment