On Thu, 2018-12-20 at 14:48 -0700, Jens Axboe wrote: +AD4 -void blk+AF8-mq+AF8-free+AF8-rqs(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct blk+AF8-mq+AF8-tags +ACo-tags, +AD4 - unsigned int hctx+AF8-idx) +AD4 +-static void blk+AF8-mq+AF8-rcu+AF8-free+AF8-pages(struct work+AF8-struct +ACo-work) +AD4 +AHs +AD4 +- struct blk+AF8-mq+AF8-tags +ACo-tags +AD0 container+AF8-of(to+AF8-rcu+AF8-work(work), +AD4 +- struct blk+AF8-mq+AF8-tags, rcu+AF8-work)+ADs +AD4 struct page +ACo-page+ADs +AD4 +AD4 +- while (+ACE-list+AF8-empty(+ACY-tags-+AD4-page+AF8-list)) +AHs +AD4 +- page +AD0 list+AF8-first+AF8-entry(+ACY-tags-+AD4-page+AF8-list, struct page, lru)+ADs +AD4 +- list+AF8-del+AF8-init(+ACY-page-+AD4-lru)+ADs +AD4 +- /+ACo +AD4 +- +ACo Remove kmemleak object previously allocated in +AD4 +- +ACo blk+AF8-mq+AF8-init+AF8-rq+AF8-map(). +AD4 +- +ACo-/ +AD4 +- kmemleak+AF8-free(page+AF8-address(page))+ADs +AD4 +- +AF8AXw-free+AF8-pages(page, page-+AD4-private)+ADs +AD4 +- +AH0 +AD4 +-+AH0 +AD4 +- +AD4 +-void blk+AF8-mq+AF8-free+AF8-rqs(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct blk+AF8-mq+AF8-tags +ACo-tags, +AD4 +- unsigned int hctx+AF8-idx) +AD4 +-+AHs +AD4 if (tags-+AD4-rqs +ACYAJg set-+AD4-ops-+AD4-exit+AF8-request) +AHs +AD4 int i+ADs +AD4 +AD4 +AEAAQA -2038,16 +-2061,9 +AEAAQA void blk+AF8-mq+AF8-free+AF8-rqs(struct blk+AF8-mq+AF8-tag+AF8-set +ACo-set, struct blk+AF8-mq+AF8-tags +ACo-tags, +AD4 +AH0 +AD4 +AH0 +AD4 +AD4 - while (+ACE-list+AF8-empty(+ACY-tags-+AD4-page+AF8-list)) +AHs +AD4 - page +AD0 list+AF8-first+AF8-entry(+ACY-tags-+AD4-page+AF8-list, struct page, lru)+ADs +AD4 - list+AF8-del+AF8-init(+ACY-page-+AD4-lru)+ADs +AD4 - /+ACo +AD4 - +ACo Remove kmemleak object previously allocated in +AD4 - +ACo blk+AF8-mq+AF8-init+AF8-rq+AF8-map(). +AD4 - +ACo-/ +AD4 - kmemleak+AF8-free(page+AF8-address(page))+ADs +AD4 - +AF8AXw-free+AF8-pages(page, page-+AD4-private)+ADs +AD4 - +AH0 +AD4 +- /+ACo Punt to RCU free, so we don't race with tag iteration +ACo-/ +AD4 +- INIT+AF8-RCU+AF8-WORK(+ACY-tags-+AD4-rcu+AF8-work, blk+AF8-mq+AF8-rcu+AF8-free+AF8-pages)+ADs +AD4 +- queue+AF8-rcu+AF8-work(system+AF8-wq, +ACY-tags-+AD4-rcu+AF8-work)+ADs +AD4 +AH0 This can only work correctly if blk+AF8-mq+AF8-rcu+AF8-free+AF8-pages() is called before INIT+AF8-RCU+AF8-WORK() is called a second time for the same bkl+AF8-mq+AF8-tags structure and if blk+AF8-mq+AF8-rcu+AF8-free+AF8-pages() is called before struct blk+AF8-mq+AF8-tags is freed. What provides these guarantees? Did I perhaps miss something? Thanks, Bart.