Skip to content

Commit

Permalink
Merge tag 'for-linus-20190112' of git://git.kernel.dk/linux-block
Browse files Browse the repository at this point in the history
Pull block fixes from Jens Axboe:

 - NVMe pull request from Christoph, with little fixes all over the map

 - Loop caching fix for offset/bs change (Jaegeuk Kim)

 - Block documentation tweaks (Jeff, Jon, Weiping, John)

 - null_blk zoned tweak (John)

 - ahch mvebu suspend/resume support. Should have gone into the merge
   window, but there was some confusion on which tree had it. (Miquel)

* tag 'for-linus-20190112' of git://git.kernel.dk/linux-block: (22 commits)
  ata: ahci: mvebu: request PHY suspend/resume for Armada 3700
  ata: ahci: mvebu: add Armada 3700 initialization needed for S2RAM
  ata: ahci: mvebu: do Armada 38x configuration only on relevant SoCs
  ata: ahci: mvebu: remove stale comment
  ata: libahci_platform: comply to PHY framework
  loop: drop caches if offset or block_size are changed
  block: fix kerneldoc comment for blk_attempt_plug_merge()
  nvme: don't initlialize ctrl->cntlid twice
  nvme: introduce NVME_QUIRK_IGNORE_DEV_SUBNQN
  nvme: pad fake subsys NQN vid and ssvid with zeros
  nvme-multipath: zero out ANA log buffer
  nvme-fabrics: unset write/poll queues for discovery controllers
  nvme-tcp: don't ask if controller is fabrics
  nvme-tcp: remove dead code
  nvme-pci: fix out of bounds access in nvme_cqe_pending
  nvme-pci: rerun irq setup on IO queue init errors
  nvme-pci: use the same attributes when freeing host_mem_desc_bufs.
  nvme-pci: fix the wrong setting of nr_maps
  block: doc: add slice_idle_us to bfq documentation
  block: clarify documentation for blk_{start|finish}_plug
  ...
  • Loading branch information
torvalds committed Jan 12, 2019
2 parents 66c56cf + bde0b5c commit b8c3b89
Show file tree
Hide file tree
Showing 16 changed files with 229 additions and 66 deletions.
9 changes: 9 additions & 0 deletions Documentation/ABI/testing/sysfs-block
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,12 @@ Description:
size in 512B sectors of the zones of the device, with
the eventual exception of the last zone of the device
which may be smaller.

What: /sys/block/<disk>/queue/io_timeout
Date: November 2018
Contact: Weiping Zhang <[email protected]>
Description:
io_timeout is the request timeout in milliseconds. If a request
does not complete in this time then the block driver timeout
handler is invoked. That timeout handler can decide to retry
the request, to fail it or to start a device recovery strategy.
7 changes: 7 additions & 0 deletions Documentation/block/bfq-iosched.txt
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,13 @@ video playing/streaming, a very low drop rate may be more important
than maximum throughput. In these cases, consider setting the
strict_guarantees parameter.

slice_idle_us
-------------

Controls the same tuning parameter as slice_idle, but in microseconds.
Either tunable can be used to set idling behavior. Afterwards, the
other tunable will reflect the newly set value in sysfs.

strict_guarantees
-----------------

Expand Down
3 changes: 2 additions & 1 deletion Documentation/block/null_blk.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ shared_tags=[0/1]: Default: 0

zoned=[0/1]: Default: 0
0: Block device is exposed as a random-access block device.
1: Block device is exposed as a host-managed zoned block device.
1: Block device is exposed as a host-managed zoned block device. Requires
CONFIG_BLK_DEV_ZONED.

zone_size=[MB]: Default: 256
Per zone size when exposed as a zoned block device. Must be a power of two.
7 changes: 7 additions & 0 deletions Documentation/block/queue-sysfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ If set to a value larger than 0, the kernel will put the process issuing
IO to sleep for this amount of microseconds before entering classic
polling.

io_timeout (RW)
---------------
io_timeout is the request timeout in milliseconds. If a request does not
complete in this time then the block driver timeout handler is invoked.
That timeout handler can decide to retry the request, to fail it or to start
a device recovery strategy.

