drivers/mmc/host/dw_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
The Synopsys DesignWare mmc controller on the JH7110 SoC
(dw_mmc-starfive.c driver) is using a 32-bit IDMAC address bus width,
and thus requires the use of SWIOTLB.
The commit 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages
bigger than 4K") increased the max_seq_size, even for 4K pages, causing
"swiotlb buffer is full" to happen because swiotlb can only handle a
memory size up to 256kB only.
Fix the issue, by making sure the dw_mmc driver doesn't use segments
bigger than what SWIOTLB can handle.
Reported-by: Ron Economos <re@w6rz.net>
Reported-by: Jing Luo <jing@jing.rocks>
Fixes: 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K")
Cc: stable@vger.kernel.org
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
drivers/mmc/host/dw_mmc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 41e451235f637..dc0d6201f7b73 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2958,7 +2958,8 @@ static int dw_mci_init_slot(struct dw_mci *host)
mmc->max_segs = host->ring_size;
mmc->max_blk_size = 65535;
mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size;
- mmc->max_seg_size = mmc->max_req_size;
+ mmc->max_seg_size =
+ min_t(size_t, mmc->max_req_size, dma_max_mapping_size(host->dev));
mmc->max_blk_count = mmc->max_req_size / 512;
} else if (host->use_dma == TRANS_MODE_EDMAC) {
mmc->max_segs = 64;
--
2.45.2
+ Adam, Arnd, Shawn-Lin, sydarn On Sun, 20 Oct 2024 at 16:30, Aurelien Jarno <aurelien@aurel32.net> wrote: > > The Synopsys DesignWare mmc controller on the JH7110 SoC > (dw_mmc-starfive.c driver) is using a 32-bit IDMAC address bus width, > and thus requires the use of SWIOTLB. > > The commit 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages > bigger than 4K") increased the max_seq_size, even for 4K pages, causing > "swiotlb buffer is full" to happen because swiotlb can only handle a > memory size up to 256kB only. > > Fix the issue, by making sure the dw_mmc driver doesn't use segments > bigger than what SWIOTLB can handle. > > Reported-by: Ron Economos <re@w6rz.net> > Reported-by: Jing Luo <jing@jing.rocks> > Fixes: 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K") > Cc: stable@vger.kernel.org > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Thanks for working on this! Looks like we have managed to mess things up. Besides the issue that you have been working on to fix, apparently there seems to be another one too [1]. Unfortunately, $subject patch doesn't seem to fix the problem in [1], as has been reported by Adam. I have looped in some more people to this thread, hopefully we agree on how this should be fixed properly. Otherwise, I tend to say that we should simply revert the offending commit and start over. Kind regards Uffe [1] https://lore.kernel.org/all/CAC8uq=Ppnmv98mpa1CrWLawWoPnu5abtU69v-=G-P7ysATQ2Pw@mail.gmail.com/ > --- > drivers/mmc/host/dw_mmc.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 41e451235f637..dc0d6201f7b73 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2958,7 +2958,8 @@ static int dw_mci_init_slot(struct dw_mci *host) > mmc->max_segs = host->ring_size; > mmc->max_blk_size = 65535; > mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size; > - mmc->max_seg_size = mmc->max_req_size; > + mmc->max_seg_size = > + min_t(size_t, mmc->max_req_size, dma_max_mapping_size(host->dev)); > mmc->max_blk_count = mmc->max_req_size / 512; > } else if (host->use_dma == TRANS_MODE_EDMAC) { > mmc->max_segs = 64; > -- > 2.45.2 >
Ulf Hansson wrote: > + Adam, Arnd, Shawn-Lin, sydarn > > > On Sun, 20 Oct 2024 at 16:30, Aurelien Jarno <aurelien@aurel32.net> wrote: > > > > The Synopsys DesignWare mmc controller on the JH7110 SoC > > (dw_mmc-starfive.c driver) is using a 32-bit IDMAC address bus width, > > and thus requires the use of SWIOTLB. > > > > The commit 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages > > bigger than 4K") increased the max_seq_size, even for 4K pages, causing > > "swiotlb buffer is full" to happen because swiotlb can only handle a > > memory size up to 256kB only. > > > > Fix the issue, by making sure the dw_mmc driver doesn't use segments > > bigger than what SWIOTLB can handle. > > > > Reported-by: Ron Economos <re@w6rz.net> > > Reported-by: Jing Luo <jing@jing.rocks> > > Fixes: 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K") > > Cc: stable@vger.kernel.org > > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> > > Thanks for working on this! +1 > Looks like we have managed to mess things > up. Besides the issue that you have been working on to fix, apparently > there seems to be another one too [1]. > > Unfortunately, $subject patch doesn't seem to fix the problem in [1], > as has been reported by Adam. > > I have looped in some more people to this thread, hopefully we agree > on how this should be fixed properly. Otherwise, I tend to say that we > should simply revert the offending commit and start over. Yes, unfortunately this patch also doesn't fix MMC when running 6.12-rc4 on the StarFive VisionFive V1 (JH7100 SoC). /Emil
On 2024-10-20 23:29, Aurelien Jarno wrote: > The Synopsys DesignWare mmc controller on the JH7110 SoC > (dw_mmc-starfive.c driver) is using a 32-bit IDMAC address bus width, > and thus requires the use of SWIOTLB. > > The commit 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages > bigger than 4K") increased the max_seq_size, even for 4K pages, causing > "swiotlb buffer is full" to happen because swiotlb can only handle a > memory size up to 256kB only. > > Fix the issue, by making sure the dw_mmc driver doesn't use segments > bigger than what SWIOTLB can handle. > > Reported-by: Ron Economos <re@w6rz.net> > Reported-by: Jing Luo <jing@jing.rocks> > Fixes: 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages > bigger than 4K") > Cc: stable@vger.kernel.org > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Feel free to add: Tested-by: Jing Luo <jing@jing.rocks> This patch not only fixes the kernel log spam by dwmmc_starfive reporting "swiotlb buffer is full", but also seems to have fixed a serious bug that causes data corruption on emmc (as I reported to Debian [1]), which at least can be observed on both Visionfive 2 and Star64 boards. To add a cherry on the top, with this patch applied, I see massive performance improvement (sequential rw speed) on emmc: with a quick-and-dirty test using `dd bs=1M`, on Visionfive 2, it goes from 28MB/s to 42MB/s (+50%); on Star64, it goes from 13MB/s to 46MB/s (+253%). [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1085425 Thanks & cheers, Jing Luo > --- > drivers/mmc/host/dw_mmc.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 41e451235f637..dc0d6201f7b73 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2958,7 +2958,8 @@ static int dw_mci_init_slot(struct dw_mci *host) > mmc->max_segs = host->ring_size; > mmc->max_blk_size = 65535; > mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size; > - mmc->max_seg_size = mmc->max_req_size; > + mmc->max_seg_size = > + min_t(size_t, mmc->max_req_size, > dma_max_mapping_size(host->dev)); > mmc->max_blk_count = mmc->max_req_size / 512; > } else if (host->use_dma == TRANS_MODE_EDMAC) { > mmc->max_segs = 64;
Hi Aurelien, On Sun, 20 Oct 2024 at 20:01, Aurelien Jarno <aurelien@aurel32.net> wrote: > > The Synopsys DesignWare mmc controller on the JH7110 SoC > (dw_mmc-starfive.c driver) is using a 32-bit IDMAC address bus width, > and thus requires the use of SWIOTLB. > > The commit 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages > bigger than 4K") increased the max_seq_size, even for 4K pages, causing > "swiotlb buffer is full" to happen because swiotlb can only handle a > memory size up to 256kB only. > > Fix the issue, by making sure the dw_mmc driver doesn't use segments > bigger than what SWIOTLB can handle. > > Reported-by: Ron Economos <re@w6rz.net> > Reported-by: Jing Luo <jing@jing.rocks> > Fixes: 8396c793ffdf ("mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K") > Cc: stable@vger.kernel.org > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> > --- Please add my Tested-by: Anand Moon <linux.amoon@gmail.com> Thanks for fixing the warning below. [ 511.837216][ T148] dwmmc_starfive 16020000.mmc: swiotlb buffer is full (sz: 290816 bytes), total 65536 (slots), used 246 (slots) [ 511.837423][ C0] dwmmc_starfive 16020000.mmc: swiotlb buffer is full (sz: 278528 bytes), total 65536 (slots), used 222 (slots) [ 511.916951][ C0] dwmmc_starfive 16020000.mmc: swiotlb buffer is full (sz: 290816 bytes), total 65536 (slots), used 24 (slots) [ 516.803916][ T575] dwmmc_starfive 16020000.mmc: swiotlb buffer is full (sz: 507904 bytes), total 65536 (slots), used 122 (slots) [ 516.805450][ C0] dwmmc_starfive 16020000.mmc: swiotlb buffer is full (sz: 507904 bytes), total 65536 (slots), used 364 (slots) Thanks -Anand > drivers/mmc/host/dw_mmc.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 41e451235f637..dc0d6201f7b73 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -2958,7 +2958,8 @@ static int dw_mci_init_slot(struct dw_mci *host) > mmc->max_segs = host->ring_size; > mmc->max_blk_size = 65535; > mmc->max_req_size = DW_MCI_DESC_DATA_LENGTH * host->ring_size; > - mmc->max_seg_size = mmc->max_req_size; > + mmc->max_seg_size = > + min_t(size_t, mmc->max_req_size, dma_max_mapping_size(host->dev)); > mmc->max_blk_count = mmc->max_req_size / 512; > } else if (host->use_dma == TRANS_MODE_EDMAC) { > mmc->max_segs = 64; > -- > 2.45.2 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
© 2016 - 2024 Red Hat, Inc.