NFSv4.1: Shrink struct nfs4_sequence_res by moving the session pointer

Move the session pointer into the slot table, then have struct nfs4_slot
point to that slot table.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Trond Myklebust 2012-11-16 12:25:01 -05:00
parent 933602e368
commit e3725ec015
6 changed files with 33 additions and 16 deletions

View File

@ -258,7 +258,8 @@ extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
bool sync); bool sync);
extern struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags); extern struct nfs4_slot *nfs4_alloc_slots(struct nfs4_slot_table *table,
u32 max_slots, gfp_t gfp_flags);
static inline bool static inline bool
is_ds_only_client(struct nfs_client *clp) is_ds_only_client(struct nfs_client *clp)

View File

@ -467,25 +467,28 @@ void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
{ {
struct nfs4_session *session;
struct nfs4_slot_table *tbl; struct nfs4_slot_table *tbl;
tbl = &res->sr_session->fc_slot_table;
if (!res->sr_slot) { if (!res->sr_slot) {
/* just wake up the next guy waiting since /* just wake up the next guy waiting since
* we may have not consumed a slot after all */ * we may have not consumed a slot after all */
dprintk("%s: No slot\n", __func__); dprintk("%s: No slot\n", __func__);
return; return;
} }
tbl = res->sr_slot->table;
session = tbl->session;
spin_lock(&tbl->slot_tbl_lock); spin_lock(&tbl->slot_tbl_lock);
nfs4_free_slot(tbl, res->sr_slot - tbl->slots); nfs4_free_slot(tbl, res->sr_slot - tbl->slots);
nfs4_check_drain_fc_complete(res->sr_session); nfs4_check_drain_fc_complete(session);
spin_unlock(&tbl->slot_tbl_lock); spin_unlock(&tbl->slot_tbl_lock);
res->sr_slot = NULL; res->sr_slot = NULL;
} }
static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
{ {
struct nfs4_session *session;
struct nfs4_slot *slot; struct nfs4_slot *slot;
unsigned long timestamp; unsigned long timestamp;
struct nfs_client *clp; struct nfs_client *clp;
@ -504,6 +507,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
goto out; goto out;
slot = res->sr_slot; slot = res->sr_slot;
session = slot->table->session;
/* Check the SEQUENCE operation status */ /* Check the SEQUENCE operation status */
switch (res->sr_status) { switch (res->sr_status) {
@ -511,7 +515,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
/* Update the slot's sequence and clientid lease timer */ /* Update the slot's sequence and clientid lease timer */
++slot->seq_nr; ++slot->seq_nr;
timestamp = slot->renewal_time; timestamp = slot->renewal_time;
clp = res->sr_session->clp; clp = session->clp;
do_renew_lease(clp, timestamp); do_renew_lease(clp, timestamp);
/* Check sequence flags */ /* Check sequence flags */
if (res->sr_status_flags != 0) if (res->sr_status_flags != 0)
@ -524,7 +528,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
*/ */
dprintk("%s: slot=%td seq=%d: Operation in progress\n", dprintk("%s: slot=%td seq=%d: Operation in progress\n",
__func__, __func__,
slot - res->sr_session->fc_slot_table.slots, slot - session->fc_slot_table.slots,
slot->seq_nr); slot->seq_nr);
goto out_retry; goto out_retry;
default: default:
@ -546,7 +550,7 @@ out_retry:
static int nfs4_sequence_done(struct rpc_task *task, static int nfs4_sequence_done(struct rpc_task *task,
struct nfs4_sequence_res *res) struct nfs4_sequence_res *res)
{ {
if (res->sr_session == NULL) if (res->sr_slot == NULL)
return 1; return 1;
return nfs41_sequence_done(task, res); return nfs41_sequence_done(task, res);
} }
@ -591,7 +595,6 @@ static void nfs41_init_sequence(struct nfs4_sequence_args *args,
args->sa_cache_this = 0; args->sa_cache_this = 0;
if (cache_reply) if (cache_reply)
args->sa_cache_this = 1; args->sa_cache_this = 1;
res->sr_session = NULL;
res->sr_slot = NULL; res->sr_slot = NULL;
} }
@ -646,7 +649,6 @@ int nfs41_setup_sequence(struct nfs4_session *session,
dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr); dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
res->sr_session = session;
res->sr_slot = slot; res->sr_slot = slot;
res->sr_status_flags = 0; res->sr_status_flags = 0;
/* /*
@ -5659,9 +5661,18 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
return status; return status;
} }
struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags) struct nfs4_slot *nfs4_alloc_slots(struct nfs4_slot_table *table,
u32 max_slots, gfp_t gfp_flags)
{ {
return kmalloc_array(max_slots, sizeof(struct nfs4_slot), gfp_flags); struct nfs4_slot *tbl;
u32 i;
tbl = kmalloc_array(max_slots, sizeof(*tbl), gfp_flags);
if (tbl != NULL) {
for (i = 0; i < max_slots; i++)
tbl[i].table = table;
}
return tbl;
} }
static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
@ -5699,7 +5710,7 @@ static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
/* Does the newly negotiated max_reqs match the existing slot table? */ /* Does the newly negotiated max_reqs match the existing slot table? */
if (max_reqs != tbl->max_slots) { if (max_reqs != tbl->max_slots) {
new = nfs4_alloc_slots(max_reqs, GFP_NOFS); new = nfs4_alloc_slots(tbl, max_reqs, GFP_NOFS);
if (!new) if (!new)
goto out; goto out;
} }
@ -5738,11 +5749,13 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
dprintk("--> %s\n", __func__); dprintk("--> %s\n", __func__);
/* Fore channel */ /* Fore channel */
tbl = &ses->fc_slot_table; tbl = &ses->fc_slot_table;
tbl->session = ses;
status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
if (status) /* -ENOMEM */ if (status) /* -ENOMEM */
return status; return status;
/* Back channel */ /* Back channel */
tbl = &ses->bc_slot_table; tbl = &ses->bc_slot_table;
tbl->session = ses;
status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
if (status && tbl->slots == NULL) if (status && tbl->slots == NULL)
/* Fore and back channel share a connection so get /* Fore and back channel share a connection so get

View File

@ -2033,7 +2033,7 @@ static int nfs4_recall_slot(struct nfs_client *clp)
return 0; return 0;
nfs4_begin_drain_session(clp); nfs4_begin_drain_session(clp);
fc_tbl = &clp->cl_session->fc_slot_table; fc_tbl = &clp->cl_session->fc_slot_table;
new = nfs4_alloc_slots(fc_tbl->target_max_slots, GFP_NOFS); new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_max_slots, GFP_NOFS);
if (!new) if (!new)
return -ENOMEM; return -ENOMEM;

View File

@ -5507,12 +5507,13 @@ static int decode_sequence(struct xdr_stream *xdr,
struct rpc_rqst *rqstp) struct rpc_rqst *rqstp)
{ {
#if defined(CONFIG_NFS_V4_1) #if defined(CONFIG_NFS_V4_1)
struct nfs4_session *session;
struct nfs4_sessionid id; struct nfs4_sessionid id;
u32 dummy; u32 dummy;
int status; int status;
__be32 *p; __be32 *p;
if (!res->sr_session) if (res->sr_slot == NULL)
return 0; return 0;
status = decode_op_hdr(xdr, OP_SEQUENCE); status = decode_op_hdr(xdr, OP_SEQUENCE);
@ -5526,8 +5527,9 @@ static int decode_sequence(struct xdr_stream *xdr,
* sequence number, the server is looney tunes. * sequence number, the server is looney tunes.
*/ */
status = -EREMOTEIO; status = -EREMOTEIO;
session = res->sr_slot->table->session;
if (memcmp(id.data, res->sr_session->sess_id.data, if (memcmp(id.data, session->sess_id.data,
NFS4_MAX_SESSIONID_LEN)) { NFS4_MAX_SESSIONID_LEN)) {
dprintk("%s Invalid session id\n", __func__); dprintk("%s Invalid session id\n", __func__);
goto out_err; goto out_err;
@ -5545,7 +5547,7 @@ static int decode_sequence(struct xdr_stream *xdr,
} }
/* slot id */ /* slot id */
dummy = be32_to_cpup(p++); dummy = be32_to_cpup(p++);
if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) { if (dummy != res->sr_slot - session->fc_slot_table.slots) {
dprintk("%s Invalid slot id\n", __func__); dprintk("%s Invalid slot id\n", __func__);
goto out_err; goto out_err;
} }

View File

@ -209,6 +209,7 @@ struct nfs_server {
/* Sessions */ /* Sessions */
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
struct nfs4_slot_table { struct nfs4_slot_table {
struct nfs4_session *session; /* Parent session */
struct nfs4_slot *slots; /* seqid per slot */ struct nfs4_slot *slots; /* seqid per slot */
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;

View File

@ -187,6 +187,7 @@ struct nfs4_channel_attrs {
/* nfs41 sessions slot seqid */ /* nfs41 sessions slot seqid */
struct nfs4_slot { struct nfs4_slot {
struct nfs4_slot_table *table;
unsigned long renewal_time; unsigned long renewal_time;
u32 seq_nr; u32 seq_nr;
}; };
@ -198,7 +199,6 @@ struct nfs4_sequence_args {
}; };
struct nfs4_sequence_res { struct nfs4_sequence_res {
struct nfs4_session *sr_session;
struct nfs4_slot *sr_slot; /* slot used to send request */ struct nfs4_slot *sr_slot; /* slot used to send request */
int sr_status; /* sequence operation status */ int sr_status; /* sequence operation status */
u32 sr_status_flags; u32 sr_status_flags;