[dpdk-dev] [PATCH 1/3] net/bnx2x: fix read VF id

Rasesh Mody rmody at marvell.com
Thu Jul 4 01:43:11 CEST 2019


The logic, to read vf_id used by ACQUIRE/TEARDOWN_Q/RELEASE TLVs,
multiplexed return value to convey vf_id value and status of read vf_id
API. This lets to segfault at dev_start() as resources are not properly
cleaned and re-allocated.

Fix read vf_id API to differentiate between vf_id value and return
status. Adjust the status checking accordingly.
Added bnx2x_vf_teardown_queue() API and moved relevant code from
bnx2x_vf_unload() to new API.

Fixes: 540a211084a7 ("bnx2x: driver core")
Cc: stable at dpdk.org

Signed-off-by: Rasesh Mody <rmody at marvell.com>
---
 drivers/net/bnx2x/bnx2x.c      |   2 +
 drivers/net/bnx2x/bnx2x_vfpf.c | 140 ++++++++++++++++++++-------------
 drivers/net/bnx2x/bnx2x_vfpf.h |   1 +
 3 files changed, 87 insertions(+), 56 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x.c b/drivers/net/bnx2x/bnx2x.c
index d523f4f2c..877f5b73d 100644
--- a/drivers/net/bnx2x/bnx2x.c
+++ b/drivers/net/bnx2x/bnx2x.c
@@ -2015,6 +2015,8 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link
 	uint8_t global = FALSE;
 	uint32_t val;
 
+	PMD_INIT_FUNC_TRACE(sc);
+
 	PMD_DRV_LOG(DEBUG, sc, "Starting NIC unload...");
 
 	/* mark driver as unloaded in shmem2 */
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.c b/drivers/net/bnx2x/bnx2x_vfpf.c
index 7cf738a82..8f7559c67 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/bnx2x/bnx2x_vfpf.c
@@ -162,20 +162,26 @@ static inline uint16_t bnx2x_check_me_flags(uint32_t val)
 #define BNX2X_ME_ANSWER_DELAY 100
 #define BNX2X_ME_ANSWER_TRIES 10
 
-static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc)
+static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc, uint32_t *vf_id)
 {
 	uint32_t val;
 	uint8_t i = 0;
 
 	while (i <= BNX2X_ME_ANSWER_TRIES) {
 		val = BNX2X_DB_READ(DOORBELL_ADDR(sc, 0));
-		if (bnx2x_check_me_flags(val))
-			return VF_ID(val);
+		if (bnx2x_check_me_flags(val)) {
+			PMD_DRV_LOG(DEBUG, sc,
+				    "valid register value: 0x%08x", val);
+			*vf_id = VF_ID(val);
+			return 0;
+		}
 
 		DELAY_MS(BNX2X_ME_ANSWER_DELAY);
 		i++;
 	}
 
+	PMD_DRV_LOG(ERR, sc, "Invalid register value: 0x%08x", val);
+
 	return -EINVAL;
 }
 
@@ -240,14 +246,13 @@ int bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
 {
 	struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
-	int vf_id;
+	uint32_t vf_id;
 	int rc;
 
 	bnx2x_vf_close(sc);
 	bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
 
-	vf_id = bnx2x_read_vf_id(sc);
-	if (vf_id < 0) {
+	if (bnx2x_read_vf_id(sc, &vf_id)) {
 		rc = -EAGAIN;
 		goto out;
 	}
@@ -318,25 +323,30 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
 {
 	struct vf_release_tlv *query;
 	struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
-	int vf_id = bnx2x_read_vf_id(sc);
+	uint32_t vf_id;
 	int rc;
 
-	if (vf_id >= 0) {
-		query = &sc->vf2pf_mbox->query[0].release;
-		bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
-			      sizeof(*query));
+	query = &sc->vf2pf_mbox->query[0].release;
+	bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
+		      sizeof(*query));
 
-		query->vf_id = vf_id;
-		bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
-			      BNX2X_VF_TLV_LIST_END,
-			      sizeof(struct channel_list_end_tlv));
+	if (bnx2x_read_vf_id(sc, &vf_id)) {
+		rc = -EAGAIN;
+		goto out;
+	}
 
-		rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
-		if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
-			PMD_DRV_LOG(ERR, sc, "Failed to release VF");
+	query->vf_id = vf_id;
 
-		bnx2x_vf_finalize(sc, &query->first_tlv);
-	}
+	bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+		      BNX2X_VF_TLV_LIST_END,
+		      sizeof(struct channel_list_end_tlv));
+
+	rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+	if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
+		PMD_DRV_LOG(ERR, sc, "Failed to release VF");
+
+out:
+	bnx2x_vf_finalize(sc, &query->first_tlv);
 }
 
 /* Let PF know the VF status blocks phys_addrs */
