Commit ab2a7a35 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'block-5.15-2021-10-01' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "A few block fixes for this release:

   - Revert a BFQ commit that causes breakage for people. Unfortunately
     it was auto-selected for stable as well, so now 5.14.7 suffers from
     it too. Hopefully stable will pick up this revert quickly too, so
     we can remove the issue on that end as well.

   - Add a quirk for Apple NVMe controllers, which due to their
     non-compliance broke due to the introduction of command sequences
     (Keith)

   - Use shifts in nbd, fixing a __divdi3 issue (Nick)"

* tag 'block-5.15-2021-10-01' of git://git.kernel.dk/linux-block:
  nbd: use shifts rather than multiplies
  Revert "block, bfq: honor already-setup queue merges"
  nvme: add command id quirk for apple controllers
parents 65893b49 41e76c6a
...@@ -2662,15 +2662,6 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ...@@ -2662,15 +2662,6 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
* are likely to increase the throughput. * are likely to increase the throughput.
*/ */
bfqq->new_bfqq = new_bfqq; bfqq->new_bfqq = new_bfqq;
/*
* The above assignment schedules the following redirections:
* each time some I/O for bfqq arrives, the process that
* generated that I/O is disassociated from bfqq and
* associated with new_bfqq. Here we increases new_bfqq->ref
* in advance, adding the number of processes that are
* expected to be associated with new_bfqq as they happen to
* issue I/O.
*/
new_bfqq->ref += process_refs; new_bfqq->ref += process_refs;
return new_bfqq; return new_bfqq;
} }
...@@ -2733,10 +2724,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ...@@ -2733,10 +2724,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
{ {
struct bfq_queue *in_service_bfqq, *new_bfqq; struct bfq_queue *in_service_bfqq, *new_bfqq;
/* if a merge has already been setup, then proceed with that first */
if (bfqq->new_bfqq)
return bfqq->new_bfqq;
/* /*
* Check delayed stable merge for rotational or non-queueing * Check delayed stable merge for rotational or non-queueing
* devs. For this branch to be executed, bfqq must not be * devs. For this branch to be executed, bfqq must not be
...@@ -2838,6 +2825,9 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ...@@ -2838,6 +2825,9 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
if (bfq_too_late_for_merging(bfqq)) if (bfq_too_late_for_merging(bfqq))
return NULL; return NULL;
if (bfqq->new_bfqq)
return bfqq->new_bfqq;
if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq)) if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq))
return NULL; return NULL;
......
...@@ -97,13 +97,18 @@ struct nbd_config { ...@@ -97,13 +97,18 @@ struct nbd_config {
atomic_t recv_threads; atomic_t recv_threads;
wait_queue_head_t recv_wq; wait_queue_head_t recv_wq;
loff_t blksize; unsigned int blksize_bits;
loff_t bytesize; loff_t bytesize;
#if IS_ENABLED(CONFIG_DEBUG_FS) #if IS_ENABLED(CONFIG_DEBUG_FS)
struct dentry *dbg_dir; struct dentry *dbg_dir;
#endif #endif
}; };
static inline unsigned int nbd_blksize(struct nbd_config *config)
{
return 1u << config->blksize_bits;
}
struct nbd_device { struct nbd_device {
struct blk_mq_tag_set tag_set; struct blk_mq_tag_set tag_set;
...@@ -146,7 +151,7 @@ static struct dentry *nbd_dbg_dir; ...@@ -146,7 +151,7 @@ static struct dentry *nbd_dbg_dir;
#define NBD_MAGIC 0x68797548 #define NBD_MAGIC 0x68797548
#define NBD_DEF_BLKSIZE 1024 #define NBD_DEF_BLKSIZE_BITS 10
static unsigned int nbds_max = 16; static unsigned int nbds_max = 16;
static int max_part = 16; static int max_part = 16;
...@@ -317,12 +322,12 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, ...@@ -317,12 +322,12 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
loff_t blksize) loff_t blksize)
{ {
if (!blksize) if (!blksize)
blksize = NBD_DEF_BLKSIZE; blksize = 1u << NBD_DEF_BLKSIZE_BITS;
if (blksize < 512 || blksize > PAGE_SIZE || !is_power_of_2(blksize)) if (blksize < 512 || blksize > PAGE_SIZE || !is_power_of_2(blksize))
return -EINVAL; return -EINVAL;
nbd->config->bytesize = bytesize; nbd->config->bytesize = bytesize;
nbd->config->blksize = blksize; nbd->config->blksize_bits = __ffs(blksize);
if (!nbd->task_recv) if (!nbd->task_recv)
return 0; return 0;
...@@ -1337,7 +1342,7 @@ static int nbd_start_device(struct nbd_device *nbd) ...@@ -1337,7 +1342,7 @@ static int nbd_start_device(struct nbd_device *nbd)
args->index = i; args->index = i;
queue_work(nbd->recv_workq, &args->work); queue_work(nbd->recv_workq, &args->work);
} }
return nbd_set_size(nbd, config->bytesize, config->blksize); return nbd_set_size(nbd, config->bytesize, nbd_blksize(config));
} }
static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *bdev) static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *bdev)
...@@ -1406,11 +1411,11 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, ...@@ -1406,11 +1411,11 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
case NBD_SET_BLKSIZE: case NBD_SET_BLKSIZE:
return nbd_set_size(nbd, config->bytesize, arg); return nbd_set_size(nbd, config->bytesize, arg);
case NBD_SET_SIZE: case NBD_SET_SIZE:
return nbd_set_size(nbd, arg, config->blksize); return nbd_set_size(nbd, arg, nbd_blksize(config));
case NBD_SET_SIZE_BLOCKS: case NBD_SET_SIZE_BLOCKS:
if (check_mul_overflow((loff_t)arg, config->blksize, &bytesize)) if (check_shl_overflow(arg, config->blksize_bits, &bytesize))
return -EINVAL; return -EINVAL;
return nbd_set_size(nbd, bytesize, config->blksize); return nbd_set_size(nbd, bytesize, nbd_blksize(config));
case NBD_SET_TIMEOUT: case NBD_SET_TIMEOUT:
nbd_set_cmd_timeout(nbd, arg); nbd_set_cmd_timeout(nbd, arg);
return 0; return 0;
...@@ -1476,7 +1481,7 @@ static struct nbd_config *nbd_alloc_config(void) ...@@ -1476,7 +1481,7 @@ static struct nbd_config *nbd_alloc_config(void)
atomic_set(&config->recv_threads, 0); atomic_set(&config->recv_threads, 0);
init_waitqueue_head(&config->recv_wq); init_waitqueue_head(&config->recv_wq);
init_waitqueue_head(&config->conn_wait); init_waitqueue_head(&config->conn_wait);
config->blksize = NBD_DEF_BLKSIZE; config->blksize_bits = NBD_DEF_BLKSIZE_BITS;
atomic_set(&config->live_connections, 0); atomic_set(&config->live_connections, 0);
try_module_get(THIS_MODULE); try_module_get(THIS_MODULE);
return config; return config;
...@@ -1604,7 +1609,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd) ...@@ -1604,7 +1609,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd)
debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_fops); debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_fops);
debugfs_create_u64("size_bytes", 0444, dir, &config->bytesize); debugfs_create_u64("size_bytes", 0444, dir, &config->bytesize);
debugfs_create_u32("timeout", 0444, dir, &nbd->tag_set.timeout); debugfs_create_u32("timeout", 0444, dir, &nbd->tag_set.timeout);
debugfs_create_u64("blocksize", 0444, dir, &config->blksize); debugfs_create_u32("blocksize_bits", 0444, dir, &config->blksize_bits);
debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_fops); debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_fops);
return 0; return 0;
...@@ -1826,7 +1831,7 @@ nbd_device_policy[NBD_DEVICE_ATTR_MAX + 1] = { ...@@ -1826,7 +1831,7 @@ nbd_device_policy[NBD_DEVICE_ATTR_MAX + 1] = {
static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd) static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
{ {
struct nbd_config *config = nbd->config; struct nbd_config *config = nbd->config;
u64 bsize = config->blksize; u64 bsize = nbd_blksize(config);
u64 bytes = config->bytesize; u64 bytes = config->bytesize;
if (info->attrs[NBD_ATTR_SIZE_BYTES]) if (info->attrs[NBD_ATTR_SIZE_BYTES])
...@@ -1835,7 +1840,7 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd) ...@@ -1835,7 +1840,7 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES])
bsize = nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]); bsize = nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]);
if (bytes != config->bytesize || bsize != config->blksize) if (bytes != config->bytesize || bsize != nbd_blksize(config))
return nbd_set_size(nbd, bytes, bsize); return nbd_set_size(nbd, bytes, bsize);
return 0; return 0;
} }
......
...@@ -978,6 +978,7 @@ EXPORT_SYMBOL_GPL(nvme_cleanup_cmd); ...@@ -978,6 +978,7 @@ EXPORT_SYMBOL_GPL(nvme_cleanup_cmd);
blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req) blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
{ {
struct nvme_command *cmd = nvme_req(req)->cmd; struct nvme_command *cmd = nvme_req(req)->cmd;
struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
blk_status_t ret = BLK_STS_OK; blk_status_t ret = BLK_STS_OK;
if (!(req->rq_flags & RQF_DONTPREP)) { if (!(req->rq_flags & RQF_DONTPREP)) {
...@@ -1026,7 +1027,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req) ...@@ -1026,7 +1027,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
return BLK_STS_IOERR; return BLK_STS_IOERR;
} }
nvme_req(req)->genctr++; if (!(ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN))
nvme_req(req)->genctr++;
cmd->common.command_id = nvme_cid(req); cmd->common.command_id = nvme_cid(req);
trace_nvme_setup_cmd(req, cmd); trace_nvme_setup_cmd(req, cmd);
return ret; return ret;
......
...@@ -138,6 +138,12 @@ enum nvme_quirks { ...@@ -138,6 +138,12 @@ enum nvme_quirks {
* 48 bits. * 48 bits.
*/ */
NVME_QUIRK_DMA_ADDRESS_BITS_48 = (1 << 16), NVME_QUIRK_DMA_ADDRESS_BITS_48 = (1 << 16),
/*
* The controller requires the command_id value be be limited, so skip
* encoding the generation sequence number.
*/
NVME_QUIRK_SKIP_CID_GEN = (1 << 17),
}; };
/* /*
......
...@@ -3369,7 +3369,8 @@ static const struct pci_device_id nvme_id_table[] = { ...@@ -3369,7 +3369,8 @@ static const struct pci_device_id nvme_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005),
.driver_data = NVME_QUIRK_SINGLE_VECTOR | .driver_data = NVME_QUIRK_SINGLE_VECTOR |
NVME_QUIRK_128_BYTES_SQES | NVME_QUIRK_128_BYTES_SQES |
NVME_QUIRK_SHARED_TAGS }, NVME_QUIRK_SHARED_TAGS |
NVME_QUIRK_SKIP_CID_GEN },
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
{ 0, } { 0, }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment