diff mbox series

[4.19,240/321] mmc: core: align max segment size with logical block size

Message ID 20191203223439.627632861@linuxfoundation.org (mailing list archive)
State New, archived
Headers show
Series None | expand

Commit Message

Greg Kroah-Hartman Dec. 3, 2019, 10:35 p.m. UTC
From: Ming Lei <ming.lei@redhat.com>

[ Upstream commit c53336c8f5f29043fded57912cc06c24e12613d7 ]

Logical block size is the lowest possible block size that the storage
device can address. Max segment size is often related with controller's
DMA capability. And it is reasonable to align max segment size with
logical block size.

SDHCI sets un-aligned max segment size, and causes ADMA error, so
fix it by aligning max segment size with logical block size.

Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Naresh Kamboju <naresh.kamboju@linaro.org>
Cc: Faiz Abbas <faiz_abbas@ti.com>
Cc: linux-block@vger.kernel.org
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/mmc/core/block.c | 6 ------
 drivers/mmc/core/queue.c | 9 ++++++++-
 2 files changed, 8 insertions(+), 7 deletions(-)

Comments

Pavel Machek Dec. 5, 2019, 10:22 p.m. UTC | #1
Hi!

> From: Ming Lei <ming.lei@redhat.com>
> 
> [ Upstream commit c53336c8f5f29043fded57912cc06c24e12613d7 ]
> 
> Logical block size is the lowest possible block size that the storage
> device can address. Max segment size is often related with controller's
> DMA capability. And it is reasonable to align max segment size with
> logical block size.

> SDHCI sets un-aligned max segment size, and causes ADMA error, so
> fix it by aligning max segment size with logical block size.

If un-aligned max segment sizes are problem, should we add checks to
prevent setting them?

At least these set unaligned problems; is that a problem?

drivers/block/nbd.c:	blk_queue_max_segment_size(disk->queue, UINT_MAX);
drivers/block/virtio_blk.c:		blk_queue_max_segment_size(q, -1U);
drivers/block/rbd.c:	blk_queue_max_segment_size(q, UINT_MAX);

Best regards,
									Pavel
Ming Lei Dec. 6, 2019, 12:54 a.m. UTC | #2
On Thu, Dec 05, 2019 at 11:22:47PM +0100, Pavel Machek wrote:
> Hi!
> 
> > From: Ming Lei <ming.lei@redhat.com>
> > 
> > [ Upstream commit c53336c8f5f29043fded57912cc06c24e12613d7 ]
> > 
> > Logical block size is the lowest possible block size that the storage
> > device can address. Max segment size is often related with controller's
> > DMA capability. And it is reasonable to align max segment size with
> > logical block size.
> 
> > SDHCI sets un-aligned max segment size, and causes ADMA error, so
> > fix it by aligning max segment size with logical block size.
> 
> If un-aligned max segment sizes are problem, should we add checks to
> prevent setting them?
> 
> At least these set unaligned problems; is that a problem?
> 
> drivers/block/nbd.c:	blk_queue_max_segment_size(disk->queue, UINT_MAX);
> drivers/block/virtio_blk.c:		blk_queue_max_segment_size(q, -1U);
> drivers/block/rbd.c:	blk_queue_max_segment_size(q, UINT_MAX);

In theory, all segment size should be aligned, however the above MAX
value just means the queue hasn't max segment size limit, so it won't
be applied actually.


Thanks,
Ming
diff mbox series

Patch

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index eee004fb3c3e3..527ab15c421f9 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2384,12 +2384,6 @@  static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
 	snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
 		 "mmcblk%u%s", card->host->index, subname ? subname : "");
 
-	if (mmc_card_mmc(card))
-		blk_queue_logical_block_size(md->queue.queue,
-					     card->ext_csd.data_sector_size);
-	else
-		blk_queue_logical_block_size(md->queue.queue, 512);
-
 	set_capacity(md->disk, size);
 
 	if (mmc_host_cmd23(card->host)) {
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 18aae28845ec9..becc6594a8a47 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -355,6 +355,7 @@  static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
 	u64 limit = BLK_BOUNCE_HIGH;
+	unsigned block_size = 512;
 
 	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
 		limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
@@ -368,7 +369,13 @@  static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 	blk_queue_max_hw_sectors(mq->queue,
 		min(host->max_blk_count, host->max_req_size / 512));
 	blk_queue_max_segments(mq->queue, host->max_segs);
-	blk_queue_max_segment_size(mq->queue, host->max_seg_size);
+
+	if (mmc_card_mmc(card))
+		block_size = card->ext_csd.data_sector_size;
+
+	blk_queue_logical_block_size(mq->queue, block_size);
+	blk_queue_max_segment_size(mq->queue,
+			round_down(host->max_seg_size, block_size));
 
 	INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
 	INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);