Skip to content

Commit 73e3715

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: add special APIs for run-time disabling of discard and friends
A few drivers optimistically try to support discard, write zeroes and secure erase and disable the features from the I/O completion handler if the hardware can't support them. This disable can't be done using the atomic queue limits API because the I/O completion handlers can't take sleeping locks or freeze the queue. Keep the existing clearing of the relevant field to zero, but replace the old blk_queue_max_* APIs with new disable APIs that force the value to 0. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Reviewed-by: John Garry <[email protected]> Reviewed-by: Nitesh Shetty <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 1652b0b commit 73e3715

File tree

5 files changed

+28
-53
lines changed

5 files changed

+28
-53
lines changed

arch/um/drivers/ubd_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,9 @@ static void ubd_end_request(struct io_thread_req *io_req)
451451
{
452452
if (io_req->error == BLK_STS_NOTSUPP) {
453453
if (req_op(io_req->req) == REQ_OP_DISCARD)
454-
blk_queue_max_discard_sectors(io_req->req->q, 0);
454+
blk_queue_disable_discard(io_req->req->q);
455455
else if (req_op(io_req->req) == REQ_OP_WRITE_ZEROES)
456-
blk_queue_max_write_zeroes_sectors(io_req->req->q, 0);
456+
blk_queue_disable_write_zeroes(io_req->req->q);
457457
}
458458
blk_mq_end_request(io_req->req, io_req->error);
459459
kfree(io_req);

block/blk-settings.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -293,47 +293,6 @@ int queue_limits_set(struct request_queue *q, struct queue_limits *lim)
293293
}
294294
EXPORT_SYMBOL_GPL(queue_limits_set);
295295

296-
/**
297-
* blk_queue_max_discard_sectors - set max sectors for a single discard
298-
* @q: the request queue for the device
299-
* @max_discard_sectors: maximum number of sectors to discard
300-
**/
301-
void blk_queue_max_discard_sectors(struct request_queue *q,
302-
unsigned int max_discard_sectors)
303-
{
304-
struct queue_limits *lim = &q->limits;
305-
306-
lim->max_hw_discard_sectors = max_discard_sectors;
307-
lim->max_discard_sectors =
308-
min(max_discard_sectors, lim->max_user_discard_sectors);
309-
}
310-
EXPORT_SYMBOL(blk_queue_max_discard_sectors);
311-
312-
/**
313-
* blk_queue_max_secure_erase_sectors - set max sectors for a secure erase
314-
* @q: the request queue for the device
315-
* @max_sectors: maximum number of sectors to secure_erase
316-
**/
317-
void blk_queue_max_secure_erase_sectors(struct request_queue *q,
318-
unsigned int max_sectors)
319-
{
320-
q->limits.max_secure_erase_sectors = max_sectors;
321-
}
322-
EXPORT_SYMBOL(blk_queue_max_secure_erase_sectors);
323-
324-
/**
325-
* blk_queue_max_write_zeroes_sectors - set max sectors for a single
326-
* write zeroes
327-
* @q: the request queue for the device
328-
* @max_write_zeroes_sectors: maximum number of sectors to write per command
329-
**/
330-
void blk_queue_max_write_zeroes_sectors(struct request_queue *q,
331-
unsigned int max_write_zeroes_sectors)
332-
{
333-
q->limits.max_write_zeroes_sectors = max_write_zeroes_sectors;
334-
}
335-
EXPORT_SYMBOL(blk_queue_max_write_zeroes_sectors);
336-
337296
void disk_update_readahead(struct gendisk *disk)
338297
{
339298
blk_apply_bdi_limits(disk->bdi, &disk->queue->limits);

drivers/block/xen-blkfront.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,8 +1605,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
16051605
blkif_req(req)->error = BLK_STS_NOTSUPP;
16061606
info->feature_discard = 0;
16071607
info->feature_secdiscard = 0;
1608-
blk_queue_max_discard_sectors(rq, 0);
1609-
blk_queue_max_secure_erase_sectors(rq, 0);
1608+
blk_queue_disable_discard(rq);
1609+
blk_queue_disable_secure_erase(rq);
16101610
}
16111611
break;
16121612
case BLKIF_OP_FLUSH_DISKCACHE:

drivers/scsi/sd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
837837
static void sd_disable_discard(struct scsi_disk *sdkp)
838838
{
839839
sdkp->provisioning_mode = SD_LBP_DISABLE;
840-
blk_queue_max_discard_sectors(sdkp->disk->queue, 0);
840+
blk_queue_disable_discard(sdkp->disk->queue);
841841
}
842842

843843
static void sd_config_discard(struct scsi_disk *sdkp, struct queue_limits *lim,
@@ -1019,7 +1019,7 @@ static void sd_disable_write_same(struct scsi_disk *sdkp)
10191019
{
10201020
sdkp->device->no_write_same = 1;
10211021
sdkp->max_ws_blocks = 0;
1022-
blk_queue_max_write_zeroes_sectors(sdkp->disk->queue, 0);
1022+
blk_queue_disable_write_zeroes(sdkp->disk->queue);
10231023
}
10241024

10251025
static void sd_config_write_same(struct scsi_disk *sdkp,

include/linux/blkdev.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -912,15 +912,31 @@ static inline void queue_limits_cancel_update(struct request_queue *q)
912912
mutex_unlock(&q->limits_lock);
913913
}
914914

915+
/*
916+
* These helpers are for drivers that have sloppy feature negotiation and might
917+
* have to disable DISCARD, WRITE_ZEROES or SECURE_DISCARD from the I/O
918+
* completion handler when the device returned an indicator that the respective
919+
* feature is not actually supported. They are racy and the driver needs to
920+
* cope with that. Try to avoid this scheme if you can.
921+
*/
922+
static inline void blk_queue_disable_discard(struct request_queue *q)
923+
{
924+
q->limits.max_discard_sectors = 0;
925+
}
926+
927+
static inline void blk_queue_disable_secure_erase(struct request_queue *q)
928+
{
929+
q->limits.max_secure_erase_sectors = 0;
930+
}
931+
932+
static inline void blk_queue_disable_write_zeroes(struct request_queue *q)
933+
{
934+
q->limits.max_write_zeroes_sectors = 0;
935+
}
936+
915937
/*
916938
* Access functions for manipulating queue properties
917939
*/
918-
void blk_queue_max_secure_erase_sectors(struct request_queue *q,
919-
unsigned int max_sectors);
920-
extern void blk_queue_max_discard_sectors(struct request_queue *q,
921-
unsigned int max_discard_sectors);
922-
extern void blk_queue_max_write_zeroes_sectors(struct request_queue *q,
923-
unsigned int max_write_same_sectors);
924940
void disk_update_readahead(struct gendisk *disk);
925941
extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min);
926942
extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);

0 commit comments

Comments
 (0)