linux/dim: Do nothing if no time delta between samples
authorRoy Novich <royno@nvidia.com>
Sun, 7 May 2023 13:57:43 +0000 (16:57 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 May 2023 16:32:31 +0000 (17:32 +0100)
[ Upstream commit 162bd18eb55adf464a0fa2b4144b8d61c75ff7c2 ]

Add return value for dim_calc_stats. This is an indication for the
caller if curr_stats was assigned by the function. Avoid using
curr_stats uninitialized over {rdma/net}_dim, when no time delta between
samples. Coverity reported this potential use of an uninitialized
variable.

Fixes: 4c4dbb4a7363 ("net/mlx5e: Move dynamic interrupt coalescing code to include/linux")
Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
Signed-off-by: Roy Novich <royno@nvidia.com>
Reviewed-by: Aya Levin <ayal@nvidia.com>
Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
Link: https://lore.kernel.org/r/20230507135743.138993-1-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/dim.h
lib/dim/dim.c
lib/dim/net_dim.c
lib/dim/rdma_dim.c

index 6c57339..f343bc9 100644 (file)
@@ -236,8 +236,9 @@ void dim_park_tired(struct dim *dim);
  *
  * Calculate the delta between two samples (in data rates).
  * Takes into consideration counter wrap-around.
+ * Returned boolean indicates whether curr_stats are reliable.
  */
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
                    struct dim_stats *curr_stats);
 
 /**
index 38045d6..e89aaf0 100644 (file)
@@ -54,7 +54,7 @@ void dim_park_tired(struct dim *dim)
 }
 EXPORT_SYMBOL(dim_park_tired);
 
-void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
+bool dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
                    struct dim_stats *curr_stats)
 {
        /* u32 holds up to 71 minutes, should be enough */
@@ -66,7 +66,7 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
                             start->comp_ctr);
 
        if (!delta_us)
-               return;
+               return false;
 
        curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
        curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
@@ -79,5 +79,6 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,
        else
                curr_stats->cpe_ratio = 0;
 
+       return true;
 }
 EXPORT_SYMBOL(dim_calc_stats);
index 53f6b9c..4e32f7a 100644 (file)
@@ -227,7 +227,8 @@ void net_dim(struct dim *dim, struct dim_sample end_sample)
                                  dim->start_sample.event_ctr);
                if (nevents < DIM_NEVENTS)
                        break;
-               dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats);
+               if (!dim_calc_stats(&dim->start_sample, &end_sample, &curr_stats))
+                       break;
                if (net_dim_decision(&curr_stats, dim)) {
                        dim->state = DIM_APPLY_NEW_PROFILE;
                        schedule_work(&dim->work);
index 15462d5..88f7794 100644 (file)
@@ -88,7 +88,8 @@ void rdma_dim(struct dim *dim, u64 completions)
                nevents = curr_sample->event_ctr - dim->start_sample.event_ctr;
                if (nevents < DIM_NEVENTS)
                        break;
-               dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats);
+               if (!dim_calc_stats(&dim->start_sample, curr_sample, &curr_stats))
+                       break;
                if (rdma_dim_decision(&curr_stats, dim)) {
                        dim->state = DIM_APPLY_NEW_PROFILE;
                        schedule_work(&dim->work);