/* * Queue up a socket with data pending. If there are idle nfsd * processes, wake 'em up. * * This must be called with svsk->sk_lock held. */ static void svc_sock_enqueue(struct svc_sock *svsk) { struct svc_serv *serv = svsk->sk_server; struct svc_rqst *rqstp; /* NOTE: Local BH is already disabled by our caller. */ spin_lock(&serv->sv_lock); if (serv->sv_threads && serv->sv_sockets) printk(KERN_ERR "svc_sock_enqueue: threads and sockets both waiting??\n"); if (svsk->sk_busy) { /* Don't enqueue socket while daemon is receiving */ dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk); goto out_unlock; } /* Mark socket as busy. It will remain in this state until the * server has processed all pending data and put the socket back * on the idle list. */ svsk->sk_busy = 1; if ((rqstp = serv->sv_threads) != NULL) { dprintk("svc: socket %p served by daemon %p\n", svsk->sk_sk, rqstp); svc_serv_dequeue(serv, rqstp); if (rqstp->rq_sock) printk(KERN_ERR "svc_sock_enqueue: server %p, rq_sock=%p!\n", rqstp, rqstp->rq_sock); rqstp->rq_sock = svsk; svsk->sk_inuse++; wake_up(&rqstp->rq_wait); } else { dprintk("svc: socket %p put into queue\n", svsk->sk_sk); rpc_append_list(&serv->sv_sockets, svsk); svsk->sk_qued = 1; } out_unlock: spin_unlock(&serv->sv_lock); }
/* * Add new request to wait queue. * * Swapper tasks always get inserted at the head of the queue. * This should avoid many nasty memory deadlocks and hopefully * improve overall performance. * Everyone else gets appended to the queue to ensure proper FIFO behavior. */ int rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task) { if (task->tk_rpcwait) { if (task->tk_rpcwait != queue) { printk(KERN_WARNING "RPC: doubly enqueued task!\n"); return -EWOULDBLOCK; } return 0; } if (RPC_IS_SWAPPER(task)) rpc_insert_list(&queue->task, task); else rpc_append_list(&queue->task, task); task->tk_rpcwait = queue; dprintk("RPC: %4d added to queue %p \"%s\"\n", task->tk_pid, queue, rpc_qname(queue)); return 0; }
/* * Queue up an idle server thread. Must have serv->sv_lock held. */ static inline void svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp) { rpc_append_list(&serv->sv_threads, rqstp); }