@@ -726,11 +726,15 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of,
726
726
static void show_rdt_tasks (struct rdtgroup * r , struct seq_file * s )
727
727
{
728
728
struct task_struct * p , * t ;
729
+ pid_t pid ;
729
730
730
731
rcu_read_lock ();
731
732
for_each_process_thread (p , t ) {
732
- if (is_closid_match (t , r ) || is_rmid_match (t , r ))
733
- seq_printf (s , "%d\n" , t -> pid );
733
+ if (is_closid_match (t , r ) || is_rmid_match (t , r )) {
734
+ pid = task_pid_vnr (t );
735
+ if (pid )
736
+ seq_printf (s , "%d\n" , pid );
737
+ }
734
738
}
735
739
rcu_read_unlock ();
736
740
}
@@ -2301,15 +2305,34 @@ static struct rdtgroup *kernfs_to_rdtgroup(struct kernfs_node *kn)
2301
2305
}
2302
2306
}
2303
2307
2308
+ static void rdtgroup_kn_get (struct rdtgroup * rdtgrp , struct kernfs_node * kn )
2309
+ {
2310
+ atomic_inc (& rdtgrp -> waitcount );
2311
+ kernfs_break_active_protection (kn );
2312
+ }
2313
+
2314
+ static void rdtgroup_kn_put (struct rdtgroup * rdtgrp , struct kernfs_node * kn )
2315
+ {
2316
+ if (atomic_dec_and_test (& rdtgrp -> waitcount ) &&
2317
+ (rdtgrp -> flags & RDT_DELETED )) {
2318
+ if (rdtgrp -> mode == RDT_MODE_PSEUDO_LOCKSETUP ||
2319
+ rdtgrp -> mode == RDT_MODE_PSEUDO_LOCKED )
2320
+ rdtgroup_pseudo_lock_remove (rdtgrp );
2321
+ kernfs_unbreak_active_protection (kn );
2322
+ rdtgroup_remove (rdtgrp );
2323
+ } else {
2324
+ kernfs_unbreak_active_protection (kn );
2325
+ }
2326
+ }
2327
+
2304
2328
struct rdtgroup * rdtgroup_kn_lock_live (struct kernfs_node * kn )
2305
2329
{
2306
2330
struct rdtgroup * rdtgrp = kernfs_to_rdtgroup (kn );
2307
2331
2308
2332
if (!rdtgrp )
2309
2333
return NULL ;
2310
2334
2311
- atomic_inc (& rdtgrp -> waitcount );
2312
- kernfs_break_active_protection (kn );
2335
+ rdtgroup_kn_get (rdtgrp , kn );
2313
2336
2314
2337
mutex_lock (& rdtgroup_mutex );
2315
2338
@@ -2328,17 +2351,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
2328
2351
return ;
2329
2352
2330
2353
mutex_unlock (& rdtgroup_mutex );
2331
-
2332
- if (atomic_dec_and_test (& rdtgrp -> waitcount ) &&
2333
- (rdtgrp -> flags & RDT_DELETED )) {
2334
- if (rdtgrp -> mode == RDT_MODE_PSEUDO_LOCKSETUP ||
2335
- rdtgrp -> mode == RDT_MODE_PSEUDO_LOCKED )
2336
- rdtgroup_pseudo_lock_remove (rdtgrp );
2337
- kernfs_unbreak_active_protection (kn );
2338
- rdtgroup_remove (rdtgrp );
2339
- } else {
2340
- kernfs_unbreak_active_protection (kn );
2341
- }
2354
+ rdtgroup_kn_put (rdtgrp , kn );
2342
2355
}
2343
2356
2344
2357
static int mkdir_mondata_all (struct kernfs_node * parent_kn ,
@@ -3505,6 +3518,133 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
3505
3518
return ret ;
3506
3519
}
3507
3520
3521
+ /**
3522
+ * mongrp_reparent() - replace parent CTRL_MON group of a MON group
3523
+ * @rdtgrp: the MON group whose parent should be replaced
3524
+ * @new_prdtgrp: replacement parent CTRL_MON group for @rdtgrp
3525
+ * @cpus: cpumask provided by the caller for use during this call
3526
+ *
3527
+ * Replaces the parent CTRL_MON group for a MON group, resulting in all member
3528
+ * tasks' CLOSID immediately changing to that of the new parent group.
3529
+ * Monitoring data for the group is unaffected by this operation.
3530
+ */
3531
+ static void mongrp_reparent (struct rdtgroup * rdtgrp ,
3532
+ struct rdtgroup * new_prdtgrp ,
3533
+ cpumask_var_t cpus )
3534
+ {
3535
+ struct rdtgroup * prdtgrp = rdtgrp -> mon .parent ;
3536
+
3537
+ WARN_ON (rdtgrp -> type != RDTMON_GROUP );
3538
+ WARN_ON (new_prdtgrp -> type != RDTCTRL_GROUP );
3539
+
3540
+ /* Nothing to do when simply renaming a MON group. */
3541
+ if (prdtgrp == new_prdtgrp )
3542
+ return ;
3543
+
3544
+ WARN_ON (list_empty (& prdtgrp -> mon .crdtgrp_list ));
3545
+ list_move_tail (& rdtgrp -> mon .crdtgrp_list ,
3546
+ & new_prdtgrp -> mon .crdtgrp_list );
3547
+
3548
+ rdtgrp -> mon .parent = new_prdtgrp ;
3549
+ rdtgrp -> closid = new_prdtgrp -> closid ;
3550
+
3551
+ /* Propagate updated closid to all tasks in this group. */
3552
+ rdt_move_group_tasks (rdtgrp , rdtgrp , cpus );
3553
+
3554
+ update_closid_rmid (cpus , NULL );
3555
+ }
3556
+
3557
+ static int rdtgroup_rename (struct kernfs_node * kn ,
3558
+ struct kernfs_node * new_parent , const char * new_name )
3559
+ {
3560
+ struct rdtgroup * new_prdtgrp ;
3561
+ struct rdtgroup * rdtgrp ;
3562
+ cpumask_var_t tmpmask ;
3563
+ int ret ;
3564
+
3565
+ rdtgrp = kernfs_to_rdtgroup (kn );
3566
+ new_prdtgrp = kernfs_to_rdtgroup (new_parent );
3567
+ if (!rdtgrp || !new_prdtgrp )
3568
+ return - ENOENT ;
3569
+
3570
+ /* Release both kernfs active_refs before obtaining rdtgroup mutex. */
3571
+ rdtgroup_kn_get (rdtgrp , kn );
3572
+ rdtgroup_kn_get (new_prdtgrp , new_parent );
3573
+
3574
+ mutex_lock (& rdtgroup_mutex );
3575
+
3576
+ rdt_last_cmd_clear ();
3577
+
3578
+ /*
3579
+ * Don't allow kernfs_to_rdtgroup() to return a parent rdtgroup if
3580
+ * either kernfs_node is a file.
3581
+ */
3582
+ if (kernfs_type (kn ) != KERNFS_DIR ||
3583
+ kernfs_type (new_parent ) != KERNFS_DIR ) {
3584
+ rdt_last_cmd_puts ("Source and destination must be directories" );
3585
+ ret = - EPERM ;
3586
+ goto out ;
3587
+ }
3588
+
3589
+ if ((rdtgrp -> flags & RDT_DELETED ) || (new_prdtgrp -> flags & RDT_DELETED )) {
3590
+ ret = - ENOENT ;
3591
+ goto out ;
3592
+ }
3593
+
3594
+ if (rdtgrp -> type != RDTMON_GROUP || !kn -> parent ||
3595
+ !is_mon_groups (kn -> parent , kn -> name )) {
3596
+ rdt_last_cmd_puts ("Source must be a MON group\n" );
3597
+ ret = - EPERM ;
3598
+ goto out ;
3599
+ }
3600
+
3601
+ if (!is_mon_groups (new_parent , new_name )) {
3602
+ rdt_last_cmd_puts ("Destination must be a mon_groups subdirectory\n" );
3603
+ ret = - EPERM ;
3604
+ goto out ;
3605
+ }
3606
+
3607
+ /*
3608
+ * If the MON group is monitoring CPUs, the CPUs must be assigned to the
3609
+ * current parent CTRL_MON group and therefore cannot be assigned to
3610
+ * the new parent, making the move illegal.
3611
+ */
3612
+ if (!cpumask_empty (& rdtgrp -> cpu_mask ) &&
3613
+ rdtgrp -> mon .parent != new_prdtgrp ) {
3614
+ rdt_last_cmd_puts ("Cannot move a MON group that monitors CPUs\n" );
3615
+ ret = - EPERM ;
3616
+ goto out ;
3617
+ }
3618
+
3619
+ /*
3620
+ * Allocate the cpumask for use in mongrp_reparent() to avoid the
3621
+ * possibility of failing to allocate it after kernfs_rename() has
3622
+ * succeeded.
3623
+ */
3624
+ if (!zalloc_cpumask_var (& tmpmask , GFP_KERNEL )) {
3625
+ ret = - ENOMEM ;
3626
+ goto out ;
3627
+ }
3628
+
3629
+ /*
3630
+ * Perform all input validation and allocations needed to ensure
3631
+ * mongrp_reparent() will succeed before calling kernfs_rename(),
3632
+ * otherwise it would be necessary to revert this call if
3633
+ * mongrp_reparent() failed.
3634
+ */
3635
+ ret = kernfs_rename (kn , new_parent , new_name );
3636
+ if (!ret )
3637
+ mongrp_reparent (rdtgrp , new_prdtgrp , tmpmask );
3638
+
3639
+ free_cpumask_var (tmpmask );
3640
+
3641
+ out :
3642
+ mutex_unlock (& rdtgroup_mutex );
3643
+ rdtgroup_kn_put (rdtgrp , kn );
3644
+ rdtgroup_kn_put (new_prdtgrp , new_parent );
3645
+ return ret ;
3646
+ }
3647
+
3508
3648
static int rdtgroup_show_options (struct seq_file * seq , struct kernfs_root * kf )
3509
3649
{
3510
3650
if (resctrl_arch_get_cdp_enabled (RDT_RESOURCE_L3 ))
@@ -3522,6 +3662,7 @@ static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)
3522
3662
static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = {
3523
3663
.mkdir = rdtgroup_mkdir ,
3524
3664
.rmdir = rdtgroup_rmdir ,
3665
+ .rename = rdtgroup_rename ,
3525
3666
.show_options = rdtgroup_show_options ,
3526
3667
};
3527
3668
0 commit comments