Commit adb25343 authored by Rasmus Villemoes's avatar Rasmus Villemoes Committed by Martin K. Petersen

scsi: bnx2i: Make bnx2i_process_iscsi_error() simpler and more robust

Instead of strcpy'ing into a stack buffer, just let additional_notice point
to a string literal living in .rodata. This is better in a few ways:

 - Smaller .text - instead of gcc compiling the strcpys as a bunch of
   immediate stores (effectively encoding the string literal in the
   instruction stream), we only pay the price of storing the literal in
   .rodata.

 - Faster, because there's no string copying.

 - Smaller stack usage (with my compiler, 72 bytes instead of 176 for the
   sole caller, bnx2i_indicate_kcqe)

Moreover, it's currently possible for additional_notice[] to get used
uninitialized, so some random stack garbage would be passed to printk() -
in the worst case without any '\0' anywhere in those 64 bytes. That could
be fixed by initializing additional_notice[0], but the same is achieved
here by initializing the new pointer variable to "".

Also give the message pointer a similar treatment - there's no point making
temporary copies on the stack of those two strings.

Link: https://lore.kernel.org/r/20210310221602.2494422-1-linux@rasmusvillemoes.dkSigned-off-by: default avatarRasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent be20b96b
...@@ -2206,10 +2206,8 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba, ...@@ -2206,10 +2206,8 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba,
{ {
struct bnx2i_conn *bnx2i_conn; struct bnx2i_conn *bnx2i_conn;
u32 iscsi_cid; u32 iscsi_cid;
char warn_notice[] = "iscsi_warning"; const char *additional_notice = "";
char error_notice[] = "iscsi_error"; const char *message;
char additional_notice[64];
char *message;
int need_recovery; int need_recovery;
u64 err_mask64; u64 err_mask64;
...@@ -2224,133 +2222,132 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba, ...@@ -2224,133 +2222,132 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba,
if (err_mask64 & iscsi_error_mask) { if (err_mask64 & iscsi_error_mask) {
need_recovery = 0; need_recovery = 0;
message = warn_notice; message = "iscsi_warning";
} else { } else {
need_recovery = 1; need_recovery = 1;
message = error_notice; message = "iscsi_error";
} }
switch (iscsi_err->completion_status) { switch (iscsi_err->completion_status) {
case ISCSI_KCQE_COMPLETION_STATUS_HDR_DIG_ERR: case ISCSI_KCQE_COMPLETION_STATUS_HDR_DIG_ERR:
strcpy(additional_notice, "hdr digest err"); additional_notice = "hdr digest err";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_DATA_DIG_ERR: case ISCSI_KCQE_COMPLETION_STATUS_DATA_DIG_ERR:
strcpy(additional_notice, "data digest err"); additional_notice = "data digest err";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_OPCODE: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_OPCODE:
strcpy(additional_notice, "wrong opcode rcvd"); additional_notice = "wrong opcode rcvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_AHS_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_AHS_LEN:
strcpy(additional_notice, "AHS len > 0 rcvd"); additional_notice = "AHS len > 0 rcvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ITT: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ITT:
strcpy(additional_notice, "invalid ITT rcvd"); additional_notice = "invalid ITT rcvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_STATSN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_STATSN:
strcpy(additional_notice, "wrong StatSN rcvd"); additional_notice = "wrong StatSN rcvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN:
strcpy(additional_notice, "wrong DataSN rcvd"); additional_notice = "wrong DataSN rcvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T:
strcpy(additional_notice, "pend R2T violation"); additional_notice = "pend R2T violation";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_0: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_0:
strcpy(additional_notice, "ERL0, UO"); additional_notice = "ERL0, UO";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_1: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_1:
strcpy(additional_notice, "ERL0, U1"); additional_notice = "ERL0, U1";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_2: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_2:
strcpy(additional_notice, "ERL0, U2"); additional_notice = "ERL0, U2";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_3: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_3:
strcpy(additional_notice, "ERL0, U3"); additional_notice = "ERL0, U3";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_4: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_4:
strcpy(additional_notice, "ERL0, U4"); additional_notice = "ERL0, U4";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_5: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_5:
strcpy(additional_notice, "ERL0, U5"); additional_notice = "ERL0, U5";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_6: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_6:
strcpy(additional_notice, "ERL0, U6"); additional_notice = "ERL0, U6";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_RCV_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_RCV_LEN:
strcpy(additional_notice, "invalid resi len"); additional_notice = "invalid resi len";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_RCV_PDU_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_RCV_PDU_LEN:
strcpy(additional_notice, "MRDSL violation"); additional_notice = "MRDSL violation";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_F_BIT_ZERO: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_F_BIT_ZERO:
strcpy(additional_notice, "F-bit not set"); additional_notice = "F-bit not set";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_NOT_RSRV: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_NOT_RSRV:
strcpy(additional_notice, "invalid TTT"); additional_notice = "invalid TTT";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATASN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATASN:
strcpy(additional_notice, "invalid DataSN"); additional_notice = "invalid DataSN";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_BURST_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_BURST_LEN:
strcpy(additional_notice, "burst len violation"); additional_notice = "burst len violation";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_BUFFER_OFF: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_BUFFER_OFF:
strcpy(additional_notice, "buf offset violation"); additional_notice = "buf offset violation";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN:
strcpy(additional_notice, "invalid LUN field"); additional_notice = "invalid LUN field";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_R2TSN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_R2TSN:
strcpy(additional_notice, "invalid R2TSN field"); additional_notice = "invalid R2TSN field";
break; break;
#define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0 \ #define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0 \
ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_0 ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_0
case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0: case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0:
strcpy(additional_notice, "invalid cmd len1"); additional_notice = "invalid cmd len1";
break; break;
#define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1 \ #define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1 \
ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_1 ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_1
case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1: case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1:
strcpy(additional_notice, "invalid cmd len2"); additional_notice = "invalid cmd len2";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_EXCEED: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_EXCEED:
strcpy(additional_notice, additional_notice = "pend r2t exceeds MaxOutstandingR2T value";
"pend r2t exceeds MaxOutstandingR2T value");
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_IS_RSRV: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_IS_RSRV:
strcpy(additional_notice, "TTT is rsvd"); additional_notice = "TTT is rsvd";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_BURST_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_BURST_LEN:
strcpy(additional_notice, "MBL violation"); additional_notice = "MBL violation";
break; break;
#define BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO \ #define BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO \
ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATA_SEG_LEN_NOT_ZERO ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATA_SEG_LEN_NOT_ZERO
case BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO: case BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO:
strcpy(additional_notice, "data seg len != 0"); additional_notice = "data seg len != 0";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REJECT_PDU_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REJECT_PDU_LEN:
strcpy(additional_notice, "reject pdu len error"); additional_notice = "reject pdu len error";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ASYNC_PDU_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ASYNC_PDU_LEN:
strcpy(additional_notice, "async pdu len error"); additional_notice = "async pdu len error";
break; break;
case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_NOPIN_PDU_LEN: case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_NOPIN_PDU_LEN:
strcpy(additional_notice, "nopin pdu len error"); additional_notice = "nopin pdu len error";
break; break;
#define BNX2_ERR_PEND_R2T_IN_CLEANUP \ #define BNX2_ERR_PEND_R2T_IN_CLEANUP \
ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_IN_CLEANUP ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_IN_CLEANUP
case BNX2_ERR_PEND_R2T_IN_CLEANUP: case BNX2_ERR_PEND_R2T_IN_CLEANUP:
strcpy(additional_notice, "pend r2t in cleanup"); additional_notice = "pend r2t in cleanup";
break; break;
case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_FRAGMENT: case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_FRAGMENT:
strcpy(additional_notice, "IP fragments rcvd"); additional_notice = "IP fragments rcvd";
break; break;
case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_OPTIONS: case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_OPTIONS:
strcpy(additional_notice, "IP options error"); additional_notice = "IP options error";
break; break;
case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_URGENT_FLAG: case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_URGENT_FLAG:
strcpy(additional_notice, "urgent flag error"); additional_notice = "urgent flag error";
break; break;
default: default:
printk(KERN_ALERT "iscsi_err - unknown err %x\n", printk(KERN_ALERT "iscsi_err - unknown err %x\n",
......
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