All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Gao Xiang <gaoxiang25@huawei.com>,
	Chao Yu <yuchao0@huawei.com>
Subject: [PATCH 4.19 02/68] staging: erofs: fix mis-acted TAIL merging behavior
Date: Fri,  8 Mar 2019 13:49:32 +0100	[thread overview]
Message-ID: <20190308124910.847984709@linuxfoundation.org> (raw)
In-Reply-To: <20190308124910.696595153@linuxfoundation.org>

4.19-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gao Xiang <gaoxiang25@huawei.com>

commit a112152f6f3a2a88caa6f414d540bd49e406af60 upstream.

EROFS has an optimized path called TAIL merging, which is designed
to merge multiple reads and the corresponding decompressions into
one if these requests read continuous pages almost at the same time.

In general, it behaves as follows:
 ________________________________________________________________
  ... |  TAIL  .  HEAD  |  PAGE  |  PAGE  |  TAIL    . HEAD | ...
 _____|_combined page A_|________|________|_combined page B_|____
        1  ]  ->  [  2                          ]  ->  [ 3
If the above three reads are requested in the order 1-2-3, it will
generate a large work chain rather than 3 individual work chains
to reduce scheduling overhead and boost up sequential read.

However, if Read 2 is processed slightly earlier than Read 1,
currently it still generates 2 individual work chains (chain 1, 2)
but it does in-place decompression for combined page A, moreover,
if chain 2 decompresses ahead of chain 1, it will be a race and
lead to corrupted decompressed page. This patch fixes it.

Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support")
Cc: <stable@vger.kernel.org> # 4.19+
Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


---
 drivers/staging/erofs/unzip_vle.c |   69 ++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 25 deletions(-)

--- a/drivers/staging/erofs/unzip_vle.c
+++ b/drivers/staging/erofs/unzip_vle.c
@@ -57,15 +57,30 @@ enum z_erofs_vle_work_role {
 	Z_EROFS_VLE_WORK_SECONDARY,
 	Z_EROFS_VLE_WORK_PRIMARY,
 	/*
-	 * The current work has at least been linked with the following
-	 * processed chained works, which means if the processing page
-	 * is the tail partial page of the work, the current work can
-	 * safely use the whole page, as illustrated below:
-	 * +--------------+-------------------------------------------+
-	 * |  tail page   |      head page (of the previous work)     |
-	 * +--------------+-------------------------------------------+
-	 *   /\  which belongs to the current work
-	 * [  (*) this page can be used for the current work itself.  ]
+	 * The current work was the tail of an exist chain, and the previous
+	 * processed chained works are all decided to be hooked up to it.
+	 * A new chain should be created for the remaining unprocessed works,
+	 * therefore different from Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED,
+	 * the next work cannot reuse the whole page in the following scenario:
+	 *  ________________________________________________________________
+	 * |      tail (partial) page     |       head (partial) page       |
+	 * |  (belongs to the next work)  |  (belongs to the current work)  |
+	 * |_______PRIMARY_FOLLOWED_______|________PRIMARY_HOOKED___________|
+	 */
+	Z_EROFS_VLE_WORK_PRIMARY_HOOKED,
+	/*
+	 * The current work has been linked with the processed chained works,
+	 * and could be also linked with the potential remaining works, which
+	 * means if the processing page is the tail partial page of the work,
+	 * the current work can safely use the whole page (since the next work
+	 * is under control) for in-place decompression, as illustrated below:
+	 *  ________________________________________________________________
+	 * |  tail (partial) page  |          head (partial) page           |
+	 * | (of the current work) |         (of the previous work)         |
+	 * |  PRIMARY_FOLLOWED or  |                                        |
+	 * |_____PRIMARY_HOOKED____|____________PRIMARY_FOLLOWED____________|
+	 *
+	 * [  (*) the above page can be used for the current work itself.  ]
 	 */
 	Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED,
 	Z_EROFS_VLE_WORK_MAX
@@ -234,10 +249,10 @@ static int z_erofs_vle_work_add_page(
 	return ret ? 0 : -EAGAIN;
 }
 
-static inline bool try_to_claim_workgroup(
-	struct z_erofs_vle_workgroup *grp,
-	z_erofs_vle_owned_workgrp_t *owned_head,
-	bool *hosted)
+static enum z_erofs_vle_work_role
+try_to_claim_workgroup(struct z_erofs_vle_workgroup *grp,
+		       z_erofs_vle_owned_workgrp_t *owned_head,
+		       bool *hosted)
 {
 	DBG_BUGON(*hosted == true);
 
@@ -251,6 +266,9 @@ retry:
 
 		*owned_head = grp;
 		*hosted = true;
+		/* lucky, I am the followee :) */
+		return Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
+
 	} else if (grp->next == Z_EROFS_VLE_WORKGRP_TAIL) {
 		/*
 		 * type 2, link to the end of a existing open chain,
@@ -260,12 +278,11 @@ retry:
 		if (Z_EROFS_VLE_WORKGRP_TAIL != cmpxchg(&grp->next,
 			Z_EROFS_VLE_WORKGRP_TAIL, *owned_head))
 			goto retry;
-
 		*owned_head = Z_EROFS_VLE_WORKGRP_TAIL;
-	} else
-		return false;	/* :( better luck next time */
+		return Z_EROFS_VLE_WORK_PRIMARY_HOOKED;
+	}
 
-	return true;	/* lucky, I am the followee :) */
+	return Z_EROFS_VLE_WORK_PRIMARY; /* :( better luck next time */
 }
 
 static struct z_erofs_vle_work *
@@ -337,12 +354,8 @@ z_erofs_vle_work_lookup(struct super_blo
 	*hosted = false;
 	if (!primary)
 		*role = Z_EROFS_VLE_WORK_SECONDARY;
-	/* claim the workgroup if possible */
-	else if (try_to_claim_workgroup(grp, owned_head, hosted))
-		*role = Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED;
-	else
-		*role = Z_EROFS_VLE_WORK_PRIMARY;
-
+	else	/* claim the workgroup if possible */
+		*role = try_to_claim_workgroup(grp, owned_head, hosted);
 	return work;
 }
 
@@ -419,6 +432,9 @@ static inline void __update_workgrp_llen
 	}
 }
 
