[PATCH] cpuhp: Expedite synchronize_rcu during SMT switch

Vishal Chourasia posted 1 patch 2 weeks, 5 days ago
There is a newer version of this series
include/linux/rcupdate.h | 3 +++
kernel/cpu.c             | 4 ++++
2 files changed, 7 insertions(+)
[PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Vishal Chourasia 2 weeks, 5 days ago
Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] path to
accelerate the operation.

Bulk CPU hotplug operations—such as switching SMT modes across all
cores—require hotplugging multiple CPUs in rapid succession. On large
systems, this process takes significant time, increasing as the number
of CPUs to hotplug during SMT switch grows, leading to substantial
delays on high-core-count machines. Analysis [1] reveals that the
majority of this time is spent waiting for synchronize_rcu().

SMT switch is a user-initiated administrative task, it should complete
as quickly as possible.

Performance data on a PPC64 system with 2048 CPUs:

+ ppc64_cpu --smt=1 (SMT8 to SMT1)
Before: real 30m53.194s
After:  real 6m4.678s  # ~5x improvement

+ ppc64_cpu --smt=8 (SMT1 to SMT8)
Before: real 49m5.920s
After:  real 36m47.798s  # ~1.3x improvement

[1] https://lore.kernel.org/all/5f2ab8a44d685701fe36cdaa8042a1aef215d10d.camel@linux.vnet.ibm.com

Signed-off-by: Vishal Chourasia <vishalc@linux.ibm.com>
Tested-by: Samir M <samir@linux.ibm.com>

---
 include/linux/rcupdate.h | 3 +++
 kernel/cpu.c             | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c5b30054cd01..03c06cfb2b6d 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -1192,6 +1192,9 @@ rcu_head_after_call_rcu(struct rcu_head *rhp, rcu_callback_t f)
 extern int rcu_expedited;
 extern int rcu_normal;
 
+extern void rcu_expedite_gp(void);
+extern void rcu_unexpedite_gp(void);
+
 DEFINE_LOCK_GUARD_0(rcu,
 	do {
 		rcu_read_lock();
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8df2d773fe3b..a264d7170842 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
 	int cpu, ret = 0;
 
 	cpu_maps_update_begin();
+	rcu_expedite_gp();
 	for_each_online_cpu(cpu) {
 		if (topology_is_primary_thread(cpu))
 			continue;
@@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
 	}
 	if (!ret)
 		cpu_smt_control = ctrlval;
+	rcu_unexpedite_gp();
 	cpu_maps_update_done();
 	return ret;
 }
@@ -2716,6 +2718,7 @@ int cpuhp_smt_enable(void)
 
 	cpu_maps_update_begin();
 	cpu_smt_control = CPU_SMT_ENABLED;
+	rcu_expedite_gp();
 	for_each_present_cpu(cpu) {
 		/* Skip online CPUs and CPUs on offline nodes */
 		if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
@@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
 		/* See comment in cpuhp_smt_disable() */
 		cpuhp_online_cpu_device(cpu);
 	}
+	rcu_unexpedite_gp();
 	cpu_maps_update_done();
 	return ret;
 }
-- 
2.52.0

Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Peter Zijlstra 2 weeks, 5 days ago
On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
> Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] path to
> accelerate the operation.
> 
> Bulk CPU hotplug operations—such as switching SMT modes across all
> cores—require hotplugging multiple CPUs in rapid succession. On large
> systems, this process takes significant time, increasing as the number
> of CPUs to hotplug during SMT switch grows, leading to substantial
> delays on high-core-count machines. Analysis [1] reveals that the
> majority of this time is spent waiting for synchronize_rcu().
> 

You seem to have left out all the useful bits from your changelog again
:/

Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
something we can't live with either.

Also, memory got jogged and I think something like the below will remove
2/3 of your rcu woes as well.

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8df2d773fe3b..1365c19444b2 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
 	int cpu, ret = 0;
 
 	cpu_maps_update_begin();
