代码之家  ›  专栏  ›  技术社区  ›  melonfsck

是否允许在堆栈上分配旋转锁?

  •  0
  • melonfsck  · 技术社区  · 1 年前

    在Linux(系统模式)上,我们通常使用动态分配的内存来设置自旋锁,例如:

    spinlock_t *my_lock = kzalloc(sizeof(spinlock_t), GFP_KERNEL);
    spin_lock_init(my_lock);
    

    我想也有可能(很可能)在没有任何动态分配的情况下设置它们,只需要在堆栈上使用空间:

    char spinspace[sizeof(spinlock_t)];
    
    spinlock_t *my_lock = (void*)&spinspace;
    spin_lock_init(my_lock);
    

    它似乎有效,但我想知道在我的内核模块中以这种方式使用自旋锁是否允许且安全。 该旋转锁最终可能会被导出或传递给其他内核代码。

    1 回复  |  直到 1 年前
        1
  •  1
  •   Marco Bonelli    1 年前

    没有必要用一个 char 数组,您可以很好地做到:

    spinlock_t my_lock;
    spin_lock_init(&my_lock);
    

    以上是完全有效的代码。在堆栈上声明自旋锁可能很有用,也更容易,但如果您想与其他并发运行的代码共享它,则必须小心。在函数内声明具有自动存储持续时间的变量只会使在函数的生存期内引用该变量有效。一旦函数返回(或者,根据情况,甚至可能早于此),该变量将变得无效,因此将成为您传递的任何引用。因此,在这种情况下,您的函数需要比它定义的spinlock的任何其他用户都活得更长。

    事实上,您可以看到一些(非常罕见的)内核代码片段这样做,例如 here in arch/mips/sgi-ip22/ip22-mc.c 。在这种特定情况下,自旋锁甚至不会被传递,它只用于临时禁用IRQ,所以没关系。