Skip to content

Commit c9819f4

Browse files
Christoph LameterLinus Torvalds
authored andcommitted
[PATCH] sched: use softirq for load balancing
Call rebalance_tick (renamed to run_rebalance_domains) from a newly introduced softirq. We calculate the earliest time for each layer of sched domains to be rescanned (this is the rescan time for idle) and use the earliest of those to schedule the softirq via a new field "next_balance" added to struct rq. Signed-off-by: Christoph Lameter <[email protected]> Cc: Peter Williams <[email protected]> Cc: Nick Piggin <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: "Siddha, Suresh B" <[email protected]> Cc: "Chen, Kenneth W" <[email protected]> Acked-by: Ingo Molnar <[email protected]> Cc: KAMEZAWA Hiroyuki <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent e418e1c commit c9819f4

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

include/linux/interrupt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ enum
231231
NET_TX_SOFTIRQ,
232232
NET_RX_SOFTIRQ,
233233
BLOCK_SOFTIRQ,
234-
TASKLET_SOFTIRQ
234+
TASKLET_SOFTIRQ,
235+
SCHED_SOFTIRQ,
235236
};
236237

237238
/* softirq mask and active fields moved to irq_cpustat_t in

kernel/sched.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ struct rq {
227227
unsigned long expired_timestamp;
228228
unsigned long long timestamp_last_tick;
229229
struct task_struct *curr, *idle;
230+
unsigned long next_balance;
230231
struct mm_struct *prev_mm;
231232
struct prio_array *active, *expired, arrays[2];
232233
int best_expired_prio;
@@ -2858,17 +2859,18 @@ static void update_load(struct rq *this_rq)
28582859
}
28592860

28602861
/*
2861-
* rebalance_tick will get called every timer tick, on every CPU.
2862+
* run_rebalance_domains is triggered when needed from the scheduler tick.
28622863
*
28632864
* It checks each scheduling domain to see if it is due to be balanced,
28642865
* and initiates a balancing operation if so.
28652866
*
28662867
* Balancing parameters are set up in arch_init_sched_domains.
28672868
*/
28682869

2869-
static void
2870-
rebalance_tick(int this_cpu, struct rq *this_rq)
2870+
static void run_rebalance_domains(struct softirq_action *h)
28712871
{
2872+
int this_cpu = smp_processor_id();
2873+
struct rq *this_rq = cpu_rq(this_cpu);
28722874
unsigned long interval;
28732875
struct sched_domain *sd;
28742876
/*
@@ -2877,6 +2879,8 @@ rebalance_tick(int this_cpu, struct rq *this_rq)
28772879
*/
28782880
enum idle_type idle = !this_rq->nr_running ?
28792881
SCHED_IDLE : NOT_IDLE;
2882+
/* Earliest time when we have to call run_rebalance_domains again */
2883+
unsigned long next_balance = jiffies + 60*HZ;
28802884

28812885
for_each_domain(this_cpu, sd) {
28822886
if (!(sd->flags & SD_LOAD_BALANCE))
@@ -2891,7 +2895,7 @@ rebalance_tick(int this_cpu, struct rq *this_rq)
28912895
if (unlikely(!interval))
28922896
interval = 1;
28932897

2894-
if (jiffies - sd->last_balance >= interval) {
2898+
if (time_after_eq(jiffies, sd->last_balance + interval)) {
28952899
if (load_balance(this_cpu, this_rq, sd, idle)) {
28962900
/*
28972901
* We've pulled tasks over so either we're no
@@ -2902,7 +2906,10 @@ rebalance_tick(int this_cpu, struct rq *this_rq)
29022906
}
29032907
sd->last_balance += interval;
29042908
}
2909+
if (time_after(next_balance, sd->last_balance + interval))
2910+
next_balance = sd->last_balance + interval;
29052911
}
2912+
this_rq->next_balance = next_balance;
29062913
}
29072914
#else
29082915
/*
@@ -3155,7 +3162,8 @@ void scheduler_tick(void)
31553162
task_running_tick(rq, p);
31563163
#ifdef CONFIG_SMP
31573164
update_load(rq);
3158-
rebalance_tick(cpu, rq);
3165+
if (time_after_eq(jiffies, rq->next_balance))
3166+
raise_softirq(SCHED_SOFTIRQ);
31593167
#endif
31603168
}
31613169

@@ -6859,6 +6867,10 @@ void __init sched_init(void)
68596867

68606868
set_load_weight(&init_task);
68616869

6870+
#ifdef CONFIG_SMP
6871+
open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL);
6872+
#endif
6873+
68626874
#ifdef CONFIG_RT_MUTEXES
68636875
plist_head_init(&init_task.pi_waiters, &init_task.pi_lock);
68646876
#endif

0 commit comments

Comments
 (0)