Skip to content

Commit

Permalink
mmc: bcm2835-sdhost: use Host Software Queueing mechanism
Browse files Browse the repository at this point in the history
See commit 511ce37 ("mmc: Add MMC host software queue support")

Introduced in 5.8, this feature lets the block layer issue up to 2
pending requests to the MMC layer which in certain cases can improve
throughput, but in the case of this driver can significantly reduce
context switching when performing random reads.

On bcm2837 with a performant class A1 card, context switches under FIO
random 4k reads go from ~8800 per second to ~5800, with a reduction in
hardIRQs per second from ~5800 to ~4000. There is no appreciable
difference in throughput.

For bcm2835, and for workloads other than random read, HSQ is a wash in
terms of throughput and CPU load.

So, use it by default.

Signed-off-by: Jonathan Bell <[email protected]>
  • Loading branch information
P33M authored and popcornmix committed Jan 22, 2024
1 parent 82db5ba commit 60781d6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/mmc/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ config MMC_BCM2835_PIO_DMA_BARRIER
config MMC_BCM2835_SDHOST
tristate "Support for the SDHost controller on BCM2708/9"
depends on ARCH_BCM2835
select MMC_HSQ
help
This selects the SDHost controller on BCM2835/6.

Expand Down
27 changes: 22 additions & 5 deletions drivers/mmc/host/bcm2835-sdhost.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@

/* For mmc_card_blockaddr */
#include "../core/card.h"
#include "mmc_hsq.h"

#define DRIVER_NAME "sdhost-bcm2835"

Expand Down Expand Up @@ -1891,13 +1892,16 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param)
mmc_hostname(host->mmc));
}

mmc_request_done(host->mmc, mrq);
if (!mmc_hsq_finalize_request(host->mmc, mrq))
mmc_request_done(host->mmc, mrq);
log_event("TSK>", mrq, 0);
}

int bcm2835_sdhost_add_host(struct bcm2835_host *host)
int bcm2835_sdhost_add_host(struct platform_device *pdev)
{
struct bcm2835_host *host = platform_get_drvdata(pdev);
struct mmc_host *mmc;
struct mmc_hsq *hsq;
struct dma_slave_config cfg;
char pio_limit_string[20];
int ret;
Expand Down Expand Up @@ -1992,6 +1996,16 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host)
goto untasklet;
}

hsq = devm_kzalloc(&pdev->dev, sizeof(*hsq), GFP_KERNEL);
if (!hsq) {
ret = -ENOMEM;
goto free_irq;
}

ret = mmc_hsq_init(hsq, host->mmc);
if (ret)
goto free_irq;

mmc_add_host(mmc);

pio_limit_string[0] = '\0';
Expand All @@ -2004,6 +2018,9 @@ int bcm2835_sdhost_add_host(struct bcm2835_host *host)

return 0;

free_irq:
free_irq(host->irq, host);

untasklet:
tasklet_kill(&host->finish_tasklet);

Expand Down Expand Up @@ -2134,12 +2151,12 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)

host->firmware_sets_cdiv = (msg[1] != ~0);

ret = bcm2835_sdhost_add_host(host);
platform_set_drvdata(pdev, host);

ret = bcm2835_sdhost_add_host(pdev);
if (ret)
goto err;

platform_set_drvdata(pdev, host);

pr_debug("bcm2835_sdhost_probe -> OK\n");

return 0;
Expand Down

0 comments on commit 60781d6

Please sign in to comment.