Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "mpi3mr: Enhancements for mpi3mr"

Ranjan Kumar <ranjan.kumar@broadcom.com> says:

Enhancements for mpi3mr driver

Link: https://patch.msgid.link/20260320090326.47544-1-ranjan.kumar@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+74 -8
+16
drivers/scsi/mpi3mr/mpi3mr.h
··· 159 159 /* Controller Reset related definitions */ 160 160 #define MPI3MR_HOSTDIAG_UNLOCK_RETRY_COUNT 5 161 161 #define MPI3MR_MAX_RESET_RETRY_COUNT 3 162 + #define MPI3MR_MAX_SHUTDOWN_RETRY_COUNT 2 162 163 163 164 /* ResponseCode definitions */ 164 165 #define MPI3MR_RI_MASK_RESPCODE (0x000000FF) ··· 324 323 MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT = 29, 325 324 MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT = 30, 326 325 MPI3MR_RESET_FROM_TRIGGER = 31, 326 + MPI3MR_RESET_FROM_INVALID_COMPLETION = 32, 327 327 }; 328 328 329 329 #define MPI3MR_RESET_REASON_OSTYPE_LINUX 1 ··· 430 428 * @q_segments: Segment descriptor pointer 431 429 * @q_segment_list: Segment list base virtual address 432 430 * @q_segment_list_dma: Segment list base DMA address 431 + * @last_full_host_tag: Hosttag of last IO returned to SML 432 + * due to queue full 433 + * @qfull_io_count: Number of IOs returned back to SML 434 + * due to queue full 435 + * @qfull_instances: Total queue full occurrences.One occurrence 436 + * starts with queue full detection and ends 437 + * with queue full breaks. 438 + * 433 439 */ 434 440 struct op_req_qinfo { 435 441 u16 ci; ··· 451 441 struct segments *q_segments; 452 442 void *q_segment_list; 453 443 dma_addr_t q_segment_list_dma; 444 + u16 last_full_host_tag; 445 + u64 qfull_io_count; 446 + u32 qfull_instances; 447 + 454 448 }; 455 449 456 450 /** ··· 1197 1183 * @num_tb_segs: Number of Segments in Trace buffer 1198 1184 * @trace_buf_pool: DMA pool for Segmented trace buffer segments 1199 1185 * @trace_buf: Trace buffer segments memory descriptor 1186 + * @invalid_io_comp: Invalid IO completion 1200 1187 */ 1201 1188 struct mpi3mr_ioc { 1202 1189 struct list_head list; ··· 1409 1394 u32 num_tb_segs; 1410 1395 struct dma_pool *trace_buf_pool; 1411 1396 struct segments *trace_buf; 1397 + u8 invalid_io_comp; 1412 1398 1413 1399 }; 1414 1400
+49 -6
drivers/scsi/mpi3mr/mpi3mr_fw.c
··· 996 996 { MPI3MR_RESET_FROM_FIRMWARE, "firmware asynchronous reset" }, 997 997 { MPI3MR_RESET_FROM_CFG_REQ_TIMEOUT, "configuration request timeout"}, 998 998 { MPI3MR_RESET_FROM_SAS_TRANSPORT_TIMEOUT, "timeout of a SAS transport layer request" }, 999 + { MPI3MR_RESET_FROM_INVALID_COMPLETION, "invalid cmd completion" }, 999 1000 }; 1000 1001 1001 1002 /** ··· 2362 2361 op_req_q->ci = 0; 2363 2362 op_req_q->pi = 0; 2364 2363 op_req_q->reply_qid = reply_qid; 2364 + op_req_q->last_full_host_tag = MPI3MR_HOSTTAG_INVALID; 2365 + op_req_q->qfull_io_count = 0; 2366 + op_req_q->qfull_instances = 0; 2365 2367 spin_lock_init(&op_req_q->q_lock); 2366 2368 2367 2369 if (!op_req_q->q_segments) { ··· 2551 2547 u16 req_sz = mrioc->facts.op_req_sz; 2552 2548 struct segments *segments = op_req_q->q_segments; 2553 2549 struct op_reply_qinfo *op_reply_q = NULL; 2550 + struct mpi3_scsi_io_request *scsiio_req = 2551 + (struct mpi3_scsi_io_request *)req; 2554 2552 2555 2553 reply_qidx = op_req_q->reply_qid - 1; 2556 2554 op_reply_q = mrioc->op_reply_qinfo + reply_qidx; ··· 2570 2564 mpi3mr_process_op_reply_q(mrioc, mrioc->intr_info[midx].op_reply_q); 2571 2565 2572 2566 if (mpi3mr_check_req_qfull(op_req_q)) { 2567 + 2568 + if (op_req_q->last_full_host_tag == 2569 + MPI3MR_HOSTTAG_INVALID) 2570 + op_req_q->qfull_instances++; 2571 + 2572 + op_req_q->last_full_host_tag = scsiio_req->host_tag; 2573 + op_req_q->qfull_io_count++; 2573 2574 retval = -EAGAIN; 2574 2575 goto out; 2575 2576 } 2576 2577 } 2578 + 2579 + if (op_req_q->last_full_host_tag != MPI3MR_HOSTTAG_INVALID) 2580 + op_req_q->last_full_host_tag = MPI3MR_HOSTTAG_INVALID; 2577 2581 2578 2582 if (mrioc->reset_in_progress) { 2579 2583 ioc_err(mrioc, "OpReqQ submit reset in progress\n"); ··· 2892 2876 ioc_err(mrioc, 2893 2877 "flush pending commands for unrecoverable controller\n"); 2894 2878 mpi3mr_flush_cmds_for_unrecovered_controller(mrioc); 2879 + return; 2880 + } 2881 + 2882 + if (mrioc->invalid_io_comp) { 2883 + mpi3mr_soft_reset_handler(mrioc, MPI3MR_RESET_FROM_INVALID_COMPLETION, 1); 2895 2884 return; 2896 2885 } 2897 2886 ··· 4842 4821 mrioc->req_qinfo[i].qid = 0; 4843 4822 mrioc->req_qinfo[i].reply_qid = 0; 4844 4823 spin_lock_init(&mrioc->req_qinfo[i].q_lock); 4824 + mrioc->req_qinfo[i].last_full_host_tag = 0; 4845 4825 mpi3mr_memset_op_req_q_buffers(mrioc, i); 4846 4826 } 4847 4827 ··· 5058 5036 */ 5059 5037 static void mpi3mr_issue_ioc_shutdown(struct mpi3mr_ioc *mrioc) 5060 5038 { 5061 - u32 ioc_config, ioc_status; 5062 - u8 retval = 1; 5063 - u32 timeout = MPI3MR_DEFAULT_SHUTDOWN_TIME * 10; 5039 + u32 ioc_config, ioc_status, shutdown_action; 5040 + u8 retval = 1, retry = 0; 5041 + u32 timeout = MPI3MR_DEFAULT_SHUTDOWN_TIME * 10, timeout_remaining = 0; 5064 5042 5065 5043 ioc_info(mrioc, "Issuing shutdown Notification\n"); 5066 5044 if (mrioc->unrecoverable) { ··· 5075 5053 return; 5076 5054 } 5077 5055 5056 + shutdown_action = MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL | 5057 + MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; 5078 5058 ioc_config = readl(&mrioc->sysif_regs->ioc_configuration); 5079 - ioc_config |= MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL; 5080 - ioc_config |= MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; 5059 + ioc_config |= shutdown_action; 5081 5060 5082 5061 writel(ioc_config, &mrioc->sysif_regs->ioc_configuration); 5083 5062 5084 5063 if (mrioc->facts.shutdown_timeout) 5085 5064 timeout = mrioc->facts.shutdown_timeout * 10; 5065 + timeout_remaining = timeout; 5086 5066 5087 5067 do { 5088 5068 ioc_status = readl(&mrioc->sysif_regs->ioc_status); ··· 5093 5069 retval = 0; 5094 5070 break; 5095 5071 } 5072 + if (mrioc->unrecoverable) 5073 + break; 5074 + if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) { 5075 + mpi3mr_print_fault_info(mrioc); 5076 + if (retry >= MPI3MR_MAX_SHUTDOWN_RETRY_COUNT) 5077 + break; 5078 + if (mpi3mr_issue_reset(mrioc, 5079 + MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, 5080 + MPI3MR_RESET_FROM_CTLR_CLEANUP)) 5081 + break; 5082 + ioc_config = 5083 + readl(&mrioc->sysif_regs->ioc_configuration); 5084 + ioc_config |= shutdown_action; 5085 + writel(ioc_config, 5086 + &mrioc->sysif_regs->ioc_configuration); 5087 + timeout_remaining = timeout; 5088 + retry++; 5089 + } 5096 5090 msleep(100); 5097 - } while (--timeout); 5091 + } while (--timeout_remaining); 5098 5092 5099 5093 ioc_status = readl(&mrioc->sysif_regs->ioc_status); 5100 5094 ioc_config = readl(&mrioc->sysif_regs->ioc_configuration); ··· 5686 5644 ssleep(MPI3MR_RESET_TOPOLOGY_SETTLE_TIME); 5687 5645 5688 5646 out: 5647 + mrioc->invalid_io_comp = 0; 5689 5648 if (!retval) { 5690 5649 mrioc->diagsave_timeout = 0; 5691 5650 mrioc->reset_in_progress = 0;
+9 -2
drivers/scsi/mpi3mr/mpi3mr_os.c
··· 3459 3459 } 3460 3460 scmd = mpi3mr_scmd_from_host_tag(mrioc, host_tag, qidx); 3461 3461 if (!scmd) { 3462 - panic("%s: Cannot Identify scmd for host_tag 0x%x\n", 3463 - mrioc->name, host_tag); 3462 + ioc_err(mrioc, "Cannot Identify scmd for host_tag 0x%x", host_tag); 3463 + ioc_err(mrioc, 3464 + "reply_desc_type(%d) host_tag(%d(0x%04x)): qid(%d): command issued to\n" 3465 + "handle(0x%04x) returned with ioc_status(0x%04x), log_info(0x%08x),\n" 3466 + "scsi_state(0x%02x), scsi_status(0x%02x), xfer_count(%d), resp_data(0x%08x)\n", 3467 + reply_desc_type, host_tag, host_tag, qidx+1, dev_handle, ioc_status, 3468 + ioc_loginfo, scsi_state, scsi_status, xfer_count, 3469 + resp_data); 3470 + mrioc->invalid_io_comp = 1; 3464 3471 goto out; 3465 3472 } 3466 3473 priv = scsi_cmd_priv(scmd);