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

Commit 3587cb87 authored by Tomer Tayar's avatar Tomer Tayar Committed by David S. Miller
Browse files

qed: Revise alloc/setup/free flow



Re-organize the logic that allocates and frees memory of various
sub-components of the hw-function -

 a. No need to pass pointers to said structure as parameters;
    The internal logic knows exactly where to find/set the data.

 b. Nullify pointers after cleanup to prevent possible errors to
    re-entrant code.

Signed-off-by: default avatarTomer Tayar <Tomer.Tayar@cavium.com>
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 492a1d98
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -923,6 +923,7 @@ int qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn)
void qed_dcbx_info_free(struct qed_hwfn *p_hwfn)
{
	kfree(p_hwfn->p_dcbx_info);
	p_hwfn->p_dcbx_info = NULL;
}

static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
+33 −46
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ void qed_resc_free(struct qed_dev *cdev)
	cdev->fw_data = NULL;

	kfree(cdev->reset_stats);
	cdev->reset_stats = NULL;

	for_each_hwfn(cdev, i) {
		struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
@@ -168,18 +169,18 @@ void qed_resc_free(struct qed_dev *cdev)
		qed_cxt_mngr_free(p_hwfn);
		qed_qm_info_free(p_hwfn);
		qed_spq_free(p_hwfn);
		qed_eq_free(p_hwfn, p_hwfn->p_eq);
		qed_consq_free(p_hwfn, p_hwfn->p_consq);
		qed_eq_free(p_hwfn);
		qed_consq_free(p_hwfn);
		qed_int_free(p_hwfn);
#ifdef CONFIG_QED_LL2
		qed_ll2_free(p_hwfn, p_hwfn->p_ll2_info);
		qed_ll2_free(p_hwfn);
#endif
		if (p_hwfn->hw_info.personality == QED_PCI_FCOE)
			qed_fcoe_free(p_hwfn, p_hwfn->p_fcoe_info);
			qed_fcoe_free(p_hwfn);

		if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) {
			qed_iscsi_free(p_hwfn, p_hwfn->p_iscsi_info);
			qed_ooo_free(p_hwfn, p_hwfn->p_ooo_info);
			qed_iscsi_free(p_hwfn);
			qed_ooo_free(p_hwfn);
		}
		qed_iov_free(p_hwfn);
		qed_dmae_info_free(p_hwfn);
@@ -843,15 +844,7 @@ static int qed_alloc_qm_data(struct qed_hwfn *p_hwfn)

int qed_resc_alloc(struct qed_dev *cdev)
{
	struct qed_iscsi_info *p_iscsi_info;
	struct qed_fcoe_info *p_fcoe_info;
	struct qed_ooo_info *p_ooo_info;
#ifdef CONFIG_QED_LL2
	struct qed_ll2_info *p_ll2_info;
#endif
	u32 rdma_tasks, excess_tasks;
	struct qed_consq *p_consq;
	struct qed_eq *p_eq;
	u32 line_count;
	int i, rc = 0;

@@ -956,45 +949,38 @@ int qed_resc_alloc(struct qed_dev *cdev)
			DP_ERR(p_hwfn,
			       "Cannot allocate 0x%x EQ elements. The maximum of a u16 chain is 0x%x\n",
			       n_eqes, 0xFFFF);
			rc = -EINVAL;
			goto alloc_err;
			goto alloc_no_mem;
		}

		p_eq = qed_eq_alloc(p_hwfn, (u16) n_eqes);
		if (!p_eq)
			goto alloc_no_mem;
		p_hwfn->p_eq = p_eq;
		rc = qed_eq_alloc(p_hwfn, (u16) n_eqes);
		if (rc)
			goto alloc_err;

		p_consq = qed_consq_alloc(p_hwfn);
		if (!p_consq)
			goto alloc_no_mem;
		p_hwfn->p_consq = p_consq;
		rc = qed_consq_alloc(p_hwfn);
		if (rc)
			goto alloc_err;

#ifdef CONFIG_QED_LL2
		if (p_hwfn->using_ll2) {
			p_ll2_info = qed_ll2_alloc(p_hwfn);
			if (!p_ll2_info)
				goto alloc_no_mem;
			p_hwfn->p_ll2_info = p_ll2_info;
			rc = qed_ll2_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
		}
#endif

		if (p_hwfn->hw_info.personality == QED_PCI_FCOE) {
			p_fcoe_info = qed_fcoe_alloc(p_hwfn);
			if (!p_fcoe_info)
				goto alloc_no_mem;
			p_hwfn->p_fcoe_info = p_fcoe_info;
			rc = qed_fcoe_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
		}

		if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) {
			p_iscsi_info = qed_iscsi_alloc(p_hwfn);
			if (!p_iscsi_info)
				goto alloc_no_mem;
			p_hwfn->p_iscsi_info = p_iscsi_info;
			p_ooo_info = qed_ooo_alloc(p_hwfn);
			if (!p_ooo_info)
				goto alloc_no_mem;
			p_hwfn->p_ooo_info = p_ooo_info;
			rc = qed_iscsi_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
			rc = qed_ooo_alloc(p_hwfn);
			if (rc)
				goto alloc_err;
		}

		/* DMA info initialization */
@@ -1033,8 +1019,8 @@ void qed_resc_setup(struct qed_dev *cdev)

		qed_cxt_mngr_setup(p_hwfn);
		qed_spq_setup(p_hwfn);
		qed_eq_setup(p_hwfn, p_hwfn->p_eq);
		qed_consq_setup(p_hwfn, p_hwfn->p_consq);
		qed_eq_setup(p_hwfn);
		qed_consq_setup(p_hwfn);

		/* Read shadow of current MFW mailbox */
		qed_mcp_read_mb(p_hwfn, p_hwfn->p_main_ptt);
