[PATCH 3/7] be2iscsi : Fix IRQ_Affinity support in driver.

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

 



  Provides IRQ_Affinity setting for the driver. Enabling IRQ_Affinity
  is through  module params. Default IRQ_AFFINITY  support is OFF.

Signed-off-by: John Soni Jose <sony.john-n@xxxxxxxxxx>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@xxxxxxxxxx>
---
 drivers/scsi/be2iscsi/be_cmds.h |    9 +++-
 drivers/scsi/be2iscsi/be_main.c |   97 +++++++++++++++++++++++++++++++++++++--
 drivers/scsi/be2iscsi/be_main.h |   22 +++++++--
 drivers/scsi/be2iscsi/be_mgmt.c |   63 +++++++++++++++++++++++--
 drivers/scsi/be2iscsi/be_mgmt.h |   49 ++++++++++++++++++--
 5 files changed, 222 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 770b6c8..69f849e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -174,6 +174,7 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_EQ_DESTROY			55
 #define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG		58
 #define OPCODE_COMMON_FUNCTION_RESET			61
+#define OPCODE_COMMON_GET_CNTL_ADV_ATTRIB		121
 
 /**
  * LIST of opcodes that are common between Initiator and Target
@@ -197,6 +198,8 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_ISCSI_WRBQ_CREATE			66
 #define OPCODE_COMMON_ISCSI_WRBQ_DESTROY		67
 
+#define MBOX_CMD_V2					0x01
+
 struct be_cmd_req_hdr {
 	u8 opcode;		/* dword 0 */
 	u8 subsystem;		/* dword 0 */
@@ -966,6 +969,9 @@ struct amap_it_dmsg_cqe_v2 {
 #define DB_DEF_PDU_WRB_INDEX_SHIFT	16
 #define DB_DEF_PDU_NUM_POSTED_SHIFT	24
 
+#define BEISCSI_IFD_STATE_DISABLE      0x0
+#define BEISCSI_IFD_STATE_ENABLE       0x1
+
 struct fragnum_bits_for_sgl_cra_in {
 	struct be_cmd_req_hdr hdr;
 	u32 num_bits;
@@ -1002,7 +1008,8 @@ struct tcp_connect_and_offload_in {
 	u16 hdr_ring_id;
 	u16 data_ring_id;
 	u8 do_offload;
-	u8 rsvd0[3];
+	u8 ifd_state;
+	u8 rsvd0[2];
 } __packed;
 
 struct tcp_connect_and_offload_out {
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 1a1729b..89bf558 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -47,6 +47,7 @@
 static unsigned int be_iopoll_budget = 10;
 static unsigned int be_max_phys_size = 64;
 static unsigned int enable_msix = 1;
+static unsigned int beiscsi_irq_affinity_enable;
 
 MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
 MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
@@ -59,6 +60,7 @@ module_param(be_max_phys_size, uint, S_IRUGO);
 MODULE_PARM_DESC(be_max_phys_size,
 		"Maximum Size (In Kilobytes) of physically contiguous "
 		"memory that can be allocated. Range is 16 - 128");
+module_param(beiscsi_irq_affinity_enable, uint, 0);
 
 #define beiscsi_disp_param(_name)\
 ssize_t	\
@@ -1026,6 +1028,46 @@ static irqreturn_t be_isr(int irq, void *dev_id)
 	}
 }
 
+static void beiscsi_set_irq_affinity_params(struct beiscsi_hba *phba,
+		uint16_t cpu_index, uint16_t eqcq_index, uint16_t msix_vec)
+{
+	struct hwi_controller *phwi_ctrlr;
+	struct hwi_context_memory *phwi_context;
+
+	phwi_ctrlr = phba->phwi_ctrlr;
+	phwi_context = phwi_ctrlr->phwi_ctxt;
+
+	if (msix_vec) {
+		if (cpu_online(cpu_index))
+			cpumask_set_cpu(cpu_index,
+					&phba->msix_cpu_map[
+					cpu_index].affinity_mask);
+		else
+			cpumask_copy(&phba->msix_cpu_map[
+				     cpu_index].affinity_mask,
+				     cpu_online_mask);
+
+		phba->msix_cpu_map[cpu_index].eq_id =
+			phwi_context->be_eq[eqcq_index].q.id;
+		phba->msix_cpu_map[cpu_index].cq_id =
+			phwi_context->be_cq[eqcq_index].id;
+		phba->msix_cpu_map[cpu_index].cpu_id = cpu_index;
+		phba->msix_cpu_map[cpu_index].nvec = msix_vec;
+		phba->msix_cpu_map[cpu_index].node_id =
+			cpu_to_node(cpu_index);
+
+		irq_set_affinity_hint(msix_vec,
+				      &phba->msix_cpu_map[
+				      cpu_index].affinity_mask);
+	} else {
+		phba->msix_cpu_map[cpu_index].eq_id =
+			phba->msix_cpu_map[eqcq_index].eq_id;
+		phba->msix_cpu_map[cpu_index].cq_id =
+			phba->msix_cpu_map[eqcq_index].cq_id;
+		phba->msix_cpu_map[cpu_index].cpu_id = cpu_index;
+	}
+}
+
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
 	struct pci_dev *pcidev = phba->pcidev;
@@ -1059,7 +1101,11 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 				kfree(phba->msi_name[i]);
 				goto free_msix_irqs;
 			}
