int send_sync_buf (tux_req_t *req, struct socket *sock, const char *buf, const size_t length, unsigned long flags) { struct msghdr msg; struct iovec iov; int len, written = 0, left = length; struct tcp_opt *tp = tcp_sk(sock->sk); tp->nonagle = 2; msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = flags | MSG_NOSIGNAL; repeat_send: msg.msg_iov->iov_len = left; msg.msg_iov->iov_base = (char *) buf + written; len = sock_sendmsg(sock, &msg, left); Dprintk("sendmsg ret: %d, written: %d, left: %d.\n", len,written,left); if ((len == -ERESTARTSYS) || (!(flags & MSG_DONTWAIT) && (len == -EAGAIN))) { flush_all_signals(); goto repeat_send; } if (len > 0) { written += len; left -= len; if (left) goto repeat_send; } if (len >= 0) { if (written != length) TUX_BUG(); if (left) TUX_BUG(); } if (req && (written > 0)) req->bytes_sent += written; Dprintk("sendmsg FINAL ret: %d, written: %d, left: %d.\n", len,written,left); return written ? written : len; }
static int cachemiss_thread (void *data) { tux_req_t *req; struct k_sigaction *ka; DECLARE_WAITQUEUE(wait, current); iothread_t *iot = data; int nr = iot->ti->cpu, wake_up; Dprintk("iot %p/%p got started.\n", iot, current); drop_permissions(); spin_lock(&iot->async_lock); iot->threads++; sprintf(current->comm, "async IO %d/%d", nr, iot->threads); spin_lock_irq(¤t->sighand->siglock); ka = current->sighand->action + SIGCHLD-1; ka->sa.sa_handler = SIG_IGN; siginitsetinv(¤t->blocked, sigmask(SIGCHLD)); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); spin_unlock(&iot->async_lock); #ifdef CONFIG_SMP { cpumask_t mask; if (cpu_isset(nr, cpu_online_map)) { cpus_clear(mask); cpu_set(nr, mask); set_cpus_allowed(current, mask); } } #endif add_wait_queue_exclusive(&iot->async_sleep, &wait); for (;;) { while (!list_empty(&iot->async_queue) && (req = get_cachemiss(iot))) { if (!req->atom_idx) { add_tux_atom(req, flush_request); add_req_to_workqueue(req); continue; } tux_schedule_atom(req, 1); if (signal_pending(current)) flush_all_signals(); } if (signal_pending(current)) flush_all_signals(); if (!list_empty(&iot->async_queue)) continue; if (iot->shutdown) { Dprintk("iot %p/%p got shutdown!\n", iot, current); break; } __set_current_state(TASK_INTERRUPTIBLE); if (list_empty(&iot->async_queue)) { Dprintk("iot %p/%p going to sleep.\n", iot, current); schedule(); Dprintk("iot %p/%p got woken up.\n", iot, current); } __set_current_state(TASK_RUNNING); } remove_wait_queue(&iot->async_sleep, &wait); wake_up = 0; spin_lock(&iot->async_lock); if (!--iot->threads) wake_up = 1; spin_unlock(&iot->async_lock); Dprintk("iot %p/%p has finished shutdown!\n", iot, current); if (wake_up) { Dprintk("iot %p/%p waking up master.\n", iot, current); wake_up(&iot->wait_shutdown); } return 0; }