@@ -1047,14 +1033,14 @@ void qed_resc_setup(struct qed_dev *cdev)
		qed_iov_setup(p_hwfn, p_hwfn->p_main_ptt);
#ifdef CONFIG_QED_LL2
		if (p_hwfn->using_ll2)
			qed_ll2_setup(p_hwfn, p_hwfn->p_ll2_info);
			qed_ll2_setup(p_hwfn);
#endif
		if (p_hwfn->hw_info.personality == QED_PCI_FCOE)
			qed_fcoe_setup(p_hwfn, p_hwfn->p_fcoe_info);
			qed_fcoe_setup(p_hwfn);

		if (p_hwfn->hw_info.personality == QED_PCI_ISCSI) {
			qed_iscsi_setup(p_hwfn, p_hwfn->p_iscsi_info);
			qed_ooo_setup(p_hwfn, p_hwfn->p_ooo_info);
			qed_iscsi_setup(p_hwfn);
			qed_ooo_setup(p_hwfn);
		}
	}
}
@@ -1968,6 +1954,7 @@ static void qed_hw_hwfn_free(struct qed_hwfn *p_hwfn)
{
	qed_ptt_pool_free(p_hwfn);
	kfree(p_hwfn->hw_info.p_igu_info);
	p_hwfn->hw_info.p_igu_info = NULL;
}

/* Setup bar access */
+13 −10
Original line number Diff line number Diff line
@@ -538,7 +538,7 @@ static void __iomem *qed_fcoe_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn,
	}
}

struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
{
	struct qed_fcoe_info *p_fcoe_info;

@@ -546,19 +546,21 @@ struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
	p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL);
	if (!p_fcoe_info) {
		DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n");
		return NULL;
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&p_fcoe_info->free_list);
	return p_fcoe_info;

	p_hwfn->p_fcoe_info = p_fcoe_info;
	return 0;
}

void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info)
void qed_fcoe_setup(struct qed_hwfn *p_hwfn)
{
	struct fcoe_task_context *p_task_ctx = NULL;
	int rc;
	u32 i;

	spin_lock_init(&p_fcoe_info->lock);
	spin_lock_init(&p_hwfn->p_fcoe_info->lock);
	for (i = 0; i < p_hwfn->pf_params.fcoe_pf_params.num_tasks; i++) {
		rc = qed_cxt_get_task_ctx(p_hwfn, i,
					  QED_CTX_WORKING_MEM,
@@ -576,15 +578,15 @@ void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info)
	}
}

void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info)
void qed_fcoe_free(struct qed_hwfn *p_hwfn)
{
	struct qed_fcoe_conn *p_conn = NULL;

	if (!p_fcoe_info)
	if (!p_hwfn->p_fcoe_info)
		return;

	while (!list_empty(&p_fcoe_info->free_list)) {
		p_conn = list_first_entry(&p_fcoe_info->free_list,
	while (!list_empty(&p_hwfn->p_fcoe_info->free_list)) {
		p_conn = list_first_entry(&p_hwfn->p_fcoe_info->free_list,
					  struct qed_fcoe_conn, list_entry);
		if (!p_conn)
			break;
@@ -592,7 +594,8 @@ void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info)
		qed_fcoe_free_connection(p_hwfn, p_conn);
	}

	kfree(p_fcoe_info);
	kfree(p_hwfn->p_fcoe_info);
	p_hwfn->p_fcoe_info = NULL;
}

static int
+7 −15
Original line number Diff line number Diff line
@@ -49,29 +49,21 @@ struct qed_fcoe_info {
};

#if IS_ENABLED(CONFIG_QED_FCOE)
struct qed_fcoe_info *qed_fcoe_alloc(struct qed_hwfn *p_hwfn);
int qed_fcoe_alloc(struct qed_hwfn *p_hwfn);

void qed_fcoe_setup(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info);
void qed_fcoe_setup(struct qed_hwfn *p_hwfn);

void qed_fcoe_free(struct qed_hwfn *p_hwfn, struct qed_fcoe_info *p_fcoe_info);
void qed_fcoe_free(struct qed_hwfn *p_hwfn);
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
				 struct qed_mcp_fcoe_stats *stats);
#else /* CONFIG_QED_FCOE */
static inline struct qed_fcoe_info *
qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
static inline int qed_fcoe_alloc(struct qed_hwfn *p_hwfn)
{
	return NULL;
	return -EINVAL;
}

static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn,
				  struct qed_fcoe_info *p_fcoe_info)
{
}

static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn,
				 struct qed_fcoe_info *p_fcoe_info)
{
}
static inline void qed_fcoe_setup(struct qed_hwfn *p_hwfn) {}
static inline void qed_fcoe_free(struct qed_hwfn *p_hwfn) {}

static inline void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,
					       struct qed_mcp_fcoe_stats *stats)
+4 −0
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ int qed_init_alloc(struct qed_hwfn *p_hwfn)
				    GFP_KERNEL);
	if (!rt_data->init_val) {
		kfree(rt_data->b_valid);
		rt_data->b_valid = NULL;
		return -ENOMEM;
	}

@@ -167,7 +168,9 @@ int qed_init_alloc(struct qed_hwfn *p_hwfn)
void qed_init_free(struct qed_hwfn *p_hwfn)
{
	kfree(p_hwfn->rt_data.init_val);
	p_hwfn->rt_data.init_val = NULL;
	kfree(p_hwfn->rt_data.b_valid);
	p_hwfn->rt_data.b_valid = NULL;
}

static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
@@ -525,6 +528,7 @@ int qed_init_run(struct qed_hwfn *p_hwfn,
	}

	kfree(p_hwfn->unzip_buf);
	p_hwfn->unzip_buf = NULL;
	return rc;
}

Loading