Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp3309020ybv; Mon, 24 Feb 2020 22:44:22 -0800 (PST) X-Google-Smtp-Source: APXvYqxorncWh5tcNhOveNcxR07WNfrQxrREl0bpDnTTqk4YVDb+SCLZOEo+c9tZuAM5dkYgHZsE X-Received: by 2002:a54:4010:: with SMTP id x16mr2438266oie.174.1582613062743; Mon, 24 Feb 2020 22:44:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582613062; cv=none; d=google.com; s=arc-20160816; b=tufH2IkRfEZvsDI+hEJtcBLRhUV3PGf1aByGkzrh6dzwXAeu0OB+WEbKsewJXNC99v VduZqKjM1RnNSs3qETrQk8cYnr53+RDK11BlOePkEGMiL1eybLOPdd5mUpk+crJj2Uie ySe1HOKx1lB/qIszgbmnE+3XsScipwI3Ji87fWjnVwYCUuGA9HFTBCrauAnA6mvm4A/2 VfqgVgkj4nNurd+3OjlM5FXruiXjJyZbLBENp5BzZmqnOiB1Z43N7K2CthHEwMS9TE03 wyv8siDmD1XUgjkfwIrNJ5RvpB6dVO596ENoCZR7Nn8UXMB7+icBRkcZi2/jhUI6VGsp tjeA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=LHa86/wmoQGkRYQ2PfZCXHRW/f0snyckDltYTbnlufE=; b=EbRJz1vs1e0XzZNeZVc8eXYnhk9U8gq2t4SpiGCZ4TIrArIPSu0hmWbOztDkgxONRt MNdDPdyIj5gh/Sx82qFKlkwDOhvS3TnTEFOjxV8oDMze097Y4pfEay2/7f1IibR3WIzU 5L742vPdbS28/q7rlnIAkJlWyPN/qk3tmndLRqqENHmq11Eq34rPay/LjphaNUwxD6GB d9FGHELkWTeMCJUgZRvW2tzWsggOD5+mldf7DAkEvsZMZNkE2eMtA7twr65OGjTOe31c QR73hDl21YxSmFvvXhldAwfKNN/TYtRJ6JN8ncx9yqAPKi7HFRtQz32LfNnvy2lITbFX NdUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pzJx44Re; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z7si5753387oid.150.2020.02.24.22.44.10; Mon, 24 Feb 2020 22:44:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pzJx44Re; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728965AbgBYGhc (ORCPT + 99 others); Tue, 25 Feb 2020 01:37:32 -0500 Received: from mail-ua1-f65.google.com ([209.85.222.65]:37703 "EHLO mail-ua1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726019AbgBYGhb (ORCPT ); Tue, 25 Feb 2020 01:37:31 -0500 Received: by mail-ua1-f65.google.com with SMTP id h32so4148085uah.4 for ; Mon, 24 Feb 2020 22:37:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=LHa86/wmoQGkRYQ2PfZCXHRW/f0snyckDltYTbnlufE=; b=pzJx44Reo3ZBGEHnlCeQRfKf6QzDFvJC9/ESlgVuvLhTrtTskumX6XphWt72F8lz2i XWG7l+mZMXdlrk4XyHjwoZ2bGXyjL40Em6EI3SXpPaottaA42LL7Yxjncjsjvq8DVZBS xANCTPnmEOLJNgY76ATtZfAuZpceX2T7nMLZT11M3xhVFssAl+bKzexO0s0Wy/a38ey8 dFtKBGVNfXr40Kk0G6g3xWCeo2XUttx5hCAHD9YltgGe6OIe0UoEo61IIq0bqm4VSskd 7voyXOOKTMUYEXt24mxb5bC8k19X0RxbRg+sXmbt+kSflI3bx4byu1jJM2sMCWToaYPc jQfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=LHa86/wmoQGkRYQ2PfZCXHRW/f0snyckDltYTbnlufE=; b=TremeZVJUWXsVTvVYQsCoP98KkVVmONax6enZhVOHPD2fc8LUyEcLqi4yCZI0SN/44 kcA4axCphRvfed6RyGeeATWM13GISJiHapguZpBq0Ixzfss52wp7+ZiRks3L3CjwaC8B oiQRCcE9i7NmQMT2ttrXQCArLv6rT2ahXu4g27pyErrOGOvWJdORHylABEnameGsyqW/ KUbLhMagOW1f39KUbNnf6HQZOX8lPKc3xRgk2O9RU9EuNS/4oha8klPS1yWh9O3oVTsw GAHqGz2NNbBV2KXKCnl4dk3pgrIbbfzPAO1ZxPDTwCsd7xVWcoG2zcKj6xuTj8rgL4md JfBQ== X-Gm-Message-State: APjAAAXu/CTd16Clacu6/47EsWC5SyconKJegf6Gob+gJ8+97ISDupCL rXfFjaJlF7f3SDSwlRkitGLy6uOZLRHcPekOWXK2XH1EF2Q= X-Received: by 2002:ab0:374a:: with SMTP id i10mr26445743uat.97.1582612647087; Mon, 24 Feb 2020 22:37:27 -0800 (PST) MIME-Version: 1.0 References: <20200225014257.83903-1-yuchao0@huawei.com> In-Reply-To: <20200225014257.83903-1-yuchao0@huawei.com> From: Ju Hyung Park Date: Tue, 25 Feb 2020 15:37:15 +0900 Message-ID: Subject: Re: [PATCH] f2fs: use kmem_cache pool during inline xattr lookups To: Chao Yu Cc: Jaegeuk Kim , linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, Chao Yu Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Chao. Sorry for the late reply, I've been busy with my uni stuffs. It's nice to see this issue getting some attentions back, but unfortunately, I can't test it at the moment. Here's the patch we used to see the alloc statistics: https://pastebin.com/bhBh2dgs by Sultan Alsawaf. Hope it helps. On Tue, Feb 25, 2020 at 10:43 AM Chao Yu wrote: > > It's been observed that kzalloc() on lookup_all_xattrs() are called millions > of times on Android, quickly becoming the top abuser of slub memory allocator. > > Use a dedicated kmem cache pool for xattr lookups to mitigate this. > > Signed-off-by: Park Ju Hyung > Signed-off-by: Chao Yu > --- > > Hi, Ju Hyung, > > Let me know if you have any objection on this patch. :) > > fs/f2fs/f2fs.h | 3 +++ > fs/f2fs/super.c | 10 ++++++++- > fs/f2fs/xattr.c | 54 ++++++++++++++++++++++++++++++++++++++++++++----- > fs/f2fs/xattr.h | 4 ++++ > 4 files changed, 65 insertions(+), 6 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 12a197e89a3e..23b93a116c73 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -1486,6 +1486,9 @@ struct f2fs_sb_info { > __u32 s_chksum_seed; > > struct workqueue_struct *post_read_wq; /* post read workqueue */ > + > + struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ > + unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ > }; > > struct f2fs_private_dio { > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index d241e07c0bfa..0b16204d3b7d 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -1201,6 +1201,7 @@ static void f2fs_put_super(struct super_block *sb) > kvfree(sbi->raw_super); > > destroy_device_list(sbi); > + f2fs_destroy_xattr_caches(sbi); > mempool_destroy(sbi->write_io_dummy); > #ifdef CONFIG_QUOTA > for (i = 0; i < MAXQUOTAS; i++) > @@ -3457,12 +3458,17 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) > } > } > > + /* init per sbi slab cache */ > + err = f2fs_init_xattr_caches(sbi); > + if (err) > + goto free_io_dummy; > + > /* get an inode for meta space */ > sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi)); > if (IS_ERR(sbi->meta_inode)) { > f2fs_err(sbi, "Failed to read F2FS meta data inode"); > err = PTR_ERR(sbi->meta_inode); > - goto free_io_dummy; > + goto free_xattr_cache; > } > > err = f2fs_get_valid_checkpoint(sbi); > @@ -3735,6 +3741,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) > make_bad_inode(sbi->meta_inode); > iput(sbi->meta_inode); > sbi->meta_inode = NULL; > +free_xattr_cache: > + f2fs_destroy_xattr_caches(sbi); > free_io_dummy: > mempool_destroy(sbi->write_io_dummy); > free_percpu: > diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c > index a3360a97e624..e46a10eb0e42 100644 > --- a/fs/f2fs/xattr.c > +++ b/fs/f2fs/xattr.c > @@ -23,6 +23,25 @@ > #include "xattr.h" > #include "segment.h" > > +static void *xattr_alloc(struct f2fs_sb_info *sbi, int size, bool *is_inline) > +{ > + *is_inline = (size == sbi->inline_xattr_slab_size); > + > + if (*is_inline) > + return kmem_cache_zalloc(sbi->inline_xattr_slab, GFP_NOFS); > + > + return f2fs_kzalloc(sbi, size, GFP_NOFS); > +} > + > +static void xattr_free(struct f2fs_sb_info *sbi, void *xattr_addr, > + bool is_inline) > +{ > + if (is_inline) > + kmem_cache_free(sbi->inline_xattr_slab, xattr_addr); > + else > + kvfree(xattr_addr); > +} > + > static int f2fs_xattr_generic_get(const struct xattr_handler *handler, > struct dentry *unused, struct inode *inode, > const char *name, void *buffer, size_t size) > @@ -301,7 +320,8 @@ static int read_xattr_block(struct inode *inode, void *txattr_addr) > static int lookup_all_xattrs(struct inode *inode, struct page *ipage, > unsigned int index, unsigned int len, > const char *name, struct f2fs_xattr_entry **xe, > - void **base_addr, int *base_size) > + void **base_addr, int *base_size, > + bool *is_inline) > { > void *cur_addr, *txattr_addr, *last_txattr_addr; > void *last_addr = NULL; > @@ -313,7 +333,7 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, > return -ENODATA; > > *base_size = XATTR_SIZE(inode) + XATTR_PADDING_SIZE; > - txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS); > + txattr_addr = xattr_alloc(F2FS_I_SB(inode), *base_size, is_inline); > if (!txattr_addr) > return -ENOMEM; > > @@ -362,7 +382,7 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage, > *base_addr = txattr_addr; > return 0; > out: > - kvfree(txattr_addr); > + xattr_free(F2FS_I_SB(inode), txattr_addr, *is_inline); > return err; > } > > @@ -499,6 +519,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, > unsigned int size, len; > void *base_addr = NULL; > int base_size; > + bool is_inline; > > if (name == NULL) > return -EINVAL; > @@ -509,7 +530,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, > > down_read(&F2FS_I(inode)->i_xattr_sem); > error = lookup_all_xattrs(inode, ipage, index, len, name, > - &entry, &base_addr, &base_size); > + &entry, &base_addr, &base_size, &is_inline); > up_read(&F2FS_I(inode)->i_xattr_sem); > if (error) > return error; > @@ -532,7 +553,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, > } > error = size; > out: > - kvfree(base_addr); > + xattr_free(F2FS_I_SB(inode), base_addr, is_inline); > return error; > } > > @@ -767,3 +788,26 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, > f2fs_update_time(sbi, REQ_TIME); > return err; > } > + > +int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) > +{ > + dev_t dev = sbi->sb->s_bdev->bd_dev; > + char slab_name[32]; > + > + sprintf(slab_name, "f2fs_xattr_entry-%u:%u", MAJOR(dev), MINOR(dev)); > + > + sbi->inline_xattr_slab_size = F2FS_OPTION(sbi).inline_xattr_size * > + sizeof(__le32) + XATTR_PADDING_SIZE; > + > + sbi->inline_xattr_slab = f2fs_kmem_cache_create(slab_name, > + sbi->inline_xattr_slab_size); > + if (!sbi->inline_xattr_slab) > + return -ENOMEM; > + > + return 0; > +} > + > +void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) > +{ > + kmem_cache_destroy(sbi->inline_xattr_slab); > +} > diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h > index 574beea46494..7345dfa7b7a9 100644 > --- a/fs/f2fs/xattr.h > +++ b/fs/f2fs/xattr.h > @@ -131,6 +131,8 @@ extern int f2fs_setxattr(struct inode *, int, const char *, > extern int f2fs_getxattr(struct inode *, int, const char *, void *, > size_t, struct page *); > extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); > +extern int f2fs_init_xattr_caches(struct f2fs_sb_info *); > +extern void f2fs_destroy_xattr_caches(struct f2fs_sb_info *); > #else > > #define f2fs_xattr_handlers NULL > @@ -151,6 +153,8 @@ static inline ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, > { > return -EOPNOTSUPP; > } > +static int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) { return 0; } > +static void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) { return 0; } > #endif > > #ifdef CONFIG_F2FS_FS_SECURITY > -- > 2.18.0.rc1 >