Skip to the content.

rcu wq

配套代码 : ~/vn/m/workqueue.c 中的 testcase 18

这种需求来自两个机制的叠加:

  1. 释放必须等 RCU grace period
  2. 但真正的清理工作又不能在 RCU 回调上下文里做,需要放到 workqueue 中
static void rcu_work_rcufn(struct rcu_head *rcu)
{
   struct rcu_work *rwork = container_of(rcu, struct rcu_work, rcu);
   local_irq_disable();
   __queue_work(WORK_CPU_UNBOUND, rwork->wq, &rwork->work);  // 只干这一件事
   local_irq_enable();
}

回调里什么都不做,只是把 work 入队。这就是全部设计:call_rcu 负责”什么时候安全”,workqueue 负责”在什么上下文干”。

经典案例

aio

kioctx 的 table->table[] 查找是 RCU 保护的,free_ioctx 要做大量可睡眠的清理

static void free_ioctx_reqs(struct percpu_ref *ref)
{
	struct kioctx *ctx = container_of(ref, struct kioctx, reqs);

	/* At this point we know that there are no any in-flight requests */
	if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
		complete(&ctx->rq_wait->comp);

	/* Synchronize against RCU protected table->table[] dereferences */
	INIT_RCU_WORK(&ctx->free_rwork, free_ioctx);
	queue_rcu_work(system_percpu_wq, &ctx->free_rwork);
}

首先,执行到 rcu 中:

然后让工作放到 workqueue ,workqueue 执行其 callback ,结果如下:

@[
        free_ioctx+5
        process_one_work+414
        worker_thread+422
        kthread+228
        ret_from_fork+417
        ret_from_fork_asm+26
]: 1

其他案例

kmem_cache 销毁

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。