iostats (RW)
-------------
This file is used to control (on/off) the iostats accounting of the
Expand Down
20 changes: 19 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ bool bio_attempt_discard_merge(struct request_queue *q, struct request *req,
* blk_attempt_plug_merge - try to merge with %current's plugged list
* @q: request_queue new bio is being queued at
* @bio: new bio being queued
* @request_count: out parameter for number of traversed plugged requests
* @same_queue_rq: pointer to &struct request that gets filled in when
* another request associated with @q is found on the plug list
* (optional, may be %NULL)
Expand Down Expand Up @@ -1683,6 +1682,15 @@ EXPORT_SYMBOL(kblockd_mod_delayed_work_on);
* @plug: The &struct blk_plug that needs to be initialized
*
* Description:
* blk_start_plug() indicates to the block layer an intent by the caller
* to submit multiple I/O requests in a batch. The block layer may use
* this hint to defer submitting I/Os from the caller until blk_finish_plug()
* is called. However, the block layer may choose to submit requests
* before a call to blk_finish_plug() if the number of queued I/Os
* exceeds %BLK_MAX_REQUEST_COUNT, or if the size of the I/O is larger than
* %BLK_PLUG_FLUSH_SIZE. The queued I/Os may also be submitted early if
* the task schedules (see below).
*
* Tracking blk_plug inside the task_struct will help with auto-flushing the
* pending I/O should the task end up blocking between blk_start_plug() and
* blk_finish_plug(). This is important from a performance perspective, but
Expand Down Expand Up @@ -1765,6 +1773,16 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
blk_mq_flush_plug_list(plug, from_schedule);
}

