cifs, freezer: add wait_event_freezekillable and have cifs use it
CIFS currently uses wait_event_killable to put tasks to sleep while they await replies from the server. That function though does not allow the freezer to run. In many cases, the network interface may be going down anyway, in which case the reply will never come. The client then ends up blocking the computer from suspending. Fix this by adding a new wait_event_freezable variant -- wait_event_freezekillable. The idea is to combine the behavior of wait_event_killable and wait_event_freezable -- put the task to sleep and only allow it to be awoken by fatal signals, but also allow the freezer to do its job. Signed-off-by: Jeff Layton <jlayton@redhat.com>
This commit is contained in:
parent
fef33df88b
commit
f06ac72e92
|
@ -26,6 +26,7 @@
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/freezer.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <linux/mempool.h>
|
#include <linux/mempool.h>
|
||||||
|
@ -324,7 +325,7 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = wait_event_killable(server->response_q,
|
error = wait_event_freezekillable(server->response_q,
|
||||||
midQ->midState != MID_REQUEST_SUBMITTED);
|
midQ->midState != MID_REQUEST_SUBMITTED);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
|
@ -134,10 +134,25 @@ static inline void set_freezable_with_signal(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Freezer-friendly wrappers around wait_event_interruptible() and
|
* Freezer-friendly wrappers around wait_event_interruptible(),
|
||||||
* wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
|
* wait_event_killable() and wait_event_interruptible_timeout(), originally
|
||||||
|
* defined in <linux/wait.h>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define wait_event_freezekillable(wq, condition) \
|
||||||
|
({ \
|
||||||
|
int __retval; \
|
||||||
|
do { \
|
||||||
|
__retval = wait_event_killable(wq, \
|
||||||
|
(condition) || freezing(current)); \
|
||||||
|
if (__retval && !freezing(current)) \
|
||||||
|
break; \
|
||||||
|
else if (!(condition)) \
|
||||||
|
__retval = -ERESTARTSYS; \
|
||||||
|
} while (try_to_freeze()); \
|
||||||
|
__retval; \
|
||||||
|
})
|
||||||
|
|
||||||
#define wait_event_freezable(wq, condition) \
|
#define wait_event_freezable(wq, condition) \
|
||||||
({ \
|
({ \
|
||||||
int __retval; \
|
int __retval; \
|
||||||
|
|
Loading…
Reference in a new issue