@@ -507,6 +507,24 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of,
507
507
return ret ?: nbytes ;
508
508
}
509
509
510
+ /**
511
+ * rdtgroup_remove - the helper to remove resource group safely
512
+ * @rdtgrp: resource group to remove
513
+ *
514
+ * On resource group creation via a mkdir, an extra kernfs_node reference is
515
+ * taken to ensure that the rdtgroup structure remains accessible for the
516
+ * rdtgroup_kn_unlock() calls where it is removed.
517
+ *
518
+ * Drop the extra reference here, then free the rdtgroup structure.
519
+ *
520
+ * Return: void
521
+ */
522
+ static void rdtgroup_remove (struct rdtgroup * rdtgrp )
523
+ {
524
+ kernfs_put (rdtgrp -> kn );
525
+ kfree (rdtgrp );
526
+ }
527
+
510
528
struct task_move_callback {
511
529
struct callback_head work ;
512
530
struct rdtgroup * rdtgrp ;
@@ -529,7 +547,7 @@ static void move_myself(struct callback_head *head)
529
547
(rdtgrp -> flags & RDT_DELETED )) {
530
548
current -> closid = 0 ;
531
549
current -> rmid = 0 ;
532
- kfree (rdtgrp );
550
+ rdtgroup_remove (rdtgrp );
533
551
}
534
552
535
553
if (unlikely (current -> flags & PF_EXITING ))
@@ -1769,7 +1787,6 @@ static int rdtgroup_mkdir_info_resdir(struct rdt_resource *r, char *name,
1769
1787
if (IS_ERR (kn_subdir ))
1770
1788
return PTR_ERR (kn_subdir );
1771
1789
1772
- kernfs_get (kn_subdir );
1773
1790
ret = rdtgroup_kn_set_ugid (kn_subdir );
1774
1791
if (ret )
1775
1792
return ret ;
@@ -1792,7 +1809,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
1792
1809
kn_info = kernfs_create_dir (parent_kn , "info" , parent_kn -> mode , NULL );
1793
1810
if (IS_ERR (kn_info ))
1794
1811
return PTR_ERR (kn_info );
1795
- kernfs_get (kn_info );
1796
1812
1797
1813
ret = rdtgroup_add_files (kn_info , RF_TOP_INFO );
1798
1814
if (ret )
@@ -1813,12 +1829,6 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn)
1813
1829
goto out_destroy ;
1814
1830
}
1815
1831
1816
- /*
1817
- * This extra ref will be put in kernfs_remove() and guarantees
1818
- * that @rdtgrp->kn is always accessible.
1819
- */
1820
- kernfs_get (kn_info );
1821
-
1822
1832
ret = rdtgroup_kn_set_ugid (kn_info );
1823
1833
if (ret )
1824
1834
goto out_destroy ;
@@ -1847,12 +1857,6 @@ mongroup_create_dir(struct kernfs_node *parent_kn, struct rdtgroup *prgrp,
1847
1857
if (dest_kn )
1848
1858
* dest_kn = kn ;
1849
1859
1850
- /*
1851
- * This extra ref will be put in kernfs_remove() and guarantees
1852
- * that @rdtgrp->kn is always accessible.
1853
- */
1854
- kernfs_get (kn );
1855
-
1856
1860
ret = rdtgroup_kn_set_ugid (kn );
1857
1861
if (ret )
1858
1862
goto out_destroy ;
@@ -2079,8 +2083,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
2079
2083
rdtgrp -> mode == RDT_MODE_PSEUDO_LOCKED )
2080
2084
rdtgroup_pseudo_lock_remove (rdtgrp );
2081
2085
kernfs_unbreak_active_protection (kn );
2082
- kernfs_put (rdtgrp -> kn );
2083
- kfree (rdtgrp );
2086
+ rdtgroup_remove (rdtgrp );
2084
2087
} else {
2085
2088
kernfs_unbreak_active_protection (kn );
2086
2089
}
@@ -2139,13 +2142,11 @@ static int rdt_get_tree(struct fs_context *fc)
2139
2142
& kn_mongrp );
2140
2143
if (ret < 0 )
2141
2144
goto out_info ;
2142
- kernfs_get (kn_mongrp );
2143
2145
2144
2146
ret = mkdir_mondata_all (rdtgroup_default .kn ,
2145
2147
& rdtgroup_default , & kn_mondata );
2146
2148
if (ret < 0 )
2147
2149
goto out_mongrp ;
2148
- kernfs_get (kn_mondata );
2149
2150
rdtgroup_default .mon .mon_data_kn = kn_mondata ;
2150
2151
}
2151
2152
@@ -2357,7 +2358,7 @@ static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp)
2357
2358
if (atomic_read (& sentry -> waitcount ) != 0 )
2358
2359
sentry -> flags = RDT_DELETED ;
2359
2360
else
2360
- kfree (sentry );
2361
+ rdtgroup_remove (sentry );
2361
2362
}
2362
2363
}
2363
2364
@@ -2399,7 +2400,7 @@ static void rmdir_all_sub(void)
2399
2400
if (atomic_read (& rdtgrp -> waitcount ) != 0 )
2400
2401
rdtgrp -> flags = RDT_DELETED ;
2401
2402
else
2402
- kfree (rdtgrp );
2403
+ rdtgroup_remove (rdtgrp );
2403
2404
}
2404
2405
/* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */
2405
2406
update_closid_rmid (cpu_online_mask , & rdtgroup_default );
@@ -2499,11 +2500,6 @@ static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
2499
2500
if (IS_ERR (kn ))
2500
2501
return PTR_ERR (kn );
2501
2502
2502
- /*
2503
- * This extra ref will be put in kernfs_remove() and guarantees
2504
- * that kn is always accessible.
2505
- */
2506
- kernfs_get (kn );
2507
2503
ret = rdtgroup_kn_set_ugid (kn );
2508
2504
if (ret )
2509
2505
goto out_destroy ;
@@ -2838,8 +2834,8 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
2838
2834
/*
2839
2835
* kernfs_remove() will drop the reference count on "kn" which
2840
2836
* will free it. But we still need it to stick around for the
2841
- * rdtgroup_kn_unlock(kn} call below . Take one extra reference
2842
- * here, which will be dropped inside rdtgroup_kn_unlock ().
2837
+ * rdtgroup_kn_unlock(kn) call. Take one extra reference here,
2838
+ * which will be dropped by kernfs_put() in rdtgroup_remove ().
2843
2839
*/
2844
2840
kernfs_get (kn );
2845
2841
@@ -2880,6 +2876,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
2880
2876
out_idfree :
2881
2877
free_rmid (rdtgrp -> mon .rmid );
2882
2878
out_destroy :
2879
+ kernfs_put (rdtgrp -> kn );
2883
2880
kernfs_remove (rdtgrp -> kn );
2884
2881
out_free_rgrp :
2885
2882
kfree (rdtgrp );
@@ -2892,7 +2889,7 @@ static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp)
2892
2889
{
2893
2890
kernfs_remove (rgrp -> kn );
2894
2891
free_rmid (rgrp -> mon .rmid );
2895
- kfree (rgrp );
2892
+ rdtgroup_remove (rgrp );
2896
2893
}
2897
2894
2898
2895
/*
@@ -3049,11 +3046,6 @@ static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp,
3049
3046
WARN_ON (list_empty (& prdtgrp -> mon .crdtgrp_list ));
3050
3047
list_del (& rdtgrp -> mon .crdtgrp_list );
3051
3048
3052
- /*
3053
- * one extra hold on this, will drop when we kfree(rdtgrp)
3054
- * in rdtgroup_kn_unlock()
3055
- */
3056
- kernfs_get (kn );
3057
3049
kernfs_remove (rdtgrp -> kn );
3058
3050
3059
3051
return 0 ;
@@ -3065,11 +3057,6 @@ static int rdtgroup_ctrl_remove(struct kernfs_node *kn,
3065
3057
rdtgrp -> flags = RDT_DELETED ;
3066
3058
list_del (& rdtgrp -> rdtgroup_list );
3067
3059
3068
- /*
3069
- * one extra hold on this, will drop when we kfree(rdtgrp)
3070
- * in rdtgroup_kn_unlock()
3071
- */
3072
- kernfs_get (kn );
3073
3060
kernfs_remove (rdtgrp -> kn );
3074
3061
return 0 ;
3075
3062
}
0 commit comments