Commit 07416d29bcf608257f1e5280642dcbe0021518a3

Authored by Jens Axboe
1 parent aa94b5371f

cfq-iosched: fix RCU race in the cfq io_context destructor handling

put_io_context() drops the RCU read lock before calling into cfq_dtor(),
however we need to hold off freeing there before grabbing and
dereferencing the first object on the list.

So extend the rcu_read_lock() scope to cover the calling of cfq_dtor(),
and optimize cfq_free_io_context() to use a new variant for
call_for_each_cic() that assumes the RCU read lock is already held.

Hit in the wild by Alexey Dobriyan <adobriyan@gmail.com>

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 2 changed files with 14 additions and 7 deletions Side-by-side Diff

... ... @@ -41,8 +41,8 @@
41 41 rcu_read_lock();
42 42 if (ioc->aic && ioc->aic->dtor)
43 43 ioc->aic->dtor(ioc->aic);
44   - rcu_read_unlock();
45 44 cfq_dtor(ioc);
  45 + rcu_read_unlock();
46 46  
47 47 kmem_cache_free(iocontext_cachep, ioc);
48 48 return 1;
... ... @@ -1142,6 +1142,17 @@
1142 1142 kmem_cache_free(cfq_pool, cfqq);
1143 1143 }
1144 1144  
  1145 +static void
  1146 +__call_for_each_cic(struct io_context *ioc,
  1147 + void (*func)(struct io_context *, struct cfq_io_context *))
  1148 +{
  1149 + struct cfq_io_context *cic;
  1150 + struct hlist_node *n;
  1151 +
  1152 + hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
  1153 + func(ioc, cic);
  1154 +}
  1155 +
1145 1156 /*
1146 1157 * Call func for each cic attached to this ioc.
1147 1158 */
1148 1159  
... ... @@ -1149,12 +1160,8 @@
1149 1160 call_for_each_cic(struct io_context *ioc,
1150 1161 void (*func)(struct io_context *, struct cfq_io_context *))
1151 1162 {
1152   - struct cfq_io_context *cic;
1153   - struct hlist_node *n;
1154   -
1155 1163 rcu_read_lock();
1156   - hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
1157   - func(ioc, cic);
  1164 + __call_for_each_cic(ioc, func);
1158 1165 rcu_read_unlock();
1159 1166 }
1160 1167  
... ... @@ -1198,7 +1205,7 @@
1198 1205 * should be ok to iterate over the known list, we will see all cic's
1199 1206 * since no new ones are added.
1200 1207 */
1201   - call_for_each_cic(ioc, cic_free_func);
  1208 + __call_for_each_cic(ioc, cic_free_func);
1202 1209 }
1203 1210  
1204 1211 static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)