Commit c2462288 authored by Jayamohan Kallickal's avatar Jayamohan Kallickal Committed by James Bottomley

[SCSI] be2iscsi: Move freeing of resources to stop_conn

We need to hold on to ep resources untill invalidate and
  close connection are completed
Signed-off-by: default avatarJayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 7da50879
...@@ -460,14 +460,12 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) ...@@ -460,14 +460,12 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
* beiscsi_free_ep - free endpoint * beiscsi_free_ep - free endpoint
* @ep: pointer to iscsi endpoint structure * @ep: pointer to iscsi endpoint structure
*/ */
static void beiscsi_free_ep(struct iscsi_endpoint *ep) static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
{ {
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
struct beiscsi_hba *phba = beiscsi_ep->phba; struct beiscsi_hba *phba = beiscsi_ep->phba;
beiscsi_put_cid(phba, beiscsi_ep->ep_cid); beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
beiscsi_ep->phba = NULL; beiscsi_ep->phba = NULL;
iscsi_destroy_endpoint(ep);
} }
/** /**
...@@ -498,7 +496,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, ...@@ -498,7 +496,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
if (phba->state) { if (phba->state) {
ret = -EBUSY; ret = -EBUSY;
SE_DEBUG(DBG_LVL_1, "The Adapet state is Not UP \n"); SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP \n");
return ERR_PTR(ret); return ERR_PTR(ret);
} }
...@@ -510,9 +508,10 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, ...@@ -510,9 +508,10 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
beiscsi_ep = ep->dd_data; beiscsi_ep = ep->dd_data;
beiscsi_ep->phba = phba; beiscsi_ep->phba = phba;
beiscsi_ep->openiscsi_ep = ep;
if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) { if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n"); SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn \n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_ep; goto free_ep;
} }
...@@ -520,7 +519,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, ...@@ -520,7 +519,7 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
return ep; return ep;
free_ep: free_ep:
beiscsi_free_ep(ep); beiscsi_free_ep(beiscsi_ep);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
...@@ -547,15 +546,14 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) ...@@ -547,15 +546,14 @@ int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
* @ep: The iscsi endpoint * @ep: The iscsi endpoint
* @flag: The type of connection closure * @flag: The type of connection closure
*/ */
static int beiscsi_close_conn(struct iscsi_endpoint *ep, int flag) static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
{ {
int ret = 0; int ret = 0;
struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
struct beiscsi_hba *phba = beiscsi_ep->phba; struct beiscsi_hba *phba = beiscsi_ep->phba;
if (MGMT_STATUS_SUCCESS != if (MGMT_STATUS_SUCCESS !=
mgmt_upload_connection(phba, beiscsi_ep->ep_cid, mgmt_upload_connection(phba, beiscsi_ep->ep_cid,
CONNECTION_UPLOAD_GRACEFUL)) { flag)) {
SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x", SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
beiscsi_ep->ep_cid); beiscsi_ep->ep_cid);
ret = -1; ret = -1;
...@@ -575,19 +573,15 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) ...@@ -575,19 +573,15 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
struct beiscsi_conn *beiscsi_conn; struct beiscsi_conn *beiscsi_conn;
struct beiscsi_endpoint *beiscsi_ep; struct beiscsi_endpoint *beiscsi_ep;
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
int flag = 0;
beiscsi_ep = ep->dd_data; beiscsi_ep = ep->dd_data;
phba = beiscsi_ep->phba; phba = beiscsi_ep->phba;
SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect\n");
if (beiscsi_ep->conn) { if (beiscsi_ep->conn) {
beiscsi_conn = beiscsi_ep->conn; beiscsi_conn = beiscsi_ep->conn;
iscsi_suspend_queue(beiscsi_conn->conn); iscsi_suspend_queue(beiscsi_conn->conn);
beiscsi_close_conn(ep, flag);
} }
beiscsi_free_ep(ep);
} }
/** /**
...@@ -637,6 +631,9 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) ...@@ -637,6 +631,9 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
"mgmt_invalidate_connection Failed for cid=%d \n", "mgmt_invalidate_connection Failed for cid=%d \n",
beiscsi_ep->ep_cid); beiscsi_ep->ep_cid);
} }
beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
beiscsi_free_ep(beiscsi_ep);
iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
iscsi_conn_stop(cls_conn, flag); iscsi_conn_stop(cls_conn, flag);
} }
...@@ -1434,6 +1434,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) ...@@ -1434,6 +1434,8 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
unsigned int tot_nump = 0; unsigned int tot_nump = 0;
struct beiscsi_conn *beiscsi_conn; struct beiscsi_conn *beiscsi_conn;
struct sgl_handle *psgl_handle = NULL; struct sgl_handle *psgl_handle = NULL;
struct beiscsi_endpoint *beiscsi_ep;
struct iscsi_endpoint *ep;
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
cq = pbe_eq->cq; cq = pbe_eq->cq;
...@@ -1449,28 +1451,15 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) ...@@ -1449,28 +1451,15 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
dw[offsetof(struct amap_sol_cqe_ring, dw[offsetof(struct amap_sol_cqe_ring,
icd_index) / 32] & SOL_ICD_INDEX_MASK) icd_index) / 32] & SOL_ICD_INDEX_MASK)
>> 6)]; >> 6)];
beiscsi_conn = phba->conn_table[psgl_handle->cid]; ep = phba->ep_array[psgl_handle->cid];
if (!beiscsi_conn || !beiscsi_conn->ep) {
shost_printk(KERN_WARNING, phba->shost,
"Connection table empty for cid = %d\n",
psgl_handle->cid);
return 0;
}
} else { } else {
beiscsi_conn = phba->conn_table[(u32) ((sol-> ep = phba->ep_array[(u32) ((sol->
dw[offsetof(struct amap_sol_cqe, cid) / 32] & dw[offsetof(struct amap_sol_cqe, cid) / 32] &
SOL_CID_MASK) >> 6) - SOL_CID_MASK) >> 6) -
phba->fw_config.iscsi_cid_start]; phba->fw_config.iscsi_cid_start];
if (!beiscsi_conn || !beiscsi_conn->ep) {
shost_printk(KERN_WARNING, phba->shost,
"Connection table empty for cid = %d\n",
(u32)(sol->dw[offsetof(struct amap_sol_cqe,
cid) / 32] & SOL_CID_MASK) >> 6);
return 0;
}
} }
beiscsi_ep = ep->dd_data;
beiscsi_conn = beiscsi_ep->conn;
if (num_processed >= 32) { if (num_processed >= 32) {
hwi_ring_cq_db(phba, cq->id, hwi_ring_cq_db(phba, cq->id,
num_processed, 0, 0); num_processed, 0, 0);
...@@ -3044,7 +3033,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) ...@@ -3044,7 +3033,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
{ {
int i, new_cid; int i, new_cid;
phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl, phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
GFP_KERNEL); GFP_KERNEL);
if (!phba->cid_array) { if (!phba->cid_array) {
shost_printk(KERN_ERR, phba->shost, shost_printk(KERN_ERR, phba->shost,
...@@ -3052,7 +3041,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) ...@@ -3052,7 +3041,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
"hba_setup_cid_tbls\n"); "hba_setup_cid_tbls\n");
return -ENOMEM; return -ENOMEM;
} }
phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) * phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) *
phba->params.cxns_per_ctrl * 2, GFP_KERNEL); phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
if (!phba->ep_array) { if (!phba->ep_array) {
shost_printk(KERN_ERR, phba->shost, shost_printk(KERN_ERR, phba->shost,
......
...@@ -231,6 +231,7 @@ struct beiscsi_endpoint { ...@@ -231,6 +231,7 @@ struct beiscsi_endpoint {
struct beiscsi_hba *phba; struct beiscsi_hba *phba;
struct beiscsi_sess *sess; struct beiscsi_sess *sess;
struct beiscsi_conn *conn; struct beiscsi_conn *conn;
struct iscsi_endpoint *openiscsi_ep;
unsigned short ip_type; unsigned short ip_type;
char dst6_addr[ISCSI_ADDRESS_BUF_LEN]; char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
unsigned long dst_addr; unsigned long dst_addr;
......
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