Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5965934 authored by Mustafa Ismail's avatar Mustafa Ismail Committed by Doug Ledford
Browse files

i40iw: Add missing cleanup on device close



On i40iw device close, disconnect all connected QPs by moving
them to error state; and block further QPs, PDs and CQs from
being created. Additionally, make sure all resources have been
freed before deallocating the ibdev as part of the device close.

Signed-off-by: default avatarMustafa Ismail <mustafa.ismail@intel.com>
Signed-off-by: default avatarShiraz Saleem <shiraz.saleem@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f26c7c83
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -303,10 +303,13 @@ struct i40iw_device {
	u32 mr_stagmask;
	u32 mpa_version;
	bool dcb;
	bool closing;
	u32 used_pds;
	u32 used_cqs;
	u32 used_mrs;
	u32 used_qps;
	wait_queue_head_t close_wq;
	atomic64_t use_count;
};

struct i40iw_ib_device {
@@ -521,6 +524,8 @@ int i40iw_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *)

void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev);
void i40iw_add_pdusecount(struct i40iw_pd *iwpd);
void i40iw_rem_devusecount(struct i40iw_device *iwdev);
void i40iw_add_devusecount(struct i40iw_device *iwdev);
void i40iw_hw_modify_qp(struct i40iw_device *iwdev, struct i40iw_qp *iwqp,
			struct i40iw_modify_qp_info *info, bool wait);

+31 −0
Original line number Diff line number Diff line
@@ -4128,3 +4128,34 @@ static void i40iw_cm_post_event(struct i40iw_cm_event *event)

	queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
}

/**
 * i40iw_cm_disconnect_all - disconnect all connected qp's
 * @iwdev: device pointer
 */
void i40iw_cm_disconnect_all(struct i40iw_device *iwdev)
{
	struct i40iw_cm_core *cm_core = &iwdev->cm_core;
	struct list_head *list_core_temp;
	struct list_head *list_node;
	struct i40iw_cm_node *cm_node;
	unsigned long flags;
	struct list_head connected_list;
	struct ib_qp_attr attr;

	INIT_LIST_HEAD(&connected_list);
	spin_lock_irqsave(&cm_core->ht_lock, flags);
	list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) {
		cm_node = container_of(list_node, struct i40iw_cm_node, list);
		atomic_inc(&cm_node->ref_count);
		list_add(&cm_node->connected_entry, &connected_list);
	}
	spin_unlock_irqrestore(&cm_core->ht_lock, flags);

	list_for_each_safe(list_node, list_core_temp, &connected_list) {
		cm_node = container_of(list_node, struct i40iw_cm_node, connected_entry);
		attr.qp_state = IB_QPS_ERR;
		i40iw_modify_qp(&cm_node->iwqp->ibqp, &attr, IB_QP_STATE, NULL);
		i40iw_rem_ref_cm_node(cm_node);
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -339,6 +339,7 @@ struct i40iw_cm_node {
	int accept_pend;
	struct list_head timer_entry;
	struct list_head reset_entry;
	struct list_head connected_entry;
	atomic_t passive_state;
	bool qhash_set;
	u8 user_pri;
@@ -443,4 +444,5 @@ int i40iw_arp_table(struct i40iw_device *iwdev,
		    u8 *mac_addr,
		    u32 action);

void i40iw_cm_disconnect_all(struct i40iw_device *iwdev);
#endif /* I40IW_CM_H */
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#ifndef I40IW_D_H
#define I40IW_D_H

#define I40IW_FIRST_USER_QP_ID  2

#define I40IW_DB_ADDR_OFFSET    (4 * 1024 * 1024 - 64 * 1024)
#define I40IW_VF_DB_ADDR_OFFSET (64 * 1024)

+4 −0
Original line number Diff line number Diff line
@@ -1546,6 +1546,7 @@ static enum i40iw_status_code i40iw_setup_init_state(struct i40iw_handler *hdl,

	init_waitqueue_head(&iwdev->vchnl_waitq);
	init_waitqueue_head(&dev->vf_reqs);
	init_waitqueue_head(&iwdev->close_wq);

	status = i40iw_initialize_dev(iwdev, ldev);
exit:
@@ -1748,6 +1749,9 @@ static void i40iw_close(struct i40e_info *ldev, struct i40e_client *client, bool
		return;

	iwdev = &hdl->device;
	iwdev->closing = true;

	i40iw_cm_disconnect_all(iwdev);
	destroy_workqueue(iwdev->virtchnl_wq);
	i40iw_deinit_device(iwdev, reset);
}
Loading