Skip to content

Commit 3ae629d

Browse files
jtlaytonsmfrench
authored andcommitted
cifs: on CONFIG_HIGHMEM machines, limit the rsize/wsize to the kmap space
We currently rely on being able to kmap all of the pages in an async read or write request. If you're on a machine that has CONFIG_HIGHMEM set then that kmap space is limited, sometimes to as low as 512 slots. With 512 slots, we can only support up to a 2M r/wsize, and that's assuming that we can get our greedy little hands on all of them. There are other users however, so it's possible we'll end up stuck with a size that large. Since we can't handle a rsize or wsize larger than that currently, cap those options at the number of kmap slots we have. We could consider capping it even lower, but we currently default to a max of 1M. Might as well allow those luddites on 32 bit arches enough rope to hang themselves. A more robust fix would be to teach the send and receive routines how to contend with an array of pages so we don't need to marshal up a kvec array at all. That's a fairly significant overhaul though, so we'll need this limit in place until that's ready. Cc: <[email protected]> Reported-by: Jian Li <[email protected]> Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent ffc61cc commit 3ae629d

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

fs/cifs/connect.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3445,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
34453445
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
34463446
#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
34473447

3448+
/*
3449+
* On hosts with high memory, we can't currently support wsize/rsize that are
3450+
* larger than we can kmap at once. Cap the rsize/wsize at
3451+
* LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request
3452+
* larger than that anyway.
3453+
*/
3454+
#ifdef CONFIG_HIGHMEM
3455+
#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE)
3456+
#else /* CONFIG_HIGHMEM */
3457+
#define CIFS_KMAP_SIZE_LIMIT (1<<24)
3458+
#endif /* CONFIG_HIGHMEM */
3459+
34483460
static unsigned int
34493461
cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
34503462
{
@@ -3475,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
34753487
wsize = min_t(unsigned int, wsize,
34763488
server->maxBuf - sizeof(WRITE_REQ) + 4);
34773489

3490+
/* limit to the amount that we can kmap at once */
3491+
wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT);
3492+
34783493
/* hard limit of CIFS_MAX_WSIZE */
34793494
wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
34803495

@@ -3516,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
35163531
if (!(server->capabilities & CAP_LARGE_READ_X))
35173532
rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
35183533

3534+
/* limit to the amount that we can kmap at once */
3535+
rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT);
3536+
35193537
/* hard limit of CIFS_MAX_RSIZE */
35203538
rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
35213539

0 commit comments

Comments
 (0)