[PATCH] aio: remove kioctx from mm_struct
authorZach Brown <zach.brown@oracle.com>
Mon, 14 Nov 2005 00:07:33 +0000 (16:07 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 14 Nov 2005 02:14:16 +0000 (18:14 -0800)
Sync iocbs have a life cycle that don't need a kioctx.  Their retrying, if
any, is done in the context of their owner who has allocated them on the
stack.

The sole user of a sync iocb's ctx reference was aio_complete() checking for
an elevated iocb ref count that could never happen.  No path which grabs an
iocb ref has access to sync iocbs.

If we were to implement sync iocb cancelation it would be done by the owner of
the iocb using its on-stack reference.

Removing this chunk from aio_complete allows us to remove the entire kioctx
instance from mm_struct, reducing its size by a third.  On a i386 testing box
the slab size went from 768 to 504 bytes and from 5 to 8 per page.

Signed-off-by: Zach Brown <zach.brown@oracle.com>
Acked-by: Benjamin LaHaise <bcrl@kvack.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/aio.c
include/linux/aio.h
include/linux/init_task.h
include/linux/sched.h
kernel/fork.c

index 20bb919eb1958e6e4dbbf96f6f04812a23983a24..e7cd40b626b7f3bd06446e7d01da5c7aaab623de 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -937,28 +937,19 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
        unsigned long   tail;
        int             ret;
 
-       /* Special case handling for sync iocbs: events go directly
-        * into the iocb for fast handling.  Note that this will not 
-        * work if we allow sync kiocbs to be cancelled. in which
-        * case the usage count checks will have to move under ctx_lock
-        * for all cases.
+       /*
+        * Special case handling for sync iocbs:
+        *  - events go directly into the iocb for fast handling
+        *  - the sync task with the iocb in its stack holds the single iocb
+        *    ref, no other paths have a way to get another ref
+        *  - the sync task helpfully left a reference to itself in the iocb
         */
        if (is_sync_kiocb(iocb)) {
-               int ret;
-
+               BUG_ON(iocb->ki_users != 1);
                iocb->ki_user_data = res;
-               if (iocb->ki_users == 1) {
-                       iocb->ki_users = 0;
-                       ret = 1;
-               } else {
-                       spin_lock_irq(&ctx->ctx_lock);
-                       iocb->ki_users--;
-                       ret = (0 == iocb->ki_users);
-                       spin_unlock_irq(&ctx->ctx_lock);
-               }
-               /* sync iocbs put the task here for us */
+               iocb->ki_users = 0;
                wake_up_process(iocb->ki_obj.tsk);
-               return ret;
+               return 1;
        }
 
        info = &ctx->ring_info;
index 403d71dcb7c818beb2b43101af33d6133f6d5622..9e0ae87112763035192a6301a6aa8a3ab2e179c9 100644 (file)
@@ -124,7 +124,7 @@ struct kiocb {
                (x)->ki_users = 1;                      \
                (x)->ki_key = KIOCB_SYNC_KEY;           \
                (x)->ki_filp = (filp);                  \
-               (x)->ki_ctx = &tsk->active_mm->default_kioctx;  \
+               (x)->ki_ctx = NULL;                     \
                (x)->ki_cancel = NULL;                  \
                (x)->ki_dtor = NULL;                    \
                (x)->ki_obj.tsk = tsk;                  \
index 68ab5f2ab9cdb35bd8249f03b7e3b5b0bc54e443..dcfd2ecccb5d63dbcb2718a2f3e827aef9d68a23 100644 (file)
@@ -51,7 +51,6 @@
        .page_table_lock =  SPIN_LOCK_UNLOCKED,                 \
        .mmlist         = LIST_HEAD_INIT(name.mmlist),          \
        .cpu_vm_mask    = CPU_MASK_ALL,                         \
-       .default_kioctx = INIT_KIOCTX(name.default_kioctx, name),       \
 }
 
 #define INIT_SIGNALS(sig) {    \
index 41df813957190adecba9015a4d17b7c13524f5f8..2038bd27b0413c74bcb66290adc3cfe33b5c0fd3 100644 (file)
@@ -357,7 +357,6 @@ struct mm_struct {
        /* aio bits */
        rwlock_t                ioctx_list_lock;
        struct kioctx           *ioctx_list;
-       struct kioctx           default_kioctx;
 };
 
 struct sighand_struct {
index 2c70c9cdf5dcf0c3f5955a467c5e47b68a77463b..e0d0b77343f880b60d8551338c26e05420c47291 100644 (file)
@@ -323,7 +323,6 @@ static struct mm_struct * mm_init(struct mm_struct * mm)
        spin_lock_init(&mm->page_table_lock);
        rwlock_init(&mm->ioctx_list_lock);
        mm->ioctx_list = NULL;
-       mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
        mm->free_area_cache = TASK_UNMAPPED_BASE;
        mm->cached_hole_size = ~0UL;