mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 12:14:01 +08:00
sched/wait: Reimplement wait_event_freezable()
Provide better implementations of wait_event_freezable() APIs. The problem is with freezer_do_not_count(), it hides the thread from the freezer, even though this thread might not actually freeze/sleep at all. Cc: oleg@redhat.com Cc: Rafael Wysocki <rjw@rjwysocki.net> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Len Brown <len.brown@intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Pavel Machek <pavel@ucw.cz> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Cc: linux-pm@vger.kernel.org Link: http://lkml.kernel.org/n/tip-d86fz1jmso9wjxa8jfpinp8o@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
cb6538e740
commit
36df04bc52
@ -265,35 +265,6 @@ static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
|
||||
__retval; \
|
||||
})
|
||||
|
||||
#define wait_event_freezable(wq, condition) \
|
||||
({ \
|
||||
int __retval; \
|
||||
freezer_do_not_count(); \
|
||||
__retval = wait_event_interruptible(wq, (condition)); \
|
||||
freezer_count(); \
|
||||
__retval; \
|
||||
})
|
||||
|
||||
#define wait_event_freezable_timeout(wq, condition, timeout) \
|
||||
({ \
|
||||
long __retval = timeout; \
|
||||
freezer_do_not_count(); \
|
||||
__retval = wait_event_interruptible_timeout(wq, (condition), \
|
||||
__retval); \
|
||||
freezer_count(); \
|
||||
__retval; \
|
||||
})
|
||||
|
||||
#define wait_event_freezable_exclusive(wq, condition) \
|
||||
({ \
|
||||
int __retval; \
|
||||
freezer_do_not_count(); \
|
||||
__retval = wait_event_interruptible_exclusive(wq, condition); \
|
||||
freezer_count(); \
|
||||
__retval; \
|
||||
})
|
||||
|
||||
|
||||
#else /* !CONFIG_FREEZER */
|
||||
static inline bool frozen(struct task_struct *p) { return false; }
|
||||
static inline bool freezing(struct task_struct *p) { return false; }
|
||||
@ -331,15 +302,6 @@ static inline void set_freezable(void) {}
|
||||
#define freezable_schedule_hrtimeout_range(expires, delta, mode) \
|
||||
schedule_hrtimeout_range(expires, delta, mode)
|
||||
|
||||
#define wait_event_freezable(wq, condition) \
|
||||
wait_event_interruptible(wq, condition)
|
||||
|
||||
#define wait_event_freezable_timeout(wq, condition, timeout) \
|
||||
wait_event_interruptible_timeout(wq, condition, timeout)
|
||||
|
||||
#define wait_event_freezable_exclusive(wq, condition) \
|
||||
wait_event_interruptible_exclusive(wq, condition)
|
||||
|
||||
#define wait_event_freezekillable(wq, condition) \
|
||||
wait_event_killable(wq, condition)
|
||||
|
||||
|
@ -267,6 +267,31 @@ do { \
|
||||
__wait_event(wq, condition); \
|
||||
} while (0)
|
||||
|
||||
#define __wait_event_freezable(wq, condition) \
|
||||
___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \
|
||||
schedule(); try_to_freeze())
|
||||
|
||||
/**
|
||||
* wait_event - sleep (or freeze) until a condition gets true
|
||||
* @wq: the waitqueue to wait on
|
||||
* @condition: a C expression for the event to wait for
|
||||
*
|
||||
* The process is put to sleep (TASK_INTERRUPTIBLE -- so as not to contribute
|
||||
* to system load) until the @condition evaluates to true. The
|
||||
* @condition is checked each time the waitqueue @wq is woken up.
|
||||
*
|
||||
* wake_up() has to be called after changing any variable that could
|
||||
* change the result of the wait condition.
|
||||
*/
|
||||
#define wait_event_freezable(wq, condition) \
|
||||
({ \
|
||||
int __ret = 0; \
|
||||
might_sleep(); \
|
||||
if (!(condition)) \
|
||||
__ret = __wait_event_freezable(wq, condition); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define __wait_event_timeout(wq, condition, timeout) \
|
||||
___wait_event(wq, ___wait_cond_timeout(condition), \
|
||||
TASK_UNINTERRUPTIBLE, 0, timeout, \
|
||||
@ -300,6 +325,24 @@ do { \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define __wait_event_freezable_timeout(wq, condition, timeout) \
|
||||
___wait_event(wq, ___wait_cond_timeout(condition), \
|
||||
TASK_INTERRUPTIBLE, 0, timeout, \
|
||||
__ret = schedule_timeout(__ret); try_to_freeze())
|
||||
|
||||
/*
|
||||
* like wait_event_timeout() -- except it uses TASK_INTERRUPTIBLE to avoid
|
||||
* increasing load and is freezable.
|
||||
*/
|
||||
#define wait_event_freezable_timeout(wq, condition, timeout) \
|
||||
({ \
|
||||
long __ret = timeout; \
|
||||
might_sleep(); \
|
||||
if (!___wait_cond_timeout(condition)) \
|
||||
__ret = __wait_event_freezable_timeout(wq, condition, timeout); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define __wait_event_cmd(wq, condition, cmd1, cmd2) \
|
||||
(void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \
|
||||
cmd1; schedule(); cmd2)
|
||||
@ -480,6 +523,20 @@ do { \
|
||||
})
|
||||
|
||||
|
||||
#define __wait_event_freezable_exclusive(wq, condition) \
|
||||
___wait_event(wq, condition, TASK_INTERRUPTIBLE, 1, 0, \
|
||||
schedule(); try_to_freeze())
|
||||
|
||||
#define wait_event_freezable_exclusive(wq, condition) \
|
||||
({ \
|
||||
int __ret = 0; \
|
||||
might_sleep(); \
|
||||
if (!(condition)) \
|
||||
__ret = __wait_event_freezable_exclusive(wq, condition);\
|
||||
__ret; \
|
||||
})
|
||||
|
||||
|
||||
#define __wait_event_interruptible_locked(wq, condition, exclusive, irq) \
|
||||
({ \
|
||||
int __ret = 0; \
|
||||
|
Loading…
Reference in New Issue
Block a user