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,
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
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)
{
struct nfs4_session *session;
struct nfs4_slot_table *tbl;
tbl = &res->sr_session->fc_slot_table;
if (!res->sr_slot) {
/* just wake up the next guy waiting since
* we may have not consumed a slot after all */
dprintk("%s: No slot\n", __func__);
return;
}
tbl = res->sr_slot->table;
session = tbl->session;
spin_lock(&tbl->slot_tbl_lock);
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);
res->sr_slot = NULL;
}
static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
{
struct nfs4_session *session;
struct nfs4_slot *slot;
unsigned long timestamp;
struct nfs_client *clp;
@ -504,6 +507,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
goto out;
slot = res->sr_slot;
session = slot->table->session;
/* Check the SEQUENCE operation 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 */
++slot->seq_nr;
timestamp = slot->renewal_time;
clp = res->sr_session->clp;
clp = session->clp;
do_renew_lease(clp, timestamp);
/* Check sequence flags */
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",
__func__,
slot - res->sr_session->fc_slot_table.slots,
slot - session->fc_slot_table.slots,
slot->seq_nr);
goto out_retry;
default:
@ -546,7 +550,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
static int nfs4_sequence_done(struct rpc_task *task,
struct nfs4_sequence_res *res)
{
if (res->sr_session == NULL)
if (res->sr_slot == NULL)
return 1;
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;
if (cache_reply)
args->sa_cache_this = 1;
res->sr_session = 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);
res->sr_session = session;
res->sr_slot = slot;
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;
}
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,
@ -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? */
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)
goto out;
}
@ -5738,11 +5749,13 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
dprintk("--> %s\n", __func__);
/* Fore channel */
tbl = &ses->fc_slot_table;
tbl->session = ses;
status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
if (status) /* -ENOMEM */
return status;
/* Back channel */
tbl = &ses->bc_slot_table;
tbl->session = ses;
status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
if (status && tbl->slots == NULL)
/* 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;
nfs4_begin_drain_session(clp);
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)
return -ENOMEM;

View File

@ -5507,12 +5507,13 @@ static int decode_sequence(struct xdr_stream *xdr,
struct rpc_rqst *rqstp)
{
#if defined(CONFIG_NFS_V4_1)
struct nfs4_session *session;
struct nfs4_sessionid id;
u32 dummy;
int status;
__be32 *p;
if (!res->sr_session)
if (res->sr_slot == NULL)
return 0;
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.
*/
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)) {
dprintk("%s Invalid session id\n", __func__);
goto out_err;
@ -5545,7 +5547,7 @@ static int decode_sequence(struct xdr_stream *xdr,
}
/* slot id */
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__);
goto out_err;
}

View File

@ -209,6 +209,7 @@ struct nfs_server {
/* Sessions */
#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
struct nfs4_slot_table {
struct nfs4_session *session; /* Parent session */
struct nfs4_slot *slots; /* seqid per slot */
unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
spinlock_t slot_tbl_lock;

View File

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