@@ -1392,6 +1392,9 @@ static void cgroup_destroy_root(struct cgroup_root *root)
1392
1392
cgroup_free_root (root );
1393
1393
}
1394
1394
1395
+ /*
1396
+ * Returned cgroup is without refcount but it's valid as long as cset pins it.
1397
+ */
1395
1398
static inline struct cgroup * __cset_cgroup_from_root (struct css_set * cset ,
1396
1399
struct cgroup_root * root )
1397
1400
{
@@ -1403,6 +1406,7 @@ static inline struct cgroup *__cset_cgroup_from_root(struct css_set *cset,
1403
1406
res_cgroup = cset -> dfl_cgrp ;
1404
1407
} else {
1405
1408
struct cgrp_cset_link * link ;
1409
+ lockdep_assert_held (& css_set_lock );
1406
1410
1407
1411
list_for_each_entry (link , & cset -> cgrp_links , cgrp_link ) {
1408
1412
struct cgroup * c = link -> cgrp ;
@@ -1414,6 +1418,7 @@ static inline struct cgroup *__cset_cgroup_from_root(struct css_set *cset,
1414
1418
}
1415
1419
}
1416
1420
1421
+ BUG_ON (!res_cgroup );
1417
1422
return res_cgroup ;
1418
1423
}
1419
1424
@@ -1436,23 +1441,36 @@ current_cgns_cgroup_from_root(struct cgroup_root *root)
1436
1441
1437
1442
rcu_read_unlock ();
1438
1443
1439
- BUG_ON (!res );
1440
1444
return res ;
1441
1445
}
1442
1446
1447
+ /*
1448
+ * Look up cgroup associated with current task's cgroup namespace on the default
1449
+ * hierarchy.
1450
+ *
1451
+ * Unlike current_cgns_cgroup_from_root(), this doesn't need locks:
1452
+ * - Internal rcu_read_lock is unnecessary because we don't dereference any rcu
1453
+ * pointers.
1454
+ * - css_set_lock is not needed because we just read cset->dfl_cgrp.
1455
+ * - As a bonus returned cgrp is pinned with the current because it cannot
1456
+ * switch cgroup_ns asynchronously.
1457
+ */
1458
+ static struct cgroup * current_cgns_cgroup_dfl (void )
1459
+ {
1460
+ struct css_set * cset ;
1461
+
1462
+ cset = current -> nsproxy -> cgroup_ns -> root_cset ;
1463
+ return __cset_cgroup_from_root (cset , & cgrp_dfl_root );
1464
+ }
1465
+
1443
1466
/* look up cgroup associated with given css_set on the specified hierarchy */
1444
1467
static struct cgroup * cset_cgroup_from_root (struct css_set * cset ,
1445
1468
struct cgroup_root * root )
1446
1469
{
1447
- struct cgroup * res = NULL ;
1448
-
1449
1470
lockdep_assert_held (& cgroup_mutex );
1450
1471
lockdep_assert_held (& css_set_lock );
1451
1472
1452
- res = __cset_cgroup_from_root (cset , root );
1453
-
1454
- BUG_ON (!res );
1455
- return res ;
1473
+ return __cset_cgroup_from_root (cset , root );
1456
1474
}
1457
1475
1458
1476
/*
@@ -6191,9 +6209,7 @@ struct cgroup *cgroup_get_from_id(u64 id)
6191
6209
if (!cgrp )
6192
6210
return ERR_PTR (- ENOENT );
6193
6211
6194
- spin_lock_irq (& css_set_lock );
6195
- root_cgrp = current_cgns_cgroup_from_root (& cgrp_dfl_root );
6196
- spin_unlock_irq (& css_set_lock );
6212
+ root_cgrp = current_cgns_cgroup_dfl ();
6197
6213
if (!cgroup_is_descendant (cgrp , root_cgrp )) {
6198
6214
cgroup_put (cgrp );
6199
6215
return ERR_PTR (- ENOENT );
@@ -6294,16 +6310,42 @@ void cgroup_fork(struct task_struct *child)
6294
6310
INIT_LIST_HEAD (& child -> cg_list );
6295
6311
}
6296
6312
6297
- static struct cgroup * cgroup_get_from_file (struct file * f )
6313
+ /**
6314
+ * cgroup_v1v2_get_from_file - get a cgroup pointer from a file pointer
6315
+ * @f: file corresponding to cgroup_dir
6316
+ *
6317
+ * Find the cgroup from a file pointer associated with a cgroup directory.
6318
+ * Returns a pointer to the cgroup on success. ERR_PTR is returned if the
6319
+ * cgroup cannot be found.
6320
+ */
6321
+ static struct cgroup * cgroup_v1v2_get_from_file (struct file * f )
6298
6322
{
6299
6323
struct cgroup_subsys_state * css ;
6300
- struct cgroup * cgrp ;
6301
6324
6302
6325
css = css_tryget_online_from_dir (f -> f_path .dentry , NULL );
6303
6326
if (IS_ERR (css ))
6304
6327
return ERR_CAST (css );
6305
6328
6306
- cgrp = css -> cgroup ;
6329
+ return css -> cgroup ;
6330
+ }
6331
+
6332
+ /**
6333
+ * cgroup_get_from_file - same as cgroup_v1v2_get_from_file, but only supports
6334
+ * cgroup2.
6335
+ * @f: file corresponding to cgroup2_dir
6336
+ */
6337
+ static struct cgroup * cgroup_get_from_file (struct file * f )
6338
+ {
6339
+ struct cgroup * cgrp = cgroup_v1v2_get_from_file (f );
6340
+
6341
+ if (IS_ERR (cgrp ))
6342
+ return ERR_CAST (cgrp );
6343
+
6344
+ if (!cgroup_on_dfl (cgrp )) {
6345
+ cgroup_put (cgrp );
6346
+ return ERR_PTR (- EBADF );
6347
+ }
6348
+
6307
6349
return cgrp ;
6308
6350
}
6309
6351
@@ -6772,10 +6814,8 @@ struct cgroup *cgroup_get_from_path(const char *path)
6772
6814
struct cgroup * cgrp = ERR_PTR (- ENOENT );
6773
6815
struct cgroup * root_cgrp ;
6774
6816
6775
- spin_lock_irq (& css_set_lock );
6776
- root_cgrp = current_cgns_cgroup_from_root (& cgrp_dfl_root );
6817
+ root_cgrp = current_cgns_cgroup_dfl ();
6777
6818
kn = kernfs_walk_and_get (root_cgrp -> kn , path );
6778
- spin_unlock_irq (& css_set_lock );
6779
6819
if (!kn )
6780
6820
goto out ;
6781
6821
@@ -6800,15 +6840,15 @@ struct cgroup *cgroup_get_from_path(const char *path)
6800
6840
EXPORT_SYMBOL_GPL (cgroup_get_from_path );
6801
6841
6802
6842
/**
6803
- * cgroup_get_from_fd - get a cgroup pointer from a fd
6804
- * @fd: fd obtained by open(cgroup2_dir )
6843
+ * cgroup_v1v2_get_from_fd - get a cgroup pointer from a fd
6844
+ * @fd: fd obtained by open(cgroup_dir )
6805
6845
*
6806
6846
* Find the cgroup from a fd which should be obtained
6807
6847
* by opening a cgroup directory. Returns a pointer to the
6808
6848
* cgroup on success. ERR_PTR is returned if the cgroup
6809
6849
* cannot be found.
6810
6850
*/
6811
- struct cgroup * cgroup_get_from_fd (int fd )
6851
+ struct cgroup * cgroup_v1v2_get_from_fd (int fd )
6812
6852
{
6813
6853
struct cgroup * cgrp ;
6814
6854
struct file * f ;
@@ -6817,10 +6857,29 @@ struct cgroup *cgroup_get_from_fd(int fd)
6817
6857
if (!f )
6818
6858
return ERR_PTR (- EBADF );
6819
6859
6820
- cgrp = cgroup_get_from_file (f );
6860
+ cgrp = cgroup_v1v2_get_from_file (f );
6821
6861
fput (f );
6822
6862
return cgrp ;
6823
6863
}
6864
+
6865
+ /**
6866
+ * cgroup_get_from_fd - same as cgroup_v1v2_get_from_fd, but only supports
6867
+ * cgroup2.
6868
+ * @fd: fd obtained by open(cgroup2_dir)
6869
+ */
6870
+ struct cgroup * cgroup_get_from_fd (int fd )
6871
+ {
6872
+ struct cgroup * cgrp = cgroup_v1v2_get_from_fd (fd );
6873
+
6874
+ if (IS_ERR (cgrp ))
6875
+ return ERR_CAST (cgrp );
6876
+
6877
+ if (!cgroup_on_dfl (cgrp )) {
6878
+ cgroup_put (cgrp );
6879
+ return ERR_PTR (- EBADF );
6880
+ }
6881
+ return cgrp ;
6882
+ }
6824
6883
EXPORT_SYMBOL_GPL (cgroup_get_from_fd );
6825
6884
6826
6885
static u64 power_of_ten (int power )
0 commit comments