+			if (beiscsi_irq_affinity_enable)
+				beiscsi_set_irq_affinity_params(phba,
+								i, i, msix_vec);
 		}
+
 		phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME, GFP_KERNEL);
 		if (!phba->msi_name[i]) {
 			ret = -ENOMEM;
@@ -1078,6 +1124,12 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 			goto free_msix_irqs;
 		}
 
+		if (beiscsi_irq_affinity_enable) {
+			j = i;
+			while (i++ < num_online_cpus())
+				beiscsi_set_irq_affinity_params(phba,
+								i, (i - j), 0);
+		}
 	} else {
 		ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED,
 				  "beiscsi", phba);
@@ -4663,10 +4715,9 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
 
 	/* Check for the adapter family */
 	if (is_chip_be2_be3r(phba))
-		beiscsi_offload_cxn_v0(params, pwrb_handle,
-				       phba->init_mem);
+		beiscsi_offload_cxn_v0(phba, params, pwrb_handle);
 	else
-		beiscsi_offload_cxn_v2(params, pwrb_handle);
+		beiscsi_offload_cxn_v2(phba, params, pwrb_handle);
 
 	be_dws_le_to_cpu(pwrb_handle->pwrb,
 			 sizeof(struct iscsi_target_context_update_wrb));
@@ -4860,6 +4911,8 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg,
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
 	struct iscsi_wrb *pwrb = NULL;
 	unsigned int doorbell = 0;
+	uint8_t cpu_num;
+	u8 cq_num;
 
 	pwrb = io_task->pwrb_handle->pwrb;
 
@@ -4891,6 +4944,13 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg,
 		      io_task->psgl_handle->sgl_index);
 
 	hwi_write_sgl_v2(pwrb, sg, num_sg, io_task);
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP) {
+		cpu_num = get_cpu();
+		cq_num = phba->msix_cpu_map[cpu_num].cq_id;
+		AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cq_id, pwrb, cq_num);
+		put_cpu();
+	}
+
 	AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb,
 		      io_task->pwrb_handle->nxt_wrb_index);
 
@@ -4917,6 +4977,7 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
 	struct iscsi_wrb *pwrb = NULL;
 	unsigned int doorbell = 0;
+	uint8_t cpu_num, cq_num;
 
 	pwrb = io_task->pwrb_handle->pwrb;
 	io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
@@ -4948,6 +5009,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
 
 	hwi_write_sgl(pwrb, sg, num_sg, io_task);
 
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP) {
+		cpu_num = get_cpu();
+		cq_num = phba->msix_cpu_map[cpu_num].cq_id;
+		AMAP_SET_BITS(struct amap_iscsi_wrb, cq_id, pwrb, cq_num);
+		put_cpu();
+	}
+
 	AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
 		      io_task->pwrb_handle->nxt_wrb_index);
 	be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
@@ -4972,6 +5040,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
 	unsigned int doorbell = 0;
 	unsigned int cid;
 	unsigned int pwrb_typeoffset = 0;
+	uint8_t cpu_num, cq_num;
 
 	cid = beiscsi_conn->beiscsi_conn_cid;
 	pwrb = io_task->pwrb_handle->pwrb;
@@ -5003,6 +5072,19 @@ static int beiscsi_mtask(struct iscsi_task *task)
 		pwrb_typeoffset = SKH_WRB_TYPE_OFFSET;
 	}
 
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP) {
+		cpu_num = get_cpu();
+		cq_num = phba->msix_cpu_map[cpu_num].cq_id;
+
+		if (is_chip_be2_be3r(phba))
+			AMAP_SET_BITS(struct amap_iscsi_wrb,
+				      cq_id, pwrb, cq_num);
+		else
+			AMAP_SET_BITS(struct amap_iscsi_wrb_v2,
+				      cq_id, pwrb, cq_num);
+		put_cpu();
+	}
+
 
 	switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
 	case ISCSI_OP_LOGIN:
@@ -5587,6 +5669,15 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
 			phba->num_cpus = 1;
 	}
 
