c - Why linux workqueue __queue_work doesn't guard read on wq->flags? - Stack Overflow

I was learning the workqueue mechanism of linux.I meet this codes:When user want to queue a work to a

I was learning the workqueue mechanism of linux. I meet this codes: When user want to queue a work to a workqueue, they call __queue_work, at the beginning of this function, it first check if the workqueue is at destroying or draining state by reading a flag variable. But it doesn't use mutex_lock to guard the read.

// linux-src-code/kernel/workqueue.c
static void __queue_work(int cpu, struct workqueue_struct *wq,
             struct work_struct *work)
{
    struct pool_workqueue *pwq;
    struct worker_pool *last_pool, *pool;
    unsigned int work_flags;
    unsigned int req_cpu = cpu;
    lockdep_assert_irqs_disabled();
    if (unlikely(wq->flags & (__WQ_DESTROYING | __WQ_DRAINING) &&
             WARN_ON_ONCE(!is_chained_work(wq))))
        return;
...
}

But in the drain_workqueue and destroy_workqueue, they guard the flags variable with mutex lock, this confuse me. I think there could be a race between reading and writing to the flags:

// linux-src-code/kernel/workqueue.c
void drain_workqueue(struct workqueue_struct *wq)
{
    unsigned int flush_cnt = 0;
    struct pool_workqueue *pwq;
    mutex_lock(&wq->mutex);
    if (!wq->nr_drainers++)
        wq->flags |= __WQ_DRAINING;
    mutex_unlock(&wq->mutex);
reflush:
    __flush_workqueue(wq);
...
}

My question is: why the read access of wq->flags in queue_work function is not guarded by mutex but the write access in destroy_workqueue does.

Add this function for more information: this means the mutex is not only protecting the combination of flags and nr_drainers, but also applies to single flags variable.

void destroy_workqueue(struct workqueue_struct *wq)
{
    struct pool_workqueue *pwq;
    int cpu;
    workqueue_sysfs_unregister(wq);
    /* mark the workqueue destruction is in progress */
    mutex_lock(&wq->mutex);
    wq->flags |= __WQ_DESTROYING;
    mutex_unlock(&wq->mutex);
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742278109a4413973.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信