Linux kernel 内核模块';s参考计数

Linux kernel 内核模块';s参考计数,linux-kernel,kernel-module,Linux Kernel,Kernel Module,我有一个模块要维护,而且它似乎在内核中保留引用计数器时出现问题,这导致我无法rmmod我的模块,因为我杀死了打开3个模块原始套接字的守护进程。有趣的是,在加载守护进程'lsmod'后,显示了对模块exist的6个引用,我预计只有三个 这种情况发生在基于ARM的嵌入式系统Linux-2.6.31上,rmmod没有强制卸载模块的“强制”模式(无论如何,这不是个好主意) 我已经分析了代码,下面是我得到的: 1) 模块创建新的套接字地址系列AF_HSL,并向内核注册: static struct pro

我有一个模块要维护,而且它似乎在内核中保留引用计数器时出现问题,这导致我无法rmmod我的模块,因为我杀死了打开3个模块原始套接字的守护进程。有趣的是,在加载守护进程'lsmod'后,显示了对模块exist的6个引用,我预计只有三个

这种情况发生在基于ARM的嵌入式系统Linux-2.6.31上,rmmod没有强制卸载模块的“强制”模式(无论如何,这不是个好主意)

我已经分析了代码,下面是我得到的: 1) 模块创建新的套接字地址系列AF_HSL,并向内核注册:

static struct proto_ops SOCKOPS_WRAPPED (hsl_ops) = {
  family:       AF_HSL,

  owner:        THIS_MODULE,
  release:      hsl_sock_release,
  bind:         _hsl_sock_bind,
  connect:      sock_no_connect,
  socketpair:   sock_no_socketpair,
  accept:       sock_no_accept,
  getname:      _hsl_sock_getname,
  poll:         datagram_poll,
  ioctl:        sock_no_ioctl,
  listen:       sock_no_listen,
  shutdown:     sock_no_shutdown,
  setsockopt:   sock_no_setsockopt,
  getsockopt:   sock_no_getsockopt,
  sendmsg:      _hsl_sock_sendmsg,
  recvmsg:      _hsl_sock_recvmsg,
  mmap:         sock_no_mmap,
  sendpage:     sock_no_sendpage,
};

static struct net_proto_family hsl_family_ops = {
  family:               AF_HSL,
  create:               _hsl_sock_create,
  owner:                THIS_MODULE
};
...

static int
_hsl_sock_create (struct net *net, struct socket *sock, int protocol)
{
  struct sock *sk = NULL;

  sock->state = SS_UNCONNECTED;
  sk = sk_alloc (current->nsproxy->net_ns, AF_HSL, GFP_KERNEL, &_prot);
  if (sk == NULL)
    goto ERR;

  sock->ops = &SOCKOPS_WRAPPED(hsl_ops);
  sock_init_data (sock,sk);

  sock_hold (sk);  /* XXX */
  ...

}

static void
_hsl_sock_destruct (struct sock *sk)
{
  struct hsl_sock *hsk, *phsk;

  if (!sk)
    return;

  ...
  sock_orphan (sk);
  skb_queue_purge (&sk->sk_receive_queue);

  sock_put (sk);
}

int
hsl_sock_release (struct socket *sock)
{
  struct sock *sk = sock->sk;

  /* Here goes logic to destroy net_devices */
  ...

  _hsl_sock_destruct (sk);

  sock->sk = NULL;

  return 0;
}
2) 守护进程以这种方式创建套接字

fd = socket(AF_HSL, SOCK_RAW, 0);;
bind();
getsockname();
但是我不认为_hsl_sock_create()应该调用sock_hold(),这会影响套接字的引用计数,但是sock_init_data()已经将其设置为1,并且在套接字删除阶段,sock_put()将减少1,但是这不会使套接字空闲;d并从系统中完全移除

所以我做了个实验,把袜子脱了下来;现在杀死守护进程会导致删除所有引用,并且“rmmod”成功,但是启动守护进程后的引用数仍然是3

我还检查了socket\u create()中的代码,该代码调用内部函数\u socket\u create(),该函数依次调用try\u module\u get()并保存模块的引用计数。这似乎是我发现的唯一一个显式增加模块refcnt的地方

我还是很困惑。有人会试图帮助理解正在发生的事情吗

期待您的来信

标记