Re: [PATCH v3 1/2] qla2xxx: Change in PUREX to handle FPIN ELS requests.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks for the review James, response inline.

> On Jun 25, 2020, at 4:38 PM, James Smart <james.smart@xxxxxxxxxxxx> wrote:
> 
> 
> 
> On 6/10/2020 7:15 AM, Nilesh Javali wrote:
>> From: Shyam Sundar <ssundar@xxxxxxxxxxx>
>> 
>> SAN Congestion Management generates ELS pkts whose size
>> can vary, and be > 64 bytes. Change the purex
>> handling code to support non standard ELS pkt size.
>> 
>> Signed-off-by: Shyam Sundar <ssundar@xxxxxxxxxxx>
>> Signed-off-by: Arun Easi <aeasi@xxxxxxxxxxx>
>> Signed-off-by: Nilesh Javali <njavali@xxxxxxxxxxx>
>> Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx>
>> ---
>>  drivers/scsi/qla2xxx/qla_def.h |  20 +++++-
>>  drivers/scsi/qla2xxx/qla_gbl.h |   3 +-
>>  drivers/scsi/qla2xxx/qla_isr.c | 116 ++++++++++++++++++++++++---------
>>  drivers/scsi/qla2xxx/qla_mbx.c |  22 +++++--
>>  drivers/scsi/qla2xxx/qla_os.c  |  19 ++++--
>>  include/uapi/scsi/fc/fc_els.h  |   1 +
>>  6 files changed, 139 insertions(+), 42 deletions(-)
>> 
>> diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
>> index 172ea4e5887d..2e058ac4fec7 100644
>> --- a/drivers/scsi/qla2xxx/qla_def.h
>> +++ b/drivers/scsi/qla2xxx/qla_def.h
>> @@ -34,6 +34,8 @@
>>  #include <scsi/scsi_transport_fc.h>
>>  #include <scsi/scsi_bsg_fc.h>
>>  +#include <uapi/scsi/fc/fc_els.h>
>> +
>>  /* Big endian Fibre Channel S_ID (source ID) or D_ID (destination ID). */
>>  typedef struct {
>>  	uint8_t domain;
>> @@ -1269,7 +1271,11 @@ static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
>>  #define RNID_TYPE_ASIC_TEMP	0xC
>>    #define ELS_CMD_MAP_SIZE	32
>> -#define ELS_COMMAND_RDP		0x18
>> +#define ELS_COMMAND_RDP		ELS_RDP
>> +/* Fabric Perf Impact Notification */
>> +#define ELS_COMMAND_FPIN	ELS_FPIN
>> +/* Read Diagnostic Functions */
>> +#define ELS_COMMAND_RDF		ELS_RDF
> 
> there shouldn't be a need for a new define for these. The native ELS_xxx define should be used.
Was doing this to maintain uniformity, but I see the point, will change this.
> 
>>    /*
>>   * Firmware state codes from get firmware state mailbox command
>> @@ -4487,10 +4493,19 @@ struct active_regions {
>>  #define QLA_SET_DATA_RATE_NOLR	1
>>  #define QLA_SET_DATA_RATE_LR	2 /* Set speed and initiate LR */
>>  +#define QLA_DEFAULT_PAYLOAD_SIZE	64
>> +/*
>> + * This item might be allocated with a size > sizeof(struct purex_item).
>> + * The "size" variable gives the size of the payload (which
>> + * is variable) starting at "iocb".
>> + */
>>  struct purex_item {
>>  	struct list_head list;
>>  	struct scsi_qla_host *vha;
>> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt);
>> +	void (*process_item)(struct scsi_qla_host *vha,
>> +			     struct purex_item *pkt);
>> +	atomic_t in_use;
>> +	uint16_t size;
>>  	struct {
>>  		uint8_t iocb[64];
>>  	} iocb;
>> @@ -4690,6 +4705,7 @@ typedef struct scsi_qla_host {
>>  		struct list_head head;
>>  		spinlock_t lock;
>>  	} purex_list;
>> +	struct purex_item default_item;
>>    	struct name_list_extended gnl;
>>  	/* Count of active session/fcport */
>> diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
>> index f62b71e47581..54d82f7d478f 100644
>> --- a/drivers/scsi/qla2xxx/qla_gbl.h
>> +++ b/drivers/scsi/qla2xxx/qla_gbl.h
>> @@ -229,7 +229,8 @@ void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
>>  int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
>>  int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
>>  void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
>> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt);
>> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
>> +			       struct purex_item *pkt);
>>    /*
>>   * Global Functions in qla_mid.c source file.
>> diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
>> index a9e8513e1cf1..401ce0023cd5 100644
>> --- a/drivers/scsi/qla2xxx/qla_isr.c
>> +++ b/drivers/scsi/qla2xxx/qla_isr.c
>> @@ -31,35 +31,11 @@ const char *const port_state_str[] = {
>>  	"ONLINE"
>>  };
>>  -static void qla24xx_purex_iocb(scsi_qla_host_t *vha, void *pkt,
>> -	void (*process_item)(struct scsi_qla_host *vha, void *pkt))
>> -{
>> -	struct purex_list *list = &vha->purex_list;
>> -	struct purex_item *item;
>> -	ulong flags;
>> -
>> -	item = kzalloc(sizeof(*item), GFP_KERNEL);
>> -	if (!item) {
>> -		ql_log(ql_log_warn, vha, 0x5092,
>> -		    ">> Failed allocate purex list item.\n");
>> -		return;
>> -	}
>> -
>> -	item->vha = vha;
>> -	item->process_item = process_item;
>> -	memcpy(&item->iocb, pkt, sizeof(item->iocb));
>> -
>> -	spin_lock_irqsave(&list->lock, flags);
>> -	list_add_tail(&item->list, &list->head);
>> -	spin_unlock_irqrestore(&list->lock, flags);
>> -
>> -	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
>> -}
>> -
>>  static void
>> -qla24xx_process_abts(struct scsi_qla_host *vha, void *pkt)
>> +qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt)
>>  {
>> -	struct abts_entry_24xx *abts = pkt;
>> +	struct abts_entry_24xx *abts =
>> +	    (struct abts_entry_24xx *)&pkt->iocb;
>>  	struct qla_hw_data *ha = vha->hw;
>>  	struct els_entry_24xx *rsp_els;
>>  	struct abts_entry_24xx *abts_rsp;
>> @@ -790,6 +766,76 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
>>  	}
>>  }
>>  +struct purex_item *
>> +qla24xx_alloc_purex_item(scsi_qla_host_t *vha, uint16_t size)
>> +{
>> +	struct purex_item *item = NULL;
>> +	uint8_t item_hdr_size = sizeof(*item);
>> +	uint8_t default_usable = 0;
>> +
>> +	if (size > QLA_DEFAULT_PAYLOAD_SIZE) {
>> +		item = kzalloc(item_hdr_size +
>> +		    (size - QLA_DEFAULT_PAYLOAD_SIZE), GFP_ATOMIC);
>> +	} else {
>> +		item = kzalloc(item_hdr_size, GFP_ATOMIC);
> I thought GFP_ATOMICs are looked down upon as a last resort. This is replacing code that used GFP_KERNEL.
The use of GFP_KERNEL was leading to a stack trace on some systems given that this is invoked thru the interrupt handler, hence the change. Given that the allocation is for a small size (64-128 bytes in general), and it has a short life, we went on to use the GFP_ATOMIC.
>> +		default_usable = 1;
>> +	}
>> +	if (!item) {
>> +		if (default_usable &&
>> +		    (atomic_inc_return(&vha->default_item.in_use) == 1)) {
>> +			item = &vha->default_item;
>> +			goto initialize_purex_header;
>> +		}
>> +		ql_log(ql_log_warn, vha, 0x5092,
>> +		       ">> Failed allocate purex list item.\n");
>> +
>> +		return NULL;
>> +	}
>> +
>> +initialize_purex_header:
>> +	item->vha = vha;
>> +	item->size = size;
>> +	return item;
>> +}
>> +
>> +static void
>> +qla24xx_queue_purex_item(scsi_qla_host_t *vha, struct purex_item *pkt,
>> +			 void (*process_item)(struct scsi_qla_host *vha,
>> +					      struct purex_item *pkt))
>> +{
>> +	struct purex_list *list = &vha->purex_list;
>> +	ulong flags;
>> +
>> +	pkt->process_item = process_item;
>> +
>> +	spin_lock_irqsave(&list->lock, flags);
>> +	list_add_tail(&pkt->list, &list->head);
>> +	spin_unlock_irqrestore(&list->lock, flags);
>> +
>> +	set_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags);
>> +}
>> +
>> +/**
>> + * qla24xx_copy_std_pkt() - Copy over purex ELS which is
>> + * contained in a single IOCB.
>> + * purex packet.
>> + * @vha: SCSI driver HA context
>> + * @pkt: ELS packet
>> + */
>> +struct purex_item
>> +*qla24xx_copy_std_pkt(struct scsi_qla_host *vha, void *pkt)
>> +{
>> +	struct purex_item *item;
>> +
>> +	item = qla24xx_alloc_purex_item(vha,
>> +					QLA_DEFAULT_PAYLOAD_SIZE);
>> +	if (!item)
>> +		return item;
>> +
>> +	memcpy(&item->iocb, pkt, sizeof(item->iocb));
>> +	return item;
>> +}
>> +
>>  /**
>>   * qla2x00_async_event() - Process aynchronous events.
>>   * @vha: SCSI driver HA context
>> @@ -3233,6 +3279,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>>  {
>>  	struct sts_entry_24xx *pkt;
>>  	struct qla_hw_data *ha = vha->hw;
>> +	struct purex_item *pure_item;
>>    	if (!ha->flags.fw_started)
>>  		return;
>> @@ -3284,8 +3331,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>>  			break;
>>  		case ABTS_RECV_24XX:
>>  			if (qla_ini_mode_enabled(vha)) {
>> -				qla24xx_purex_iocb(vha, pkt,
>> -				    qla24xx_process_abts);
>> +				pure_item = qla24xx_copy_std_pkt(vha, pkt);
>> +				if (!pure_item)
>> +					break;
>> +
>> +				qla24xx_queue_purex_item(vha, pure_item,
>> +							 qla24xx_process_abts);
>>  				break;
>>  			}
>>  			if (IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
>> @@ -3342,7 +3393,12 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
>>  				    purex->els_frame_payload[3]);
>>  				break;
>>  			}
>> -			qla24xx_purex_iocb(vha, pkt, qla24xx_process_purex_rdp);
>> +			pure_item = qla24xx_copy_std_pkt(vha, pkt);
>> +			if (!pure_item)
>> +				break;
>> +
>> +			qla24xx_queue_purex_item(vha, pure_item,
>> +						 qla24xx_process_purex_rdp);
>>  			break;
>>  		}
>>  		default:
>> diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
>> index 9fd83d1bffe0..a1f899bb8c94 100644
>> --- a/drivers/scsi/qla2xxx/qla_mbx.c
>> +++ b/drivers/scsi/qla2xxx/qla_mbx.c
>> @@ -59,6 +59,7 @@ static struct rom_cmd {
>>  	{ MBC_IOCB_COMMAND_A64 },
>>  	{ MBC_GET_ADAPTER_LOOP_ID },
>>  	{ MBC_READ_SFP },
>> +	{ MBC_SET_RNID_PARAMS },
>>  	{ MBC_GET_RNID_PARAMS },
>>  	{ MBC_GET_SET_ZIO_THRESHOLD },
>>  };
>> @@ -4867,6 +4868,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
>>  	return rval;
>>  }
>>  +#define PUREX_CMD_COUNT	2
>>  int
>>  qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>  {
>> @@ -4875,12 +4877,12 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>  	mbx_cmd_t *mcp = &mc;
>>  	uint8_t *els_cmd_map;
>>  	dma_addr_t els_cmd_map_dma;
>> -	uint cmd_opcode = ELS_COMMAND_RDP;
>> -	uint index = cmd_opcode / 8;
>> -	uint bit = cmd_opcode % 8;
>> +	uint cmd_opcode[PUREX_CMD_COUNT];
>> +	uint i, index, purex_bit;
>>  	struct qla_hw_data *ha = vha->hw;
>>  -	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) && !IS_QLA27XX(ha))
>> +	if (!IS_QLA25XX(ha) && !IS_QLA2031(ha) &&
>> +	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
>>  		return QLA_SUCCESS;
>>    	ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1197,
>> @@ -4896,7 +4898,17 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha)
>>    	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
>>  -	els_cmd_map[index] |= 1 << bit;
>> +	memset(els_cmd_map, 0, ELS_CMD_MAP_SIZE);
>> +
>> +	/* List of Purex ELS */
>> +	cmd_opcode[0] = ELS_COMMAND_FPIN;
>> +	cmd_opcode[1] = ELS_COMMAND_RDP;
> need to deal with endianness on this assigment ?   8bit values going into a uint ?
Agree, will address.
>> +
>> +	for (i = 0; i < PUREX_CMD_COUNT; i++) {
>> +		index = cmd_opcode[i] / 8;
>> +		purex_bit = cmd_opcode[i] % 8;
>> +		els_cmd_map[index] |= 1 << purex_bit;
>> +	}
>>    	mcp->mb[0] = MBC_SET_RNID_PARAMS;
>>  	mcp->mb[1] = RNID_TYPE_ELS_CMD << 8;
>> diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
>> index 382e1f977d01..007f39128dbf 100644
>> --- a/drivers/scsi/qla2xxx/qla_os.c
>> +++ b/drivers/scsi/qla2xxx/qla_os.c
>> @@ -5891,10 +5891,12 @@ qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha)
>>   * vha:	SCSI qla host
>>   * purex: RDP request received by HBA
>>   */
>> -void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
>> +void qla24xx_process_purex_rdp(struct scsi_qla_host *vha,
>> +			       struct purex_item *item)
>>  {
>>  	struct qla_hw_data *ha = vha->hw;
>> -	struct purex_entry_24xx *purex = pkt;
>> +	struct purex_entry_24xx *purex =
>> +	    (struct purex_entry_24xx *)&item->iocb;
>>  	dma_addr_t rsp_els_dma;
>>  	dma_addr_t rsp_payload_dma;
>>  	dma_addr_t stat_dma;
>> @@ -6304,6 +6306,15 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, void *pkt)
>>  		    rsp_els, rsp_els_dma);
>>  }
>>  +void
>> +qla24xx_free_purex_item(struct purex_item *item)
>> +{
>> +	if (item == &item->vha->default_item)
>> +		memset(&item->vha->default_item, 0, sizeof(struct purex_item));
>> +	else
>> +		kfree(item);
>> +}
>> +
>>  void qla24xx_process_purex_list(struct purex_list *list)
>>  {
>>  	struct list_head head = LIST_HEAD_INIT(head);
>> @@ -6316,8 +6327,8 @@ void qla24xx_process_purex_list(struct purex_list *list)
>>    	list_for_each_entry_safe(item, next, &head, list) {
>>  		list_del(&item->list);
>> -		item->process_item(item->vha, &item->iocb);
>> -		kfree(item);
>> +		item->process_item(item->vha, item);
>> +		qla24xx_free_purex_item(item);
>>  	}
>>  }
>>  diff --git a/include/uapi/scsi/fc/fc_els.h b/include/uapi/scsi/fc/fc_els.h
>> index 66318c44acd7..cb7ffc37c4f9 100644
>> --- a/include/uapi/scsi/fc/fc_els.h
>> +++ b/include/uapi/scsi/fc/fc_els.h
>> @@ -41,6 +41,7 @@ enum fc_els_cmd {
>>  	ELS_REC =	0x13,	/* read exchange concise */
>>  	ELS_SRR =	0x14,	/* sequence retransmission request */
>>  	ELS_FPIN =	0x16,	/* Fabric Performance Impact Notification */
>> +	ELS_RDP =	0x18,	/* Read Diagnostic Parameters */
>>  	ELS_RDF =	0x19,	/* Register Diagnostic Functions */
>>  	ELS_PRLI =	0x20,	/* process login */
>>  	ELS_PRLO =	0x21,	/* process logout */
> you're missing the :
>   [ELS_RDP] =    "RDP",                 \
> 
> line in the respective location of FC_ELS_CMDS_INIT
Agree, will address.
> 
> -- james





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux