forked from Minki/linux
block-6.1-2022-10-20
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmNSA3oQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpoTfEACwFAyQsAGMVVsTmU/XggFsNRczTKH+J7dO 4tBhOhfrVEWyDbB++3kUepN0GenSiu3dvcAzWQbX0lPiLjkqFWvpj2GIrqHwXJCt Li8SPoPsQARBvJYUERmdlQDUeEKCK/IwOREQSH4LZaNVvU2l0MSAqjihUjmcXHBE OeCWwYLJ27Bo0j5py9xSo7Z1C84YtXHDKAbx1nVhX6ByyCvpSGLLunrwT7oeEjT7 FAbVvL4p5xwZe5e3XiiC5J7g85BkIZGwhqViYrVyHPWrUVWycSvXQdqXGGHiSqlj g3jcT6nLNBscAPuWnnP4jobaFVjm1Lr3eXtVX1k66kRwrxVcB+tZGszvjh4cuneO N23OjrRjtGIXenSyOslCxMAIxgMjsxeuuoQb66Js9g8bA9zJeKPcpKWbXplkaXoH VsT23W24Xp72MkBAz9nP9sHXbQEAkfNGK+6qZLBpkb8bJsymc+4Vn6lpV6ybl8WF LJWouLss2/I+G/D/WLvVcygvefQxVSLDFjWcU8BcJjDkdXgQWUjZfcZEsRE2v0cr tLZOh1WhHgVwTBCZxEus+QoAE1tXn2C+xhMu0uqRQ7zlngy5AycM6eSJtQ5Lwm2H 91MSYoUvGkOx5Hqp265AnZEBayOg+xnsp7qMZghoQqLUc5yU4zyUbvxPi0vNuduJ mbys/sxVsg== =YfkM -----END PGP SIGNATURE----- Merge tag 'block-6.1-2022-10-20' of git://git.kernel.dk/linux Pull block fixes from Jens Axboe: - NVMe pull request via Christoph: - fix nvme-hwmon for DMA non-cohehrent architectures (Serge Semin) - add a nvme-hwmong maintainer (Christoph Hellwig) - fix error pointer dereference in error handling (Dan Carpenter) - fix invalid memory reference in nvmet_subsys_attr_qid_max_show (Daniel Wagner) - don't limit the DMA segment size in nvme-apple (Russell King) - fix workqueue MEM_RECLAIM flushing dependency (Sagi Grimberg) - disable write zeroes on various Kingston SSDs (Xander Li) - fix a memory leak with block device tracing (Ye) - flexible-array fix for ublk (Yushan) - document the ublk recovery feature from this merge window (ZiyangZhang) - remove dead bfq variable in struct (Yuwei) - error handling rq clearing fix (Yu) - add an IRQ safety check for the cached bio freeing (Pavel) - drbd bio cloning fix (Christoph) * tag 'block-6.1-2022-10-20' of git://git.kernel.dk/linux: blktrace: remove unnessary stop block trace in 'blk_trace_shutdown' blktrace: fix possible memleak in '__blk_trace_remove' blktrace: introduce 'blk_trace_{start,stop}' helper bio: safeguard REQ_ALLOC_CACHE bio put block, bfq: remove unused variable for bfq_queue drbd: only clone bio if we have a backing device ublk_drv: use flexible-array member instead of zero-length array nvmet: fix invalid memory reference in nvmet_subsys_attr_qid_max_show nvmet: fix workqueue MEM_RECLAIM flushing dependency nvme-hwmon: kmalloc the NVME SMART log buffer nvme-hwmon: consistently ignore errors from nvme_hwmon_init nvme: add Guenther as nvme-hwmon maintainer nvme-apple: don't limit DMA segement size nvme-pci: disable write zeroes on various Kingston SSD nvme: fix error pointer dereference in error handling Documentation: document ublk user recovery feature blk-mq: fix null pointer dereference in blk_mq_clear_rq_mapping()
This commit is contained in:
commit
d4b7332eef
@ -144,6 +144,42 @@ managing and controlling ublk devices with help of several control commands:
|
|||||||
For retrieving device info via ``ublksrv_ctrl_dev_info``. It is the server's
|
For retrieving device info via ``ublksrv_ctrl_dev_info``. It is the server's
|
||||||
responsibility to save IO target specific info in userspace.
|
responsibility to save IO target specific info in userspace.
|
||||||
|
|
||||||
|
- ``UBLK_CMD_START_USER_RECOVERY``
|
||||||
|
|
||||||
|
This command is valid if ``UBLK_F_USER_RECOVERY`` feature is enabled. This
|
||||||
|
command is accepted after the old process has exited, ublk device is quiesced
|
||||||
|
and ``/dev/ublkc*`` is released. User should send this command before he starts
|
||||||
|
a new process which re-opens ``/dev/ublkc*``. When this command returns, the
|
||||||
|
ublk device is ready for the new process.
|
||||||
|
|
||||||
|
- ``UBLK_CMD_END_USER_RECOVERY``
|
||||||
|
|
||||||
|
This command is valid if ``UBLK_F_USER_RECOVERY`` feature is enabled. This
|
||||||
|
command is accepted after ublk device is quiesced and a new process has
|
||||||
|
opened ``/dev/ublkc*`` and get all ublk queues be ready. When this command
|
||||||
|
returns, ublk device is unquiesced and new I/O requests are passed to the
|
||||||
|
new process.
|
||||||
|
|
||||||
|
- user recovery feature description
|
||||||
|
|
||||||
|
Two new features are added for user recovery: ``UBLK_F_USER_RECOVERY`` and
|
||||||
|
``UBLK_F_USER_RECOVERY_REISSUE``.
|
||||||
|
|
||||||
|
With ``UBLK_F_USER_RECOVERY`` set, after one ubq_daemon(ublk server's io
|
||||||
|
handler) is dying, ublk does not delete ``/dev/ublkb*`` during the whole
|
||||||
|
recovery stage and ublk device ID is kept. It is ublk server's
|
||||||
|
responsibility to recover the device context by its own knowledge.
|
||||||
|
Requests which have not been issued to userspace are requeued. Requests
|
||||||
|
which have been issued to userspace are aborted.
|
||||||
|
|
||||||
|
With ``UBLK_F_USER_RECOVERY_REISSUE`` set, after one ubq_daemon(ublk
|
||||||
|
server's io handler) is dying, contrary to ``UBLK_F_USER_RECOVERY``,
|
||||||
|
requests which have been issued to userspace are requeued and will be
|
||||||
|
re-issued to the new process after handling ``UBLK_CMD_END_USER_RECOVERY``.
|
||||||
|
``UBLK_F_USER_RECOVERY_REISSUE`` is designed for backends who tolerate
|
||||||
|
double-write since the driver may issue the same I/O request twice. It
|
||||||
|
might be useful to a read-only FS or a VM backend.
|
||||||
|
|
||||||
Data plane
|
Data plane
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -14713,6 +14713,12 @@ F: drivers/nvme/target/auth.c
|
|||||||
F: drivers/nvme/target/fabrics-cmd-auth.c
|
F: drivers/nvme/target/fabrics-cmd-auth.c
|
||||||
F: include/linux/nvme-auth.h
|
F: include/linux/nvme-auth.h
|
||||||
|
|
||||||
|
NVM EXPRESS HARDWARE MONITORING SUPPORT
|
||||||
|
M: Guenter Roeck <linux@roeck-us.net>
|
||||||
|
L: linux-nvme@lists.infradead.org
|
||||||
|
S: Supported
|
||||||
|
F: drivers/nvme/host/hwmon.c
|
||||||
|
|
||||||
NVM EXPRESS FC TRANSPORT DRIVERS
|
NVM EXPRESS FC TRANSPORT DRIVERS
|
||||||
M: James Smart <james.smart@broadcom.com>
|
M: James Smart <james.smart@broadcom.com>
|
||||||
L: linux-nvme@lists.infradead.org
|
L: linux-nvme@lists.infradead.org
|
||||||
|
@ -369,12 +369,8 @@ struct bfq_queue {
|
|||||||
unsigned long split_time; /* time of last split */
|
unsigned long split_time; /* time of last split */
|
||||||
|
|
||||||
unsigned long first_IO_time; /* time of first I/O for this queue */
|
unsigned long first_IO_time; /* time of first I/O for this queue */
|
||||||
|
|
||||||
unsigned long creation_time; /* when this queue is created */
|
unsigned long creation_time; /* when this queue is created */
|
||||||
|
|
||||||
/* max service rate measured so far */
|
|
||||||
u32 max_service_rate;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointer to the waker queue for this queue, i.e., to the
|
* Pointer to the waker queue for this queue, i.e., to the
|
||||||
* queue Q such that this queue happens to get new I/O right
|
* queue Q such that this queue happens to get new I/O right
|
||||||
|
@ -741,7 +741,7 @@ void bio_put(struct bio *bio)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bio->bi_opf & REQ_ALLOC_CACHE) {
|
if ((bio->bi_opf & REQ_ALLOC_CACHE) && !WARN_ON_ONCE(in_interrupt())) {
|
||||||
struct bio_alloc_cache *cache;
|
struct bio_alloc_cache *cache;
|
||||||
|
|
||||||
bio_uninit(bio);
|
bio_uninit(bio);
|
||||||
|
@ -3112,8 +3112,11 @@ static void blk_mq_clear_rq_mapping(struct blk_mq_tags *drv_tags,
|
|||||||
struct page *page;
|
struct page *page;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* There is no need to clear a driver tags own mapping */
|
/*
|
||||||
if (drv_tags == tags)
|
* There is no need to clear mapping if driver tags is not initialized
|
||||||
|
* or the mapping belongs to the driver tags.
|
||||||
|
*/
|
||||||
|
if (!drv_tags || drv_tags == tags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_entry(page, &tags->page_list, lru) {
|
list_for_each_entry(page, &tags->page_list, lru) {
|
||||||
|
@ -30,11 +30,6 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset(req, 0, sizeof(*req));
|
memset(req, 0, sizeof(*req));
|
||||||
|
|
||||||
req->private_bio = bio_alloc_clone(device->ldev->backing_bdev, bio_src,
|
|
||||||
GFP_NOIO, &drbd_io_bio_set);
|
|
||||||
req->private_bio->bi_private = req;
|
|
||||||
req->private_bio->bi_end_io = drbd_request_endio;
|
|
||||||
|
|
||||||
req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0)
|
req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0)
|
||||||
| (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0)
|
| (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0)
|
||||||
| (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0);
|
| (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0);
|
||||||
@ -1219,9 +1214,12 @@ drbd_request_prepare(struct drbd_device *device, struct bio *bio)
|
|||||||
/* Update disk stats */
|
/* Update disk stats */
|
||||||
req->start_jif = bio_start_io_acct(req->master_bio);
|
req->start_jif = bio_start_io_acct(req->master_bio);
|
||||||
|
|
||||||
if (!get_ldev(device)) {
|
if (get_ldev(device)) {
|
||||||
bio_put(req->private_bio);
|
req->private_bio = bio_alloc_clone(device->ldev->backing_bdev,
|
||||||
req->private_bio = NULL;
|
bio, GFP_NOIO,
|
||||||
|
&drbd_io_bio_set);
|
||||||
|
req->private_bio->bi_private = req;
|
||||||
|
req->private_bio->bi_end_io = drbd_request_endio;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process discards always from our submitter thread */
|
/* process discards always from our submitter thread */
|
||||||
|
@ -124,7 +124,7 @@ struct ublk_queue {
|
|||||||
bool force_abort;
|
bool force_abort;
|
||||||
unsigned short nr_io_ready; /* how many ios setup */
|
unsigned short nr_io_ready; /* how many ios setup */
|
||||||
struct ublk_device *dev;
|
struct ublk_device *dev;
|
||||||
struct ublk_io ios[0];
|
struct ublk_io ios[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UBLK_DAEMON_MONITOR_PERIOD (5 * HZ)
|
#define UBLK_DAEMON_MONITOR_PERIOD (5 * HZ)
|
||||||
|
@ -1039,6 +1039,8 @@ static void apple_nvme_reset_work(struct work_struct *work)
|
|||||||
dma_max_mapping_size(anv->dev) >> 9);
|
dma_max_mapping_size(anv->dev) >> 9);
|
||||||
anv->ctrl.max_segments = NVME_MAX_SEGS;
|
anv->ctrl.max_segments = NVME_MAX_SEGS;
|
||||||
|
|
||||||
|
dma_set_max_seg_size(anv->dev, 0xffffffff);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable NVMMU and linear submission queues.
|
* Enable NVMMU and linear submission queues.
|
||||||
* While we could keep those disabled and pretend this is slightly
|
* While we could keep those disabled and pretend this is slightly
|
||||||
|
@ -3262,8 +3262,12 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
|
if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
|
||||||
|
/*
|
||||||
|
* Do not return errors unless we are in a controller reset,
|
||||||
|
* the controller works perfectly fine without hwmon.
|
||||||
|
*/
|
||||||
ret = nvme_hwmon_init(ctrl);
|
ret = nvme_hwmon_init(ctrl);
|
||||||
if (ret < 0)
|
if (ret == -EINTR)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4846,7 +4850,7 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_cleanup_admin_q:
|
out_cleanup_admin_q:
|
||||||
blk_mq_destroy_queue(ctrl->fabrics_q);
|
blk_mq_destroy_queue(ctrl->admin_q);
|
||||||
out_free_tagset:
|
out_free_tagset:
|
||||||
blk_mq_free_tag_set(ctrl->admin_tagset);
|
blk_mq_free_tag_set(ctrl->admin_tagset);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
struct nvme_hwmon_data {
|
struct nvme_hwmon_data {
|
||||||
struct nvme_ctrl *ctrl;
|
struct nvme_ctrl *ctrl;
|
||||||
struct nvme_smart_log log;
|
struct nvme_smart_log *log;
|
||||||
struct mutex read_lock;
|
struct mutex read_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,14 +60,14 @@ static int nvme_set_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under,
|
|||||||
static int nvme_hwmon_get_smart_log(struct nvme_hwmon_data *data)
|
static int nvme_hwmon_get_smart_log(struct nvme_hwmon_data *data)
|
||||||
{
|
{
|
||||||
return nvme_get_log(data->ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0,
|
return nvme_get_log(data->ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0,
|
||||||
NVME_CSI_NVM, &data->log, sizeof(data->log), 0);
|
NVME_CSI_NVM, data->log, sizeof(*data->log), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
||||||
u32 attr, int channel, long *val)
|
u32 attr, int channel, long *val)
|
||||||
{
|
{
|
||||||
struct nvme_hwmon_data *data = dev_get_drvdata(dev);
|
struct nvme_hwmon_data *data = dev_get_drvdata(dev);
|
||||||
struct nvme_smart_log *log = &data->log;
|
struct nvme_smart_log *log = data->log;
|
||||||
int temp;
|
int temp;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
|
|||||||
case hwmon_temp_max:
|
case hwmon_temp_max:
|
||||||
case hwmon_temp_min:
|
case hwmon_temp_min:
|
||||||
if ((!channel && data->ctrl->wctemp) ||
|
if ((!channel && data->ctrl->wctemp) ||
|
||||||
(channel && data->log.temp_sensor[channel - 1])) {
|
(channel && data->log->temp_sensor[channel - 1])) {
|
||||||
if (data->ctrl->quirks &
|
if (data->ctrl->quirks &
|
||||||
NVME_QUIRK_NO_TEMP_THRESH_CHANGE)
|
NVME_QUIRK_NO_TEMP_THRESH_CHANGE)
|
||||||
return 0444;
|
return 0444;
|
||||||
@ -176,7 +176,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
|
|||||||
break;
|
break;
|
||||||
case hwmon_temp_input:
|
case hwmon_temp_input:
|
||||||
case hwmon_temp_label:
|
case hwmon_temp_label:
|
||||||
if (!channel || data->log.temp_sensor[channel - 1])
|
if (!channel || data->log->temp_sensor[channel - 1])
|
||||||
return 0444;
|
return 0444;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -230,7 +230,13 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
|
|||||||
|
|
||||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
data->log = kzalloc(sizeof(*data->log), GFP_KERNEL);
|
||||||
|
if (!data->log) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_free_data;
|
||||||
|
}
|
||||||
|
|
||||||
data->ctrl = ctrl;
|
data->ctrl = ctrl;
|
||||||
mutex_init(&data->read_lock);
|
mutex_init(&data->read_lock);
|
||||||
@ -238,8 +244,7 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
|
|||||||
err = nvme_hwmon_get_smart_log(data);
|
err = nvme_hwmon_get_smart_log(data);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_warn(dev, "Failed to read smart log (error %d)\n", err);
|
dev_warn(dev, "Failed to read smart log (error %d)\n", err);
|
||||||
kfree(data);
|
goto err_free_log;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hwmon = hwmon_device_register_with_info(dev, "nvme",
|
hwmon = hwmon_device_register_with_info(dev, "nvme",
|
||||||
@ -247,11 +252,17 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
|
|||||||
NULL);
|
NULL);
|
||||||
if (IS_ERR(hwmon)) {
|
if (IS_ERR(hwmon)) {
|
||||||
dev_warn(dev, "Failed to instantiate hwmon device\n");
|
dev_warn(dev, "Failed to instantiate hwmon device\n");
|
||||||
kfree(data);
|
err = PTR_ERR(hwmon);
|
||||||
return PTR_ERR(hwmon);
|
goto err_free_log;
|
||||||
}
|
}
|
||||||
ctrl->hwmon_device = hwmon;
|
ctrl->hwmon_device = hwmon;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_free_log:
|
||||||
|
kfree(data->log);
|
||||||
|
err_free_data:
|
||||||
|
kfree(data);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
|
void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
|
||||||
@ -262,6 +273,7 @@ void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
|
|||||||
|
|
||||||
hwmon_device_unregister(ctrl->hwmon_device);
|
hwmon_device_unregister(ctrl->hwmon_device);
|
||||||
ctrl->hwmon_device = NULL;
|
ctrl->hwmon_device = NULL;
|
||||||
|
kfree(data->log);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3511,6 +3511,16 @@ static const struct pci_device_id nvme_id_table[] = {
|
|||||||
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
||||||
{ PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */
|
{ PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */
|
||||||
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
|
||||||
|
{ PCI_DEVICE(0x2646, 0x5018), /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */
|
||||||
|
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
|
||||||
|
{ PCI_DEVICE(0x2646, 0x5016), /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */
|
||||||
|
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
|
||||||
|
{ PCI_DEVICE(0x2646, 0x501A), /* KINGSTON OM8PGP4xxxxP OS21005 NVMe SSD */
|
||||||
|
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
|
||||||
|
{ PCI_DEVICE(0x2646, 0x501B), /* KINGSTON OM8PGP4xxxxQ OS21005 NVMe SSD */
|
||||||
|
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
|
||||||
|
{ PCI_DEVICE(0x2646, 0x501E), /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
|
||||||
|
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
|
||||||
{ PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */
|
{ PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */
|
||||||
.driver_data = NVME_QUIRK_BOGUS_NID, },
|
.driver_data = NVME_QUIRK_BOGUS_NID, },
|
||||||
{ PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */
|
{ PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */
|
||||||
|
@ -1290,12 +1290,8 @@ static ssize_t nvmet_subsys_attr_qid_max_show(struct config_item *item,
|
|||||||
static ssize_t nvmet_subsys_attr_qid_max_store(struct config_item *item,
|
static ssize_t nvmet_subsys_attr_qid_max_store(struct config_item *item,
|
||||||
const char *page, size_t cnt)
|
const char *page, size_t cnt)
|
||||||
{
|
{
|
||||||
struct nvmet_port *port = to_nvmet_port(item);
|
|
||||||
u16 qid_max;
|
u16 qid_max;
|
||||||
|
|
||||||
if (nvmet_is_port_enabled(port, __func__))
|
|
||||||
return -EACCES;
|
|
||||||
|
|
||||||
if (sscanf(page, "%hu\n", &qid_max) != 1)
|
if (sscanf(page, "%hu\n", &qid_max) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1176,7 +1176,7 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl)
|
|||||||
* reset the keep alive timer when the controller is enabled.
|
* reset the keep alive timer when the controller is enabled.
|
||||||
*/
|
*/
|
||||||
if (ctrl->kato)
|
if (ctrl->kato)
|
||||||
mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ);
|
mod_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl)
|
static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl)
|
||||||
|
@ -346,8 +346,40 @@ static void put_probe_ref(void)
|
|||||||
mutex_unlock(&blk_probe_mutex);
|
mutex_unlock(&blk_probe_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int blk_trace_start(struct blk_trace *bt)
|
||||||
|
{
|
||||||
|
if (bt->trace_state != Blktrace_setup &&
|
||||||
|
bt->trace_state != Blktrace_stopped)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
blktrace_seq++;
|
||||||
|
smp_mb();
|
||||||
|
bt->trace_state = Blktrace_running;
|
||||||
|
raw_spin_lock_irq(&running_trace_lock);
|
||||||
|
list_add(&bt->running_list, &running_trace_list);
|
||||||
|
raw_spin_unlock_irq(&running_trace_lock);
|
||||||
|
trace_note_time(bt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int blk_trace_stop(struct blk_trace *bt)
|
||||||
|
{
|
||||||
|
if (bt->trace_state != Blktrace_running)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
bt->trace_state = Blktrace_stopped;
|
||||||
|
raw_spin_lock_irq(&running_trace_lock);
|
||||||
|
list_del_init(&bt->running_list);
|
||||||
|
raw_spin_unlock_irq(&running_trace_lock);
|
||||||
|
relay_flush(bt->rchan);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void blk_trace_cleanup(struct request_queue *q, struct blk_trace *bt)
|
static void blk_trace_cleanup(struct request_queue *q, struct blk_trace *bt)
|
||||||
{
|
{
|
||||||
|
blk_trace_stop(bt);
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
blk_trace_free(q, bt);
|
blk_trace_free(q, bt);
|
||||||
put_probe_ref();
|
put_probe_ref();
|
||||||
@ -362,8 +394,7 @@ static int __blk_trace_remove(struct request_queue *q)
|
|||||||
if (!bt)
|
if (!bt)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (bt->trace_state != Blktrace_running)
|
blk_trace_cleanup(q, bt);
|
||||||
blk_trace_cleanup(q, bt);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -658,7 +689,6 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name,
|
|||||||
|
|
||||||
static int __blk_trace_startstop(struct request_queue *q, int start)
|
static int __blk_trace_startstop(struct request_queue *q, int start)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct blk_trace *bt;
|
struct blk_trace *bt;
|
||||||
|
|
||||||
bt = rcu_dereference_protected(q->blk_trace,
|
bt = rcu_dereference_protected(q->blk_trace,
|
||||||
@ -666,36 +696,10 @@ static int __blk_trace_startstop(struct request_queue *q, int start)
|
|||||||
if (bt == NULL)
|
if (bt == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
if (start)
|
||||||
* For starting a trace, we can transition from a setup or stopped
|
return blk_trace_start(bt);
|
||||||
* trace. For stopping a trace, the state must be running
|
else
|
||||||
*/
|
return blk_trace_stop(bt);
|
||||||
ret = -EINVAL;
|
|
||||||
if (start) {
|
|
||||||
if (bt->trace_state == Blktrace_setup ||
|
|
||||||
bt->trace_state == Blktrace_stopped) {
|
|
||||||
blktrace_seq++;
|
|
||||||
smp_mb();
|
|
||||||
bt->trace_state = Blktrace_running;
|
|
||||||
raw_spin_lock_irq(&running_trace_lock);
|
|
||||||
list_add(&bt->running_list, &running_trace_list);
|
|
||||||
raw_spin_unlock_irq(&running_trace_lock);
|
|
||||||
|
|
||||||
trace_note_time(bt);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (bt->trace_state == Blktrace_running) {
|
|
||||||
bt->trace_state = Blktrace_stopped;
|
|
||||||
raw_spin_lock_irq(&running_trace_lock);
|
|
||||||
list_del_init(&bt->running_list);
|
|
||||||
raw_spin_unlock_irq(&running_trace_lock);
|
|
||||||
relay_flush(bt->rchan);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int blk_trace_startstop(struct request_queue *q, int start)
|
int blk_trace_startstop(struct request_queue *q, int start)
|
||||||
@ -772,10 +776,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
|
|||||||
void blk_trace_shutdown(struct request_queue *q)
|
void blk_trace_shutdown(struct request_queue *q)
|
||||||
{
|
{
|
||||||
if (rcu_dereference_protected(q->blk_trace,
|
if (rcu_dereference_protected(q->blk_trace,
|
||||||
lockdep_is_held(&q->debugfs_mutex))) {
|
lockdep_is_held(&q->debugfs_mutex)))
|
||||||
__blk_trace_startstop(q, 0);
|
|
||||||
__blk_trace_remove(q);
|
__blk_trace_remove(q);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BLK_CGROUP
|
#ifdef CONFIG_BLK_CGROUP
|
||||||
@ -1614,13 +1616,7 @@ static int blk_trace_remove_queue(struct request_queue *q)
|
|||||||
if (bt == NULL)
|
if (bt == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (bt->trace_state == Blktrace_running) {
|
blk_trace_stop(bt);
|
||||||
bt->trace_state = Blktrace_stopped;
|
|
||||||
raw_spin_lock_irq(&running_trace_lock);
|
|
||||||
list_del_init(&bt->running_list);
|
|
||||||
raw_spin_unlock_irq(&running_trace_lock);
|
|
||||||
relay_flush(bt->rchan);
|
|
||||||
}
|
|
||||||
|
|
||||||
put_probe_ref();
|
put_probe_ref();
|
||||||
synchronize_rcu();
|
synchronize_rcu();
|
||||||
|
Loading…
Reference in New Issue
Block a user