- while ((n = rb_first(&ioc->cic_root)) != NULL) {
- __cic = rb_entry(n, struct cfq_io_context, rb_node);
- rb_erase(&__cic->rb_node, &ioc->cic_root);
- kmem_cache_free(cfq_ioc_pool, __cic);
- freed++;
- }
+ do {
+ int i;
+
+ /*
+ * Perhaps there's a better way - this just gang lookups from
+ * 0 to the end, restarting after each CIC_GANG_NR from the
+ * last key + 1.
+ */
+ nr = radix_tree_gang_lookup(&ioc->radix_root, (void **) cics,
+ index, CIC_GANG_NR);
+ if (!nr)
+ break;
+
+ called += nr;
+ index = 1 + (unsigned long) cics[nr - 1]->key;
+
+ for (i = 0; i < nr; i++)
+ func(ioc, cics[i]);
+ } while (nr == CIC_GANG_NR);
+
+ rcu_read_unlock();
+
+ return called;
+}
+
+static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
+{
+ unsigned long flags;
+
+ BUG_ON(!cic->dead_key);
+
+ spin_lock_irqsave(&ioc->lock, flags);
+ radix_tree_delete(&ioc->radix_root, cic->dead_key);
+ spin_unlock_irqrestore(&ioc->lock, flags);
+
+ kmem_cache_free(cfq_ioc_pool, cic);
+}
+
+static void cfq_free_io_context(struct io_context *ioc)
+{
+ int freed;
+
+ /*
+ * ioc->refcount is zero here, so no more cic's are allowed to be
+ * linked into this ioc. So it should be ok to iterate over the known
+ * list, we will see all cic's since no new ones are added.
+ */
+ freed = call_for_each_cic(ioc, cic_free_func);