+#define builder_is_hooked(builder) \
+	((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_HOOKED)
+
 #define builder_is_followed(builder) \
 	((builder)->role >= Z_EROFS_VLE_WORK_PRIMARY_FOLLOWED)
 
@@ -583,7 +599,7 @@ static int z_erofs_do_read_page(struct z
 	struct z_erofs_vle_work_builder *const builder = &fe->builder;
 	const loff_t offset = page_offset(page);
 
-	bool tight = builder_is_followed(builder);
+	bool tight = builder_is_hooked(builder);
 	struct z_erofs_vle_work *work = builder->work;
 
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
@@ -646,7 +662,7 @@ repeat:
 		builder->role = Z_EROFS_VLE_WORK_PRIMARY;
 #endif
 
-	tight &= builder_is_followed(builder);
+	tight &= builder_is_hooked(builder);
 	work = builder->work;
 hitted:
 	cur = end - min_t(unsigned, offset + end - map->m_la, end);
@@ -661,6 +677,9 @@ hitted:
 			(tight ? Z_EROFS_PAGE_TYPE_EXCLUSIVE :
 				Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED));
 
+	if (cur)
+		tight &= builder_is_followed(builder);
+
 retry:
 	err = z_erofs_vle_work_add_page(builder, page, page_type);
 	/* should allocate an additional staging page for pagevec */



  parent reply	other threads:[~2019-03-08 13:04 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-08 12:49 [PATCH 4.19 00/68] 4.19.28-stable review Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 01/68] cpufreq: Use struct kobj_attribute instead of struct global_attr Greg Kroah-Hartman
2019-03-08 12:49 ` Greg Kroah-Hartman [this message]
2019-03-08 12:49 ` [PATCH 4.19 03/68] USB: serial: option: add Telit ME910 ECM composition Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 04/68] USB: serial: cp210x: add ID for Ingenico 3070 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 05/68] USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 06/68] staging: erofs: fix illegal address access under memory pressure Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 07/68] staging: erofs: compressed_pages should not be accessed again after freed Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 08/68] staging: comedi: ni_660x: fix missing break in switch statement Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 09/68] staging: wilc1000: fix to set correct value for vif_num Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 10/68] staging: android: ion: fix sys heap pools gfp_flags Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 11/68] staging: android: ashmem: Dont call fallocate() with ashmem_mutex held Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 12/68] staging: android: ashmem: Avoid range_alloc() allocation " Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 13/68] ip6mr: Do not call __IP6_INC_STATS() from preemptible context Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 14/68] net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in mv88e6xxx_port_set_duplex Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 15/68] net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 16/68] net: sched: put back q.qlen into a single location Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 17/68] net-sysfs: Fix mem leak in netdev_register_kobject Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 18/68] qmi_wwan: Add support for Quectel EG12/EM12 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 19/68] sctp: call iov_iter_revert() after sending ABORT Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 20/68] sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 21/68] team: Free BPF filter when unregistering netdev Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 22/68] tipc: fix RDM/DGRAM connect() regression Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 23/68] bnxt_en: Drop oversize TX packets to prevent errors Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 24/68] geneve: correctly handle ipv6.disable module parameter Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 25/68] hv_netvsc: Fix IP header checksum for coalesced packets Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 26/68] ipv4: Add ICMPv6 support when parse route ipproto Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 27/68] lan743x: Fix TX Stall Issue Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 28/68] net: dsa: mv88e6xxx: Fix statistics on mv88e6161 Greg Kroah-Hartman
2019-03-08 12:49 ` [PATCH 4.19 29/68] net: dsa: mv88e6xxx: Fix u64 statistics Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 30/68] netlabel: fix out-of-bounds memory accesses Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 31/68] net: netem: fix skb length BUG_ON in __skb_to_sgvec Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 32/68] net: nfc: Fix NULL dereference on nfc_llcp_build_tlv fails Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 33/68] net: phy: Micrel KSZ8061: link failure after cable connect Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 34/68] net: phy: phylink: fix uninitialized variable in phylink_get_mac_state Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 35/68] net: sit: fix memory leak in sit_init_net() Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 36/68] net: socket: set sock->sk to NULL after calling proto_ops::release() Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 37/68] tipc: fix race condition causing hung sendto Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 38/68] tun: fix blocking read Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 39/68] xen-netback: dont populate the hash cache on XenBus disconnect Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 40/68] xen-netback: fix occasional leak of grant ref mappings under memory pressure Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 41/68] tun: remove unnecessary memory barrier Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 42/68] net: Add __icmp_send helper Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 43/68] net: avoid use IPCB in cipso_v4_error Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 44/68] ipv4: Return error for RTA_VIA attribute Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 45/68] ipv6: " Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 46/68] mpls: Return error for RTA_GATEWAY attribute Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 47/68] ipv4: Pass original device to ip_rcv_finish_core Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 48/68] net: dsa: mv88e6xxx: power serdes on/off for 10G interfaces on 6390X Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 49/68] net: dsa: mv88e6xxx: prevent interrupt storm caused by mv88e6390x_port_set_cmode Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 50/68] net/sched: act_ipt: fix refcount leak when replace fails Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 51/68] net/sched: act_skbedit: " Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 52/68] net: sched: act_tunnel_key: fix NULL pointer dereference during init Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 53/68] x86/CPU/AMD: Set the CPB bit unconditionally on F17h Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 54/68] x86/boot/compressed/64: Do not read legacy ROM on EFI system Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 55/68] tracing: Fix event filters and triggers to handle negative numbers Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 56/68] usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on INTEL_SUNRISEPOINT_LP_XHCI Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 57/68] applicom: Fix potential Spectre v1 vulnerabilities Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 58/68] MIPS: irq: Allocate accurate order pages for irq stack Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 59/68] aio: Fix locking in aio_poll() Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 60/68] xtensa: fix get_wchan Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 61/68] gnss: sirf: fix premature wakeup interrupt enable Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 62/68] USB: serial: cp210x: fix GPIO in autosuspend Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 63/68] selftests: firmware: fix verify_reqs() return value Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 64/68] Bluetooth: btrtl: Restore old logic to assume firmware is already loaded Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 65/68] Bluetooth: Fix locking in bt_accept_enqueue() for BH context Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 66/68] exec: Fix mem leak in kernel_read_file Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 67/68] scsi: core: reset host byte in DID_NEXUS_FAILURE case Greg Kroah-Hartman
2019-03-08 12:50 ` [PATCH 4.19 68/68] bpf: fix sanitation rewrite in case of non-pointers Greg Kroah-Hartman
2019-03-08 16:03 ` [PATCH 4.19 00/68] 4.19.28-stable review Jon Hunter
2019-03-08 16:03   ` Jon Hunter
2019-03-08 20:59 ` shuah
2019-03-09  6:41 ` Naresh Kamboju
2019-03-09 22:35 ` Guenter Roeck

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=20190308124910.847984709@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=gaoxiang25@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=yuchao0@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.