block-6.5-2023-07-28

-----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmTD2VcQHGF4Ym9lQGtl
 cm5lbC5kawAKCRD301j7KXHgpqzgEADT9lc0fr8wnp2fu/7NhkdsaPtuoUKiH7ju
 qxWExXIzxxKYM6OdCdYho9SvIjtdblraZOGqrEni8KMcKnR6vDd8BjGzPJ2BJQe2
 GhU0VLVqAw2uoaLhWIZ3m+CyKn7rggoCwpTAUFQG7vL6vSW+ExkWs6g4XcrWhq5V
 XCPJnNRc2o6OdFnv1xBNy1YRrP2ME+HaghJdDNxVM4R9hOv4PVvYrW7P2fK1gurD
 o3JgTAQg6//16ZBAMcZDkwuGGFVdvG16EiE/0z3QdP4WeDqSFqqxYtk8m/LqAx31
 FswUI+YDmKJHSfbLCh6pW4j81xH+svVi0LiANdlxCMGg3zouft+wh/KGdQJC/rcb
 ocFgUCOL4P4208wXkuUjtcAI0zmEMPAIoRQirOzDExja0bI4LJrp3GKJ78U4MbDo
 iBM5qgkH+MqwD/jXMOY5MnEEBzqceW7Q5Al6emE093kRenIYulEL6ZFy05vfqG1+
 NuQcvSJ9f0mgTDUGr0bXytshTG4vSHtKZ9UfAgh5FzPBnPYpwRbxlq6i/7+DxU6k
 33FTzNLuRwDSEo33Uj75KwK1glizofYj6lrqYxVw/9jkVAEEzpjr6H8Su1+dTt8L
 ZbXSQKdxsAxGdbIMeA1lUfUmqQHi1ouTLsBzwkceKCeN3UXmzGOnNBXmvoVXSv0A
 v4RNV+WHCA==
 =TD54
 -----END PGP SIGNATURE-----

Merge tag 'block-6.5-2023-07-28' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:
 "A few fixes that should go into the current kernel release, mainly:

   - Set of fixes for dasd (Stefan)

   - Handle interruptible waits returning because of a signal for ublk
     (Ming)"

* tag 'block-6.5-2023-07-28' of git://git.kernel.dk/linux:
  ublk: return -EINTR if breaking from waiting for existed users in DEL_DEV
  ublk: fail to recover device if queue setup is interrupted
  ublk: fail to start device if queue setup is interrupted
  block: Fix a source code comment in include/uapi/linux/blkzoned.h
  s390/dasd: print copy pair message only for the correct error
  s390/dasd: fix hanging device after request requeue
  s390/dasd: use correct number of retries for ERP requests
  s390/dasd: fix hanging device after quiesce/resume
This commit is contained in:
Linus Torvalds 2023-07-28 10:23:41 -07:00
commit 818680d154
5 changed files with 64 additions and 89 deletions

View File

@ -1847,7 +1847,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
if (ublksrv_pid <= 0)
return -EINVAL;
wait_for_completion_interruptible(&ub->completion);
if (wait_for_completion_interruptible(&ub->completion) != 0)
return -EINTR;
schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD);
@ -2125,8 +2126,8 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub)
* - the device number is freed already, we will not find this
* device via ublk_get_device_from_id()
*/
wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx));
if (wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx)))
return -EINTR;
return 0;
}
@ -2323,7 +2324,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n",
__func__, ub->dev_info.nr_hw_queues, header->dev_id);
/* wait until new ubq_daemon sending all FETCH_REQ */
wait_for_completion_interruptible(&ub->completion);
if (wait_for_completion_interruptible(&ub->completion))
return -EINTR;
pr_devel("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n",
__func__, ub->dev_info.nr_hw_queues, header->dev_id);

View File

