net/mlx5: fix count query when flow has not counters

Message ID de3b01f085f9e05b27db0ca10e8e14fdf3a19c75.1532508321.git.nelio.laranjeiro@6wind.com (mailing list archive)
State Accepted, archived
Delegated to: Shahaf Shuler
Headers
Series net/mlx5: fix count query when flow has not counters |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Nélio Laranjeiro July 25, 2018, 8:46 a.m. UTC
  Querying a counters on a flow without counter is ending with a
segmentation fault.

Fixes: 60bd8c9747e8 ("net/mlx5: add count flow action")

Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
---
 drivers/net/mlx5/mlx5_flow.c | 56 ++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 24 deletions(-)
  

Comments

Ori Kam July 25, 2018, 12:55 p.m. UTC | #1
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Nelio Laranjeiro
> Sent: Wednesday, July 25, 2018 11:46 AM
> To: dev@dpdk.org; Shahaf Shuler <shahafs@mellanox.com>; Yongseok Koh
> <yskoh@mellanox.com>
> Subject: [dpdk-dev] [PATCH] net/mlx5: fix count query when flow has not
> counters
> 
> Querying a counters on a flow without counter is ending with a
> segmentation fault.
> 
> Fixes: 60bd8c9747e8 ("net/mlx5: add count flow action")
> 
> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> ---
>  drivers/net/mlx5/mlx5_flow.c | 56 ++++++++++++++++++++----------------
>  1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 6fa4e30ae..efaa8b4fb 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -3192,32 +3192,40 @@ mlx5_flow_query_count(struct rte_flow *flow
> __rte_unused,
>  		      struct rte_flow_error *error)
>  {
>  #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
> -	struct rte_flow_query_count *qc = data;
> -	uint64_t counters[2] = {0, 0};
> -	struct ibv_query_counter_set_attr query_cs_attr = {
> -		.cs = flow->counter->cs,
> -		.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
> -	};
> -	struct ibv_counter_set_data query_out = {
> -		.out = counters,
> -		.outlen = 2 * sizeof(uint64_t),
> -	};
> -	int err = mlx5_glue->query_counter_set(&query_cs_attr,
> &query_out);
> +	if (flow->modifier & MLX5_FLOW_MOD_COUNT) {
> +		struct rte_flow_query_count *qc = data;
> +		uint64_t counters[2] = {0, 0};
> +		struct ibv_query_counter_set_attr query_cs_attr = {
> +			.cs = flow->counter->cs,
> +			.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
> +		};
> +		struct ibv_counter_set_data query_out = {
> +			.out = counters,
> +			.outlen = 2 * sizeof(uint64_t),
> +		};
> +		int err = mlx5_glue->query_counter_set(&query_cs_attr,
> +						       &query_out);
> 
> -	if (err)
> -		return rte_flow_error_set(error, err,
> -
> RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> -					  NULL,
> -					  "cannot read counter");
> -	qc->hits_set = 1;
> -	qc->bytes_set = 1;
> -	qc->hits = counters[0] - flow->counter->hits;
> -	qc->bytes = counters[1] - flow->counter->bytes;
> -	if (qc->reset) {
> -		flow->counter->hits = counters[0];
> -		flow->counter->bytes = counters[1];
> +		if (err)
> +			return rte_flow_error_set
> +				(error, err,
> +				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				 NULL,
> +				 "cannot read counter");
> +		qc->hits_set = 1;
> +		qc->bytes_set = 1;
> +		qc->hits = counters[0] - flow->counter->hits;
> +		qc->bytes = counters[1] - flow->counter->bytes;
> +		if (qc->reset) {
> +			flow->counter->hits = counters[0];
> +			flow->counter->bytes = counters[1];
> +		}
> +		return 0;
>  	}
> -	return 0;
> +	return rte_flow_error_set(error, ENOTSUP,
> +				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				  NULL,
> +				  "flow does not have counter");
>  #endif
>  	return rte_flow_error_set(error, ENOTSUP,
>  				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> --
> 2.18.0

Acked-by: Ori Kam <orika@mellanox.com>

Best,
Ori
  
Yongseok Koh July 25, 2018, 5:25 p.m. UTC | #2
> On Jul 25, 2018, at 1:46 AM, Nelio Laranjeiro <nelio.laranjeiro@6wind.com> wrote:
> 
> Querying a counters on a flow without counter is ending with a
> segmentation fault.
> 
> Fixes: 60bd8c9747e8 ("net/mlx5: add count flow action")
> 
> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> ---
> drivers/net/mlx5/mlx5_flow.c | 56 ++++++++++++++++++++----------------
> 1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 6fa4e30ae..efaa8b4fb 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -3192,32 +3192,40 @@ mlx5_flow_query_count(struct rte_flow *flow __rte_unused,
> 		      struct rte_flow_error *error)
> {
> #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
> -	struct rte_flow_query_count *qc = data;
> -	uint64_t counters[2] = {0, 0};
> -	struct ibv_query_counter_set_attr query_cs_attr = {
> -		.cs = flow->counter->cs,
> -		.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
> -	};
> -	struct ibv_counter_set_data query_out = {
> -		.out = counters,
> -		.outlen = 2 * sizeof(uint64_t),
> -	};
> -	int err = mlx5_glue->query_counter_set(&query_cs_attr, &query_out);
> +	if (flow->modifier & MLX5_FLOW_MOD_COUNT) {

Instead of adding extra indentation, how about returning error immediately if
the flow doesn't have a counter? That looks more natural. But even if you insist
this way, I'm also okay. Please let Shahaf know if you will submit v2.

Acked-by: Yongseok Koh <yskoh@mellanox.com>
 
Thanks

> +		struct rte_flow_query_count *qc = data;
> +		uint64_t counters[2] = {0, 0};
> +		struct ibv_query_counter_set_attr query_cs_attr = {
> +			.cs = flow->counter->cs,
> +			.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
> +		};
> +		struct ibv_counter_set_data query_out = {
> +			.out = counters,
> +			.outlen = 2 * sizeof(uint64_t),
> +		};
> +		int err = mlx5_glue->query_counter_set(&query_cs_attr,
> +						       &query_out);
> 
> -	if (err)
> -		return rte_flow_error_set(error, err,
> -					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> -					  NULL,
> -					  "cannot read counter");
> -	qc->hits_set = 1;
> -	qc->bytes_set = 1;
> -	qc->hits = counters[0] - flow->counter->hits;
> -	qc->bytes = counters[1] - flow->counter->bytes;
> -	if (qc->reset) {
> -		flow->counter->hits = counters[0];
> -		flow->counter->bytes = counters[1];
> +		if (err)
> +			return rte_flow_error_set
> +				(error, err,
> +				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				 NULL,
> +				 "cannot read counter");
> +		qc->hits_set = 1;
> +		qc->bytes_set = 1;
> +		qc->hits = counters[0] - flow->counter->hits;
> +		qc->bytes = counters[1] - flow->counter->bytes;
> +		if (qc->reset) {
> +			flow->counter->hits = counters[0];
> +			flow->counter->bytes = counters[1];
> +		}
> +		return 0;
> 	}
> -	return 0;
> +	return rte_flow_error_set(error, ENOTSUP,
> +				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> +				  NULL,
> +				  "flow does not have counter");
> #endif
> 	return rte_flow_error_set(error, ENOTSUP,
> 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
> -- 
> 2.18.0
>
  
Shahaf Shuler July 26, 2018, 5:39 a.m. UTC | #3
Wednesday, July 25, 2018 8:25 PM, Yongseok Koh:
> Subject: Re: [PATCH] net/mlx5: fix count query when flow has not counters
> 
> 
> > On Jul 25, 2018, at 1:46 AM, Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> wrote:
> >
> > Querying a counters on a flow without counter is ending with a
> > segmentation fault.
> >
> > Fixes: 60bd8c9747e8 ("net/mlx5: add count flow action")
> >
> > Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> > ---
> > drivers/net/mlx5/mlx5_flow.c | 56 ++++++++++++++++++++----------------
> > 1 file changed, 32 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5_flow.c
> > b/drivers/net/mlx5/mlx5_flow.c index 6fa4e30ae..efaa8b4fb 100644
> > --- a/drivers/net/mlx5/mlx5_flow.c
> > +++ b/drivers/net/mlx5/mlx5_flow.c
> > @@ -3192,32 +3192,40 @@ mlx5_flow_query_count(struct rte_flow *flow
> __rte_unused,
> > 		      struct rte_flow_error *error)
> > {
> > #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
> > -	struct rte_flow_query_count *qc = data;
> > -	uint64_t counters[2] = {0, 0};
> > -	struct ibv_query_counter_set_attr query_cs_attr = {
> > -		.cs = flow->counter->cs,
> > -		.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
> > -	};
> > -	struct ibv_counter_set_data query_out = {
> > -		.out = counters,
> > -		.outlen = 2 * sizeof(uint64_t),
> > -	};
> > -	int err = mlx5_glue->query_counter_set(&query_cs_attr,
> &query_out);
> > +	if (flow->modifier & MLX5_FLOW_MOD_COUNT) {
> 
> Instead of adding extra indentation, how about returning error immediately
> if the flow doesn't have a counter? That looks more natural. But even if you
> insist this way, I'm also okay. Please let Shahaf know if you will submit v2.
> 
> Acked-by: Yongseok Koh <yskoh@mellanox.com>

I will take this one,

Applied to next-net-mlx, thanks.
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 6fa4e30ae..efaa8b4fb 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3192,32 +3192,40 @@  mlx5_flow_query_count(struct rte_flow *flow __rte_unused,
 		      struct rte_flow_error *error)
 {
 #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
-	struct rte_flow_query_count *qc = data;
-	uint64_t counters[2] = {0, 0};
-	struct ibv_query_counter_set_attr query_cs_attr = {
-		.cs = flow->counter->cs,
-		.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
-	};
-	struct ibv_counter_set_data query_out = {
-		.out = counters,
-		.outlen = 2 * sizeof(uint64_t),
-	};
-	int err = mlx5_glue->query_counter_set(&query_cs_attr, &query_out);
+	if (flow->modifier & MLX5_FLOW_MOD_COUNT) {
+		struct rte_flow_query_count *qc = data;
+		uint64_t counters[2] = {0, 0};
+		struct ibv_query_counter_set_attr query_cs_attr = {
+			.cs = flow->counter->cs,
+			.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
+		};
+		struct ibv_counter_set_data query_out = {
+			.out = counters,
+			.outlen = 2 * sizeof(uint64_t),
+		};
+		int err = mlx5_glue->query_counter_set(&query_cs_attr,
+						       &query_out);
 
-	if (err)
-		return rte_flow_error_set(error, err,
-					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-					  NULL,
-					  "cannot read counter");
-	qc->hits_set = 1;
-	qc->bytes_set = 1;
-	qc->hits = counters[0] - flow->counter->hits;
-	qc->bytes = counters[1] - flow->counter->bytes;
-	if (qc->reset) {
-		flow->counter->hits = counters[0];
-		flow->counter->bytes = counters[1];
+		if (err)
+			return rte_flow_error_set
+				(error, err,
+				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				 NULL,
+				 "cannot read counter");
+		qc->hits_set = 1;
+		qc->bytes_set = 1;
+		qc->hits = counters[0] - flow->counter->hits;
+		qc->bytes = counters[1] - flow->counter->bytes;
+		if (qc->reset) {
+			flow->counter->hits = counters[0];
+			flow->counter->bytes = counters[1];
+		}
+		return 0;
 	}
-	return 0;
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL,
+				  "flow does not have counter");
 #endif
 	return rte_flow_error_set(error, ENOTSUP,
 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,