+	rcu_sync_enter(&cpu_hotplug_lock.rss);
 	for_each_online_cpu(cpu) {
 		if (topology_is_primary_thread(cpu))
 			continue;
@@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
 	}
 	if (!ret)
 		cpu_smt_control = ctrlval;
+	rcu_sync_exit(&cpu_hotplug_lock.rss);
 	cpu_maps_update_done();
 	return ret;
 }
@@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
 	int cpu, ret = 0;
 
 	cpu_maps_update_begin();
+	rcu_sync_enter(&cpu_hotplug_lock.rss);
 	cpu_smt_control = CPU_SMT_ENABLED;
 	for_each_present_cpu(cpu) {
 		/* Skip online CPUs and CPUs on offline nodes */
@@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
 		/* See comment in cpuhp_smt_disable() */
 		cpuhp_online_cpu_device(cpu);
 	}
+	rcu_sync_exit(&cpu_hotplug_lock.rss);
 	cpu_maps_update_done();
 	return ret;
 }
Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Samir M 1 week, 3 days ago
On 19/01/26 5:13 pm, Peter Zijlstra wrote:
> On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
>> Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] path to
>> accelerate the operation.
>>
>> Bulk CPU hotplug operations—such as switching SMT modes across all
>> cores—require hotplugging multiple CPUs in rapid succession. On large
>> systems, this process takes significant time, increasing as the number
>> of CPUs to hotplug during SMT switch grows, leading to substantial
>> delays on high-core-count machines. Analysis [1] reveals that the
>> majority of this time is spent waiting for synchronize_rcu().
>>
> You seem to have left out all the useful bits from your changelog again
> :/
>
> Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
> something we can't live with either.
>
> Also, memory got jogged and I think something like the below will remove
> 2/3 of your rcu woes as well.
>
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 8df2d773fe3b..1365c19444b2 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
>   	int cpu, ret = 0;
>   
>   	cpu_maps_update_begin();
> +	rcu_sync_enter(&cpu_hotplug_lock.rss);
>   	for_each_online_cpu(cpu) {
>   		if (topology_is_primary_thread(cpu))
>   			continue;
> @@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
>   	}
>   	if (!ret)
>   		cpu_smt_control = ctrlval;
> +	rcu_sync_exit(&cpu_hotplug_lock.rss);
>   	cpu_maps_update_done();
>   	return ret;
>   }
> @@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
>   	int cpu, ret = 0;
>   
>   	cpu_maps_update_begin();
> +	rcu_sync_enter(&cpu_hotplug_lock.rss);
>   	cpu_smt_control = CPU_SMT_ENABLED;
>   	for_each_present_cpu(cpu) {
>   		/* Skip online CPUs and CPUs on offline nodes */
> @@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
>   		/* See comment in cpuhp_smt_disable() */
>   		cpuhp_online_cpu_device(cpu);
>   	}
> +	rcu_sync_exit(&cpu_hotplug_lock.rss);
>   	cpu_maps_update_done();
>   	return ret;
>   }


Hi,

I verified this patch using the configuration described below.
Configuration:
     •    Kernel version: 6.19.0-rc6
     •    Number of CPUs: 1536

Earlier verification of an older version of this patch was performed on 
a system with *2048 CPUs*. Due to system unavailability, the current 
verification was carried out on a *different system.*


Using this setup, I evaluated the patch with both SMT enabled and SMT 
disabled. patch shows a significant improvement in the SMT=off case and 
a measurable improvement in the SMT=on case.
The results indicate that when SMT is enabled, the system time is 
noticeably higher. In contrast, with SMT disabled, no significant 
increase in system time is observed.

SMT=ON  -> sys 50m42.805s
SMT=OFF -> sys 0m0.064s