+
+	if (beiscsi_irq_affinity_enable) {
+		if (mgmt_get_adapter_caps(phba))
+			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+				    "BM_%d : Error in getting Capabilites"
+				    "IRQ_Affinity setting is disabled\n");
+	} else
+		phba->func_caps = BEISCSI_IFD_STATE_DISABLE;
+
 	phba->shost->max_id = phba->params.cxns_per_ctrl;
 	beiscsi_get_params(phba);
 	phba->shost->can_queue = phba->params.ios_per_ctrl;
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 31fa27b..0076119 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -234,6 +234,15 @@ struct sgl_handle {
 	struct iscsi_sge *pfrag;
 };
 
+struct msix_vec_map {
+	 cpumask_t affinity_mask;
+	u16     eq_id;
+	u16     cq_id;
+	u32     nvec;
+	unsigned int cpu_id;
+	unsigned int node_id;
+};
+
 struct hba_parameters {
 	unsigned int ios_per_ctrl;
 	unsigned int cxns_per_ctrl;
@@ -412,12 +421,13 @@ struct beiscsi_hba {
 	unsigned int interface_handle;
 	struct mgmt_session_info boot_sess;
 	struct invalidate_command_table inv_tbl[128];
-
+	struct msix_vec_map msix_cpu_map[MAX_CPUS];
 	unsigned int attr_log_enable;
 	int (*iotask_fn)(struct iscsi_task *,
 			struct scatterlist *sg,
 			uint32_t num_sg, uint32_t xferlen,
 			uint32_t writedir);
+	uint32_t func_caps;
 };
 
 struct beiscsi_session {
@@ -479,20 +489,21 @@ struct be_cmd_bhs {
 
 struct beiscsi_io_task {
 	struct wrb_handle *pwrb_handle;
+	struct be_cmd_bhs *cmd_bhs;
+	unsigned short bhs_len;
 	struct sgl_handle *psgl_handle;
+	struct hwi_wrb_context *pwrb_context;
 	struct beiscsi_conn *conn;
 	struct scsi_cmnd *scsi_cmnd;
+	uint8_t wrb_type;
 	unsigned int cmd_sn;
 	unsigned int flags;
 	unsigned short cid;
 	unsigned short header_len;
 	itt_t libiscsi_itt;
-	struct be_cmd_bhs *cmd_bhs;
 	struct be_bus_address bhs_pa;
-	unsigned short bhs_len;
 	dma_addr_t mtask_addr;
 	uint32_t mtask_data_count;
-	uint8_t wrb_type;
 };
 
 struct be_nonio_bhs {
@@ -745,7 +756,8 @@ struct amap_iscsi_wrb {
 	u8 ptr2nextwrb[8];	/* DWORD 1 */
 	u8 r2t_exp_dtl[24];	/* DWORD 1 */
 	u8 sgl_icd_idx[12];	/* DWORD 2 */
-	u8 rsvd0[20];		/* DWORD 2 */
+	u8 cq_id[10];		/* DWORD 2 */
+	u8 rsvd0[10];		/* DWORD 2 */
 	u8 exp_data_sn[32];	/* DWORD 3 */
 	u8 iscsi_bhs_addr_hi[32];	/* DWORD 4 */
 	u8 iscsi_bhs_addr_lo[32];	/* DWORD 5 */
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 088bdf7..1b6c3fb 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -758,11 +758,47 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd->size);
+
+	/* Enable interrupt redirection for CXN */
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP)
+		req->ifd_state = BEISCSI_IFD_STATE_ENABLE;
+
 	be_mcc_notify(phba);
 	spin_unlock(&ctrl->mbox_lock);
 	return tag;
 }
 
+int mgmt_get_adapter_caps(struct beiscsi_hba *phba)
+{
+	struct be_ctrl_info *ctrl = &phba->ctrl;
+	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
+	struct be_mgmt_cntl_additional_attrib *req = embedded_payload(wrb);
+	int status = 0;
+
+	spin_lock(&ctrl->mbox_lock);
+	memset(wrb, 0, sizeof(*wrb));
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			   OPCODE_COMMON_GET_CNTL_ADV_ATTRIB,
+			   sizeof(*req));
+	status = be_mbox_notify(ctrl);
+
+	if (status) {
+		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
+			    "BG_%d : Failed in mgmt_get_adapter_caps\n");
+		spin_unlock(&ctrl->mbox_lock);
+		phba->func_caps = BEISCSI_IFD_STATE_DISABLE;
+		return status;
+	}
+
+	phba->func_caps = req->params.func_caps;
+	spin_unlock(&ctrl->mbox_lock);
+	return status;
+}
+
+
+
 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
 {
 	struct be_ctrl_info *ctrl = &phba->ctrl;
@@ -1525,11 +1561,13 @@ beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
 			phba->fw_config.phys_port);
 }
 
