From 005cf99f42a6796e338f4e5063255d5fb895f57e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 5 Oct 2020 09:42:04 -0700 Subject: [PATCH] scoutfs: use vmalloc for high order xattr allocs The xattr item stream is constructred from a large contiguous region that contains the struct header, the key, and the value. The value can be larger than a page so kmalloc is likely to fail as the system gets fragmented. Our recent move to the item cache added a significant source of page allocation churn which moved the system towards fragmentation much more quickly and was causing high-order allocation failures in testing. Signed-off-by: Zach Brown --- kmod/src/xattr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index 4666eecd..921eb447 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -425,7 +425,7 @@ ssize_t scoutfs_getxattr(struct dentry *dentry, const char *name, void *buffer, /* only need enough for caller's name and value sizes */ bytes = sizeof(struct scoutfs_xattr) + name_len + size; - xat = kmalloc(bytes, GFP_NOFS); + xat = __vmalloc(bytes, GFP_NOFS, PAGE_KERNEL); if (!xat) return -ENOMEM; @@ -468,7 +468,7 @@ ssize_t scoutfs_getxattr(struct dentry *dentry, const char *name, void *buffer, ret = le16_to_cpu(xat->val_len); memcpy(buffer, &xat->name[xat->name_len], ret); out: - kfree(xat); + vfree(xat); return ret; } @@ -527,7 +527,7 @@ static int scoutfs_xattr_set(struct dentry *dentry, const char *name, return -EPERM; bytes = sizeof(struct scoutfs_xattr) + name_len + size; - xat = kmalloc(bytes, GFP_NOFS); + xat = __vmalloc(bytes, GFP_NOFS, PAGE_KERNEL); if (!xat) { ret = -ENOMEM; goto out; @@ -633,7 +633,7 @@ unlock: up_write(&si->xattr_rwsem); scoutfs_unlock(sb, lck, SCOUTFS_LOCK_WRITE); out: - kfree(xat); + vfree(xat); return ret; }