Commit 85652baa authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'block-6.11-20240824' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - Fix corruption issues with s390/dasd (Eric, Stefan)

 - Fix a misuse of non irq locking grab of a lock (Li)

 - MD pull request with a single data corruption fix for raid1 (Yu)

* tag 'block-6.11-20240824' of git://git.kernel.dk/linux:
  block: Fix lockdep warning in blk_mq_mark_tag_wait
  md/raid1: Fix data corruption for degraded array with slow disk
  s390/dasd: fix error recovery leading to data corruption on ESE devices
  s390/dasd: Remove DMA alignment
parents c5ac744c b313a8c8
...@@ -38,6 +38,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags, ...@@ -38,6 +38,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags,
void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
{ {
unsigned int users; unsigned int users;
unsigned long flags;
struct blk_mq_tags *tags = hctx->tags; struct blk_mq_tags *tags = hctx->tags;
/* /*
...@@ -56,11 +57,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) ...@@ -56,11 +57,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
return; return;
} }
spin_lock_irq(&tags->lock); spin_lock_irqsave(&tags->lock, flags);
users = tags->active_queues + 1; users = tags->active_queues + 1;
WRITE_ONCE(tags->active_queues, users); WRITE_ONCE(tags->active_queues, users);
blk_mq_update_wake_batch(tags, users); blk_mq_update_wake_batch(tags, users);
spin_unlock_irq(&tags->lock); spin_unlock_irqrestore(&tags->lock, flags);
} }
/* /*
......
...@@ -617,6 +617,12 @@ static int choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio, ...@@ -617,6 +617,12 @@ static int choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio,
return -1; return -1;
} }
static bool rdev_in_recovery(struct md_rdev *rdev, struct r1bio *r1_bio)
{
return !test_bit(In_sync, &rdev->flags) &&
rdev->recovery_offset < r1_bio->sector + r1_bio->sectors;
}
static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio, static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio,
int *max_sectors) int *max_sectors)
{ {
...@@ -635,6 +641,7 @@ static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio, ...@@ -635,6 +641,7 @@ static int choose_bb_rdev(struct r1conf *conf, struct r1bio *r1_bio,
rdev = conf->mirrors[disk].rdev; rdev = conf->mirrors[disk].rdev;
if (!rdev || test_bit(Faulty, &rdev->flags) || if (!rdev || test_bit(Faulty, &rdev->flags) ||
rdev_in_recovery(rdev, r1_bio) ||
test_bit(WriteMostly, &rdev->flags)) test_bit(WriteMostly, &rdev->flags))
continue; continue;
...@@ -673,7 +680,8 @@ static int choose_slow_rdev(struct r1conf *conf, struct r1bio *r1_bio, ...@@ -673,7 +680,8 @@ static int choose_slow_rdev(struct r1conf *conf, struct r1bio *r1_bio,
rdev = conf->mirrors[disk].rdev; rdev = conf->mirrors[disk].rdev;
if (!rdev || test_bit(Faulty, &rdev->flags) || if (!rdev || test_bit(Faulty, &rdev->flags) ||
!test_bit(WriteMostly, &rdev->flags)) !test_bit(WriteMostly, &rdev->flags) ||
rdev_in_recovery(rdev, r1_bio))
continue; continue;
/* there are no bad blocks, we can use this disk */ /* there are no bad blocks, we can use this disk */
...@@ -733,9 +741,7 @@ static bool rdev_readable(struct md_rdev *rdev, struct r1bio *r1_bio) ...@@ -733,9 +741,7 @@ static bool rdev_readable(struct md_rdev *rdev, struct r1bio *r1_bio)
if (!rdev || test_bit(Faulty, &rdev->flags)) if (!rdev || test_bit(Faulty, &rdev->flags))
return false; return false;
/* still in recovery */ if (rdev_in_recovery(rdev, r1_bio))
if (!test_bit(In_sync, &rdev->flags) &&
rdev->recovery_offset < r1_bio->sector + r1_bio->sectors)
return false; return false;
/* don't read from slow disk unless have to */ /* don't read from slow disk unless have to */
......
...@@ -1601,9 +1601,15 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb) ...@@ -1601,9 +1601,15 @@ static int dasd_ese_needs_format(struct dasd_block *block, struct irb *irb)
if (!sense) if (!sense)
return 0; return 0;
return !!(sense[1] & SNS1_NO_REC_FOUND) || if (sense[1] & SNS1_NO_REC_FOUND)
!!(sense[1] & SNS1_FILE_PROTECTED) || return 1;
scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN;
if ((sense[1] & SNS1_INV_TRACK_FORMAT) &&
scsw_is_tm(&irb->scsw) &&
!(sense[2] & SNS2_ENV_DATA_PRESENT))
return 1;
return 0;
} }
static int dasd_ese_oos_cond(u8 *sense) static int dasd_ese_oos_cond(u8 *sense)
...@@ -1624,7 +1630,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, ...@@ -1624,7 +1630,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
struct dasd_device *device; struct dasd_device *device;
unsigned long now; unsigned long now;
int nrf_suppressed = 0; int nrf_suppressed = 0;
int fp_suppressed = 0; int it_suppressed = 0;
struct request *req; struct request *req;
u8 *sense = NULL; u8 *sense = NULL;
int expires; int expires;
...@@ -1679,8 +1685,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, ...@@ -1679,8 +1685,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
*/ */
sense = dasd_get_sense(irb); sense = dasd_get_sense(irb);
if (sense) { if (sense) {
fp_suppressed = (sense[1] & SNS1_FILE_PROTECTED) && it_suppressed = (sense[1] & SNS1_INV_TRACK_FORMAT) &&
test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); !(sense[2] & SNS2_ENV_DATA_PRESENT) &&
test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) && nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) &&
test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
...@@ -1695,7 +1702,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, ...@@ -1695,7 +1702,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
return; return;
} }
} }
if (!(fp_suppressed || nrf_suppressed)) if (!(it_suppressed || nrf_suppressed))
device->discipline->dump_sense_dbf(device, irb, "int"); device->discipline->dump_sense_dbf(device, irb, "int");
if (device->features & DASD_FEATURE_ERPLOG) if (device->features & DASD_FEATURE_ERPLOG)
...@@ -2459,14 +2466,17 @@ static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible) ...@@ -2459,14 +2466,17 @@ static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible)
rc = 0; rc = 0;
list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) {
/* /*
* In some cases the 'File Protected' or 'Incorrect Length' * In some cases certain errors might be expected and
* error might be expected and error recovery would be * error recovery would be unnecessary in these cases.
* unnecessary in these cases. Check if the according suppress * Check if the according suppress bit is set.
* bit is set.
*/ */
sense = dasd_get_sense(&cqr->irb); sense = dasd_get_sense(&cqr->irb);
if (sense && sense[1] & SNS1_FILE_PROTECTED && if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags)) !(sense[2] & SNS2_ENV_DATA_PRESENT) &&
test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags))
continue;
if (sense && (sense[1] & SNS1_NO_REC_FOUND) &&
test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags))
continue; continue;
if (scsw_cstat(&cqr->irb.scsw) == 0x40 && if (scsw_cstat(&cqr->irb.scsw) == 0x40 &&
test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags)) test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags))
......
...@@ -1386,14 +1386,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) ...@@ -1386,14 +1386,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
struct dasd_device *device = erp->startdev; struct dasd_device *device = erp->startdev;
/* dev_err(&device->cdev->dev,
* In some cases the 'File Protected' error might be expected and "Accessing the DASD failed because of a hardware error\n");
* log messages shouldn't be written then.
* Check if the according suppress bit is set.
*/
if (!test_bit(DASD_CQR_SUPPRESS_FP, &erp->flags))
dev_err(&device->cdev->dev,
"Accessing the DASD failed because of a hardware error\n");
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
......
...@@ -2275,6 +2275,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device) ...@@ -2275,6 +2275,7 @@ dasd_eckd_analysis_ccw(struct dasd_device *device)
cqr->status = DASD_CQR_FILLED; cqr->status = DASD_CQR_FILLED;
/* Set flags to suppress output for expected errors */ /* Set flags to suppress output for expected errors */
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
return cqr; return cqr;
} }
...@@ -2556,7 +2557,6 @@ dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata, ...@@ -2556,7 +2557,6 @@ dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata,
cqr->buildclk = get_tod_clock(); cqr->buildclk = get_tod_clock();
cqr->status = DASD_CQR_FILLED; cqr->status = DASD_CQR_FILLED;
/* Set flags to suppress output for expected errors */ /* Set flags to suppress output for expected errors */
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
return cqr; return cqr;
...@@ -4130,8 +4130,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( ...@@ -4130,8 +4130,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
/* Set flags to suppress output for expected errors */ /* Set flags to suppress output for expected errors */
if (dasd_eckd_is_ese(basedev)) { if (dasd_eckd_is_ese(basedev)) {
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
} }
...@@ -4633,9 +4631,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( ...@@ -4633,9 +4631,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
/* Set flags to suppress output for expected errors */ /* Set flags to suppress output for expected errors */
if (dasd_eckd_is_ese(basedev)) { if (dasd_eckd_is_ese(basedev)) {
set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);
set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);
} }
return cqr; return cqr;
...@@ -5780,36 +5777,32 @@ static void dasd_eckd_dump_sense(struct dasd_device *device, ...@@ -5780,36 +5777,32 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
{ {
u8 *sense = dasd_get_sense(irb); u8 *sense = dasd_get_sense(irb);
if (scsw_is_tm(&irb->scsw)) { /*
/* * In some cases certain errors might be expected and
* In some cases the 'File Protected' or 'Incorrect Length' * log messages shouldn't be written then.
* error might be expected and log messages shouldn't be written * Check if the according suppress bit is set.
* then. Check if the according suppress bit is set. */
*/ if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&
if (sense && (sense[1] & SNS1_FILE_PROTECTED) && !(sense[2] & SNS2_ENV_DATA_PRESENT) &&
test_bit(DASD_CQR_SUPPRESS_FP, &req->flags)) test_bit(DASD_CQR_SUPPRESS_IT, &req->flags))
return; return;
if (scsw_cstat(&irb->scsw) == 0x40 &&
test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
return;
dasd_eckd_dump_sense_tcw(device, req, irb); if (sense && sense[0] & SNS0_CMD_REJECT &&
} else { test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
/* return;
* In some cases the 'Command Reject' or 'No Record Found'
* error might be expected and log messages shouldn't be
* written then. Check if the according suppress bit is set.
*/
if (sense && sense[0] & SNS0_CMD_REJECT &&
test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))
return;
if (sense && sense[1] & SNS1_NO_REC_FOUND && if (sense && sense[1] & SNS1_NO_REC_FOUND &&
test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags)) test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))
return; return;
if (scsw_cstat(&irb->scsw) == 0x40 &&
test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))
return;
if (scsw_is_tm(&irb->scsw))
dasd_eckd_dump_sense_tcw(device, req, irb);
else
dasd_eckd_dump_sense_ccw(device, req, irb); dasd_eckd_dump_sense_ccw(device, req, irb);
}
} }
static int dasd_eckd_reload_device(struct dasd_device *device) static int dasd_eckd_reload_device(struct dasd_device *device)
......
...@@ -41,7 +41,6 @@ int dasd_gendisk_alloc(struct dasd_block *block) ...@@ -41,7 +41,6 @@ int dasd_gendisk_alloc(struct dasd_block *block)
*/ */
.max_segment_size = PAGE_SIZE, .max_segment_size = PAGE_SIZE,
.seg_boundary_mask = PAGE_SIZE - 1, .seg_boundary_mask = PAGE_SIZE - 1,
.dma_alignment = PAGE_SIZE - 1,
.max_segments = USHRT_MAX, .max_segments = USHRT_MAX,
}; };
struct gendisk *gdp; struct gendisk *gdp;
......
...@@ -196,7 +196,7 @@ struct dasd_ccw_req { ...@@ -196,7 +196,7 @@ struct dasd_ccw_req {
* The following flags are used to suppress output of certain errors. * The following flags are used to suppress output of certain errors.
*/ */
#define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */ #define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */
#define DASD_CQR_SUPPRESS_FP 5 /* Suppress 'File Protected' error*/ #define DASD_CQR_SUPPRESS_IT 5 /* Suppress 'Invalid Track' error*/
#define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */ #define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */
#define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */ #define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */
......
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