/**
* blk_finish_plug - mark the end of a batch of submitted I/O
* @plug: The &struct blk_plug passed to blk_start_plug()
*
* Description:
* Indicate that a batch of I/O submissions is complete. This function
* must be paired with an initial call to blk_start_plug(). The intent
* is to allow the block layer to optimize I/O submission. See the
* documentation for blk_start_plug() for more information.
*/
void blk_finish_plug(struct blk_plug *plug)
{
if (plug != current->plug)
Expand Down
2 changes: 2 additions & 0 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ enum {
AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use
SATA_MOBILE_LPM_POLICY
as default lpm_policy */
AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during
suspend/resume */

/* ap->flags bits */

Expand Down
87 changes: 64 additions & 23 deletions drivers/ata/ahci_mvebu.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
#define AHCI_WINDOW_BASE(win) (0x64 + ((win) << 4))
#define AHCI_WINDOW_SIZE(win) (0x68 + ((win) << 4))

struct ahci_mvebu_plat_data {
int (*plat_config)(struct ahci_host_priv *hpriv);
unsigned int flags;
};

static void ahci_mvebu_mbus_config(struct ahci_host_priv *hpriv,
const struct mbus_dram_target_info *dram)
{
Expand Down Expand Up @@ -62,6 +67,35 @@ static void ahci_mvebu_regret_option(struct ahci_host_priv *hpriv)
writel(0x80, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA);
}

static int ahci_mvebu_armada_380_config(struct ahci_host_priv *hpriv)
{
const struct mbus_dram_target_info *dram;
int rc = 0;

dram = mv_mbus_dram_info();
if (dram)
ahci_mvebu_mbus_config(hpriv, dram);
else
rc = -ENODEV;

ahci_mvebu_regret_option(hpriv);

return rc;
}

static int ahci_mvebu_armada_3700_config(struct ahci_host_priv *hpriv)
{
u32 reg;

writel(0, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_ADDR);

reg = readl(hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA);
reg |= BIT(6);
writel(reg, hpriv->mmio + AHCI_VENDOR_SPECIFIC_0_DATA);

return 0;
}

/**
* ahci_mvebu_stop_engine
*
Expand Down Expand Up @@ -126,13 +160,9 @@ static int ahci_mvebu_resume(struct platform_device *pdev)
{
struct ata_host *host = platform_get_drvdata(pdev);
struct ahci_host_priv *hpriv = host->private_data;
const struct mbus_dram_target_info *dram;
const struct ahci_mvebu_plat_data *pdata = hpriv->plat_data;

dram = mv_mbus_dram_info();
if (dram)
ahci_mvebu_mbus_config(hpriv, dram);

ahci_mvebu_regret_option(hpriv);
pdata->plat_config(hpriv);

return ahci_platform_resume_host(&pdev->dev);
}
Expand All @@ -154,29 +184,30 @@ static struct scsi_host_template ahci_platform_sht = {

static int ahci_mvebu_probe(struct platform_device *pdev)
{
const struct ahci_mvebu_plat_data *pdata;
struct ahci_host_priv *hpriv;
const struct mbus_dram_target_info *dram;
int rc;

pdata = of_device_get_match_data(&pdev->dev);
if (!pdata)
return -EINVAL;

hpriv = ahci_platform_get_resources(pdev, 0);
if (IS_ERR(hpriv))
return PTR_ERR(hpriv);

hpriv->flags |= pdata->flags;
hpriv->plat_data = (void *)pdata;

rc = ahci_platform_enable_resources(hpriv);
if (rc)
return rc;

hpriv->stop_engine = ahci_mvebu_stop_engine;

if (of_device_is_compatible(pdev->dev.of_node,
"marvell,armada-380-ahci")) {
dram = mv_mbus_dram_info();
if (!dram)
return -ENODEV;

ahci_mvebu_mbus_config(hpriv, dram);
ahci_mvebu_regret_option(hpriv);
}
rc = pdata->plat_config(hpriv);
if (rc)
goto disable_resources;

rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info,
&ahci_platform_sht);
Expand All @@ -190,18 +221,28 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
return rc;
}

static const struct ahci_mvebu_plat_data ahci_mvebu_armada_380_plat_data = {
.plat_config = ahci_mvebu_armada_380_config,
};

static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = {
.plat_config = ahci_mvebu_armada_3700_config,
.flags = AHCI_HFLAG_SUSPEND_PHYS,
};

static const struct of_device_id ahci_mvebu_of_match[] = {
{ .compatible = "marvell,armada-380-ahci", },
{ .compatible = "marvell,armada-3700-ahci", },
{
.compatible = "marvell,armada-380-ahci",
.data = &ahci_mvebu_armada_380_plat_data,
},
{
.compatible = "marvell,armada-3700-ahci",
.data = &ahci_mvebu_armada_3700_plat_data,
},
{ },
};
MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match);

/*
* We currently don't provide power management related operations,
* since there is no suspend/resume support at the platform level for
* Armada 38x for the moment.
*/
static struct platform_driver ahci_mvebu_driver = {
.probe = ahci_mvebu_probe,
.remove = ata_platform_remove_one,
Expand Down
13 changes: 13 additions & 0 deletions drivers/ata/libahci_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ static int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
if (rc)
goto disable_phys;

rc = phy_set_mode(hpriv->phys[i], PHY_MODE_SATA);
if (rc) {
phy_exit(hpriv->phys[i]);
goto disable_phys;
}

rc = phy_power_on(hpriv->phys[i]);
if (rc) {
phy_exit(hpriv->phys[i]);
Expand Down Expand Up @@ -738,6 +744,9 @@ int ahci_platform_suspend_host(struct device *dev)
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */

if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
ahci_platform_disable_phys(hpriv);

return ata_host_suspend(host, PMSG_SUSPEND);
}
EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
Expand All @@ -756,6 +765,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
int ahci_platform_resume_host(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;
int rc;

if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
Expand All @@ -766,6 +776,9 @@ int ahci_platform_resume_host(struct device *dev)
ahci_init_controller(host);
}

if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS)
ahci_platform_enable_phys(hpriv);

ata_host_resume(host);

return 0;
Expand Down
35 changes: 33 additions & 2 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
goto out_unlock;
}

if (lo->lo_offset != info->lo_offset ||
lo->lo_sizelimit != info->lo_sizelimit) {
sync_blockdev(lo->lo_device);
kill_bdev(lo->lo_device);
}

/* I/O need to be drained during transfer transition */
blk_mq_freeze_queue(lo->lo_queue);

Expand Down Expand Up @@ -1218,6 +1224,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)

