Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'cgroup-for-6.4-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Pull cgroup fixes from Tejun Heo:
"It's late but here are two bug fixes. Both fix problems which can be
severe but are very confined in scope. The risk to most use cases
should be minimal.

- Fix for an old bug which triggers if a cgroup subsystem is
remounted to a different hierarchy while someone is reading its
cgroup.procs/tasks file. The risk is pretty low given how seldom
cgroup subsystems are moved across hierarchies.

- We moved cpus_read_lock() outside of cgroup internal locks a while
ago but forgot to update the legacy_freezer leading to lockdep
triggers. Fixed"

* tag 'cgroup-for-6.4-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
cgroup: Do not corrupt task iteration when rebinding subsystem
cgroup,freezer: hold cpu_hotplug_lock before freezer_mutex in freezer_css_{online,offline}()

+23 -5
+17 -3
kernel/cgroup/cgroup.c
··· 1798 1798 { 1799 1799 struct cgroup *dcgrp = &dst_root->cgrp; 1800 1800 struct cgroup_subsys *ss; 1801 - int ssid, i, ret; 1801 + int ssid, ret; 1802 1802 u16 dfl_disable_ss_mask = 0; 1803 1803 1804 1804 lockdep_assert_held(&cgroup_mutex); ··· 1842 1842 struct cgroup_root *src_root = ss->root; 1843 1843 struct cgroup *scgrp = &src_root->cgrp; 1844 1844 struct cgroup_subsys_state *css = cgroup_css(scgrp, ss); 1845 - struct css_set *cset; 1845 + struct css_set *cset, *cset_pos; 1846 + struct css_task_iter *it; 1846 1847 1847 1848 WARN_ON(!css || cgroup_css(dcgrp, ss)); 1848 1849 ··· 1861 1860 css->cgroup = dcgrp; 1862 1861 1863 1862 spin_lock_irq(&css_set_lock); 1864 - hash_for_each(css_set_table, i, cset, hlist) 1863 + WARN_ON(!list_empty(&dcgrp->e_csets[ss->id])); 1864 + list_for_each_entry_safe(cset, cset_pos, &scgrp->e_csets[ss->id], 1865 + e_cset_node[ss->id]) { 1865 1866 list_move_tail(&cset->e_cset_node[ss->id], 1866 1867 &dcgrp->e_csets[ss->id]); 1868 + /* 1869 + * all css_sets of scgrp together in same order to dcgrp, 1870 + * patch in-flight iterators to preserve correct iteration. 1871 + * since the iterator is always advanced right away and 1872 + * finished when it->cset_pos meets it->cset_head, so only 1873 + * update it->cset_head is enough here. 1874 + */ 1875 + list_for_each_entry(it, &cset->task_iters, iters_node) 1876 + if (it->cset_head == &scgrp->e_csets[ss->id]) 1877 + it->cset_head = &dcgrp->e_csets[ss->id]; 1878 + } 1867 1879 spin_unlock_irq(&css_set_lock); 1868 1880 1869 1881 if (ss->css_rstat_flush) {
+6 -2
kernel/cgroup/legacy_freezer.c
··· 108 108 struct freezer *freezer = css_freezer(css); 109 109 struct freezer *parent = parent_freezer(freezer); 110 110 111 + cpus_read_lock(); 111 112 mutex_lock(&freezer_mutex); 112 113 113 114 freezer->state |= CGROUP_FREEZER_ONLINE; 114 115 115 116 if (parent && (parent->state & CGROUP_FREEZING)) { 116 117 freezer->state |= CGROUP_FREEZING_PARENT | CGROUP_FROZEN; 117 - static_branch_inc(&freezer_active); 118 + static_branch_inc_cpuslocked(&freezer_active); 118 119 } 119 120 120 121 mutex_unlock(&freezer_mutex); 122 + cpus_read_unlock(); 121 123 return 0; 122 124 } 123 125 ··· 134 132 { 135 133 struct freezer *freezer = css_freezer(css); 136 134 135 + cpus_read_lock(); 137 136 mutex_lock(&freezer_mutex); 138 137 139 138 if (freezer->state & CGROUP_FREEZING) 140 - static_branch_dec(&freezer_active); 139 + static_branch_dec_cpuslocked(&freezer_active); 141 140 142 141 freezer->state = 0; 143 142 144 143 mutex_unlock(&freezer_mutex); 144 + cpus_read_unlock(); 145 145 } 146 146 147 147 static void freezer_css_free(struct cgroup_subsys_state *css)