From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72D23C433F5 for ; Tue, 23 Nov 2021 08:08:15 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EF2736B0071; Tue, 23 Nov 2021 03:07:59 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id EA2DC6B0072; Tue, 23 Nov 2021 03:07:59 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D4C936B0073; Tue, 23 Nov 2021 03:07:59 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0171.hostedemail.com [216.40.44.171]) by kanga.kvack.org (Postfix) with ESMTP id C2C4C6B0071 for ; Tue, 23 Nov 2021 03:07:59 -0500 (EST) Received: from smtpin02.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id 653511847719F for ; Tue, 23 Nov 2021 08:07:49 +0000 (UTC) X-FDA: 78839466258.02.185D7A9 Received: from mail-yb1-f169.google.com (mail-yb1-f169.google.com [209.85.219.169]) by imf01.hostedemail.com (Postfix) with ESMTP id 8F90C50932F4 for ; Tue, 23 Nov 2021 08:07:44 +0000 (UTC) Received: by mail-yb1-f169.google.com with SMTP id v64so57271715ybi.5 for ; Tue, 23 Nov 2021 00:07:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20210112.gappssmtp.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=L7f/aUCx8NVGyPLAzQitqS+/TnPxMztetwJciVabBeY=; b=6zYWJZpyiKoP/AjChWdk1Mr9Z+WI7uA/FCe9DJ4VdNTGfHUGW6kovw2NXoBFhpBuoX dlpB/M+nkDCo/zUyd4459F4SRRQvlGSJuVTysZ2DaOizLM4EzXsiNoevCXU6PSUscy13 OWPWbbmTJ5NQZ9DSVUebf9g93zxFh8Ioj3Ec4/eE2+qDJ5pytC/DU5WMSgxgUrz0VrVJ 3O+PabJz3r7AI7YvtG+2K4CgxrUvvJsCZCvGI5RLFnDMyPTMlkbsWphicq2wyT5ZZcXH XaqjDK4q8/oe6I9pXBzNTyaqTbTEIzv4E9exyDBbk+0FF7E0UDgMIGAT2WRaz0VHl1kj dFuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=L7f/aUCx8NVGyPLAzQitqS+/TnPxMztetwJciVabBeY=; b=M2GbQchvfhfSd3wIBMBknEJQEUddRi5o1a1hZvPO53q2X9zLIDj4RkBqYBOfwXBP12 8px5sqQ41CnvHwHRrozvnqhqiFctMAnnde2riaGhUowT8gUdhym9WpaIsUB+/7bJimPG zyhekWnIu8Ht5X10nUqkXJgj8X7mxUxc0rZEXM2/1FaA5PgjriJcxoBq/POwMQQ0hxhx 0DIVp9W2Vllo4ehwzyCNzZcEF2X3LLhldWQwSv2z6wHmA8yeC6H6fw0oGsfKJ5eTrrfr z2Gt3+nyFO/xq8wMKxtEJJ8q7tw1EX0YNaK0GlusRT5mHlzvPzOsR95IVa31zu++4qiX FWJQ== X-Gm-Message-State: AOAM531oCeobG+VEVYeWc9670Yfw2NAcTKPYSiC0LyF15ImC3L/OGTBr Gwru7PfW5s0npmAjtAYpSnAI0b+Xmo1G61Q3Dn+YnQ== X-Google-Smtp-Source: ABdhPJy3xKrLsQ0i80CPUA2i00XnDJy+VKNkyTyS6MSn4PZJcxsnkeGO5hPSCe+BtbPNtMbMhCHrOuQSPHwUs6nKpuY= X-Received: by 2002:a25:38d6:: with SMTP id f205mr4321963yba.208.1637654867187; Tue, 23 Nov 2021 00:07:47 -0800 (PST) MIME-Version: 1.0 References: <20211122064126.76734-1-ligang.bdlg@bytedance.com> In-Reply-To: <20211122064126.76734-1-ligang.bdlg@bytedance.com> From: Muchun Song Date: Tue, 23 Nov 2021 16:07:08 +0800 Message-ID: Subject: Re: [PATCH v1] shmem: change shrinklist_lock form spinlock to mutex and move iput into it To: Gang Li Cc: Hugh Dickins , Andrew Morton , "Kirill A. Shutemov" , Linux Memory Management List , LKML Content-Type: text/plain; charset="UTF-8" X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: 8F90C50932F4 X-Stat-Signature: 3opa1714w4urq8hp49qzuo1tgjazz453 Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=bytedance-com.20210112.gappssmtp.com header.s=20210112 header.b=6zYWJZpy; dmarc=pass (policy=none) header.from=bytedance.com; spf=pass (imf01.hostedemail.com: domain of songmuchun@bytedance.com designates 209.85.219.169 as permitted sender) smtp.mailfrom=songmuchun@bytedance.com X-HE-Tag: 1637654864-553981 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Mon, Nov 22, 2021 at 2:41 PM Gang Li wrote: > > This patch fixes commit 779750d20b93 ("shmem: split huge pages > beyond i_size under memory pressure"). > > iput out of sbinfo->shrinklist_lock will let shmem_evict_inode grab > and delete the inode, which will berak the consistency between > shrinklist_len and shrinklist. The simultaneous deletion of adjacent > elements in the local list "list" by shmem_unused_huge_shrink and > shmem_evict_inode will also break the list. > > iput must in lock or after lock, but shrinklist_lock is a spinlock > which can not sleep and iput may sleep.[1] > > Fix it by changing shrinklist_lock from spinlock to mutex and moving iput > into this lock. > > [1]. Link: http://lkml.kernel.org/r/20170131093141.GA15899@node.shutemov.name > Fixes: 779750d20b93 ("shmem: split huge pages beyond i_size under memory pressure") > Signed-off-by: Gang Li > --- > include/linux/shmem_fs.h | 2 +- > mm/shmem.c | 16 +++++++--------- > 2 files changed, 8 insertions(+), 10 deletions(-) > > diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h > index 166158b6e917..65804fd264d0 100644 > --- a/include/linux/shmem_fs.h > +++ b/include/linux/shmem_fs.h > @@ -41,7 +41,7 @@ struct shmem_sb_info { > ino_t next_ino; /* The next per-sb inode number to use */ > ino_t __percpu *ino_batch; /* The next per-cpu inode number to use */ > struct mempolicy *mpol; /* default memory policy for mappings */ > - spinlock_t shrinklist_lock; /* Protects shrinklist */ > + struct mutex shrinklist_mutex;/* Protects shrinklist */ > struct list_head shrinklist; /* List of shinkable inodes */ > unsigned long shrinklist_len; /* Length of shrinklist */ > }; > diff --git a/mm/shmem.c b/mm/shmem.c > index 18f93c2d68f1..2165a28631c5 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -559,7 +559,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, > if (list_empty(&sbinfo->shrinklist)) > return SHRINK_STOP; > > - spin_lock(&sbinfo->shrinklist_lock); > + mutex_lock(&sbinfo->shrinklist_mutex); > list_for_each_safe(pos, next, &sbinfo->shrinklist) { > info = list_entry(pos, struct shmem_inode_info, shrinklist); > > @@ -586,7 +586,6 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, > if (!--batch) > break; > } > - spin_unlock(&sbinfo->shrinklist_lock); > > list_for_each_safe(pos, next, &to_remove) { > info = list_entry(pos, struct shmem_inode_info, shrinklist); > @@ -643,10 +642,9 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, > iput(inode); It could lead to deadlock, since we could be the last user of @inode, then shmem_evict_inode() will be called and try to acquire the mutex lock. Notice that the mutex is already held here. Thanks. > } > > - spin_lock(&sbinfo->shrinklist_lock); > list_splice_tail(&list, &sbinfo->shrinklist); > sbinfo->shrinklist_len -= removed; > - spin_unlock(&sbinfo->shrinklist_lock); > + mutex_unlock(&sbinfo->shrinklist_mutex); > > return split; > } > @@ -1137,12 +1135,12 @@ static void shmem_evict_inode(struct inode *inode) > inode->i_size = 0; > shmem_truncate_range(inode, 0, (loff_t)-1); > if (!list_empty(&info->shrinklist)) { > - spin_lock(&sbinfo->shrinklist_lock); > + mutex_lock(&sbinfo->shrinklist_mutex); > if (!list_empty(&info->shrinklist)) { > list_del_init(&info->shrinklist); > sbinfo->shrinklist_len--; > } > - spin_unlock(&sbinfo->shrinklist_lock); > + mutex_unlock(&sbinfo->shrinklist_mutex); > } > while (!list_empty(&info->swaplist)) { > /* Wait while shmem_unuse() is scanning this inode... */ > @@ -1954,7 +1952,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, > * Part of the huge page is beyond i_size: subject > * to shrink under memory pressure. > */ > - spin_lock(&sbinfo->shrinklist_lock); > + mutex_lock(&sbinfo->shrinklist_mutex); > /* > * _careful to defend against unlocked access to > * ->shrink_list in shmem_unused_huge_shrink() > @@ -1964,7 +1962,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, > &sbinfo->shrinklist); > sbinfo->shrinklist_len++; > } > - spin_unlock(&sbinfo->shrinklist_lock); > + mutex_unlock(&sbinfo->shrinklist_mutex); > } > > /* > @@ -3652,7 +3650,7 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) > raw_spin_lock_init(&sbinfo->stat_lock); > if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL)) > goto failed; > - spin_lock_init(&sbinfo->shrinklist_lock); > + mutex_init(&sbinfo->shrinklist_mutex); > INIT_LIST_HEAD(&sbinfo->shrinklist); > > sb->s_maxbytes = MAX_LFS_FILESIZE; > -- > 2.20.1 >