[Devel] [PATCH RHEL7 COMMIT] ve/sched: introduce cond_resched_may_throttle
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jan 14 05:30:29 PST 2016
The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.9.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.9.20
------>
commit ae4c55224dd102c3a6d7b578aa1ccf1af908893b
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Thu Jan 14 17:30:29 2016 +0400
ve/sched: introduce cond_resched_may_throttle
Port diff-sched-introduce-cond_resched_may_throttle by Vladimir Davydov:
Since cond_resched() is sometimes called under a semaphore, it was
forbidden to throttle tasks there in order to eliminate the possibility
of the priority inversion problem. However, it turned out that some
tasks must be throttled on cond_resched(), otherwise they won't have a
chance to be throttled at all breaking the concept of CPU limits. The
most notable (and currently the only identified) example is vm
hypervisors such as KVM or Balalaika.
To fix this problem, the patch introduces the new function
cond_resched_may_throttle(), which works just like usual cond_resched()
except it allows the scheduler to throttle the caller's task group. This
function must be used by those pieces of software that can only be
throttled on cond_resched() under certain conditions. This function is
to and will be used by Balalaika - I'm going to send the corresponding
patch. Perhaps, it's also worth while using it in KVM, however there is
no rush in it because I doubt anyone will use KVM, vzkernel, and our
hacked CPU limits altogether so it can wait.
https://jira.sw.ru/browse/PSBM-18888
https://jira.sw.ru/browse/PSBM-42358
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Reviewed-by: Vladimir Davydov <vdavydov at virtuozzo.com>
---
include/linux/sched.h | 8 ++++++++
kernel/sched/core.c | 23 +++++++++++++++++++----
kernel/sched/fair.c | 3 ++-
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4560071..4bbd391 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1246,6 +1246,7 @@ struct task_struct {
unsigned sched_interruptible_sleep:1;
unsigned woken_while_running:1;
+ unsigned may_throttle:1;
pid_t pid;
pid_t tgid;
@@ -2697,6 +2698,13 @@ extern int _cond_resched(void);
_cond_resched(); \
})
+extern int _cond_resched_may_throttle(void);
+
+#define cond_resched_may_throttle() ({ \
+ __might_sleep(__FILE__, __LINE__, 0); \
+ _cond_resched_may_throttle(); \
+})
+
extern int __cond_resched_lock(spinlock_t *lock);
#ifdef CONFIG_PREEMPT_COUNT
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 581bfd0..c8ac8bd 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4775,23 +4775,38 @@ static inline int should_resched(void)
return need_resched() && !(preempt_count() & PREEMPT_ACTIVE);
}
-static void __cond_resched(void)
+static void __cond_resched(bool may_throttle)
{
add_preempt_count(PREEMPT_ACTIVE);
+ if (may_throttle)
+ current->may_throttle = 1;
__schedule();
+ if (may_throttle)
+ current->may_throttle = 0;
sub_preempt_count(PREEMPT_ACTIVE);
}
int __sched _cond_resched(void)
{
if (should_resched()) {
- __cond_resched();
+ __cond_resched(false);
return 1;
}
return 0;
}
EXPORT_SYMBOL(_cond_resched);
+int __sched _cond_resched_may_throttle(void)
+{
+ if (should_resched()) {
+ __cond_resched(true);
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(_cond_resched_may_throttle);
+
+
/*
* __cond_resched_lock() - if a reschedule is pending, drop the given lock,
* call schedule, and on return reacquire the lock.
@@ -4810,7 +4825,7 @@ int __cond_resched_lock(spinlock_t *lock)
if (spin_needbreak(lock) || resched) {
spin_unlock(lock);
if (resched)
- __cond_resched();
+ __cond_resched(false);
else
cpu_relax();
ret = 1;
@@ -4826,7 +4841,7 @@ int __sched __cond_resched_softirq(void)
if (should_resched()) {
local_bh_enable();
- __cond_resched();
+ __cond_resched(false);
local_bh_disable();
return 1;
}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index ece14a4..dda3f57 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -957,7 +957,8 @@ static inline void update_entity_boost(struct sched_entity *se)
p->woken_while_running;
p->woken_while_running = 0;
} else
- se->boosted = sched_feat(BOOST_PREEMPT);
+ se->boosted = sched_feat(BOOST_PREEMPT) &&
+ !p->may_throttle;
}
}
More information about the Devel
mailing list