struct page             **ring_pages;
        long                    nr_pages;
 
-       struct work_struct      free_work;
+       struct rcu_head         free_rcu;
+       struct work_struct      free_work;      /* see free_ioctx() */
 
        /*
         * signals when all in-flight requests are done
        return cancel(&kiocb->common);
 }
 
+/*
+ * free_ioctx() should be RCU delayed to synchronize against the RCU
+ * protected lookup_ioctx() and also needs process context to call
+ * aio_free_ring(), so the double bouncing through kioctx->free_rcu and
+ * ->free_work.
+ */
 static void free_ioctx(struct work_struct *work)
 {
        struct kioctx *ctx = container_of(work, struct kioctx, free_work);
        kmem_cache_free(kioctx_cachep, ctx);
 }
 
+static void free_ioctx_rcufn(struct rcu_head *head)
+{
+       struct kioctx *ctx = container_of(head, struct kioctx, free_rcu);
+
+       INIT_WORK(&ctx->free_work, free_ioctx);
+       schedule_work(&ctx->free_work);
+}
+
 static void free_ioctx_reqs(struct percpu_ref *ref)
 {
        struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
        if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
                complete(&ctx->rq_wait->comp);
 
-       INIT_WORK(&ctx->free_work, free_ioctx);
-       schedule_work(&ctx->free_work);
+       /* Synchronize against RCU protected table->table[] dereferences */
+       call_rcu(&ctx->free_rcu, free_ioctx_rcufn);
 }
 
 /*
        table->table[ctx->id] = NULL;
        spin_unlock(&mm->ioctx_lock);
 
-       /* percpu_ref_kill() will do the necessary call_rcu() */
+       /* free_ioctx_reqs() will do the necessary RCU synchronization */
        wake_up_all(&ctx->wait);
 
        /*