Skip to content

Commit 5b8f8cb

Browse files
committed
Merge: scsi: mpi3mr: Critical Bug Fixes
MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-10/-/merge_requests/9 JIRA: https://issues.redhat.com/browse/RHEL-30789 scsi: mpi3mr driver bug fixes Upstream Status: Accepted Tested: Compiled and locally tested Signed-off-by: Chandrakanth Patil <chanpati@redhat.com> Approved-by: John Meneghini <jmeneghi@redhat.com> Approved-by: Jerry Snitselaar <jsnitsel@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jan Stancek <jstancek@redhat.com>
2 parents 2af7b58 + 2ebd389 commit 5b8f8cb

File tree

4 files changed

+216
-101
lines changed

4 files changed

+216
-101
lines changed

drivers/scsi/mpi3mr/mpi3mr.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ extern struct list_head mrioc_list;
5757
extern int prot_mask;
5858
extern atomic64_t event_counter;
5959

60-
#define MPI3MR_DRIVER_VERSION "8.12.0.0.50"
61-
#define MPI3MR_DRIVER_RELDATE "05-Sept-2024"
60+
#define MPI3MR_DRIVER_VERSION "8.12.1.0.50"
61+
#define MPI3MR_DRIVER_RELDATE "28-January-2025"
6262

6363
#define MPI3MR_DRIVER_NAME "mpi3mr"
6464
#define MPI3MR_DRIVER_LICENSE "GPL"
@@ -81,13 +81,14 @@ extern atomic64_t event_counter;
8181

8282
/* Admin queue management definitions */
8383
#define MPI3MR_ADMIN_REQ_Q_SIZE (2 * MPI3MR_PAGE_SIZE_4K)
84-
#define MPI3MR_ADMIN_REPLY_Q_SIZE (4 * MPI3MR_PAGE_SIZE_4K)
84+
#define MPI3MR_ADMIN_REPLY_Q_SIZE (8 * MPI3MR_PAGE_SIZE_4K)
8585
#define MPI3MR_ADMIN_REQ_FRAME_SZ 128
8686
#define MPI3MR_ADMIN_REPLY_FRAME_SZ 16
8787

8888
/* Operational queue management definitions */
8989
#define MPI3MR_OP_REQ_Q_QD 512
9090
#define MPI3MR_OP_REP_Q_QD 1024
91+
#define MPI3MR_OP_REP_Q_QD2K 2048
9192
#define MPI3MR_OP_REP_Q_QD4K 4096
9293
#define MPI3MR_OP_REQ_Q_SEG_SIZE 4096
9394
#define MPI3MR_OP_REP_Q_SEG_SIZE 4096
@@ -134,8 +135,6 @@ extern atomic64_t event_counter;
134135

135136
#define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */
136137

137-
#define MPI3MR_DEFAULT_CFG_PAGE_SZ 1024 /* in bytes */
138-
139138
#define MPI3MR_RESET_TOPOLOGY_SETTLE_TIME 10
140139

