Skip to content

Commit fb5e743

Browse files
Denis Bolotindavem330
authored andcommitted
qed: Fix SPQ entries not returned to pool in error flows
qed_sp_destroy_request() API was added for SPQ users that need to free/return the entry they acquired in their error flows. Signed-off-by: Denis Bolotin <denis.bolotin@cavium.com> Signed-off-by: Michal Kalderon <michal.kalderon@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2632f22 commit fb5e743

File tree

8 files changed

+45
-15
lines changed

8 files changed

+45
-15
lines changed

drivers/net/ethernet/qlogic/qed/qed_fcoe.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
147147
"Cannot satisfy CQ amount. CQs requested %d, CQs available %d. Aborting function start\n",
148148
fcoe_pf_params->num_cqs,
149149
p_hwfn->hw_info.feat_num[QED_FCOE_CQ]);
150-
return -EINVAL;
150+
rc = -EINVAL;
151+
goto err;
151152
}
152153

153154
p_data->mtu = cpu_to_le16(fcoe_pf_params->mtu);
@@ -156,14 +157,14 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
156157

157158
rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_FCOE, &dummy_cid);
158159
if (rc)
159-
return rc;
160+
goto err;
160161

161162
cxt_info.iid = dummy_cid;
162163
rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info);
163164
if (rc) {
164165
DP_NOTICE(p_hwfn, "Cannot find context info for dummy cid=%d\n",
165166
dummy_cid);
166-
return rc;
167+
goto err;
167168
}
168169
p_cxt = cxt_info.p_cxt;
169170
SET_FIELD(p_cxt->tstorm_ag_context.flags3,
@@ -240,6 +241,10 @@ qed_sp_fcoe_func_start(struct qed_hwfn *p_hwfn,
240241
rc = qed_spq_post(p_hwfn, p_ent, NULL);
241242

242243
return rc;
244+
245+
err:
246+
qed_sp_destroy_request(p_hwfn, p_ent);
247+
return rc;
243248
}
244249

245250
static int

drivers/net/ethernet/qlogic/qed/qed_iscsi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ qed_sp_iscsi_func_start(struct qed_hwfn *p_hwfn,
200200
"Cannot satisfy CQ amount. Queues requested %d, CQs available %d. Aborting function start\n",
201201
p_params->num_queues,
202202
p_hwfn->hw_info.feat_num[QED_ISCSI_CQ]);
203+
qed_sp_destroy_request(p_hwfn, p_ent);
203204
return -EINVAL;
204205
}
205206

drivers/net/ethernet/qlogic/qed/qed_l2.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -740,8 +740,7 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn,
740740

741741
rc = qed_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params);
742742
if (rc) {
743-
/* Return spq entry which is taken in qed_sp_init_request()*/
744-
qed_spq_return_entry(p_hwfn, p_ent);
743+
qed_sp_destroy_request(p_hwfn, p_ent);
745744
return rc;
746745
}
747746

@@ -1355,6 +1354,7 @@ qed_filter_ucast_common(struct qed_hwfn *p_hwfn,
13551354
DP_NOTICE(p_hwfn,
13561355
"%d is not supported yet\n",
13571356
p_filter_cmd->opcode);
1357+
qed_sp_destroy_request(p_hwfn, *pp_ent);
13581358
return -EINVAL;
13591359
}
13601360

