diff options
author | Tejun Heo <tj@kernel.org> | 2011-12-13 18:33:42 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-12-13 18:33:42 -0500 |
commit | 7e5a8794492e43e9eebb68a98a23be055888ccd0 (patch) | |
tree | cc049a23b2c994f910d3101860bc1c2ecb7aa35f /include/linux/iocontext.h | |
parent | 3d3c2379feb177a5fd55bb0ed76776dc9d4f3243 (diff) |
block, cfq: move io_cq exit/release to blk-ioc.c
With kmem_cache managed by blk-ioc, io_cq exit/release can be moved to
blk-ioc too. The odd ->io_cq->exit/release() callbacks are replaced
with elevator_ops->elevator_exit_icq_fn() with unlinking from both ioc
and q, and freeing automatically handled by blk-ioc. The elevator
operation only need to perform exit operation specific to the elevator
- in cfq's case, exiting the cfqq's.
Also, clearing of io_cq's on q detach is moved to block core and
automatically performed on elevator switch and q release.
Because the q io_cq points to might be freed before RCU callback for
the io_cq runs, blk-ioc code should remember to which cache the io_cq
needs to be freed when the io_cq is released. New field
io_cq->__rcu_icq_cache is added for this purpose. As both the new
field and rcu_head are used only after io_cq is released and the
q/ioc_node fields aren't, they are put into unions.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/iocontext.h')
-rw-r--r-- | include/linux/iocontext.h | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index d15ca6591f96..ac390a34c0e7 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h | |||
@@ -14,14 +14,22 @@ struct io_cq { | |||
14 | struct request_queue *q; | 14 | struct request_queue *q; |
15 | struct io_context *ioc; | 15 | struct io_context *ioc; |
16 | 16 | ||
17 | struct list_head q_node; | 17 | /* |
18 | struct hlist_node ioc_node; | 18 | * q_node and ioc_node link io_cq through icq_list of q and ioc |
19 | * respectively. Both fields are unused once ioc_exit_icq() is | ||
20 | * called and shared with __rcu_icq_cache and __rcu_head which are | ||
21 | * used for RCU free of io_cq. | ||
22 | */ | ||
23 | union { | ||
24 | struct list_head q_node; | ||
25 | struct kmem_cache *__rcu_icq_cache; | ||
26 | }; | ||
27 | union { | ||
28 | struct hlist_node ioc_node; | ||
29 | struct rcu_head __rcu_head; | ||
30 | }; | ||
19 | 31 | ||
20 | unsigned long changed; | 32 | unsigned long changed; |
21 | struct rcu_head rcu_head; | ||
22 | |||
23 | void (*exit)(struct io_cq *); | ||
24 | void (*release)(struct io_cq *); | ||
25 | }; | 33 | }; |
26 | 34 | ||
27 | /* | 35 | /* |