0

次の ksocket 接続受け入れコードを含む単純なカーネル モジュールを作成します。

.....(some ksocket initiation)

while( on_service )
{
    sockfd_c = kaccept(sockfd_s, (struct sockaddr *)&addr_cli, &addr_len);
    kclose(sockfd_c);
}

そして、このソケット サーバーに接続するための単純なクライアントを作成します。コンソールから、クライアント接続を継続的に実行すると、「free」コマンドによってメモリ使用量が増加していることがわかりました。

kaccept() と kclose() の機能は次のとおりです。

int kclose(ksocket_t sockfd)                                                                                                                                                                                     
{
    struct socket *sk;
    int ret;

    sk = (struct socket *)sockfd;
    ret = sk->ops->release(sk);

    if (sk)
    {   
        sock_release(sk);
    }   

    return ret;
}

ksocket_t kaccept(ksocket_t socket, struct sockaddr *address, int *address_len)
{
    struct socket *sk;
    struct socket *new_sk = NULL;
    int ret;

    sk = (struct socket *)socket;

    sxg_debug("family = %d, type = %d, protocol = %d\n",
                sk->sk->sk_family, sk->type, sk->sk->sk_protocol);
    //new_sk = sock_alloc();
    //sock_alloc() is not exported, so i use sock_create() instead
    ret = sock_create(sk->sk->sk_family, sk->type, sk->sk->sk_protocol, &new_sk);
    if (ret < 0)
        return NULL;
    if (!new_sk)
        return NULL;

    new_sk->type = sk->type;
    new_sk->ops = sk->ops;

    ret = sk->ops->accept(sk, new_sk, 0 /*sk->file->f_flags*/);
    if (ret < 0)
        goto error_kaccept;

    if (address)
    {
        ret = new_sk->ops->getname(new_sk, address, address_len, 2);
        if (ret < 0)
            goto error_kaccept;
    }

    return new_sk;

error_kaccept:
    sock_release(new_sk);
    return NULL;
}

メモリリークの理由/方法を知っている人はいますか?

4

2 に答える 2

0

私のカーネル バージョンは 3.2 で、カーネル ソケット サーバーを作成しようとしています。数日間の戦いの後、私は次の発見をしました。

sock_create() を使用してソケットサーバーを作成し、リッスンして接続を受け入れます

sockfd_srv = sock_create(...)
...
while(1) {
    sockfd_srv->ops->listen();
    sockfd_cli = sock_create(...);
    sockfd_srv->ops->accept(..., &sockfd_cli);
    ....(do something)
    sock_release(sockfd_cli);
}

上記のプログラムは、sock_release() によってクライアントのソケットを解放しても、メモリ リークを引き起こします。最後に、システムはメモリ不足になります。

sock_create() の代わりに sock_create_lite() を使用する場合は、次のように変更します。

sockfd_srv = sock_create(...)
...
while(1) {
    sockfd_srv->ops->listen();
    sockfd_cli = sock_create_lite(...);
    sockfd_srv->ops->accept(..., &sockfd_cli);
    ....(do something)
    sock_release(sockfd_cli);
}

その後、メモリリークの問題はなくなりました。

于 2013-09-05T13:27:01.533 に答える