@@ -194,12 +194,13 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of,
194194/*
195195 * This is safe against intel_rdt_sched_in() called from __switch_to()
196196 * because __switch_to() is executed with interrupts disabled. A local call
197- * from rdt_update_percpu_closid () is proteced against __switch_to() because
197+ * from rdt_update_closid () is proteced against __switch_to() because
198198 * preemption is disabled.
199199 */
200- static void rdt_update_cpu_closid (void * v )
200+ static void rdt_update_cpu_closid (void * closid )
201201{
202- this_cpu_write (cpu_closid , * (int * )v );
202+ if (closid )
203+ this_cpu_write (cpu_closid , * (int * )closid );
203204 /*
204205 * We cannot unconditionally write the MSR because the current
205206 * executing task might have its own closid selected. Just reuse
@@ -208,14 +209,23 @@ static void rdt_update_cpu_closid(void *v)
208209 intel_rdt_sched_in ();
209210}
210211
211- /* Update the per cpu closid and eventually the PGR_ASSOC MSR */
212- static void rdt_update_percpu_closid (const struct cpumask * cpu_mask , int closid )
212+ /*
213+ * Update the PGR_ASSOC MSR on all cpus in @cpu_mask,
214+ *
215+ * Per task closids must have been set up before calling this function.
216+ *
217+ * The per cpu closids are updated with the smp function call, when @closid
218+ * is not NULL. If @closid is NULL then all affected percpu closids must
219+ * have been set up before calling this function.
220+ */
221+ static void
222+ rdt_update_closid (const struct cpumask * cpu_mask , int * closid )
213223{
214224 int cpu = get_cpu ();
215225
216226 if (cpumask_test_cpu (cpu , cpu_mask ))
217- rdt_update_cpu_closid (& closid );
218- smp_call_function_many (cpu_mask , rdt_update_cpu_closid , & closid , 1 );
227+ rdt_update_cpu_closid (closid );
228+ smp_call_function_many (cpu_mask , rdt_update_cpu_closid , closid , 1 );
219229 put_cpu ();
220230}
221231
@@ -264,7 +274,7 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of,
264274 /* Give any dropped cpus to rdtgroup_default */
265275 cpumask_or (& rdtgroup_default .cpu_mask ,
266276 & rdtgroup_default .cpu_mask , tmpmask );
267- rdt_update_percpu_closid (tmpmask , rdtgroup_default .closid );
277+ rdt_update_closid (tmpmask , & rdtgroup_default .closid );
268278 }
269279
270280 /*
@@ -278,7 +288,7 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of,
278288 continue ;
279289 cpumask_andnot (& r -> cpu_mask , & r -> cpu_mask , tmpmask );
280290 }
281- rdt_update_percpu_closid (tmpmask , rdtgrp -> closid );
291+ rdt_update_closid (tmpmask , & rdtgrp -> closid );
282292 }
283293
284294 /* Done pushing/pulling - update this group with new mask */
@@ -807,18 +817,49 @@ static int reset_all_cbms(struct rdt_resource *r)
807817}
808818
809819/*
810- * Forcibly remove all of subdirectories under root.
820+ * Move tasks from one to the other group. If @from is NULL, then all tasks
821+ * in the systems are moved unconditionally (used for teardown).
822+ *
823+ * If @mask is not NULL the cpus on which moved tasks are running are set
824+ * in that mask so the update smp function call is restricted to affected
825+ * cpus.
811826 */
812- static void rmdir_all_sub (void )
827+ static void rdt_move_group_tasks (struct rdtgroup * from , struct rdtgroup * to ,
828+ struct cpumask * mask )
813829{
814- struct rdtgroup * rdtgrp , * tmp ;
815830 struct task_struct * p , * t ;
816831
817- /* move all tasks to default resource group */
818832 read_lock (& tasklist_lock );
819- for_each_process_thread (p , t )
820- t -> closid = 0 ;
833+ for_each_process_thread (p , t ) {
834+ if (!from || t -> closid == from -> closid ) {
835+ t -> closid = to -> closid ;
836+ #ifdef CONFIG_SMP
837+ /*
838+ * This is safe on x86 w/o barriers as the ordering
839+ * of writing to task_cpu() and t->on_cpu is
840+ * reverse to the reading here. The detection is
841+ * inaccurate as tasks might move or schedule
842+ * before the smp function call takes place. In
843+ * such a case the function call is pointless, but
844+ * there is no other side effect.
845+ */
846+ if (mask && t -> on_cpu )
847+ cpumask_set_cpu (task_cpu (t ), mask );
848+ #endif
849+ }
850+ }
821851 read_unlock (& tasklist_lock );
852+ }
853+
854+ /*
855+ * Forcibly remove all of subdirectories under root.
856+ */
857+ static void rmdir_all_sub (void )
858+ {
859+ struct rdtgroup * rdtgrp , * tmp ;
860+
861+ /* Move all tasks to the default resource group */
862+ rdt_move_group_tasks (NULL , & rdtgroup_default , NULL );
822863
823864 list_for_each_entry_safe (rdtgrp , tmp , & rdt_all_groups , rdtgroup_list ) {
824865 /* Remove each rdtgroup other than root */
@@ -833,13 +874,15 @@ static void rmdir_all_sub(void)
833874 cpumask_or (& rdtgroup_default .cpu_mask ,
834875 & rdtgroup_default .cpu_mask , & rdtgrp -> cpu_mask );
835876
836- rdt_update_percpu_closid (& rdtgrp -> cpu_mask ,
837- rdtgroup_default .closid );
838-
839877 kernfs_remove (rdtgrp -> kn );
840878 list_del (& rdtgrp -> rdtgroup_list );
841879 kfree (rdtgrp );
842880 }
881+ /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */
882+ get_online_cpus ();
883+ rdt_update_closid (cpu_online_mask , & rdtgroup_default .closid );
884+ put_online_cpus ();
885+
843886 kernfs_remove (kn_info );
844887}
845888
@@ -944,27 +987,35 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
944987
945988static int rdtgroup_rmdir (struct kernfs_node * kn )
946989{
947- struct task_struct * p , * t ;
990+ int ret , cpu , closid = rdtgroup_default . closid ;
948991 struct rdtgroup * rdtgrp ;
992+ cpumask_var_t tmpmask ;
993+
994+ if (!zalloc_cpumask_var (& tmpmask , GFP_KERNEL ))
995+ return - ENOMEM ;
949996
950997 rdtgrp = rdtgroup_kn_lock_live (kn );
951998 if (!rdtgrp ) {
952- rdtgroup_kn_unlock ( kn ) ;
953- return - EPERM ;
999+ ret = - EPERM ;
1000+ goto out ;
9541001 }
9551002
9561003 /* Give any tasks back to the default group */
957- read_lock (& tasklist_lock );
958- for_each_process_thread (p , t ) {
959- if (t -> closid == rdtgrp -> closid )
960- t -> closid = 0 ;
961- }
962- read_unlock (& tasklist_lock );
1004+ rdt_move_group_tasks (rdtgrp , & rdtgroup_default , tmpmask );
9631005
9641006 /* Give any CPUs back to the default group */
9651007 cpumask_or (& rdtgroup_default .cpu_mask ,
9661008 & rdtgroup_default .cpu_mask , & rdtgrp -> cpu_mask );
967- rdt_update_percpu_closid (& rdtgrp -> cpu_mask , rdtgroup_default .closid );
1009+
1010+ /* Update per cpu closid of the moved CPUs first */
1011+ for_each_cpu (cpu , & rdtgrp -> cpu_mask )
1012+ per_cpu (cpu_closid , cpu ) = closid ;
1013+ /*
1014+ * Update the MSR on moved CPUs and CPUs which have moved
1015+ * task running on them.
1016+ */
1017+ cpumask_or (tmpmask , tmpmask , & rdtgrp -> cpu_mask );
1018+ rdt_update_closid (tmpmask , NULL );
9681019
9691020 rdtgrp -> flags = RDT_DELETED ;
9701021 closid_free (rdtgrp -> closid );
@@ -976,9 +1027,11 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
9761027 */
9771028 kernfs_get (kn );
9781029 kernfs_remove (rdtgrp -> kn );
979-
1030+ ret = 0 ;
1031+ out :
9801032 rdtgroup_kn_unlock (kn );
981- return 0 ;
1033+ free_cpumask_var (tmpmask );
1034+ return ret ;
9821035}
9831036
9841037static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = {
0 commit comments