@@ -2056,13 +2056,13 @@ qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn,
20562056
} else {
20572057
rc = qed_fw_vport(p_hwfn, p_params->vport_id, &abs_vport_id);
20582058
if (rc)
2059-
return rc;
2059+
goto err;
20602060

20612061
if (p_params->qid != QED_RFS_NTUPLE_QID_RSS) {
20622062
rc = qed_fw_l2_queue(p_hwfn, p_params->qid,
20632063
&abs_rx_q_id);
20642064
if (rc)
2065-
return rc;
2065+
goto err;
20662066

20672067
p_ramrod->rx_qid_valid = 1;
20682068
p_ramrod->rx_qid = cpu_to_le16(abs_rx_q_id);
@@ -2083,6 +2083,10 @@ qed_configure_rfs_ntuple_filter(struct qed_hwfn *p_hwfn,
20832083
(u64)p_params->addr, p_params->length);
20842084

20852085
return qed_spq_post(p_hwfn, p_ent, NULL);
2086+
2087+
err:
2088+
qed_sp_destroy_request(p_hwfn, p_ent);
2089+
return rc;
20862090
}
20872091

20882092
int qed_get_rxq_coalesce(struct qed_hwfn *p_hwfn,

drivers/net/ethernet/qlogic/qed/qed_rdma.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,7 @@ qed_rdma_register_tid(void *rdma_cxt,
15141514
default:
15151515
rc = -EINVAL;
15161516
DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "rc = %d\n", rc);
1517+
qed_sp_destroy_request(p_hwfn, p_ent);
15171518
return rc;
15181519
}
15191520
SET_FIELD(p_ramrod->flags1,

drivers/net/ethernet/qlogic/qed/qed_roce.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ static int qed_roce_sp_destroy_qp_responder(struct qed_hwfn *p_hwfn,
745745
DP_NOTICE(p_hwfn,
746746
"qed destroy responder failed: cannot allocate memory (ramrod). rc = %d\n",
747747
rc);
748+
qed_sp_destroy_request(p_hwfn, p_ent);
748749
return rc;
749750
}
750751

drivers/net/ethernet/qlogic/qed/qed_sp.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,17 @@ struct qed_sp_init_data {
399399
struct qed_spq_comp_cb *p_comp_data;
400400
};
401401

402+
/**
403+
* @brief Returns a SPQ entry to the pool / frees the entry if allocated.
404+
* Should be called on in error flows after initializing the SPQ entry
405+
* and before posting it.
406+
*
407+
* @param p_hwfn
408+
* @param p_ent
409+
*/
410+
void qed_sp_destroy_request(struct qed_hwfn *p_hwfn,
411+
struct qed_spq_entry *p_ent);
412+
402413
int qed_sp_init_request(struct qed_hwfn *p_hwfn,
403414
struct qed_spq_entry **pp_ent,
404415
u8 cmd,

drivers/net/ethernet/qlogic/qed/qed_sp_commands.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@
4747
#include "qed_sp.h"
4848
#include "qed_sriov.h"
4949

50+
void qed_sp_destroy_request(struct qed_hwfn *p_hwfn,
51+
struct qed_spq_entry *p_ent)
52+
{
53+
/* qed_spq_get_entry() can either get an entry from the free_pool,
54+
* or, if no entries are left, allocate a new entry and add it to
55+
* the unlimited_pending list.
56+
*/
57+
if (p_ent->queue == &p_hwfn->p_spq->unlimited_pending)
58+
kfree(p_ent);
59+
else
60+
qed_spq_return_entry(p_hwfn, p_ent);
61+
}
62+
5063
int qed_sp_init_request(struct qed_hwfn *p_hwfn,
5164
struct qed_spq_entry **pp_ent,
5265
u8 cmd, u8 protocol, struct qed_sp_init_data *p_data)
@@ -111,14 +124,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn,
111124
return 0;
112125

113126
err:
114-
/* qed_spq_get_entry() can either get an entry from the free_pool,
115-
* or, if no entries are left, allocate a new entry and add it to
116-
* the unlimited_pending list.
117-
*/
118-
if (p_ent->queue == &p_hwfn->p_spq->unlimited_pending)
119-
kfree(p_ent);
120-
else
121-
qed_spq_return_entry(p_hwfn, p_ent);
127+
qed_sp_destroy_request(p_hwfn, p_ent);
122128

123129
return -EINVAL;
124130
}

drivers/net/ethernet/qlogic/qed/qed_sriov.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static int qed_sp_vf_start(struct qed_hwfn *p_hwfn, struct qed_vf_info *p_vf)
101101
default:
102102
DP_NOTICE(p_hwfn, "Unknown VF personality %d\n",
103103
p_hwfn->hw_info.personality);
104+
qed_sp_destroy_request(p_hwfn, p_ent);
104105
return -EINVAL;
105106
}
106107

0 commit comments

Comments
 (0)