4

パケットを処理するためのTCP / IPネットワークスタックのLinuxカーネルで定義されたさまざまなレイヤーと関数によって消費されるCPUサイクルを計算しようとしていました。だから私はさまざまな機能によるCPU消費にTSCを使用しました。これは、sk_data_ready() 関数への 1 回の呼び出しに多くの 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 に答える