SMT Mode    | Without Patch    | With Patch   | % Improvement   |
------------------------------------------------------------------
SMT=off     | 20m 32.210s      |  5m 30.898s  | +73.15%         |
SMT=on      | 62m 46.549s      | 55m 45.671s  | +11.18%         |


Please add below tag: 
Tested-by: Samir M <samir@linux.ibm.com>

Regards,
Samir

Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Samir M 4 days, 8 hours ago
On 27/01/26 11:18 pm, Samir M wrote:
>
> On 19/01/26 5:13 pm, Peter Zijlstra wrote:
>> On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
>>> Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] 
>>> path to
>>> accelerate the operation.
>>>
>>> Bulk CPU hotplug operations—such as switching SMT modes across all
>>> cores—require hotplugging multiple CPUs in rapid succession. On large
>>> systems, this process takes significant time, increasing as the number
>>> of CPUs to hotplug during SMT switch grows, leading to substantial
>>> delays on high-core-count machines. Analysis [1] reveals that the
>>> majority of this time is spent waiting for synchronize_rcu().
>>>
>> You seem to have left out all the useful bits from your changelog again
>> :/
>>
>> Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
>> something we can't live with either.
>>
>> Also, memory got jogged and I think something like the below will remove
>> 2/3 of your rcu woes as well.
>>
>> diff --git a/kernel/cpu.c b/kernel/cpu.c
>> index 8df2d773fe3b..1365c19444b2 100644
>> --- a/kernel/cpu.c
>> +++ b/kernel/cpu.c
>> @@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control 
>> ctrlval)
>>       int cpu, ret = 0;
>>         cpu_maps_update_begin();
>> +    rcu_sync_enter(&cpu_hotplug_lock.rss);
>>       for_each_online_cpu(cpu) {
>>           if (topology_is_primary_thread(cpu))
>>               continue;
>> @@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control 
>> ctrlval)
>>       }
>>       if (!ret)
>>           cpu_smt_control = ctrlval;
>> +    rcu_sync_exit(&cpu_hotplug_lock.rss);
>>       cpu_maps_update_done();
>>       return ret;
>>   }
>> @@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
>>       int cpu, ret = 0;
>>         cpu_maps_update_begin();
>> +    rcu_sync_enter(&cpu_hotplug_lock.rss);
>>       cpu_smt_control = CPU_SMT_ENABLED;
>>       for_each_present_cpu(cpu) {
>>           /* Skip online CPUs and CPUs on offline nodes */
>> @@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
>>           /* See comment in cpuhp_smt_disable() */
>>           cpuhp_online_cpu_device(cpu);
>>       }
>> +    rcu_sync_exit(&cpu_hotplug_lock.rss);
>>       cpu_maps_update_done();
>>       return ret;
>>   }
>
>
> Hi,
>
> I verified this patch using the configuration described below.
> Configuration:
>     •    Kernel version: 6.19.0-rc6
>     •    Number of CPUs: 1536
>
> Earlier verification of an older version of this patch was performed 
> on a system with *2048 CPUs*. Due to system unavailability, the 
> current verification was carried out on a *different system.*
>
>
> Using this setup, I evaluated the patch with both SMT enabled and SMT 
> disabled. patch shows a significant improvement in the SMT=off case 
> and a measurable improvement in the SMT=on case.
> The results indicate that when SMT is enabled, the system time is 
> noticeably higher. In contrast, with SMT disabled, no significant 
> increase in system time is observed.
>
> SMT=ON  -> sys 50m42.805s
> SMT=OFF -> sys 0m0.064s
>
>
> SMT Mode    | Without Patch    | With Patch   | % Improvement   |
> ------------------------------------------------------------------
> SMT=off     | 20m 32.210s      |  5m 30.898s  | +73.15%         |
> SMT=on      | 62m 46.549s      | 55m 45.671s  | +11.18%         |
>
>
> Please add below tag: 
Tested-by: Samir M <samir@linux.ibm.com>
>
> Regards,
> Samir
>
Hi All,


