x86: add uniq_ioapic_id to mpparse_32.c
[sfrench/cifs-2.6.git] / block / cfq-iosched.c
index 0f962ecae91fb68345fe1d916791a78e06a2f2e8..f4e1006c253d3ade81cc9b39ce80da6612b277a6 100644 (file)
@@ -1143,24 +1143,37 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
 }
 
 /*
- * Call func for each cic attached to this ioc. Returns number of cic's seen.
+ * Call func for each cic attached to this ioc.
  */
-static unsigned int
+static void
 call_for_each_cic(struct io_context *ioc,
                  void (*func)(struct io_context *, struct cfq_io_context *))
 {
        struct cfq_io_context *cic;
        struct hlist_node *n;
-       int called = 0;
 
        rcu_read_lock();
-       hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) {
+       hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list)
                func(ioc, cic);
-               called++;
-       }
        rcu_read_unlock();
+}
+
+static void cfq_cic_free_rcu(struct rcu_head *head)
+{
+       struct cfq_io_context *cic;
+
+       cic = container_of(head, struct cfq_io_context, rcu_head);
+
+       kmem_cache_free(cfq_ioc_pool, cic);
+       elv_ioc_count_dec(ioc_count);
 
-       return called;
+       if (ioc_gone && !elv_ioc_count_read(ioc_count))
+               complete(ioc_gone);
+}
+
+static void cfq_cic_free(struct cfq_io_context *cic)
+{
+       call_rcu(&cic->rcu_head, cfq_cic_free_rcu);
 }
 
 static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
@@ -1174,24 +1187,18 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic)
        hlist_del_rcu(&cic->cic_list);
        spin_unlock_irqrestore(&ioc->lock, flags);
 
-       kmem_cache_free(cfq_ioc_pool, cic);
+       cfq_cic_free(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.
+        * ioc->refcount is zero here, or we are called from elv_unregister(),
+        * 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);
-
-       elv_ioc_count_mod(ioc_count, -freed);
-
-       if (ioc_gone && !elv_ioc_count_read(ioc_count))
-               complete(ioc_gone);
+       call_for_each_cic(ioc, cic_free_func);
 }
 
 static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
@@ -1207,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
                                         struct cfq_io_context *cic)
 {
+       struct io_context *ioc = cic->ioc;
+
        list_del_init(&cic->queue_list);
 
        /*
@@ -1216,6 +1225,9 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
        cic->dead_key = (unsigned long) cic->key;
        cic->key = NULL;
 
+       if (ioc->ioc_data == cic)
+               rcu_assign_pointer(ioc->ioc_data, NULL);
+
        if (cic->cfqq[ASYNC]) {
                cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
                cic->cfqq[ASYNC] = NULL;
@@ -1248,7 +1260,6 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
  */
 static void cfq_exit_io_context(struct io_context *ioc)
 {
-       rcu_assign_pointer(ioc->ioc_data, NULL);
        call_for_each_cic(ioc, cfq_exit_single_io_context);
 }
 
@@ -1458,15 +1469,6 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc,
        return cfqq;
 }
 
-static void cfq_cic_free(struct cfq_io_context *cic)
-{
-       kmem_cache_free(cfq_ioc_pool, cic);
-       elv_ioc_count_dec(ioc_count);
-
-       if (ioc_gone && !elv_ioc_count_read(ioc_count))
-               complete(ioc_gone);
-}
-
 /*
  * We drop cfq io contexts lazily, so we may find a dead one.
  */
@@ -1480,8 +1482,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
 
        spin_lock_irqsave(&ioc->lock, flags);
 
-       if (ioc->ioc_data == cic)
-               rcu_assign_pointer(ioc->ioc_data, NULL);
+       BUG_ON(ioc->ioc_data == cic);
 
        radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
        hlist_del_rcu(&cic->cic_list);
@@ -2138,7 +2139,7 @@ static int __init cfq_slab_setup(void)
        if (!cfq_pool)
                goto fail;
 
-       cfq_ioc_pool = KMEM_CACHE(cfq_io_context, SLAB_DESTROY_BY_RCU);
+       cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
        if (!cfq_ioc_pool)
                goto fail;
 
@@ -2286,7 +2287,6 @@ static void __exit cfq_exit(void)
        smp_wmb();
        if (elv_ioc_count_read(ioc_count))
                wait_for_completion(ioc_gone);
-       synchronize_rcu();
        cfq_slab_kill();
 }