Commit 804b3c28 authored by Paul Menage's avatar Paul Menage Committed by Linus Torvalds
Browse files

cgroups: add cpu_relax() calls in css_tryget() and cgroup_clear_css_refs()



css_tryget() and cgroup_clear_css_refs() contain polling loops; these
loops should have cpu_relax calls in them to reduce cross-cache traffic.

Signed-off-by: default avatarPaul Menage <menage@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1404f065
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,7 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
	while (!atomic_inc_not_zero(&css->refcnt)) {
	while (!atomic_inc_not_zero(&css->refcnt)) {
		if (test_bit(CSS_REMOVED, &css->flags))
		if (test_bit(CSS_REMOVED, &css->flags))
			return false;
			return false;
		cpu_relax();
	}
	}
	return true;
	return true;
}
}
+5 −2
Original line number Original line Diff line number Diff line
@@ -2509,7 +2509,7 @@ static int cgroup_clear_css_refs(struct cgroup *cgrp)
	for_each_subsys(cgrp->root, ss) {
	for_each_subsys(cgrp->root, ss) {
		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
		struct cgroup_subsys_state *css = cgrp->subsys[ss->subsys_id];
		int refcnt;
		int refcnt;
		do {
		while (1) {
			/* We can only remove a CSS with a refcnt==1 */
			/* We can only remove a CSS with a refcnt==1 */
			refcnt = atomic_read(&css->refcnt);
			refcnt = atomic_read(&css->refcnt);
			if (refcnt > 1) {
			if (refcnt > 1) {
@@ -2523,7 +2523,10 @@ static int cgroup_clear_css_refs(struct cgroup *cgrp)
			 * css_tryget() to spin until we set the
			 * css_tryget() to spin until we set the
			 * CSS_REMOVED bits or abort
			 * CSS_REMOVED bits or abort
			 */
			 */
		} while (atomic_cmpxchg(&css->refcnt, refcnt, 0) != refcnt);
			if (atomic_cmpxchg(&css->refcnt, refcnt, 0) == refcnt)
				break;
			cpu_relax();
		}
	}
	}
 done:
 done:
	for_each_subsys(cgrp->root, ss) {
	for_each_subsys(cgrp->root, ss) {