diff mbox series

x86/platform/uv: Dont use smp_processor_id while preemptable

Message ID 20220520203755.266337-1-mike.travis@hpe.com (mailing list archive)
State Deferred, archived
Headers show
Series x86/platform/uv: Dont use smp_processor_id while preemptable | expand

Commit Message

Mike Travis May 20, 2022, 8:37 p.m. UTC
To avoid a "BUG: using smp_processor_id() in preemptible" debug
warning message, disable preemption around use of the processor id.

Signed-off-by: Mike Travis <mike.travis@hpe.com>
Reviewed-by: Steve Wahl <steve.wahl@hpe.com>
Reviewed-by: Dimitri Sivanich <dimitri.sivanich@hpe.com>
---
 arch/x86/platform/uv/uv_time.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Hans de Goede May 21, 2022, 1:57 p.m. UTC | #1
Hi Mike,

On 5/20/22 22:37, Mike Travis wrote:
> To avoid a "BUG: using smp_processor_id() in preemptible" debug
> warning message, disable preemption around use of the processor id.
> 
> Signed-off-by: Mike Travis <mike.travis@hpe.com>
> Reviewed-by: Steve Wahl <steve.wahl@hpe.com>
> Reviewed-by: Dimitri Sivanich <dimitri.sivanich@hpe.com>

A git blame shows that this code has been around for quite
a while; so presumably this should be backported to some of
the stable kernel series ?

Maybe add an appropriate Cc: stable tag with the range of
kernels this should be added to and/or add a Fixes: tag?

Regards,

Hans


> ---
>  arch/x86/platform/uv/uv_time.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c
> index 54663f3e00cb..094190814a28 100644
> --- a/arch/x86/platform/uv/uv_time.c
> +++ b/arch/x86/platform/uv/uv_time.c
> @@ -275,14 +275,17 @@ static int uv_rtc_unset_timer(int cpu, int force)
>   */
>  static u64 uv_read_rtc(struct clocksource *cs)
>  {
> -	unsigned long offset;
> +	unsigned long offset, time;
> +	unsigned int cpu = get_cpu();
>  
>  	if (uv_get_min_hub_revision_id() == 1)
>  		offset = 0;
>  	else
> -		offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;
> +		offset = (uv_cpu_blade_processor_id(cpu) * L1_CACHE_BYTES) % PAGE_SIZE;
>  
> -	return (u64)uv_read_local_mmr(UVH_RTC | offset);
> +	time = (u64)uv_read_local_mmr(UVH_RTC | offset);
> +	put_cpu();
> +	return time;
>  }
>  
>  /*
Mike Travis May 21, 2022, 6:50 p.m. UTC | #2
Thanks, I'll do that.
Dave Hansen May 26, 2022, 3:30 p.m. UTC | #3
On 5/20/22 13:37, Mike Travis wrote:
> To avoid a "BUG: using smp_processor_id() in preemptible" debug
> warning message, disable preemption around use of the processor id.

I'm sure this gets rid of the warning.  But, could you please take a
quick look at the callers and ensure that they can handle if this read
comes from another CPU?

In other words, what would actually go wrong if uv_read_rtc() got
preempted in this region?  What would this actually fix?
Mike Travis May 26, 2022, 10:53 p.m. UTC | #4
Dave Hansen <dave.hansen@intel.com> wrote:
  On 5/20/22 13:37, Mike Travis wrote:
  > To avoid a "BUG: using smp_processor_id() in preemptible" debug
  > warning message, disable preemption around use of the processor id.

>I'm sure this gets rid of the warning.  But, could you please take a
>quick look at the callers and ensure that they can handle if this read
>comes from another CPU?
>
>In other words, what would actually go wrong if uv_read_rtc() got
>preempted in this region?  What would this actually fix?

I talked with the author of this driver and among the preemption scenarios it always returns the same system time.  And due to the round robin aspect of the request scheduling, getting an earlier time when a second CPU reads it's time is not possible.  So getting rid of the debug warning message seems to be the only benefit from this patch.
diff mbox series

Patch

diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c
index 54663f3e00cb..094190814a28 100644
--- a/arch/x86/platform/uv/uv_time.c
+++ b/arch/x86/platform/uv/uv_time.c
@@ -275,14 +275,17 @@  static int uv_rtc_unset_timer(int cpu, int force)
  */
 static u64 uv_read_rtc(struct clocksource *cs)
 {
-	unsigned long offset;
+	unsigned long offset, time;
+	unsigned int cpu = get_cpu();
 
 	if (uv_get_min_hub_revision_id() == 1)
 		offset = 0;
 	else
-		offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;
+		offset = (uv_cpu_blade_processor_id(cpu) * L1_CACHE_BYTES) % PAGE_SIZE;
 
-	return (u64)uv_read_local_mmr(UVH_RTC | offset);
+	time = (u64)uv_read_local_mmr(UVH_RTC | offset);
+	put_cpu();
+	return time;
 }
 
 /*