mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +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; \
|
__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 */
|
#else /* !CONFIG_FREEZER */
|
||||||
static inline bool frozen(struct task_struct *p) { return false; }
|
static inline bool frozen(struct task_struct *p) { return false; }
|
||||||
static inline bool freezing(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) \
|
#define freezable_schedule_hrtimeout_range(expires, delta, mode) \
|
||||||
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) \
|
#define wait_event_freezekillable(wq, condition) \
|
||||||
wait_event_killable(wq, condition)
|
wait_event_killable(wq, condition)
|
||||||
|
|
||||||
|
@ -267,6 +267,31 @@ do { \
|
|||||||
__wait_event(wq, condition); \
|
__wait_event(wq, condition); \
|
||||||
} while (0)
|
} 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) \
|
#define __wait_event_timeout(wq, condition, timeout) \
|
||||||
___wait_event(wq, ___wait_cond_timeout(condition), \
|
___wait_event(wq, ___wait_cond_timeout(condition), \
|
||||||
TASK_UNINTERRUPTIBLE, 0, timeout, \
|
TASK_UNINTERRUPTIBLE, 0, timeout, \
|
||||||
@ -300,6 +325,24 @@ do { \
|
|||||||
__ret; \
|
__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) \
|
#define __wait_event_cmd(wq, condition, cmd1, cmd2) \
|
||||||
(void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \
|
(void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \
|
||||||
cmd1; schedule(); cmd2)
|
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) \
|
#define __wait_event_interruptible_locked(wq, condition, exclusive, irq) \
|
||||||
({ \
|
({ \
|
||||||
int __ret = 0; \
|
int __ret = 0; \
|
||||||
|
Loading…
Reference in New Issue
Block a user