-void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
-			     struct wrb_handle *pwrb_handle,
-			     struct be_mem_descriptor *mem_descr)
+void beiscsi_offload_cxn_v0(struct beiscsi_hba *phba,
+			     struct beiscsi_offload_params *params,
+			     struct wrb_handle *pwrb_handle)
 {
 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
+	struct be_mem_descriptor *mem_descr = phba->init_mem;
+	uint8_t cpu_num, cq_num;
 
 	memset(pwrb, 0, sizeof(*pwrb));
 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
@@ -1588,12 +1626,21 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
 		      pad_buffer_addr_lo, pwrb,
 		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
+
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP) {
+		cpu_num = get_cpu();
+		cq_num = phba->msix_cpu_map[cpu_num].cq_id;
+		AMAP_SET_BITS(struct amap_iscsi_wrb, cq_id, pwrb, cq_num);
+		put_cpu();
+	}
 }
 
-void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
+void beiscsi_offload_cxn_v2(struct beiscsi_hba *phba,
+			     struct beiscsi_offload_params *params,
 			     struct wrb_handle *pwrb_handle)
 {
 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
+	uint8_t cpu_num, cq_num;
 
 	memset(pwrb, 0, sizeof(*pwrb));
 
@@ -1660,4 +1707,12 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
 		      pwrb,
 		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
 		      exp_statsn) / 32] + 1));
+
+	if (phba->func_caps & BE_ADAPTER_IFD_CAP) {
+		cpu_num = get_cpu();
+		cq_num = phba->msix_cpu_map[cpu_num].cq_id;
+		AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cq_id, pwrb, cq_num);
+		put_cpu();
+	}
+
 }
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 01b8c97..e1dd796 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -221,6 +221,41 @@ struct be_mgmt_controller_attributes_resp {
 	struct mgmt_controller_attributes params;
 } __packed;
 
+#define BE_ADAPTER_IFD_CAP     0x01
+struct mgmt_cntrl_additional_attrib {
+	u16 ipl_file_number;
+	u8 ipl_file_version;
+	u8 rsvd0;
+	u8 on_die_temp;
+	u8 rsvd1[3];
+	u32 func_caps;
+	u32 rsvd2[4];
+	u8 fcoe_universal_bios_version[32];
+	u8 fcoe_x86_bios_version[32];
+	u8 fcoe_efi_bios_version[32];
+	u8 fcoe_fcode_version[32];
+	u8 uefi_bios_version[32];
+	u8 uefi_nic_version[32];
+	u8 uefi_fcode_version[32];
+	u8 uefi_iscsi_version[32];
+	u8 iscsi_x86_bios_version[32];
+	u8 pxe_x86_bios_version[32];
+	u8 fcoe_default_wwpn[8];
+	u8 ext_phy_version[32];
+	u8 fc_universal_bios_version[32];
+	u8 fc_x86_bios_version[32];
+	u8 fc_efi_bios_version[32];
+	u8 fc_fcode_version[32];
+	u8 ext_phy_crc_label[8];
+	u8 rsvd3[88];
+} __packed;
+
+struct be_mgmt_cntl_additional_attrib {
+	struct be_cmd_req_hdr hdr;
+	struct mgmt_cntrl_additional_attrib params;
+} __packed;
+
+
 struct be_bsg_vendor_cmd {
 	struct be_cmd_req_hdr hdr;
 	unsigned short region;
@@ -269,6 +304,8 @@ struct beiscsi_endpoint {
 int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
 				 struct beiscsi_hba *phba);
 
+int mgmt_get_adapter_caps(struct beiscsi_hba *phba);
+
 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
 					 struct beiscsi_endpoint *beiscsi_ep,
 					 unsigned short cid,
@@ -328,12 +365,14 @@ ssize_t beiscsi_free_session_disp(struct device *dev,
 ssize_t beiscsi_phys_port_disp(struct device *dev,
 				struct device_attribute *attr, char *buf);
 
-void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
-			     struct wrb_handle *pwrb_handle,
-			     struct be_mem_descriptor *mem_descr);
-
-void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
+void beiscsi_offload_cxn_v0(struct beiscsi_hba *phba,
+			     struct beiscsi_offload_params *params,
 			     struct wrb_handle *pwrb_handle);
+
+void beiscsi_offload_cxn_v2(struct beiscsi_hba *phba,
+			    struct beiscsi_offload_params *params,
+			    struct wrb_handle *pwrb_handle);
+
 void beiscsi_ue_detect(struct beiscsi_hba *phba);
 
 #endif
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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