From: Qian Yingjin <qian(a)ddn.com>
I was running traces of the read code against an RAID storage
system to understand why read requests were being misaligned
against the underlying RAID strips. I found that the page end
offset calculation in filemap_get_read_batch() was off by one.
When a read is submitted with end offset 1048575, then it
calculates the end page for read of 256 when it should be 255.
"last_index" is the index of the page beyond the end of the read
and it should be skipped when get a batch of pages for read in
@filemap_get_read_batch().
The below simple patch fixes the problem. This code was introduced
in kernel 5.12.
Fixes: cbd59c48ae2b ("mm/filemap: use head pages in generic_file_buffered_read")
Signed-off-by: Qian Yingjin <qian(a)ddn.com>
---
mm/filemap.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index c4d4ace9cc70..b7754760c09a 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2371,7 +2371,7 @@ static void shrink_readahead_size_eio(struct file_ra_state *ra)
* clear so that the caller can take the appropriate action.
*/
static void filemap_get_read_batch(struct address_space *mapping,
- pgoff_t index, pgoff_t max, struct folio_batch *fbatch)
+ pgoff_t index, pgoff_t last_index, struct folio_batch *fbatch)
{
XA_STATE(xas, &mapping->i_pages, index);
struct folio *folio;
@@ -2380,7 +2380,11 @@ static void filemap_get_read_batch(struct address_space *mapping,
for (folio = xas_load(&xas); folio; folio = xas_next(&xas)) {
if (xas_retry(&xas, folio))
continue;
- if (xas.xa_index > max || xa_is_value(folio))
+ /*
+ * "last_index" is the index of the page beyond the end of
+ * the read.
+ */
+ if (xas.xa_index >= last_index || xa_is_value(folio))
break;
if (xa_is_sibling(folio))
break;
@@ -2588,6 +2592,7 @@ static int filemap_get_pages(struct kiocb *iocb, struct iov_iter *iter,
struct folio *folio;
int err = 0;
+ /* "last_index" is the index of the page beyond the end of the read */
last_index = DIV_ROUND_UP(iocb->ki_pos + iter->count, PAGE_SIZE);
retry:
if (fatal_signal_pending(current))
--
2.34.1
The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
Possible dependencies:
b389286d0234 ("drm/mgag200: Fix PLL setup for G200_SE_A rev >=4")
877507bb954e ("drm/mgag200: Provide per-device callbacks for PIXPLLC")
8aeeb3144fe2 ("drm/mgag200: Provide per-device callbacks for BMC synchronization")
f639f74a7895 ("drm/mgag200: Add per-device callbacks")
1baf9127c482 ("drm/mgag200: Replace simple-KMS with regular atomic helpers")
4f4dc37e374c ("drm/mgag200: Reorganize before dropping simple-KMS helpers")
ed2ef21f1089 ("drm/mgag200: Store primary plane's color format in CRTC state")
2d70b9a1482e ("drm/mgag200: Acquire I/O-register lock in atomic_commit_tail function")
1ee181fe958a ("drm/mgag200: Move DAC-register setup into model-specific code")
44373151ab42 ("drm/mgag200: Split mgag200_modeset_init()")
98da4b99a052 ("drm/mgag200: Store maximum resolution and memory bandwidth in device info")
21e74bf99596 ("drm/mgag200: Store HW_BUG_NO_STARTADD flag in device info")
b9a577a407d9 ("drm/mgag200: Add struct mgag200_device_info")
b62d943e9686 ("drm/mgag200: Implement new init logic")
d45e32c9d98c ("drm/mgag200: Call mgag200_device_probe_vram() from per-model init")
ce19021fd99a ("drm/mgag200: Move PCI-option setup into model-specific code")
85397f6bc4ff ("drm/mgag200: Initialize each model in separate function")
73f54d5d9682 ("drm/mgag200: Remove special case for G200SE with <2 MiB")
475e2b970cc3 ("drm/mgag200: Split up connector's mode_valid helper")
69340e529a06 ("drm/mgag200: Test memory requirements in drm_mode_config_funcs.mode_valid")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From b389286d0234e1edbaf62ed8bc0892a568c33662 Mon Sep 17 00:00:00 2001
From: Jocelyn Falempe <jfalempe(a)redhat.com>
Date: Thu, 13 Oct 2022 15:28:10 +0200
Subject: [PATCH] drm/mgag200: Fix PLL setup for G200_SE_A rev >=4
For G200_SE_A, PLL M setting is wrong, which leads to blank screen,
or "signal out of range" on VGA display.
previous code had "m |= 0x80" which was changed to
m |= ((pixpllcn & BIT(8)) >> 1);
Tested on G200_SE_A rev 42
This line of code was moved to another file with
commit 877507bb954e ("drm/mgag200: Provide per-device callbacks for
PIXPLLC") but can be easily backported before this commit.
v2: * put BIT(7) First to respect MSB-to-LSB (Thomas)
* Add a comment to explain that this bit must be set (Thomas)
Fixes: 2dd040946ecf ("drm/mgag200: Store values (not bits) in struct mgag200_pll_values")
Cc: stable(a)vger.kernel.org
Signed-off-by: Jocelyn Falempe <jfalempe(a)redhat.com>
Reviewed-by: Thomas Zimmermann <tzimmermann(a)suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20221013132810.521945-1-jfale…
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index be389ed91cbd..bd6e573c9a1a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -284,7 +284,8 @@ static void mgag200_g200se_04_pixpllc_atomic_update(struct drm_crtc *crtc,
pixpllcp = pixpllc->p - 1;
pixpllcs = pixpllc->s;
- xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
+ // For G200SE A, BIT(7) should be set unconditionally.
+ xpixpllcm = BIT(7) | pixpllcm;
xpixpllcn = pixpllcn;
xpixpllcp = (pixpllcs << 3) | pixpllcp;
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
Possible dependencies:
7a7d86d14d07 ("phy: qcom-qmp-combo: fix broken power on")
d4b81490fe44 ("phy: qcom-qmp-combo: drop start and pwrdn-ctrl abstraction")
f7075f4905e7 ("phy: qcom-qmp-combo: clean up status polling")
acfee73b635b ("phy: qcom-qmp-combo: drop power-down delay config")
d71eb7083e5e ("phy: qcom-qmp-combo: drop sc8280xp power-down delay")
2e52ddf045a0 ("phy: qcom-qmp-combo: clean up power-down handling")
9d943961912c ("phy: qcom-qmp-combo: drop redundant DP config flag")
099155615ac2 ("phy: qcom-qmp-combo: consolidate lane config")
f5d6b5d613e9 ("phy: qcom-qmp-combo: fix sc8280xp PCS_USB offset")
064bbdba4f8d ("phy: qcom-qmp-combo: drop unused legacy DT workaround")
2de8a325b108 ("phy: qcom-qmp-combo: fix memleak on probe deferral")
e5cedefa7203 ("phy: qcom-qmp-combo: shorten function prefixes")
beee6ed1d63f ("phy: qcom-qmp-combo: drop unused defines")
ac439ce88edf ("phy: qcom-qmp: drop dual-lane comments")
a2e927b0e50d ("phy: qcom-qmp-combo: Add sc8280xp USB/DP combo phys")
c0c7769cdae2 ("phy: qcom-qmp: Add SC8280XP USB3 UNI phy")
712e5dffe911 ("phy: qcom-qmp-combo: Parameterize swing and pre_emphasis tables")
d88497fb6bbd ("phy: qualcomm: phy-qcom-qmp: add support for combo USB3+DP phy on SDM845")
5fc21d1bd3d7 ("phy: qcom-qmp: split allegedly 4.20 and 5.20 TX/RX registers")
87d71378c61a ("phy: qcom-qmp: move PCIE QHP registers to separate header")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7a7d86d14d073dfa3429c550667a8e78b99edbd4 Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan+linaro(a)kernel.org>
Date: Mon, 14 Nov 2022 09:13:44 +0100
Subject: [PATCH] phy: qcom-qmp-combo: fix broken power on
The PHY is powered on during phy-init by setting the SW_PWRDN bit in the
COM_POWER_DOWN_CTRL register and then setting the same bit in the in the
PCS_POWER_DOWN_CONTROL register that belongs to the USB part of the
PHY.
Currently, whether power on succeeds depends on probe order and having
the USB part of the PHY be initialised first. In case the DP part of the
PHY is instead initialised first, the intended power on of the USB block
results in a corrupted DP_PHY register (e.g. DP_PHY_AUX_CFG8).
Add a pointer to the USB part of the PHY to the driver data and use that
to power on the PHY also if the DP part of the PHY is initialised first.
Fixes: 52e013d0bffa ("phy: qcom-qmp: Add support for DP in USB3+DP combo phy")
Cc: stable(a)vger.kernel.org # 5.10
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov(a)linaro.org>
Signed-off-by: Johan Hovold <johan+linaro(a)kernel.org>
Link: https://lore.kernel.org/r/20221114081346.5116-5-johan+linaro@kernel.org
Signed-off-by: Vinod Koul <vkoul(a)kernel.org>
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
index 40c25a0ead23..17707f68d482 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
@@ -932,6 +932,7 @@ struct qcom_qmp {
struct regulator_bulk_data *vregs;
struct qmp_phy **phys;
+ struct qmp_phy *usb_phy;
struct mutex phy_mutex;
int init_count;
@@ -1911,7 +1912,7 @@ static int qmp_combo_com_init(struct qmp_phy *qphy)
{
struct qcom_qmp *qmp = qphy->qmp;
const struct qmp_phy_cfg *cfg = qphy->cfg;
- void __iomem *pcs = qphy->pcs;
+ struct qmp_phy *usb_phy = qmp->usb_phy;
void __iomem *dp_com = qmp->dp_com;
int ret;
@@ -1963,7 +1964,8 @@ static int qmp_combo_com_init(struct qmp_phy *qphy)
qphy_clrbits(dp_com, QPHY_V3_DP_COM_SWI_CTRL, 0x03);
qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
- qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
+ qphy_setbits(usb_phy->pcs, usb_phy->cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+ SW_PWRDN);
mutex_unlock(&qmp->phy_mutex);
@@ -2831,6 +2833,8 @@ static int qmp_combo_probe(struct platform_device *pdev)
goto err_node_put;
}
+ qmp->usb_phy = qmp->phys[id];
+
/*
* Register the pipe clock provided by phy.
* See function description to see details of this pipe clock.
@@ -2846,6 +2850,9 @@ static int qmp_combo_probe(struct platform_device *pdev)
id++;
}
+ if (!qmp->usb_phy)
+ return -EINVAL;
+
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);