rtmutex: Turn the plist into an rb-tree
Turn the pi-chains from plist to rb-tree, in the rt_mutex code, and provide a proper comparison function for -deadline and -priority tasks. This is done mainly because: - classical prio field of the plist is just an int, which might not be enough for representing a deadline; - manipulating such a list would become O(nr_deadline_tasks), which might be to much, as the number of -deadline task increases. Therefore, an rb-tree is used, and tasks are queued in it according to the following logic: - among two -priority (i.e., SCHED_BATCH/OTHER/RR/FIFO) tasks, the one with the higher (lower, actually!) prio wins; - among a -priority and a -deadline task, the latter always wins; - among two -deadline tasks, the one with the earliest deadline wins. Queueing and dequeueing functions are changed accordingly, for both the list of a task's pi-waiters and the list of tasks blocked on a pi-lock. Signed-off-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Dario Faggioli <raistlin@linux.it> Signed-off-by: Juri Lelli <juri.lelli@gmail.com> Signed-off-again-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1383831828-15501-10-git-send-email-juri.lelli@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:

committed by
Ingo Molnar

parent
af6ace764d
commit
fb00aca474
@@ -40,13 +40,13 @@ extern void schedule_rt_mutex_test(struct rt_mutex *lock);
|
||||
* This is the control structure for tasks blocked on a rt_mutex,
|
||||
* which is allocated on the kernel stack on of the blocked task.
|
||||
*
|
||||
* @list_entry: pi node to enqueue into the mutex waiters list
|
||||
* @pi_list_entry: pi node to enqueue into the mutex owner waiters list
|
||||
* @tree_entry: pi node to enqueue into the mutex waiters tree
|
||||
* @pi_tree_entry: pi node to enqueue into the mutex owner waiters tree
|
||||
* @task: task reference to the blocked task
|
||||
*/
|
||||
struct rt_mutex_waiter {
|
||||
struct plist_node list_entry;
|
||||
struct plist_node pi_list_entry;
|
||||
struct rb_node tree_entry;
|
||||
struct rb_node pi_tree_entry;
|
||||
struct task_struct *task;
|
||||
struct rt_mutex *lock;
|
||||
#ifdef CONFIG_DEBUG_RT_MUTEXES
|
||||
@@ -57,11 +57,11 @@ struct rt_mutex_waiter {
|
||||
};
|
||||
|
||||
/*
|
||||
* Various helpers to access the waiters-plist:
|
||||
* Various helpers to access the waiters-tree:
|
||||
*/
|
||||
static inline int rt_mutex_has_waiters(struct rt_mutex *lock)
|
||||
{
|
||||
return !plist_head_empty(&lock->wait_list);
|
||||
return !RB_EMPTY_ROOT(&lock->waiters);
|
||||
}
|
||||
|
||||
static inline struct rt_mutex_waiter *
|
||||
@@ -69,8 +69,8 @@ rt_mutex_top_waiter(struct rt_mutex *lock)
|
||||
{
|
||||
struct rt_mutex_waiter *w;
|
||||
|
||||
w = plist_first_entry(&lock->wait_list, struct rt_mutex_waiter,
|
||||
list_entry);
|
||||
w = rb_entry(lock->waiters_leftmost, struct rt_mutex_waiter,
|
||||
tree_entry);
|
||||
BUG_ON(w->lock != lock);
|
||||
|
||||
return w;
|
||||
@@ -78,14 +78,14 @@ rt_mutex_top_waiter(struct rt_mutex *lock)
|
||||
|
||||
static inline int task_has_pi_waiters(struct task_struct *p)
|
||||
{
|
||||
return !plist_head_empty(&p->pi_waiters);
|
||||
return !RB_EMPTY_ROOT(&p->pi_waiters);
|
||||
}
|
||||
|
||||
static inline struct rt_mutex_waiter *
|
||||
task_top_pi_waiter(struct task_struct *p)
|
||||
{
|
||||
return plist_first_entry(&p->pi_waiters, struct rt_mutex_waiter,
|
||||
pi_list_entry);
|
||||
return rb_entry(p->pi_waiters_leftmost, struct rt_mutex_waiter,
|
||||
pi_tree_entry);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user