@@ -347,6 +357,8 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
 	struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
 	int i, rc;
 
+	PMD_INIT_FUNC_TRACE(sc);
+
 	query = &sc->vf2pf_mbox->query[0].init;
 	bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
 		      sizeof(*query));
@@ -383,51 +395,38 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
 {
 	struct vf_close_tlv *query;
 	struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
-	struct vf_q_op_tlv *query_op;
-	int i, vf_id, rc;
-
-	vf_id = bnx2x_read_vf_id(sc);
-	if (vf_id > 0) {
-		FOR_EACH_QUEUE(sc, i) {
-			query_op = &sc->vf2pf_mbox->query[0].q_op;
-			bnx2x_vf_prep(sc, &query_op->first_tlv,
-				      BNX2X_VF_TLV_TEARDOWN_Q,
-				      sizeof(*query_op));
-
-			query_op->vf_qid = i;
+	uint32_t vf_id;
+	int i, rc;
 
-			bnx2x_add_tlv(sc, query_op,
-				      query_op->first_tlv.tl.length,
-				      BNX2X_VF_TLV_LIST_END,
-				      sizeof(struct channel_list_end_tlv));
+	PMD_INIT_FUNC_TRACE(sc);
 
-			rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
-			if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
-				PMD_DRV_LOG(ERR, sc,
-					    "Bad reply for vf_q %d teardown", i);
+	FOR_EACH_QUEUE(sc, i)
+		bnx2x_vf_teardown_queue(sc, i);
 
-			bnx2x_vf_finalize(sc, &query_op->first_tlv);
-		}
+	bnx2x_vf_set_mac(sc, false);
 
-		bnx2x_vf_set_mac(sc, false);
+	query = &sc->vf2pf_mbox->query[0].close;
+	bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
+		      sizeof(*query));
 
-		query = &sc->vf2pf_mbox->query[0].close;
-		bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
-			      sizeof(*query));
+	if (bnx2x_read_vf_id(sc, &vf_id)) {
+		rc = -EAGAIN;
+		goto out;
+	}
 
-		query->vf_id = vf_id;
+	query->vf_id = vf_id;
 
-		bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
-			      BNX2X_VF_TLV_LIST_END,
-			      sizeof(struct channel_list_end_tlv));
+	bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
+		      BNX2X_VF_TLV_LIST_END,
+		      sizeof(struct channel_list_end_tlv));
 
-		rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
-		if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
-			PMD_DRV_LOG(ERR, sc,
-				    "Bad reply from PF for close message");
+	rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+	if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
+		PMD_DRV_LOG(ERR, sc,
+			    "Bad reply from PF for close message");
 
-		bnx2x_vf_finalize(sc, &query->first_tlv);
-	}
+out:
+	bnx2x_vf_finalize(sc, &query->first_tlv);
 }
 
 static inline uint16_t
@@ -521,6 +520,35 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
 	return rc;
 }
 
+int
+bnx2x_vf_teardown_queue(struct bnx2x_softc *sc, int qid)
+{
+	struct vf_q_op_tlv *query_op;
+	struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
+	int rc;
+
+	query_op = &sc->vf2pf_mbox->query[0].q_op;
+	bnx2x_vf_prep(sc, &query_op->first_tlv,
+		      BNX2X_VF_TLV_TEARDOWN_Q,
+		      sizeof(*query_op));
+
+	query_op->vf_qid = qid;
+
+	bnx2x_add_tlv(sc, query_op,
+		      query_op->first_tlv.tl.length,
+		      BNX2X_VF_TLV_LIST_END,
+		      sizeof(struct channel_list_end_tlv));
+
+	rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
+	if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
+		PMD_DRV_LOG(ERR, sc,
+			    "Bad reply for vf_q %d teardown", qid);
+
+	bnx2x_vf_finalize(sc, &query_op->first_tlv);
+
+	return rc;
+}
+
 int
 bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
 {
diff --git a/drivers/net/bnx2x/bnx2x_vfpf.h b/drivers/net/bnx2x/bnx2x_vfpf.h
index 6964c9d98..ce0259adf 100644
--- a/drivers/net/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/bnx2x/bnx2x_vfpf.h
@@ -328,6 +328,7 @@ struct bnx2x_vf_mbx_msg {
 	union resp_tlvs resp;
 };
 
+int bnx2x_vf_teardown_queue(struct bnx2x_softc *sc, int qid);
 int bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set);
 int bnx2x_vf_config_rss(struct bnx2x_softc *sc, struct ecore_config_rss_params *params);
 
-- 
2.18.0



More information about the dev mailing list