Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nfsd: allocate new session-based DRC slots on demand.

If a client ever uses the highest available slot for a given session,
attempt to allocate more slots so there is room for the client to use
them if wanted. GFP_NOWAIT is used so if there is not plenty of
free memory, failure is expected - which is what we want. It also
allows the allocation while holding a spinlock.

Each time we increase the number of slots by 20% (rounded up). This
allows fairly quick growth while avoiding excessive over-shoot.

We would expect to stablise with around 10% more slots available than
the client actually uses.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

NeilBrown and committed by
Chuck Lever
60aa6564 601c8cb3

+32 -5
+32 -5
fs/nfsd/nfs4state.c
··· 4235 4235 slot = xa_load(&session->se_slots, seq->slotid); 4236 4236 dprintk("%s: slotid %d\n", __func__, seq->slotid); 4237 4237 4238 - /* We do not negotiate the number of slots yet, so set the 4239 - * maxslots to the session maxreqs which is used to encode 4240 - * sr_highest_slotid and the sr_target_slot id to maxslots */ 4241 - seq->maxslots = session->se_fchannel.maxreqs; 4242 - 4243 4238 trace_nfsd_slot_seqid_sequence(clp, seq, slot); 4244 4239 status = check_slot_seqid(seq->seqid, slot->sl_seqid, 4245 4240 slot->sl_flags & NFSD4_SLOT_INUSE); ··· 4283 4288 cstate->slot = slot; 4284 4289 cstate->session = session; 4285 4290 cstate->clp = clp; 4291 + 4292 + /* 4293 + * If the client ever uses the highest available slot, 4294 + * gently try to allocate another 20%. This allows 4295 + * fairly quick growth without grossly over-shooting what 4296 + * the client might use. 4297 + */ 4298 + if (seq->slotid == session->se_fchannel.maxreqs - 1 && 4299 + session->se_fchannel.maxreqs < NFSD_MAX_SLOTS_PER_SESSION) { 4300 + int s = session->se_fchannel.maxreqs; 4301 + int cnt = DIV_ROUND_UP(s, 5); 4302 + 4303 + do { 4304 + /* 4305 + * GFP_NOWAIT both allows allocation under a 4306 + * spinlock, and only succeeds if there is 4307 + * plenty of memory. 4308 + */ 4309 + slot = kzalloc(slot_bytes(&session->se_fchannel), 4310 + GFP_NOWAIT); 4311 + if (slot && 4312 + !xa_is_err(xa_store(&session->se_slots, s, slot, 4313 + GFP_NOWAIT))) { 4314 + s += 1; 4315 + session->se_fchannel.maxreqs = s; 4316 + } else { 4317 + kfree(slot); 4318 + slot = NULL; 4319 + } 4320 + } while (slot && --cnt > 0); 4321 + } 4322 + seq->maxslots = session->se_fchannel.maxreqs; 4286 4323 4287 4324 out: 4288 4325 switch (clp->cl_cb_state) {