141140
#define MPI3MR_SCMD_TIMEOUT (60 * HZ)
@@ -331,6 +330,7 @@ enum mpi3mr_reset_reason {
331330
#define MPI3MR_RESET_REASON_OSTYPE_SHIFT 28
332331
#define MPI3MR_RESET_REASON_IOCNUM_SHIFT 20
333332

333+
334334
/* Queue type definitions */
335335
enum queue_type {
336336
MPI3MR_DEFAULT_QUEUE = 0,
@@ -390,6 +390,7 @@ struct mpi3mr_ioc_facts {
390390
u16 max_msix_vectors;
391391
u8 personality;
392392
u8 dma_mask;
393+
bool max_req_limit;
393394
u8 protocol_flags;
394395
u8 sge_mod_mask;
395396
u8 sge_mod_value;
@@ -459,6 +460,8 @@ struct op_req_qinfo {
459460
* @enable_irq_poll: Flag to indicate polling is enabled
460461
* @in_use: Queue is handled by poll/ISR
461462
* @qtype: Type of queue (types defined in enum queue_type)
463+
* @qfull_watermark: Watermark defined in reply queue to avoid
464+
* reply queue full
462465
*/
463466
struct op_reply_qinfo {
464467
u16 ci;
@@ -474,6 +477,7 @@ struct op_reply_qinfo {
474477
bool enable_irq_poll;
475478
atomic_t in_use;
476479
enum queue_type qtype;
480+
u16 qfull_watermark;
477481
};
478482

479483
/**
@@ -1093,6 +1097,7 @@ struct scmd_priv {
10931097
* @ts_update_interval: Timestamp update interval
10941098
* @reset_in_progress: Reset in progress flag
10951099
* @unrecoverable: Controller unrecoverable flag
1100+
* @io_admin_reset_sync: Manage state of I/O ops during an admin reset process
10961101
* @prev_reset_result: Result of previous reset
10971102
* @reset_mutex: Controller reset mutex
10981103
* @reset_waitq: Controller reset wait queue
@@ -1133,9 +1138,6 @@ struct scmd_priv {
11331138
* @io_throttle_low: I/O size to stop throttle in 512b blocks
11341139
* @num_io_throttle_group: Maximum number of throttle groups
11351140
* @throttle_groups: Pointer to throttle group info structures
1136-
* @cfg_page: Default memory for configuration pages
1137-
* @cfg_page_dma: Configuration page DMA address
1138-
* @cfg_page_sz: Default configuration page memory size
11391141
* @sas_transport_enabled: SAS transport enabled or not
11401142
* @scsi_device_channel: Channel ID for SCSI devices
11411143
* @transport_cmds: Command tracker for SAS transport commands
@@ -1159,6 +1161,8 @@ struct scmd_priv {
11591161
* @snapdump_trigger_active: Snapdump trigger active flag
11601162
* @pci_err_recovery: PCI error recovery in progress
11611163
* @block_on_pci_err: Block IO during PCI error recovery
1164+
* @reply_qfull_count: Occurences of reply queue full avoidance kicking-in
1165+
* @prevent_reply_qfull: Enable reply queue prevention
11621166
*/
11631167
struct mpi3mr_ioc {
11641168
struct list_head list;
@@ -1282,6 +1286,7 @@ struct mpi3mr_ioc {
12821286
u16 ts_update_interval;
12831287
u8 reset_in_progress;
12841288
u8 unrecoverable;
1289+
u8 io_admin_reset_sync;
12851290
int prev_reset_result;
12861291
struct mutex reset_mutex;
12871292
wait_queue_head_t reset_waitq;
@@ -1332,10 +1337,6 @@ struct mpi3mr_ioc {
13321337
u16 num_io_throttle_group;
13331338
struct mpi3mr_throttle_group_info *throttle_groups;
13341339

1335-
void *cfg_page;
1336-
dma_addr_t cfg_page_dma;
1337-
u16 cfg_page_sz;
1338-
13391340
u8 sas_transport_enabled;
13401341
u8 scsi_device_channel;
13411342
struct mpi3mr_drv_cmd transport_cmds;
@@ -1361,6 +1362,8 @@ struct mpi3mr_ioc {
13611362
bool fw_release_trigger_active;
13621363
bool pci_err_recovery;
13631364
bool block_on_pci_err;
1365+
atomic_t reply_qfull_count;
1366+
bool prevent_reply_qfull;
13641367
};
13651368

13661369
/**

drivers/scsi/mpi3mr/mpi3mr_app.c

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,6 +2329,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
23292329
if (!mrioc)
23302330
return -ENODEV;
23312331

2332+
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex))
2333+
return -ERESTARTSYS;
2334+
2335+
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
2336+
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
2337+
mutex_unlock(&mrioc->bsg_cmds.mutex);
2338+
return -EAGAIN;
2339+
}
2340+
23322341
if (!mrioc->ioctl_sges_allocated) {
23332342
dprint_bsg_err(mrioc, "%s: DMA memory was not allocated\n",
23342343
__func__);
@@ -2339,27 +2348,32 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
23392348
karg->timeout = MPI3MR_APP_DEFAULT_TIMEOUT;
23402349

23412350
mpi_req = kzalloc(MPI3MR_ADMIN_REQ_FRAME_SZ, GFP_KERNEL);
2342-
if (!mpi_req)
2351+
if (!mpi_req) {
2352+
mutex_unlock(&mrioc->bsg_cmds.mutex);
23432353
return -ENOMEM;
2354+
}
23442355
mpi_header = (struct mpi3_request_header *)mpi_req;
23452356

23462357
bufcnt = karg->buf_entry_list.num_of_entries;
23472358
drv_bufs = kzalloc((sizeof(*drv_bufs) * bufcnt), GFP_KERNEL);
23482359
if (!drv_bufs) {
2360+
mutex_unlock(&mrioc->bsg_cmds.mutex);
23492361
rval = -ENOMEM;
23502362
goto out;
23512363
}
23522364

23532365
dout_buf = kzalloc(job->request_payload.payload_len,
23542366
GFP_KERNEL);
23552367
if (!dout_buf) {
2368+
mutex_unlock(&mrioc->bsg_cmds.mutex);
23562369
rval = -ENOMEM;
23572370
goto out;
23582371
}
23592372

23602373
din_buf = kzalloc(job->reply_payload.payload_len,
23612374
GFP_KERNEL);
23622375
if (!din_buf) {
2376+
mutex_unlock(&mrioc->bsg_cmds.mutex);
23632377
rval = -ENOMEM;
23642378
goto out;
23652379
}
@@ -2435,6 +2449,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
24352449
(mpi_msg_size > MPI3MR_ADMIN_REQ_FRAME_SZ)) {
24362450
dprint_bsg_err(mrioc, "%s: invalid MPI message size\n",
24372451
__func__);
2452+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24382453
rval = -EINVAL;
24392454
goto out;
24402455
}
@@ -2447,19 +2462,22 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
24472462
if (invalid_be) {
24482463
dprint_bsg_err(mrioc, "%s: invalid buffer entries passed\n",
24492464
__func__);
2465+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24502466
rval = -EINVAL;
24512467
goto out;
24522468
}
24532469

24542470
if (sgl_dout_iter > (dout_buf + job->request_payload.payload_len)) {
24552471
dprint_bsg_err(mrioc, "%s: data_out buffer length mismatch\n",
24562472
__func__);
2473+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24572474
rval = -EINVAL;
24582475
goto out;
24592476
}
24602477
if (sgl_din_iter > (din_buf + job->reply_payload.payload_len)) {
24612478
dprint_bsg_err(mrioc, "%s: data_in buffer length mismatch\n",
24622479
__func__);
2480+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24632481
rval = -EINVAL;
24642482
goto out;
24652483
}
@@ -2472,6 +2490,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
24722490
dprint_bsg_err(mrioc, "%s:%d: invalid data transfer size passed for function 0x%x din_size = %d, dout_size = %d\n",
24732491
__func__, __LINE__, mpi_header->function, din_size,
24742492
dout_size);
2493+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24752494
rval = -EINVAL;
24762495
goto out;
24772496
}
@@ -2480,13 +2499,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
24802499
dprint_bsg_err(mrioc,
24812500
"%s:%d: invalid data transfer size passed for function 0x%x din_size=%d\n",
24822501
__func__, __LINE__, mpi_header->function, din_size);
2502+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24832503
rval = -EINVAL;
24842504
goto out;
24852505
}
24862506
if (dout_size > MPI3MR_MAX_APP_XFER_SIZE) {
24872507
dprint_bsg_err(mrioc,
24882508
"%s:%d: invalid data transfer size passed for function 0x%x dout_size = %d\n",
24892509
__func__, __LINE__, mpi_header->function, dout_size);
2510+
mutex_unlock(&mrioc->bsg_cmds.mutex);
24902511
rval = -EINVAL;
24912512
goto out;
24922513
}
@@ -2497,6 +2518,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
24972518
dprint_bsg_err(mrioc, "%s:%d: invalid message size passed:%d:%d:%d:%d\n",
24982519
__func__, __LINE__, din_cnt, dout_cnt, din_size,
24992520
dout_size);
2521+
mutex_unlock(&mrioc->bsg_cmds.mutex);
25002522
rval = -EINVAL;
25012523
goto out;
25022524
}
@@ -2544,6 +2566,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
25442566
continue;
25452567
if (mpi3mr_map_data_buffer_dma(mrioc, drv_buf_iter, desc_count)) {
25462568
rval = -ENOMEM;
2569+
mutex_unlock(&mrioc->bsg_cmds.mutex);
25472570
dprint_bsg_err(mrioc, "%s:%d: mapping data buffers failed\n",
25482571
__func__, __LINE__);
25492572
goto out;
@@ -2556,20 +2579,11 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
25562579
sense_buff_k = kzalloc(erbsz, GFP_KERNEL);
25572580
if (!sense_buff_k) {
25582581
rval = -ENOMEM;
2582+
mutex_unlock(&mrioc->bsg_cmds.mutex);
25592583
goto out;
25602584
}
25612585
}
25622586

2563-
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex)) {
2564-
rval = -ERESTARTSYS;
2565-
goto out;
2566-
}
2567-
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
2568-
rval = -EAGAIN;
2569-
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
2570-
mutex_unlock(&mrioc->bsg_cmds.mutex);
2571-
goto out;
2572-
}
25732587
if (mrioc->unrecoverable) {
25742588
dprint_bsg_err(mrioc, "%s: unrecoverable controller\n",
25752589
__func__);
@@ -2937,6 +2951,7 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
29372951
.max_hw_sectors = MPI3MR_MAX_APP_XFER_SECTORS,
29382952
.max_segments = MPI3MR_MAX_APP_XFER_SEGMENTS,
29392953
};
2954+
struct request_queue *q;
29402955

29412956
device_initialize(bsg_dev);
29422957

@@ -2952,14 +2967,17 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
29522967
return;
29532968
}
29542969

2955-
mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim,
2970+
q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim,
29562971
mpi3mr_bsg_request, NULL, 0);
2957-
if (IS_ERR(mrioc->bsg_queue)) {
2972+
if (IS_ERR(q)) {
29582973
ioc_err(mrioc, "%s: bsg registration failed\n",
29592974
dev_name(bsg_dev));
29602975
device_del(bsg_dev);
29612976
put_device(bsg_dev);
2977+
return;
29622978
}
2979+
2980+
mrioc->bsg_queue = q;
29632981
}
29642982

29652983
/**
@@ -3042,6 +3060,29 @@ reply_queue_count_show(struct device *dev, struct device_attribute *attr,
30423060

30433061
static DEVICE_ATTR_RO(reply_queue_count);
30443062

3063+
/**
3064+
* reply_qfull_count_show - Show reply qfull count
3065+
* @dev: class device
3066+
* @attr: Device attributes
3067+
* @buf: Buffer to copy
3068+
*
3069+
* Retrieves the current value of the reply_qfull_count from the mrioc structure and
3070+
* formats it as a string for display.
3071+
*
3072+
* Return: sysfs_emit() return
3073+
*/
3074+
static ssize_t
3075+
reply_qfull_count_show(struct device *dev, struct device_attribute *attr,
3076+
char *buf)
3077+
{
3078+
struct Scsi_Host *shost = class_to_shost(dev);
3079+
struct mpi3mr_ioc *mrioc = shost_priv(shost);
3080+
3081+
return sysfs_emit(buf, "%u\n", atomic_read(&mrioc->reply_qfull_count));
3082+
}
3083+
3084+
static DEVICE_ATTR_RO(reply_qfull_count);
3085+
30453086
/**
30463087
* logging_level_show - Show controller debug level
30473088
* @dev: class device
@@ -3134,6 +3175,7 @@ static struct attribute *mpi3mr_host_attrs[] = {
31343175
&dev_attr_fw_queue_depth.attr,
31353176
&dev_attr_op_req_q_count.attr,
31363177
&dev_attr_reply_queue_count.attr,
3178+
&dev_attr_reply_qfull_count.attr,
31373179
&dev_attr_logging_level.attr,
31383180
&dev_attr_adp_state.attr,
31393181
NULL,

0 commit comments

Comments
 (0)