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: remove artificial limits on the session-based DRC

Rather than guessing how much space it might be safe to use for the DRC,
simply try allocating slots and be prepared to accept failure.

The first slot for each session is allocated with GFP_KERNEL which is
unlikely to fail. Subsequent slots are allocated with the addition of
__GFP_NORETRY which is expected to fail if there isn't much free memory.

This is probably too aggressive but clears the way for adding a
shrinker interface to free extra slots when memory is tight.

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
b5fba969 0b6e1424

+16 -113
+16 -78
fs/nfsd/nfs4state.c
··· 1938 1938 return size + sizeof(struct nfsd4_slot); 1939 1939 } 1940 1940 1941 - /* 1942 - * XXX: If we run out of reserved DRC memory we could (up to a point) 1943 - * re-negotiate active sessions and reduce their slot usage to make 1944 - * room for new connections. For now we just fail the create session. 1945 - */ 1946 - static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn) 1947 - { 1948 - u32 slotsize = slot_bytes(ca); 1949 - u32 num = ca->maxreqs; 1950 - unsigned long avail, total_avail; 1951 - unsigned int scale_factor; 1952 - 1953 - spin_lock(&nfsd_drc_lock); 1954 - if (nfsd_drc_max_mem > nfsd_drc_mem_used) 1955 - total_avail = nfsd_drc_max_mem - nfsd_drc_mem_used; 1956 - else 1957 - /* We have handed out more space than we chose in 1958 - * set_max_drc() to allow. That isn't really a 1959 - * problem as long as that doesn't make us think we 1960 - * have lots more due to integer overflow. 1961 - */ 1962 - total_avail = 0; 1963 - avail = min((unsigned long)NFSD_MAX_MEM_PER_SESSION, total_avail); 1964 - /* 1965 - * Never use more than a fraction of the remaining memory, 1966 - * unless it's the only way to give this client a slot. 1967 - * The chosen fraction is either 1/8 or 1/number of threads, 1968 - * whichever is smaller. This ensures there are adequate 1969 - * slots to support multiple clients per thread. 1970 - * Give the client one slot even if that would require 1971 - * over-allocation--it is better than failure. 1972 - */ 1973 - scale_factor = max_t(unsigned int, 8, nn->nfsd_serv->sv_nrthreads); 1974 - 1975 - avail = clamp_t(unsigned long, avail, slotsize, 1976 - total_avail/scale_factor); 1977 - num = min_t(int, num, avail / slotsize); 1978 - num = max_t(int, num, 1); 1979 - nfsd_drc_mem_used += num * slotsize; 1980 - spin_unlock(&nfsd_drc_lock); 1981 - 1982 - return num; 1983 - } 1984 - 1985 - static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca) 1986 - { 1987 - int slotsize = slot_bytes(ca); 1988 - 1989 - spin_lock(&nfsd_drc_lock); 1990 - nfsd_drc_mem_used -= slotsize * ca->maxreqs; 1991 - spin_unlock(&nfsd_drc_lock); 1992 - } 1993 - 1994 1941 static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs, 1995 1942 struct nfsd4_channel_attrs *battrs) 1996 1943 { 1997 1944 int numslots = fattrs->maxreqs; 1998 1945 int slotsize = slot_bytes(fattrs); 1999 1946 struct nfsd4_session *new; 1947 + struct nfsd4_slot *slot; 2000 1948 int i; 2001 1949 2002 1950 new = kzalloc(sizeof(*new), GFP_KERNEL); ··· 1952 2004 return NULL; 1953 2005 xa_init(&new->se_slots); 1954 2006 /* allocate each struct nfsd4_slot and data cache in one piece */ 1955 - for (i = 0; i < numslots; i++) { 1956 - struct nfsd4_slot *slot; 1957 - slot = kzalloc(slotsize, GFP_KERNEL); 2007 + slot = kzalloc(slotsize, GFP_KERNEL); 2008 + if (!slot || xa_is_err(xa_store(&new->se_slots, 0, slot, GFP_KERNEL))) 2009 + goto out_free; 2010 + 2011 + for (i = 1; i < numslots; i++) { 2012 + const gfp_t gfp = GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN; 2013 + slot = kzalloc(slotsize, gfp); 1958 2014 if (!slot) 1959 - goto out_free; 1960 - if (xa_is_err(xa_store(&new->se_slots, i, slot, GFP_KERNEL))) { 2015 + break; 2016 + if (xa_is_err(xa_store(&new->se_slots, i, slot, gfp))) { 1961 2017 kfree(slot); 1962 - goto out_free; 2018 + break; 1963 2019 } 1964 2020 } 1965 - 2021 + fattrs->maxreqs = i; 1966 2022 memcpy(&new->se_fchannel, fattrs, sizeof(struct nfsd4_channel_attrs)); 1967 2023 new->se_cb_slot_avail = ~0U; 1968 2024 new->se_cb_highest_slot = min(battrs->maxreqs - 1, ··· 1974 2022 spin_lock_init(&new->se_lock); 1975 2023 return new; 1976 2024 out_free: 1977 - while (i--) 1978 - kfree(xa_load(&new->se_slots, i)); 2025 + kfree(slot); 1979 2026 xa_destroy(&new->se_slots); 1980 2027 kfree(new); 1981 2028 return NULL; ··· 2089 2138 static void free_session(struct nfsd4_session *ses) 2090 2139 { 2091 2140 nfsd4_del_conns(ses); 2092 - nfsd4_put_drc_mem(&ses->se_fchannel); 2093 2141 __free_session(ses); 2094 2142 } 2095 2143 ··· 3736 3786 ca->maxresp_cached = min_t(u32, ca->maxresp_cached, 3737 3787 NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ); 3738 3788 ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION); 3739 - /* 3740 - * Note decreasing slot size below client's request may make it 3741 - * difficult for client to function correctly, whereas 3742 - * decreasing the number of slots will (just?) affect 3743 - * performance. When short on memory we therefore prefer to 3744 - * decrease number of slots instead of their size. Clients that 3745 - * request larger slots than they need will get poor results: 3746 - * Note that we always allow at least one slot, because our 3747 - * accounting is soft and provides no guarantees either way. 3748 - */ 3749 - ca->maxreqs = nfsd4_get_drc_mem(ca, nn); 3750 3789 3751 3790 return nfs_ok; 3752 3791 } ··· 3813 3874 return status; 3814 3875 status = check_backchannel_attrs(&cr_ses->back_channel); 3815 3876 if (status) 3816 - goto out_release_drc_mem; 3877 + goto out_err; 3817 3878 status = nfserr_jukebox; 3818 3879 new = alloc_session(&cr_ses->fore_channel, &cr_ses->back_channel); 3819 3880 if (!new) 3820 - goto out_release_drc_mem; 3881 + goto out_err; 3821 3882 conn = alloc_conn_from_crses(rqstp, cr_ses); 3822 3883 if (!conn) 3823 3884 goto out_free_session; ··· 3926 3987 free_conn(conn); 3927 3988 out_free_session: 3928 3989 __free_session(new); 3929 - out_release_drc_mem: 3930 - nfsd4_put_drc_mem(&cr_ses->fore_channel); 3990 + out_err: 3931 3991 return status; 3932 3992 } 3933 3993
-3
fs/nfsd/nfsd.h
··· 88 88 extern struct svc_program nfsd_programs[]; 89 89 extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; 90 90 extern struct mutex nfsd_mutex; 91 - extern spinlock_t nfsd_drc_lock; 92 - extern unsigned long nfsd_drc_max_mem; 93 - extern unsigned long nfsd_drc_mem_used; 94 91 extern atomic_t nfsd_th_cnt; /* number of available threads */ 95 92 96 93 extern const struct seq_operations nfs_exports_op;
-32
fs/nfsd/nfssvc.c
··· 70 70 */ 71 71 DEFINE_MUTEX(nfsd_mutex); 72 72 73 - /* 74 - * nfsd_drc_lock protects nfsd_drc_max_pages and nfsd_drc_pages_used. 75 - * nfsd_drc_max_pages limits the total amount of memory available for 76 - * version 4.1 DRC caches. 77 - * nfsd_drc_pages_used tracks the current version 4.1 DRC memory usage. 78 - */ 79 - DEFINE_SPINLOCK(nfsd_drc_lock); 80 - unsigned long nfsd_drc_max_mem; 81 - unsigned long nfsd_drc_mem_used; 82 - 83 73 #if IS_ENABLED(CONFIG_NFS_LOCALIO) 84 74 static const struct svc_version *localio_versions[] = { 85 75 [1] = &localio_version1, ··· 565 575 } 566 576 } 567 577 568 - /* 569 - * Each session guarantees a negotiated per slot memory cache for replies 570 - * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated 571 - * NFSv4.1 server might want to use more memory for a DRC than a machine 572 - * with mutiple services. 573 - * 574 - * Impose a hard limit on the number of pages for the DRC which varies 575 - * according to the machines free pages. This is of course only a default. 576 - * 577 - * For now this is a #defined shift which could be under admin control 578 - * in the future. 579 - */ 580 - static void set_max_drc(void) 581 - { 582 - #define NFSD_DRC_SIZE_SHIFT 7 583 - nfsd_drc_max_mem = (nr_free_buffer_pages() 584 - >> NFSD_DRC_SIZE_SHIFT) * PAGE_SIZE; 585 - nfsd_drc_mem_used = 0; 586 - dprintk("%s nfsd_drc_max_mem %lu \n", __func__, nfsd_drc_max_mem); 587 - } 588 - 589 578 static int nfsd_get_default_max_blksize(void) 590 579 { 591 580 struct sysinfo i; ··· 646 677 nn->nfsd_serv = serv; 647 678 spin_unlock(&nfsd_notifier_lock); 648 679 649 - set_max_drc(); 650 680 /* check if the notifier is already set */ 651 681 if (atomic_inc_return(&nfsd_notifier_refcount) == 1) { 652 682 register_inetaddr_notifier(&nfsd_inetaddr_notifier);