Apologies for the confusion in the previous report.
In the previous report, I used the b4 am command to apply the patch. As 
a result, all patches in the mail thread were applied, rather than only 
the intended one.
Consequently, the results that were posted earlier included changes from 
multiple patches, and therefore cannot be considered valid for 
evaluating this patch in isolation.
We have since tested Peter’s patch separately, applied in isolation. 
Based on this testing, we did not observe any improvement in the SMT 
timing details.

Configuration:
     •    Kernel version: 6.19.0-rc6
     •    Number of CPUs: 1536

SMT Mode    | Without Patch    | With Patch  | % Improvement  |
------------------------------------------------------------------
SMT=off     | 20m 32.210s      |  20m22.441s  | +0.79%         |
SMT=on      | 62m 46.549s      |  63m0.532s  | -0.37%         |

Regards,
Samir




Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Samir M 1 week, 2 days ago
On 27/01/26 11:18 pm, Samir M wrote:
>
> On 19/01/26 5:13 pm, Peter Zijlstra wrote:
>> On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
>>> Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] 
>>> path to
>>> accelerate the operation.
>>>
>>> Bulk CPU hotplug operations—such as switching SMT modes across all
>>> cores—require hotplugging multiple CPUs in rapid succession. On large
>>> systems, this process takes significant time, increasing as the number
>>> of CPUs to hotplug during SMT switch grows, leading to substantial
>>> delays on high-core-count machines. Analysis [1] reveals that the
>>> majority of this time is spent waiting for synchronize_rcu().
>>>
>> You seem to have left out all the useful bits from your changelog again
>> :/
>>
>> Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
>> something we can't live with either.
>>
>> Also, memory got jogged and I think something like the below will remove
>> 2/3 of your rcu woes as well.
>>
>> diff --git a/kernel/cpu.c b/kernel/cpu.c
>> index 8df2d773fe3b..1365c19444b2 100644
>> --- a/kernel/cpu.c
>> +++ b/kernel/cpu.c
>> @@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control 
>> ctrlval)
>>       int cpu, ret = 0;
>>         cpu_maps_update_begin();
>> +    rcu_sync_enter(&cpu_hotplug_lock.rss);
>>       for_each_online_cpu(cpu) {
>>           if (topology_is_primary_thread(cpu))
>>               continue;
>> @@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control 
>> ctrlval)
>>       }
>>       if (!ret)
>>           cpu_smt_control = ctrlval;
>> +    rcu_sync_exit(&cpu_hotplug_lock.rss);
>>       cpu_maps_update_done();
>>       return ret;
>>   }
>> @@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
>>       int cpu, ret = 0;
>>         cpu_maps_update_begin();
>> +    rcu_sync_enter(&cpu_hotplug_lock.rss);
>>       cpu_smt_control = CPU_SMT_ENABLED;
>>       for_each_present_cpu(cpu) {
>>           /* Skip online CPUs and CPUs on offline nodes */
>> @@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
>>           /* See comment in cpuhp_smt_disable() */
>>           cpuhp_online_cpu_device(cpu);
>>       }
>> +    rcu_sync_exit(&cpu_hotplug_lock.rss);
>>       cpu_maps_update_done();
>>       return ret;
>>   }
>
>
> Hi,
>
> I verified this patch using the configuration described below.
> Configuration:
>     •    Kernel version: 6.19.0-rc6
>     •    Number of CPUs: 1536
>
> Earlier verification of an older version of this patch was performed 
> on a system with *2048 CPUs*. Due to system unavailability, the 
> current verification was carried out on a *different system.*
>
>
> Using this setup, I evaluated the patch with both SMT enabled and SMT 
> disabled. patch shows a significant improvement in the SMT=off case 
> and a measurable improvement in the SMT=on case.
> The results indicate that when SMT is enabled, the system time is 
> noticeably higher. In contrast, with SMT disabled, no significant 
> increase in system time is observed.
>
> SMT=ON  -> sys 50m42.805s
> SMT=OFF -> sys 0m0.064s
>
>
> SMT Mode    | Without Patch    | With Patch   | % Improvement   |
> ------------------------------------------------------------------
> SMT=off     | 20m 32.210s      |  5m 30.898s  | +73.15%         |
> SMT=on      | 62m 46.549s      | 55m 45.671s  | +11.18%         |
>
>
> Please add below tag: 
Tested-by: Samir M <samir@linux.ibm.com>
>
> Regards,
> Samir
>
Hi All,

