SUNRPC: allow svc_recv to break out of 500ms sleep when alloc_page fails
svc_recv() calls alloc_page(), and if it fails it does a 500ms uninterruptible sleep and then reattempts. There doesn't seem to be any real reason for this to be uninterruptible, so change it to an interruptible sleep. Also check for kthread_stop() and signalled() after setting the task state to avoid races that might lead to sleeping after kthread_stop() wakes up the task. I've done some very basic smoke testing with this, but obviously it's hard to test the actual changes since this all depends on an alloc_page() call failing. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
parent
6aaa67b5f3
commit
7b54fe61ff
|
@ -587,10 +587,12 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
|
||||||
while (rqstp->rq_pages[i] == NULL) {
|
while (rqstp->rq_pages[i] == NULL) {
|
||||||
struct page *p = alloc_page(GFP_KERNEL);
|
struct page *p = alloc_page(GFP_KERNEL);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
int j = msecs_to_jiffies(500);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
if (kthread_should_stop())
|
if (signalled() || kthread_should_stop()) {
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
schedule_timeout_uninterruptible(j);
|
}
|
||||||
|
schedule_timeout(msecs_to_jiffies(500));
|
||||||
}
|
}
|
||||||
rqstp->rq_pages[i] = p;
|
rqstp->rq_pages[i] = p;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue