Skip to content

Commit

Permalink
[PATCH] aio: remove kioctx from mm_struct
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Benjamin LaHaise <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Zach Brown authored and Linus Torvalds committed Nov 14, 2005
1 parent 4557398 commit 20dcae3
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 22 deletions.
27 changes: 9 additions & 18 deletions fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand Down
1 change: 0 additions & 1 deletion include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) { \
Expand Down
1 change: 0 additions & 1 deletion include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 20dcae3

Please sign in to comment.