For reference, I am updating the results for the Vishal and Rezki patches.

Configuration:
Kernel version: 6.19.0-rc6
Number of CPUs: 1536

Earlier verification of an older revision of this patch was performed on 
a system with 2048 CPUs*.* Due to system unavailability, the current 
verification was carried out on a different**system. For reference, I am 
updating the results corresponding to the patches verified using the 
above configuration.


Patch: 
https://lore.kernel.org/all/20260112094332.66006-2-vishalc@linux.ibm.com/
SMT Mode    | Without Patch    | With Patch  | % Improvement   |
------------------------------------------------------------------
SMT=off     | 20m 32.210s      |  5m 31.807s | +73.09%        |
SMT=on      | 62m 46.549s      | 55m 48.801s  | +11.08%        |

SMT=ON  -> sys 50m44.105s
SMT=OFF -> sys 0m0.035s


patch: https://lore.kernel.org/all/20260114183415.286489-1-urezki@gmail.com/
SMT Mode    | Without Patch    | With Patch  | % Improvement   |
------------------------------------------------------------------
SMT=off     | 20m 32.210s      | 18m 2.012s  | +12.19%         |
SMT=on      | 62m 46.549s      | 62m 35.076s | +0.30%         |

SMT=ON  -> sys 50m43.806s
SMT=OFF -> sys 0m0.109s


Regards,
Samir




Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Shrikanth Hegde 2 weeks, 5 days ago
Hi Peter.

On 1/19/26 5:13 PM, Peter Zijlstra wrote:
> On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
>> Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] path to
>> accelerate the operation.
>>
>> Bulk CPU hotplug operations—such as switching SMT modes across all
>> cores—require hotplugging multiple CPUs in rapid succession. On large
>> systems, this process takes significant time, increasing as the number
>> of CPUs to hotplug during SMT switch grows, leading to substantial
>> delays on high-core-count machines. Analysis [1] reveals that the
>> majority of this time is spent waiting for synchronize_rcu().
>>
> 
> You seem to have left out all the useful bits from your changelog again
> :/
> 
> Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
> something we can't live with either.
> 
> Also, memory got jogged and I think something like the below will remove
> 2/3 of your rcu woes as well.
> 
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 8df2d773fe3b..1365c19444b2 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
>   	int cpu, ret = 0;
>   
>   	cpu_maps_update_begin();
> +	rcu_sync_enter(&cpu_hotplug_lock.rss);
>   	for_each_online_cpu(cpu) {
>   		if (topology_is_primary_thread(cpu))
>   			continue;
> @@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
>   	}
>   	if (!ret)
>   		cpu_smt_control = ctrlval;
> +	rcu_sync_exit(&cpu_hotplug_lock.rss);
>   	cpu_maps_update_done();
>   	return ret;
>   }
> @@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
>   	int cpu, ret = 0;
>   
>   	cpu_maps_update_begin();
> +	rcu_sync_enter(&cpu_hotplug_lock.rss);
>   	cpu_smt_control = CPU_SMT_ENABLED;
>   	for_each_present_cpu(cpu) {
>   		/* Skip online CPUs and CPUs on offline nodes */
> @@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
>   		/* See comment in cpuhp_smt_disable() */
>   		cpuhp_online_cpu_device(cpu);
>   	}
> +	rcu_sync_exit(&cpu_hotplug_lock.rss);
>   	cpu_maps_update_done();
>   	return ret;
>   }


