4

我试图计算linux 内核中定义的用于处理数据包的 TCP/IP 网络堆栈的各种层和函数消耗的 CPU 周期。所以我使用TSC通过各种功能消耗CPU。这表明单次调用 sk_data_ready() 函数会占用大量 CPU 周期。

因此,我遵循 linux 内核中 TCP/IP 堆栈的源代码获取原始套接字并获取信息,因为数据包最终在特定套接字的接收循环链表中排队。

但是在对数据包进行排队之后,sock.c 中定义为 sock_queue_rcv_skb() 的函数调用

sk->sk_data_ready(sk, skb_len); 

这是回调函数(我认为)。但我无法获得此回调函数的任何源代码。

谁能帮我找到代码及其工作原理?

recvfrom() 函数是否也与上面定义的回调函数有关?

4

2 回答 2

4

默认的 ->sk_data_ready() 回调是 sock_def_readable():

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

        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
        if (wq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
                                                POLLRDNORM | POLLRDBAND);
        sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
        rcu_read_unlock();
}

这基本上唤醒了等待这些数据的进程,例如recv(),让它们处理->sk_receive_queue中的数据。

某些协议可能会覆盖它,例如 netlink,请参阅 __netlink_kernel_create()。

顺便说一句,您可以使用perf top命令查看哪个内核函数消耗最多的 CPU 周期。

于 2012-12-26T13:31:37.703 回答
0
void sock_init_data(struct socket *sock, struct sock *sk) 
{
    sk->sk_data_ready   =   sock_def_readable;
    sk->sk_write_space  =   sock_def_write_space;
    sk->sk_error_report =   sock_def_error_report;
}
于 2018-07-10T01:24:07.173 回答