]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sunrpc/svc_xprt.c
m68k: Update defconfigs
[linux-2.6-omap-h63xx.git] / net / sunrpc / svc_xprt.c
index ea377e06afae0d1a56812e9b6771a3c055c7a410..d8e8d79a84514aebcd003b65ef2cda5002bc391c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/file.h>
 #include <linux/freezer.h>
+#include <linux/kthread.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -185,7 +186,7 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
        struct svc_xprt_class *xcl;
        struct sockaddr_in sin = {
                .sin_family             = AF_INET,
-               .sin_addr.s_addr        = INADDR_ANY,
+               .sin_addr.s_addr        = htonl(INADDR_ANY),
                .sin_port               = htons(port),
        };
        dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
@@ -586,8 +587,12 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                while (rqstp->rq_pages[i] == NULL) {
                        struct page *p = alloc_page(GFP_KERNEL);
                        if (!p) {
-                               int j = msecs_to_jiffies(500);
-                               schedule_timeout_uninterruptible(j);
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               if (signalled() || kthread_should_stop()) {
+                                       set_current_state(TASK_RUNNING);
+                                       return -EINTR;
+                               }
+                               schedule_timeout(msecs_to_jiffies(500));
                        }
                        rqstp->rq_pages[i] = p;
                }
@@ -607,7 +612,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 
        try_to_freeze();
        cond_resched();
-       if (signalled())
+       if (signalled() || kthread_should_stop())
                return -EINTR;
 
        spin_lock_bh(&pool->sp_lock);
@@ -626,6 +631,20 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                 * to bring down the daemons ...
                 */
                set_current_state(TASK_INTERRUPTIBLE);
+
+               /*
+                * checking kthread_should_stop() here allows us to avoid
+                * locking and signalling when stopping kthreads that call
+                * svc_recv. If the thread has already been woken up, then
+                * we can exit here without sleeping. If not, then it
+                * it'll be woken up quickly during the schedule_timeout
+                */
+               if (kthread_should_stop()) {
+                       set_current_state(TASK_RUNNING);
+                       spin_unlock_bh(&pool->sp_lock);
+                       return -EINTR;
+               }
+
                add_wait_queue(&rqstp->rq_wait, &wait);
                spin_unlock_bh(&pool->sp_lock);
 
@@ -641,7 +660,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                        svc_thread_dequeue(pool, rqstp);
                        spin_unlock_bh(&pool->sp_lock);
                        dprintk("svc: server %p, no data yet\n", rqstp);
-                       return signalled()? -EINTR : -EAGAIN;
+                       if (signalled() || kthread_should_stop())
+                               return -EINTR;
+                       else
+                               return -EAGAIN;
                }
        }
        spin_unlock_bh(&pool->sp_lock);