From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Kyeong Yoo <kyeong.yoo@alliedtelesis.co.nz>,
Richard Weinberger <richard@nod.at>,
Sasha Levin <sashal@kernel.org>,
dwmw2@infradead.org, joel@jms.id.au,
linux-mtd@lists.infradead.org
Subject: [PATCH AUTOSEL 5.4 53/73] jffs2: GC deadlock reading a page that is used in jffs2_write_begin()
Date: Mon, 17 Jan 2022 21:44:12 -0500 [thread overview]
Message-ID: <20220118024432.1952028-53-sashal@kernel.org> (raw)
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
From: Kyeong Yoo <kyeong.yoo@alliedtelesis.co.nz>
[ Upstream commit aa39cc675799bc92da153af9a13d6f969c348e82 ]
GC task can deadlock in read_cache_page() because it may attempt
to release a page that is actually allocated by another task in
jffs2_write_begin().
The reason is that in jffs2_write_begin() there is a small window
a cache page is allocated for use but not set Uptodate yet.
This ends up with a deadlock between two tasks:
1) A task (e.g. file copy)
- jffs2_write_begin() locks a cache page
- jffs2_write_end() tries to lock "alloc_sem" from
jffs2_reserve_space() <-- STUCK
2) GC task (jffs2_gcd_mtd3)
- jffs2_garbage_collect_pass() locks "alloc_sem"
- try to lock the same cache page in read_cache_page() <-- STUCK
So to avoid this deadlock, hold "alloc_sem" in jffs2_write_begin()
while reading data in a cache page.
Signed-off-by: Kyeong Yoo <kyeong.yoo@alliedtelesis.co.nz>
Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/jffs2/file.c | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index f8fb89b10227c..34880a4c21732 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -135,20 +135,15 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
struct page *pg;
struct inode *inode = mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
pgoff_t index = pos >> PAGE_SHIFT;
uint32_t pageofs = index << PAGE_SHIFT;
int ret = 0;
- pg = grab_cache_page_write_begin(mapping, index, flags);
- if (!pg)
- return -ENOMEM;
- *pagep = pg;
-
jffs2_dbg(1, "%s()\n", __func__);
if (pageofs > inode->i_size) {
/* Make new hole frag from old EOF to new page */
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_raw_inode ri;
struct jffs2_full_dnode *fn;
uint32_t alloc_len;
@@ -159,7 +154,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret)
- goto out_page;
+ goto out_err;
mutex_lock(&f->sem);
memset(&ri, 0, sizeof(ri));
@@ -189,7 +184,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
ret = PTR_ERR(fn);
jffs2_complete_reservation(c);
mutex_unlock(&f->sem);
- goto out_page;
+ goto out_err;
}
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
if (f->metadata) {
@@ -204,13 +199,26 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
jffs2_free_full_dnode(fn);
jffs2_complete_reservation(c);
mutex_unlock(&f->sem);
- goto out_page;
+ goto out_err;
}
jffs2_complete_reservation(c);
inode->i_size = pageofs;
mutex_unlock(&f->sem);
}
+ /*
+ * While getting a page and reading data in, lock c->alloc_sem until
+ * the page is Uptodate. Otherwise GC task may attempt to read the same
+ * page in read_cache_page(), which causes a deadlock.
+ */
+ mutex_lock(&c->alloc_sem);
+ pg = grab_cache_page_write_begin(mapping, index, flags);
+ if (!pg) {
+ ret = -ENOMEM;
+ goto release_sem;
+ }
+ *pagep = pg;
+
/*
* Read in the page if it wasn't already present. Cannot optimize away
* the whole page write case until jffs2_write_end can handle the
@@ -220,15 +228,17 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
mutex_lock(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
mutex_unlock(&f->sem);
- if (ret)
- goto out_page;
+ if (ret) {
+ unlock_page(pg);
+ put_page(pg);
+ goto release_sem;
+ }
}
jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
- return ret;
-out_page:
- unlock_page(pg);
- put_page(pg);
+release_sem:
+ mutex_unlock(&c->alloc_sem);
+out_err:
return ret;
}
--
2.34.1
next prev parent reply other threads:[~2022-01-18 3:06 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-18 2:43 [PATCH AUTOSEL 5.4 01/73] Bluetooth: Fix debugfs entry leak in hci_register_dev() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 02/73] fs: dlm: filter user dlm messages for kernel locks Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 03/73] libbpf: Validate that .BTF and .BTF.ext sections contain data Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 04/73] drm/lima: fix warning when CONFIG_DEBUG_SG=y & CONFIG_DMA_API_DEBUG=y Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 05/73] ar5523: Fix null-ptr-deref with unexpected WDCMSG_TARGET_START reply Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 06/73] drm/nouveau/pmu/gm200-: avoid touching PMU outside of DEVINIT/PREOS/ACR Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 07/73] ARM: shmobile: rcar-gen2: Add missing of_node_put() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 08/73] batman-adv: allow netlink usage in unprivileged containers Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 09/73] usb: gadget: f_fs: Use stream_open() for endpoint files Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 10/73] drm: panel-orientation-quirks: Add quirk for the Lenovo Yoga Book X91F/L Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 11/73] HID: apple: Do not reset quirks when the Fn key is not found Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 12/73] media: b2c2: Add missing check in flexcop_pci_isr: Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 13/73] EDAC/synopsys: Use the quirk for version instead of ddr version Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 14/73] ARM: imx: rename DEBUG_IMX21_IMX27_UART to DEBUG_IMX27_UART Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 15/73] mlxsw: pci: Add shutdown method in PCI driver Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 16/73] drm/bridge: megachips: Ensure both bridges are probed before registration Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 17/73] gpiolib: acpi: Do not set the IRQ type if the IRQ is already in use Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 18/73] HSI: core: Fix return freed object in hsi_new_client Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 19/73] mwifiex: Fix skb_over_panic in mwifiex_usb_recv() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 20/73] rsi: Fix use-after-free in rsi_rx_done_handler() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 21/73] rsi: Fix out-of-bounds read in rsi_read_pkt() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 22/73] usb: uhci: add aspeed ast2600 uhci support Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 23/73] floppy: Add max size check for user space request Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 24/73] x86/mm: Flush global TLB when switching to trampoline page-table Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 25/73] media: uvcvideo: Increase UVC_CTRL_CONTROL_TIMEOUT to 5 seconds Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 26/73] media: saa7146: hexium_orion: Fix a NULL pointer dereference in hexium_attach() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 27/73] media: m920x: don't use stack on USB reads Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 28/73] iwlwifi: mvm: synchronize with FW after multicast commands Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 29/73] ath10k: Fix tx hanging Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 30/73] net-sysfs: update the queue counts in the unregistration path Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 31/73] net: phy: prefer 1000baseT over 1000baseKX Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 32/73] gpio: aspeed: Convert aspeed_gpio.lock to raw_spinlock Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 33/73] net: Enable neighbor sysctls that is save for userns root Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 34/73] x86/mce: Mark mce_panic() noinstr Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 35/73] x86/mce: Mark mce_end() noinstr Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 36/73] x86/mce: Mark mce_read_aux() noinstr Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 37/73] net: bonding: debug: avoid printing debug logs when bond is not notifying peers Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 38/73] bpf: Do not WARN in bpf_warn_invalid_xdp_action() Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 39/73] HID: quirks: Allow inverting the absolute X/Y values Sasha Levin
2022-01-18 2:43 ` [PATCH AUTOSEL 5.4 40/73] media: igorplugusb: receiver overflow should be reported Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 41/73] media: saa7146: hexium_gemini: Fix a NULL pointer dereference in hexium_attach() Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 42/73] mmc: core: Fixup storing of OCR for MMC_QUIRK_NONSTD_SDIO Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 43/73] audit: ensure userspace is penalized the same as the kernel when under pressure Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 44/73] arm64: dts: ls1028a-qds: move rtc node to the correct i2c bus Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 45/73] arm64: tegra: Adjust length of CCPLEX cluster MMIO region Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 46/73] cpufreq: Fix initialization of min and max frequency QoS requests Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 47/73] usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0 Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 48/73] ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 49/73] iwlwifi: fix leaks/bad data after failed firmware load Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 50/73] iwlwifi: remove module loading failure message Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 51/73] iwlwifi: mvm: Fix calculation of frame length Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 52/73] um: registers: Rename function names to avoid conflicts and build problems Sasha Levin
2022-01-18 2:44 ` Sasha Levin [this message]
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 54/73] ACPICA: actypes.h: Expand the ACPI_ACCESS_ definitions Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 55/73] ACPICA: Utilities: Avoid deleting the same object twice in a row Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 56/73] ACPICA: Executer: Fix the REFCLASS_REFOF case in acpi_ex_opcode_1A_0T_1R() Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 57/73] ACPICA: Fix wrong interpretation of PCC address Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 58/73] ACPICA: Hardware: Do not flush CPU cache when entering S4 and S5 Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 59/73] drm/amdgpu: fixup bad vram size on gmc v8 Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 60/73] ACPI: battery: Add the ThinkPad "Not Charging" quirk Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 61/73] btrfs: remove BUG_ON() in find_parent_nodes() Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 62/73] btrfs: remove BUG_ON(!eie) in find_parent_nodes Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 63/73] net: mdio: Demote probed message to debug print Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 64/73] mac80211: allow non-standard VHT MCS-10/11 Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 65/73] dm btree: add a defensive bounds check to insert_at() Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 66/73] dm space map common: add bounds check to sm_ll_lookup_bitmap() Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 67/73] net: phy: marvell: configure RGMII delays for 88E1118 Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 68/73] net: gemini: allow any RGMII interface mode Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 69/73] regulator: qcom_smd: Align probe function with rpmh-regulator Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 70/73] serial: pl010: Drop CR register reset on set_termios Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 71/73] serial: core: Keep mctrl register state and cached copy in sync Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 72/73] random: do not throw away excess input to crng_fast_load Sasha Levin
2022-01-18 2:44 ` [PATCH AUTOSEL 5.4 73/73] parisc: Avoid calling faulthandler_disabled() twice Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220118024432.1952028-53-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=dwmw2@infradead.org \
--cc=joel@jms.id.au \
--cc=kyeong.yoo@alliedtelesis.co.nz \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=richard@nod.at \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome