From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Daley Subject: [PATCH v2] enic: fix seg fault when releasing queues Date: Wed, 25 May 2016 19:45:00 -0700 Message-ID: <1464230700-13341-1-git-send-email-johndale@cisco.com> References: <1464207514-4406-1-git-send-email-johndale@cisco.com> Cc: John Daley To: dev@dpdk.org Return-path: Received: from rcdn-iport-3.cisco.com (rcdn-iport-3.cisco.com [173.37.86.74]) by dpdk.org (Postfix) with ESMTP id 819E22BB8 for ; Thu, 26 May 2016 04:45:12 +0200 (CEST) In-Reply-To: <1464207514-4406-1-git-send-email-johndale@cisco.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" If device configuration failed due to a lack of resources, like if there were more queues requested than available, the queue release function is called with NULL pointers which were being dereferenced. Skip releasing queues if they are NULL pointers. Also, if configuration fails due to lack of resources, be more specific about which resources are lacking. Fixes: fefed3d1e62c ("enic: new driver") Signed-off-by: John Daley --- v2: Log an error for all resource deficiencies not just the first one found. drivers/net/enic/enic_main.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 996f999..411d23c 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -426,14 +426,16 @@ int enic_alloc_intr_resources(struct enic *enic) void enic_free_rq(void *rxq) { - struct vnic_rq *rq = (struct vnic_rq *)rxq; - struct enic *enic = vnic_dev_priv(rq->vdev); + if (rxq != NULL) { + struct vnic_rq *rq = (struct vnic_rq *)rxq; + struct enic *enic = vnic_dev_priv(rq->vdev); - enic_rxmbuf_queue_release(enic, rq); - rte_free(rq->mbuf_ring); - rq->mbuf_ring = NULL; - vnic_rq_free(rq); - vnic_cq_free(&enic->cq[rq->index]); + enic_rxmbuf_queue_release(enic, rq); + rte_free(rq->mbuf_ring); + rq->mbuf_ring = NULL; + vnic_rq_free(rq); + vnic_cq_free(&enic->cq[rq->index]); + } } void enic_start_wq(struct enic *enic, uint16_t queue_idx) @@ -816,22 +818,29 @@ static void enic_dev_deinit(struct enic *enic) int enic_set_vnic_res(struct enic *enic) { struct rte_eth_dev *eth_dev = enic->rte_dev; + int rc = 0; - if ((enic->rq_count < eth_dev->data->nb_rx_queues) || - (enic->wq_count < eth_dev->data->nb_tx_queues)) { - dev_err(dev, "Not enough resources configured, aborting\n"); - return -1; + if (enic->rq_count < eth_dev->data->nb_rx_queues) { + dev_err(dev, "Not enough Receive queues. Requested:%u, Configured:%u\n", + eth_dev->data->nb_rx_queues, enic->rq_count); + rc = -1; + } + if (enic->wq_count < eth_dev->data->nb_tx_queues) { + dev_err(dev, "Not enough Transmit queues. Requested:%u, Configured:%u\n", + eth_dev->data->nb_tx_queues, enic->wq_count); + rc = -1; } enic->rq_count = eth_dev->data->nb_rx_queues; enic->wq_count = eth_dev->data->nb_tx_queues; if (enic->cq_count < (enic->rq_count + enic->wq_count)) { - dev_err(dev, "Not enough resources configured, aborting\n"); - return -1; + dev_err(dev, "Not enough Completion queues. Required:%u, Configured:%u\n", + enic->rq_count + enic->wq_count, enic->cq_count); + rc = -1; } enic->cq_count = enic->rq_count + enic->wq_count; - return 0; + return rc; } static int enic_dev_init(struct enic *enic) -- 2.7.0