[dpdk-dev] [PATCH v2] enic: fix seg fault when releasing queues

2016-06-09 Thread Bruce Richardson
On Wed, May 25, 2016 at 07:45:00PM -0700, John Daley wrote:
> 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.

The "also", and a a review of the code, indicates that the error message
changes should be a separate patch, as it's not related to the NULL check fix.
:-)


> 
> 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(>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(>cq[rq->index]);
> + }
>  }

Is it not just easier to put a check at the top for: 
if (rq == NULL)
return;

Rather than putting the whole body of the function inside an if statement? It
would certainly be a smaller diff.

/Bruce



[dpdk-dev] [PATCH v2] enic: fix seg fault when releasing queues

2016-05-25 Thread John Daley
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(>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(>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