From patchwork Wed Jun 15 07:02:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: liubo X-Patchwork-Id: 12881870 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 3F95DC43334 for ; Wed, 15 Jun 2022 07:02:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CEDCD6B0073; Wed, 15 Jun 2022 03:02:39 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C9DAD6B0074; Wed, 15 Jun 2022 03:02:39 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B65A16B0075; Wed, 15 Jun 2022 03:02:39 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id A89F86B0073 for ; Wed, 15 Jun 2022 03:02:39 -0400 (EDT) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 7A24F795 for ; Wed, 15 Jun 2022 07:02:39 +0000 (UTC) X-FDA: 79579577238.03.DC4DF5A Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf16.hostedemail.com (Postfix) with ESMTP id 05067180075 for ; Wed, 15 Jun 2022 07:02:37 +0000 (UTC) Received: from dggemv711-chm.china.huawei.com (unknown [172.30.72.55]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4LNGPd4dyZzSgsZ; Wed, 15 Jun 2022 14:59:17 +0800 (CST) Received: from kwepemm600016.china.huawei.com (7.193.23.20) by dggemv711-chm.china.huawei.com (10.1.198.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Wed, 15 Jun 2022 15:02:16 +0800 Received: from huawei.com (10.175.124.27) by kwepemm600016.china.huawei.com (7.193.23.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Wed, 15 Jun 2022 15:02:15 +0800 From: liubo To: , , CC: , , , , , , , , , , , Subject: [PATCH v2 1/2] mm/swapfile: Extract operations of resource release in the swapoff process Date: Wed, 15 Jun 2022 15:02:27 +0800 Message-ID: <20220615070228.2858170-2-liubo254@huawei.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20220615070228.2858170-1-liubo254@huawei.com> References: <20220615070228.2858170-1-liubo254@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.124.27] X-ClientProxiedBy: dggems706-chm.china.huawei.com (10.3.19.183) To kwepemm600016.china.huawei.com (7.193.23.20) X-CFilter-Loop: Reflected ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1655276559; a=rsa-sha256; cv=none; b=MoQ2Qox2Cx80gipwzVRh0+B602W6CV4pjC/hZjnRINndL7lLIoEkKqPxMSINBUWhniM1zd TewtL7TXRm+8plyn3HfkwaKy2+bpM+mNNt/vN+qLfqNA2axQ6Zn7vo0yAA+m1zH7esPVuZ PRxVEmLvDokRSncLsCRx7f8Wj2R9I6w= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=none; spf=pass (imf16.hostedemail.com: domain of liubo254@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=liubo254@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1655276559; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BPT4DwNCtwGCq2rmgI1lIw631QmyxRlnRfoDWELL6ek=; b=Au4NqkWfnkYYjIeTEKtG3bC04siaIeVTPLA90uN4WVFhXdW9a+RTi/AqVqEECIoqLzvPXZ u/E3Y8mQiCe83umrgIZogjiMhXLKcjbv9Hy1z0a6YbkcdZN8yOaCZLaiF1snI8F6adjOV+ Z9vMG3t/AxUoe6NEkir34eRzjJwyrG0= X-Stat-Signature: 7hndrtdqdxktzia7dfcfypu8rwo9uoht X-Rspamd-Queue-Id: 05067180075 Authentication-Results: imf16.hostedemail.com; dkim=none; spf=pass (imf16.hostedemail.com: domain of liubo254@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=liubo254@huawei.com; dmarc=pass (policy=quarantine) header.from=huawei.com X-Rspam-User: X-Rspamd-Server: rspam02 X-HE-Tag: 1655276557-576602 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: In order to realize the interface reuse in the swapoff resource release process, some of the operations are abstracted into separate interfaces. Only code movement, no functional modifications and changes. del_useless_swap_info(): Remove specific swap_info_struct from swap_active_head and update total_swap_pages. release_swap_info_memory(): Clear the corresponding resources of swap_info_struct. Signed-off-by: liubo --- v2: Only code movement, no functional modifications and changes. Former: https://lore.kernel.org/linux-mm/20220528084941.28391-1-liubo254@huawei.com/ --- mm/swapfile.c | 168 +++++++++++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 77 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 3fa26f6971e9..2ef5e7b4918e 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2386,18 +2386,103 @@ bool has_usable_swap(void) return ret; } -SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) +static void release_swap_info_memory(struct swap_info_struct *p) { - struct swap_info_struct *p = NULL; unsigned char *swap_map; struct swap_cluster_info *cluster_info; unsigned long *frontswap_map; - struct file *swap_file, *victim; + struct file *swap_file; struct address_space *mapping; struct inode *inode; + unsigned int old_block_size; + + mutex_lock(&swapon_mutex); + spin_lock(&swap_lock); + spin_lock(&p->lock); + drain_mmlist(); + + /* wait for anyone still in scan_swap_map */ + p->highest_bit = 0; /* cuts scans short */ + while (p->flags >= SWP_SCANNING) { + spin_unlock(&p->lock); + spin_unlock(&swap_lock); + schedule_timeout_uninterruptible(1); + spin_lock(&swap_lock); + spin_lock(&p->lock); + } + + swap_file = p->swap_file; + mapping = p->swap_file->f_mapping; + old_block_size = p->old_block_size; + p->swap_file = NULL; + p->max = 0; + swap_map = p->swap_map; + p->swap_map = NULL; + cluster_info = p->cluster_info; + p->cluster_info = NULL; + frontswap_map = frontswap_map_get(p); + spin_unlock(&p->lock); + spin_unlock(&swap_lock); + arch_swap_invalidate_area(p->type); + frontswap_invalidate_area(p->type); + frontswap_map_set(p, NULL); + mutex_unlock(&swapon_mutex); + free_percpu(p->percpu_cluster); + p->percpu_cluster = NULL; + free_percpu(p->cluster_next_cpu); + p->cluster_next_cpu = NULL; + vfree(swap_map); + kvfree(cluster_info); + kvfree(frontswap_map); + /* Destroy swap account information */ + swap_cgroup_swapoff(p->type); + exit_swap_address_space(p->type); + + inode = mapping->host; + if (S_ISBLK(inode->i_mode)) { + struct block_device *bdev = I_BDEV(inode); + + set_blocksize(bdev, old_block_size); + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); + } + + inode_lock(inode); + inode->i_flags &= ~S_SWAPFILE; + inode_unlock(inode); + filp_close(swap_file, NULL); +} + +static void del_useless_swap_info(struct swap_info_struct *p) +{ + del_from_avail_list(p); + spin_lock(&p->lock); + if (p->prio < 0) { + struct swap_info_struct *si = p; + int nid; + + plist_for_each_entry_continue(si, &swap_active_head, list) { + si->prio++; + si->list.prio--; + for_each_node(nid) { + if (si->avail_lists[nid].prio != 1) + si->avail_lists[nid].prio--; + } + } + least_priority++; + } + plist_del(&p->list, &swap_active_head); + atomic_long_sub(p->pages, &nr_swap_pages); + p->flags &= ~SWP_WRITEOK; + spin_unlock(&p->lock); +} + +SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) +{ + struct swap_info_struct *p = NULL; + struct file *victim; + struct address_space *mapping; struct filename *pathname; int err, found = 0; - unsigned int old_block_size; unsigned int inuse_pages; if (!capable(CAP_SYS_ADMIN)) @@ -2440,26 +2525,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) spin_unlock(&swap_lock); goto out_dput; } - del_from_avail_list(p); - spin_lock(&p->lock); - if (p->prio < 0) { - struct swap_info_struct *si = p; - int nid; - plist_for_each_entry_continue(si, &swap_active_head, list) { - si->prio++; - si->list.prio--; - for_each_node(nid) { - if (si->avail_lists[nid].prio != 1) - si->avail_lists[nid].prio--; - } - } - least_priority++; - } - plist_del(&p->list, &swap_active_head); - atomic_long_sub(p->pages, &nr_swap_pages); - p->flags &= ~SWP_WRITEOK; - spin_unlock(&p->lock); + del_useless_swap_info(p); spin_unlock(&swap_lock); disable_swap_slots_cache_lock(); @@ -2497,60 +2564,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) if (!p->bdev || !bdev_nonrot(p->bdev)) atomic_dec(&nr_rotate_swap); - mutex_lock(&swapon_mutex); - spin_lock(&swap_lock); - spin_lock(&p->lock); - drain_mmlist(); - - /* wait for anyone still in scan_swap_map_slots */ - p->highest_bit = 0; /* cuts scans short */ - while (p->flags >= SWP_SCANNING) { - spin_unlock(&p->lock); - spin_unlock(&swap_lock); - schedule_timeout_uninterruptible(1); - spin_lock(&swap_lock); - spin_lock(&p->lock); - } - - swap_file = p->swap_file; - old_block_size = p->old_block_size; - p->swap_file = NULL; - p->max = 0; - swap_map = p->swap_map; - p->swap_map = NULL; - cluster_info = p->cluster_info; - p->cluster_info = NULL; - frontswap_map = frontswap_map_get(p); - spin_unlock(&p->lock); - spin_unlock(&swap_lock); - arch_swap_invalidate_area(p->type); - frontswap_invalidate_area(p->type); - frontswap_map_set(p, NULL); - mutex_unlock(&swapon_mutex); - free_percpu(p->percpu_cluster); - p->percpu_cluster = NULL; - free_percpu(p->cluster_next_cpu); - p->cluster_next_cpu = NULL; - vfree(swap_map); - kvfree(cluster_info); - kvfree(frontswap_map); - /* Destroy swap account information */ - swap_cgroup_swapoff(p->type); - exit_swap_address_space(p->type); - - inode = mapping->host; - if (S_ISBLK(inode->i_mode)) { - struct block_device *bdev = I_BDEV(inode); - - set_blocksize(bdev, old_block_size); - blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); - } - - inode_lock(inode); - inode->i_flags &= ~S_SWAPFILE; - inode_unlock(inode); - filp_close(swap_file, NULL); - + release_swap_info_memory(p); /* * Clear the SWP_USED flag after all resources are freed so that swapon * can reuse this swap_info in alloc_swap_info() safely. It is ok to