if (lo->lo_offset != info->lo_offset ||
lo->lo_sizelimit != info->lo_sizelimit) {
/* kill_bdev should have truncated all the pages */
if (lo->lo_device->bd_inode->i_mapping->nrpages) {
err = -EAGAIN;
pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
__func__, lo->lo_number, lo->lo_file_name,
lo->lo_device->bd_inode->i_mapping->nrpages);
goto out_unfreeze;
}
if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
err = -EFBIG;
goto out_unfreeze;
Expand Down Expand Up @@ -1443,22 +1457,39 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg)

static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
{
int err = 0;

if (lo->lo_state != Lo_bound)
return -ENXIO;

if (arg < 512 || arg > PAGE_SIZE || !is_power_of_2(arg))
return -EINVAL;

if (lo->lo_queue->limits.logical_block_size != arg) {
sync_blockdev(lo->lo_device);
kill_bdev(lo->lo_device);
}

blk_mq_freeze_queue(lo->lo_queue);

/* kill_bdev should have truncated all the pages */
if (lo->lo_queue->limits.logical_block_size != arg &&
lo->lo_device->bd_inode->i_mapping->nrpages) {
err = -EAGAIN;
pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
__func__, lo->lo_number, lo->lo_file_name,
lo->lo_device->bd_inode->i_mapping->nrpages);
goto out_unfreeze;
}

blk_queue_logical_block_size(lo->lo_queue, arg);
blk_queue_physical_block_size(lo->lo_queue, arg);
blk_queue_io_min(lo->lo_queue, arg);
loop_update_dio(lo);

out_unfreeze:
blk_mq_unfreeze_queue(lo->lo_queue);

return 0;
return err;
}

static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd,
Expand Down
1 change: 1 addition & 0 deletions drivers/block/null_blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ void null_zone_reset(struct nullb_cmd *cmd, sector_t sector);
#else
static inline int null_zone_init(struct nullb_device *dev)
{
pr_err("null_blk: CONFIG_BLK_DEV_ZONED not enabled\n");
return -EINVAL;
}
static inline void null_zone_exit(struct nullb_device *dev) {}
Expand Down
19 changes: 10 additions & 9 deletions drivers/nvme/host/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2173,18 +2173,20 @@ static void nvme_init_subnqn(struct nvme_subsystem *subsys, struct nvme_ctrl *ct
size_t nqnlen;
int off;

nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
strlcpy(subsys->subnqn, id->subnqn, NVMF_NQN_SIZE);
return;
}
if(!(ctrl->quirks & NVME_QUIRK_IGNORE_DEV_SUBNQN)) {
nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
strlcpy(subsys->subnqn, id->subnqn, NVMF_NQN_SIZE);
return;
}

if (ctrl->vs >= NVME_VS(1, 2, 1))
dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");
if (ctrl->vs >= NVME_VS(1, 2, 1))
dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");
}

/* Generate a "fake" NQN per Figure 254 in NVMe 1.3 + ECN 001 */
off = snprintf(subsys->subnqn, NVMF_NQN_SIZE,
"nqn.2014.08.org.nvmexpress:%4x%4x",
"nqn.2014.08.org.nvmexpress:%04x%04x",
le16_to_cpu(id->vid), le16_to_cpu(id->ssvid));
memcpy(subsys->subnqn + off, id->sn, sizeof(id->sn));
off += sizeof(id->sn);
Expand Down Expand Up @@ -2500,7 +2502,6 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
ctrl->oaes = le32_to_cpu(id->oaes);
atomic_set(&ctrl->abort_limit, id->acl + 1);
ctrl->vwc = id->vwc;
ctrl->cntlid = le16_to_cpup(&id->cntlid);
if (id->mdts)
max_hw_sectors = 1 << (id->mdts + page_shift - 9);
else
Expand Down
Loading

0 comments on commit b8c3b89

Please sign in to comment.