@ -2943,41 +2943,32 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data)
* Requeue a request back to the block request queue
* only works for block requests
*/
static int _dasd_requeue_request(struct dasd_ccw_req *cqr)
static void _dasd_requeue_request(struct dasd_ccw_req *cqr)
{
struct dasd_block *block = cqr->block;
struct request *req;
if (!block)
return -EINVAL;
/*
* If the request is an ERP request there is nothing to requeue.
* This will be done with the remaining original request.
*/
if (cqr->refers)
return 0;
return;
spin_lock_irq(&cqr->dq->lock);
req = (struct request *) cqr->callback_data;
blk_mq_requeue_request(req, true);
spin_unlock_irq(&cqr->dq->lock);
return 0;
return;
}
/*
* Go through all request on the dasd_block request queue, cancel them
* on the respective dasd_device, and return them to the generic
* block layer.
*/
static int dasd_flush_block_queue(struct dasd_block *block)
static int _dasd_requests_to_flushqueue(struct dasd_block *block,
struct list_head *flush_queue)
{
struct dasd_ccw_req *cqr, *n;
int rc, i;
struct list_head flush_queue;
unsigned long flags;
int rc, i;
INIT_LIST_HEAD(&flush_queue);
spin_lock_bh(&block->queue_lock);
spin_lock_irqsave(&block->queue_lock, flags);
rc = 0;
restart:
list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
@ -2992,13 +2983,32 @@ restart:
* is returned from the dasd_device layer.
*/
cqr->callback = _dasd_wake_block_flush_cb;
for (i = 0; cqr != NULL; cqr = cqr->refers, i++)
list_move_tail(&cqr->blocklist, &flush_queue);
for (i = 0; cqr; cqr = cqr->refers, i++)
list_move_tail(&cqr->blocklist, flush_queue);
if (i > 1)
/* moved more than one request - need to restart */
goto restart;
}
spin_unlock_bh(&block->queue_lock);
spin_unlock_irqrestore(&block->queue_lock, flags);
return rc;
}
/*
* Go through all request on the dasd_block request queue, cancel them
* on the respective dasd_device, and return them to the generic
* block layer.
*/
static int dasd_flush_block_queue(struct dasd_block *block)
{
struct dasd_ccw_req *cqr, *n;
struct list_head flush_queue;
unsigned long flags;
int rc;
INIT_LIST_HEAD(&flush_queue);
rc = _dasd_requests_to_flushqueue(block, &flush_queue);
/* Now call the callback function of flushed requests */
restart_cb:
list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) {
@ -3881,75 +3891,36 @@ EXPORT_SYMBOL_GPL(dasd_generic_space_avail);
*/
int dasd_generic_requeue_all_requests(struct dasd_device *device)
{
struct dasd_block *block = device->block;
struct list_head requeue_queue;
struct dasd_ccw_req *cqr, *n;
struct dasd_ccw_req *refers;
int rc;
if (!block)
return 0;
INIT_LIST_HEAD(&requeue_queue);
spin_lock_irq(get_ccwdev_lock(device->cdev));
rc = 0;
list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) {
/* Check status and move request to flush_queue */
if (cqr->status == DASD_CQR_IN_IO) {
rc = device->discipline->term_IO(cqr);
if (rc) {
/* unable to terminate requeust */
dev_err(&device->cdev->dev,
"Unable to terminate request %p "
"on suspend\n", cqr);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
dasd_put_device(device);
return rc;
}
rc = _dasd_requests_to_flushqueue(block, &requeue_queue);
/* Now call the callback function of flushed requests */
restart_cb:
list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) {
wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED));
/* Process finished ERP request. */
if (cqr->refers) {
spin_lock_bh(&block->queue_lock);
__dasd_process_erp(block->base, cqr);
spin_unlock_bh(&block->queue_lock);
/* restart list_for_xx loop since dasd_process_erp
* might remove multiple elements
*/
goto restart_cb;
}
list_move_tail(&cqr->devlist, &requeue_queue);
}
spin_unlock_irq(get_ccwdev_lock(device->cdev));
list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) {
wait_event(dasd_flush_wq,
(cqr->status != DASD_CQR_CLEAR_PENDING));
/*
* requeue requests to blocklayer will only work
* for block device requests
*/
if (_dasd_requeue_request(cqr))
continue;
/* remove requests from device and block queue */
list_del_init(&cqr->devlist);
while (cqr->refers != NULL) {
refers = cqr->refers;
/* remove the request from the block queue */
list_del(&cqr->blocklist);
/* free the finished erp request */
dasd_free_erp_request(cqr, cqr->memdev);
cqr = refers;
}
/*
* _dasd_requeue_request already checked for a valid
* blockdevice, no need to check again
* all erp requests (cqr->refers) have a cqr->block
* pointer copy from the original cqr
*/
_dasd_requeue_request(cqr);
list_del_init(&cqr->blocklist);
cqr->block->base->discipline->free_cp(
cqr, (struct request *) cqr->callback_data);
}
/*
* if requests remain then they are internal request
* and go back to the device queue
*/
if (!list_empty(&requeue_queue)) {
/* move freeze_queue to start of the ccw_queue */
spin_lock_irq(get_ccwdev_lock(device->cdev));
list_splice_tail(&requeue_queue, &device->ccw_queue);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
}
dasd_schedule_device_bh(device);
return rc;
}

View File

@ -1050,7 +1050,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
dev_err(&device->cdev->dev, "An I/O request was rejected"
" because writing is inhibited\n");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
} else if (sense[7] & SNS7_INVALID_ON_SEC) {
} else if (sense[7] == SNS7_INVALID_ON_SEC) {
dev_err(&device->cdev->dev, "An I/O request was rejected on a copy pair secondary device\n");
/* suppress dump of sense data for this error */
set_bit(DASD_CQR_SUPPRESS_CR, &erp->refers->flags);
@ -2441,7 +2441,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
erp->block = cqr->block;
erp->magic = cqr->magic;
erp->expires = cqr->expires;
erp->retries = 256;
erp->retries = device->default_retries;
erp->buildclk = get_tod_clock();
erp->status = DASD_CQR_FILLED;

View File

@ -131,6 +131,7 @@ static int dasd_ioctl_resume(struct dasd_block *block)
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
dasd_schedule_block_bh(block);
dasd_schedule_device_bh(base);
return 0;
}

View File

@ -51,13 +51,13 @@ enum blk_zone_type {
*
* The Zone Condition state machine in the ZBC/ZAC standards maps the above
* deinitions as:
* - ZC1: Empty | BLK_ZONE_EMPTY
* - ZC1: Empty | BLK_ZONE_COND_EMPTY
* - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN
* - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN
* - ZC4: Closed | BLK_ZONE_CLOSED
* - ZC5: Full | BLK_ZONE_FULL
* - ZC6: Read Only | BLK_ZONE_READONLY
* - ZC7: Offline | BLK_ZONE_OFFLINE
* - ZC4: Closed | BLK_ZONE_COND_CLOSED
* - ZC5: Full | BLK_ZONE_COND_FULL
* - ZC6: Read Only | BLK_ZONE_COND_READONLY
* - ZC7: Offline | BLK_ZONE_COND_OFFLINE
*
* Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should
* be considered invalid.