Currently, cpuhp_smt_[enable/disable] calls _cpu_up/_cpu_down
which does the same in cpus_write_lock/unlock. though it is per
cpu enable/disable one after another.

How hoisting this up will help?
Re: [PATCH] cpuhp: Expedite synchronize_rcu during SMT switch
Posted by Peter Zijlstra 2 weeks, 5 days ago
On Mon, Jan 19, 2026 at 07:15:09PM +0530, Shrikanth Hegde wrote:
> Hi Peter.
> 
> On 1/19/26 5:13 PM, Peter Zijlstra wrote:
> > On Mon, Jan 19, 2026 at 04:17:40PM +0530, Vishal Chourasia wrote:
> > > Expedite synchronize_rcu() during the cpuhp_smt_[enable|disable] path to
> > > accelerate the operation.
> > > 
> > > Bulk CPU hotplug operations—such as switching SMT modes across all
> > > cores—require hotplugging multiple CPUs in rapid succession. On large
> > > systems, this process takes significant time, increasing as the number
> > > of CPUs to hotplug during SMT switch grows, leading to substantial
> > > delays on high-core-count machines. Analysis [1] reveals that the
> > > majority of this time is spent waiting for synchronize_rcu().
> > > 
> > 
> > You seem to have left out all the useful bits from your changelog again
> > :/
> > 
> > Anyway, ISTR Joel posted a patch hoisting a lock; it was a icky, but not
> > something we can't live with either.
> > 
> > Also, memory got jogged and I think something like the below will remove
> > 2/3 of your rcu woes as well.
> > 
> > diff --git a/kernel/cpu.c b/kernel/cpu.c
> > index 8df2d773fe3b..1365c19444b2 100644
> > --- a/kernel/cpu.c
> > +++ b/kernel/cpu.c
> > @@ -2669,6 +2669,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
> >   	int cpu, ret = 0;
> >   	cpu_maps_update_begin();
> > +	rcu_sync_enter(&cpu_hotplug_lock.rss);
> >   	for_each_online_cpu(cpu) {
> >   		if (topology_is_primary_thread(cpu))
> >   			continue;
> > @@ -2698,6 +2699,7 @@ int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
> >   	}
> >   	if (!ret)
> >   		cpu_smt_control = ctrlval;
> > +	rcu_sync_exit(&cpu_hotplug_lock.rss);
> >   	cpu_maps_update_done();
> >   	return ret;
> >   }
> > @@ -2715,6 +2717,7 @@ int cpuhp_smt_enable(void)
> >   	int cpu, ret = 0;
> >   	cpu_maps_update_begin();
> > +	rcu_sync_enter(&cpu_hotplug_lock.rss);
> >   	cpu_smt_control = CPU_SMT_ENABLED;
> >   	for_each_present_cpu(cpu) {
> >   		/* Skip online CPUs and CPUs on offline nodes */
> > @@ -2728,6 +2731,7 @@ int cpuhp_smt_enable(void)
> >   		/* See comment in cpuhp_smt_disable() */
> >   		cpuhp_online_cpu_device(cpu);
> >   	}
> > +	rcu_sync_exit(&cpu_hotplug_lock.rss);
> >   	cpu_maps_update_done();
> >   	return ret;
> >   }
> 
> 
> Currently, cpuhp_smt_[enable/disable] calls _cpu_up/_cpu_down
> which does the same in cpus_write_lock/unlock. though it is per
> cpu enable/disable one after another.
> 
> How hoisting this up will help?

By holding an extra rcu_sync reference, the percpu rwsem is kept into
the the slow path, avoiding the rcu-sync on down_write(), which was very
prevalent per this:

  https://lkml.kernel.org/r/aWU9HRcs4ghazIRg@linux.ibm.com