Chinaunix首页 | 论坛 | 博客
  • 博客访问: 404863
  • 博文数量: 124
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 872
  • 用 户 组: 普通用户
  • 注册时间: 2018-03-29 14:38
个人简介

默默的一块石头

文章分类

全部博文(124)

文章存档

2022年(26)

2021年(10)

2020年(28)

2019年(60)

我的朋友

分类: LINUX

2022-01-24 14:58:31

以下内容是基于Linux-5.4.1记录
1.睡眠队列
static inline wait_queue_head_t *sk_sleep(struct sock *sk)
{
BUILD_BUG_ON(offsetof(struct socket_wq, wait) != 0);
return &rcu_dereference_raw(sk->sk_wq)->wait;
}

static inline void sock_poll_wait(struct file *filp, struct socket *sock,
  poll_table *p)
{
if (!poll_does_not_wait(p)) {
poll_wait(filp, &sock->wq.wait, p);
}
}

static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (p && p->_qproc && wait_address)
p->_qproc(filp, wait_address, p);
}

void sock_init_data(struct socket *sock, struct sock *sk)
{
if (sock) {
RCU_INIT_POINTER(sk->sk_wq, &sock->wq);

}
2.TCP
(1)accept睡眠
int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
  int __user *upeer_addrlen, int flags)
{
err = sock->ops->accept(sock, newsock, sock->file->f_flags, false);
}

int inet_accept(struct socket *sock, struct socket *newsock, int flags,
bool kern)
{
struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err, kern);
}

struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)
{
error = inet_csk_wait_for_connect(sk, timeo);
}

static int inet_csk_wait_for_connect(struct sock *sk, long timeo)
{
for (;;) {
prepare_to_wait_exclusive(sk_sleep(sk), &wait,TASK_INTERRUPTIBLE);
if (reqsk_queue_empty(&icsk->icsk_accept_queue)){
timeo = schedule_timeout(timeo);
}
}
}

(2)TCP poll
__poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
{
sock_poll_wait(file, sock, wait);
}

3.epoll
(1)睡眠过程
(2)poll过程
static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
     struct file *tfile, int fd, int full_check)
{
init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
revents = ep_item_poll(epi, &epq.pt, 1);
}

static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
{
pt->_qproc = qproc;
pt->_key   = ~(__poll_t)0; /* all events enabled */
}

static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
poll_table *pt)
{
struct epitem *epi = ep_item_from_epqueue(pt);
struct eppoll_entry *pwq;

if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) {
init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
pwq->whead = whead;
pwq->base = epi;
if (epi->event.events & EPOLLEXCLUSIVE)
add_wait_queue_exclusive(whead, &pwq->wait);
else
add_wait_queue(whead, &pwq->wait);
list_add_tail(&pwq->llink, &epi->pwqlist);
epi->nwait++;
} else {
/* We have to signal that an error occurred */
epi->nwait = -1;
}
}

static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
{
wake_up(&ep->wq);
}

Jan 24 14:09:28 chro kernel: [   12.698552] Call Trace:
Jan 24 14:09:28 chro kernel: [   12.698553]  dump_stack+0x6d/0x95
Jan 24 14:09:28 chro kernel: [   12.698554]  tcp_poll+0x1fb/0x2b0
Jan 24 14:09:28 chro kernel: [   12.698555]  sock_poll+0x79/0xb0
Jan 24 14:09:28 chro kernel: [   12.698556]  ep_item_poll.isra.16+0x43/0xc0
Jan 24 14:09:28 chro kernel: [   12.698557]  ep_insert+0x119/0x4a0
Jan 24 14:09:28 chro kernel: [   12.698558]  ? ep_show_fdinfo+0xa0/0xa0
Jan 24 14:09:28 chro kernel: [   12.698559]  __x64_sys_epoll_ctl+0x568/0x600
Jan 24 14:09:28 chro kernel: [   12.698560]  ? __x64_sys_epoll_ctl+0x568/0x600
Jan 24 14:09:28 chro kernel: [   12.698562]  do_syscall_64+0x57/0x190
Jan 24 14:09:28 chro kernel: [   12.698563]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
ep_insert通过ep_item_poll-->tcp_poll-->sock_poll_wait-->poll_wait(filp, &sock->wq.wait, p);把sock->wq.wait睡眠队列与ep_poll_callback注册在一起

