X-Git-Url: http://git.madism.org/?p=~madcoder%2Fpwqr.git;a=blobdiff_plain;f=kernel%2Fpwqr.c;h=6d822ea6bca40a2ba8de3965526f33b4a98b8649;hp=c705dfa04f1f64797adbc6ea6318c975d7238623;hb=HEAD;hpb=fff79367c87a42fdce8c024eee7d9e2870960a70 diff --git a/kernel/pwqr.c b/kernel/pwqr.c index c705dfa..6d822ea 100644 --- a/kernel/pwqr.c +++ b/kernel/pwqr.c @@ -172,10 +172,13 @@ static inline void __pwqr_sb_update_state(struct pwqr_sb *sb, int running_delta) sb->running += running_delta; if (sb->running < sb->concurrency && sb->waiting == 0 && sb->parked) { + sb->has_pollin = 0; pwqr_arm_timer(sb, PWQR_STATE_UC, PWQR_UC_DELAY); } else if (sb->running > sb->concurrency) { - pwqr_arm_timer(sb, PWQR_STATE_OC, PWQR_OC_DELAY); + if (!sb->has_pollin) + pwqr_arm_timer(sb, PWQR_STATE_OC, PWQR_OC_DELAY); } else { + sb->has_pollin = 0; sb->state = PWQR_STATE_NONE; if (!timer_pending(&sb->timer)) del_timer(&sb->timer); @@ -324,7 +327,6 @@ static void pwqr_task_detach(struct pwqr_task *pwqt, struct pwqr_sb *sb) } else { __pwqr_sb_update_state(sb, 0); } - pwqt->notifier.ops = &pwqr_preempt_noop_ops; pwqr_sb_unlock_irqrestore(sb, flags); pwqr_sb_put(sb); pwqt->sb = NULL; @@ -352,6 +354,7 @@ static void pwqr_task_release(struct pwqr_task *pwqt, bool from_notifier) hlist_del(&pwqt->link); spin_unlock(&b->lock); #endif + pwqt->notifier.ops = &pwqr_preempt_noop_ops; if (from_notifier) { /* When called from sched_{out,in}, it's not allowed to @@ -374,7 +377,7 @@ static void pwqr_task_noop_sched_in(struct preempt_notifier *notifier, int cpu) } static void pwqr_task_noop_sched_out(struct preempt_notifier *notifier, - struct task_struct *next) + struct task_struct *next) { } @@ -386,6 +389,7 @@ static void pwqr_task_blocked_sched_in(struct preempt_notifier *notifier, int cp if (unlikely(sb->state < 0)) { pwqr_task_detach(pwqt, sb); + pwqr_task_release(pwqt, true); return; } @@ -404,8 +408,7 @@ static void pwqr_task_sched_out(struct preempt_notifier *notifier, if (unlikely(p->state & TASK_DEAD) || unlikely(sb->state < 0)) { pwqr_task_detach(pwqt, sb); - if (p->state & TASK_DEAD) - pwqr_task_release(pwqt, true); + pwqr_task_release(pwqt, true); return; } if (p->state == 0 || (p->state & (__TASK_STOPPED | __TASK_TRACED)))