sched: static_key sched_feat race + cleanup
cover sched: static_key sched_feat race + cleanup
Hi,
Andi Kleen previously pointed out a get/set race in the sched_feat() infrastructure. I had previously proposed to address this with a new static_key set_true/set_false API:
http://www.gossamer-threads.com/lists/linux/kernel/1955879
However, I think its simpler to just add higher level locking as Ingo previously suggested, and that is how other consumers of the this interface are already operating. It seems a bit like overkill to add this new API, just for this one case.
So, this locking change is in patch 2. Patch 1 is a small cleanup, but no functional change.
Thanks,
-Jason
Jason Baron (2):
sched: remove extra static_key function indirection
sched: fix static_key race with sched_feat
kernel/sched/core.c | 5 +++++ kernel/sched/sched.h | 12 +----------- 2 files changed, 6 insertions(+), 11 deletions(-)
Signature · 1 line
1.8.2.rc2
PATCH 1/2 sched: remove extra static_key function indirection
I think its a bit simpler without having to follow an extra layer of static inline fuctions. No functional change just cosmetic.
--- kernel/sched/sched.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
kernel/sched/sched.h +1 -11
@@ -884,20 +884,10 @@ enum {#undef SCHED_FEAT#if defined(CONFIG_SCHED_DEBUG ) && defined(HAVE_JUMP_LABEL ) -static __always_inline bool static_branch__true(struct static_key *key) -{ -return static_key_true (key);/* Not out of line branch. */ -} - -static __always_inline bool static_branch__false(struct static_key *key) -{ -return static_key_false (key);/* Out of line branch. */ -} -#define SCHED_FEAT (name, enabled) \ static __always_inline bool static_branch_##name(struct static_key *key) \ { \ - return static_branch__##enabled(key); \ + return static_key_##enabled(key); \ }#include "features.h"
Signature · 1 line
1.8.2.rc2
tip-bot for Jason Baron
merge bot[tip:sched/core] sched: Remove extra static_key*() function indirection
sched: Remove extra static_key*() function indirection
Commit-ID: 6e76ea8a8209386c3cc7ee5594e6ea5d25525cf2 Gitweb: http://git.kernel.org/tip/6e76ea8a8209386c3cc7ee5594e6ea5d25525cf2 Author: Jason Baron <[email protected]> AuthorDate: Wed, 2 Jul 2014 15:52:41 +0000 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 16 Jul 2014 13:38:20 +0200
sched: Remove extra static_key*() function indirection
I think its a bit simpler without having to follow an extra layer of static inline fuctions. No functional change just cosmetic.
--- kernel/sched/sched.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
kernel/sched/sched.h +1 -11
@@ -887,20 +887,10 @@ enum {#undef SCHED_FEAT#if defined(CONFIG_SCHED_DEBUG ) && defined(HAVE_JUMP_LABEL ) -static __always_inline bool static_branch__true(struct static_key *key) -{ -return static_key_true (key);/* Not out of line branch. */ -} - -static __always_inline bool static_branch__false(struct static_key *key) -{ -return static_key_false (key);/* Out of line branch. */ -} -#define SCHED_FEAT (name, enabled) \ static __always_inline bool static_branch_##name(struct static_key *key) \ { \ - return static_branch__##enabled(key); \ + return static_key_##enabled(key); \ }#include "features.h"
PATCH 2/2 sched: fix static_key race with sched_feat
In reply to Jason BaronAs pointed out by Andi Kleen, the usage of static keys can be racy in sched_feat_disable() vs. sched_feat_enable(). Currently, we first check the value of keys->enabled, and subsequently update the branch direction. This, can be racy and can potentially leave the keys in an inconsistent state.
Take the i_mutex around these calls to resolve the race.
--- kernel/sched/core.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/sched/core.c +5 -0
@@ -243,6 +243,7 @@ sched_feat_write(struct file *filp, const char __user *ubuf,char buf[64 ];char *cmp;int i; +struct inode *inode;if (cnt >63 ) cnt =63 ;
@@ -253,7 +254,11 @@ sched_feat_write(struct file *filp, const char __user *ubuf, buf[cnt] =0 ; cmp =strstrip (buf); +/* Ensure the static_key remains in a consistent state */ + inode =file_inode (filp); +mutex_lock (&inode->i_mutex); i =sched_feat_set (cmp); +mutex_unlock (&inode->i_mutex);if (i == __SCHED_FEAT_NR)return -EINVAL ;
Signature · 1 line
1.8.2.rc2
tip-bot for Jason Baron
merge bot[tip:sched/core] sched: Fix static_key race with sched_feat()
sched: Fix static_key race with sched_feat()
Commit-ID: 5cd08fbfdb6baa9fe98f530b76898fc5725a6289 Gitweb: http://git.kernel.org/tip/5cd08fbfdb6baa9fe98f530b76898fc5725a6289 Author: Jason Baron <[email protected]> AuthorDate: Wed, 2 Jul 2014 15:52:44 +0000 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 16 Jul 2014 13:38:21 +0200
sched: Fix static_key race with sched_feat()
As pointed out by Andi Kleen, the usage of static keys can be racy in sched_feat_disable() vs. sched_feat_enable(). Currently, we first check the value of keys->enabled, and subsequently update the branch direction. This, can be racy and can potentially leave the keys in an inconsistent state.
Take the i_mutex around these calls to resolve the race.
--- kernel/sched/core.c | 5 +++++ 1 file changed, 5 insertions(+)
kernel/sched/core.c +5 -0
@@ -245,6 +245,7 @@ sched_feat_write(struct file *filp, const char __user *ubuf,char buf[64 ];char *cmp;int i; +struct inode *inode;if (cnt >63 ) cnt =63 ;
@@ -255,7 +256,11 @@ sched_feat_write(struct file *filp, const char __user *ubuf, buf[cnt] =0 ; cmp =strstrip (buf); +/* Ensure the static_key remains in a consistent state */ + inode =file_inode (filp); +mutex_lock (&inode->i_mutex); i =sched_feat_set (cmp); +mutex_unlock (&inode->i_mutex);if (i == __SCHED_FEAT_NR)return -EINVAL ;