所以当有数据来的时候
Jan 24 14:11:13 chro kernel: [  118.403071]  dump_stack+0x6d/0x95
Jan 24 14:11:13 chro kernel: [  118.403072]  ep_poll_callback+0x2cf/0x2e0
Jan 24 14:11:13 chro kernel: [  118.403074]  ? ksize+0x19/0x30
Jan 24 14:11:13 chro kernel: [  118.403074]  __wake_up_common+0x73/0x120
Jan 24 14:11:13 chro kernel: [  118.403075]  __wake_up_common_lock+0x7e/0xc0
Jan 24 14:11:13 chro kernel: [  118.403076]  __wake_up_sync_key+0x1e/0x30
Jan 24 14:11:13 chro kernel: [  118.403076]  sock_def_readable+0x40/0x70
Jan 24 14:11:13 chro kernel: [  118.403078]  unix_stream_sendmsg+0x271/0x390
Jan 24 14:11:13 chro kernel: [  118.403079]  sock_sendmsg+0x63/0x70
Jan 24 14:11:13 chro kernel: [  118.403080]  sock_write_iter+0x8c/0xf0
Jan 24 14:11:13 chro kernel: [  118.403082]  do_iter_readv_writev+0x159/0x1d0
Jan 24 14:11:13 chro kernel: [  118.403083]  do_iter_write+0x86/0x1a0
Jan 24 14:11:13 chro kernel: [  118.403083]  vfs_writev+0x92/0x120
Jan 24 14:11:13 chro kernel: [  118.403106]  ? tty_ldisc_deref+0x16/0x20
Jan 24 14:11:13 chro kernel: [  118.403107]  ? tty_read+0x9d/0xf0
Jan 24 14:11:13 chro kernel: [  118.403108]  ? __vfs_read+0x1b/0x40
Jan 24 14:11:13 chro kernel: [  118.403109]  do_writev+0xde/0x120
Jan 24 14:11:13 chro kernel: [  118.403109]  ? do_writev+0xde/0x120
Jan 24 14:11:13 chro kernel: [  118.403110]  __x64_sys_writev+0x1c/0x20
Jan 24 14:11:13 chro kernel: [  118.403111]  do_syscall_64+0x57/0x190
Jan 24 14:11:13 chro kernel: [  118.403112]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Jan 24 14:11:13 chro kernel: [  118.403184]  dump_stack+0x6d/0x95
Jan 24 14:11:13 chro kernel: [  118.403185]  ep_poll+0x46f/0x490
Jan 24 14:11:13 chro kernel: [  118.403187]  ? wake_up_q+0x80/0x80
Jan 24 14:11:13 chro kernel: [  118.403188]  do_epoll_wait+0xb0/0xc0
Jan 24 14:11:13 chro kernel: [  118.403189]  __x64_sys_epoll_wait+0x1e/0x30
Jan 24 14:11:13 chro kernel: [  118.403191]  do_syscall_64+0x57/0x190
Jan 24 14:11:13 chro kernel: [  118.403217]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

static void sock_def_readable(struct sock *sk)
{
struct socket_wq *wq;

rcu_read_lock();
wq = rcu_dereference(sk->sk_wq);
if (skwq_has_sleeper(wq))
wake_up_interruptible_sync_poll(&wq->wait, EPOLLIN | EPOLLPRI |
EPOLLRDNORM | EPOLLRDBAND);
sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
rcu_read_unlock();
}

阅读(653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~