]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Revert "ocfs2: change ip_unaligned_aio to of type mutex from atomit_t"
authorRyan Ding <ryan.ding@oracle.com>
Fri, 16 Oct 2015 08:26:40 +0000 (16:26 +0800)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Fri, 30 Oct 2015 16:13:42 +0000 (09:13 -0700)
This reverts commit c18ceab01240fd4c354b78d877571b729908e4a3.

Test shows ip_unaligned_aio will cost much cpu clock when doing aio+dio(in a
function named mutex_spin_on_owner), and will significant affect performance in
a system with poor cpu.

The cause is we should not call mutex_unlock(see the comments above
mutex_unlock) in ocfs2_dio_end_io, which will be in irq context when doing
aio+dio.

Revert the patch to use wait_event/wake_up_all to do the work.

Signed-off-by: Ryan Ding <ryan.ding@oracle.com>
Reviewed-by: Junxiao Bi <junxiao.bi@oracle.com>
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/file.c
fs/ocfs2/inode.h
fs/ocfs2/super.c

index e48299f7a0d4be427de074a9cf2500a5b95c0eb6..95e2dcfd8e9bc6f3e83dcb58f188dbbaa925139c 100644 (file)
@@ -615,6 +615,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
 {
        struct inode *inode = file_inode(iocb->ki_filp);
        int level;
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
@@ -625,7 +626,10 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        if (ocfs2_iocb_is_unaligned_aio(iocb)) {
                ocfs2_iocb_clear_unaligned_aio(iocb);
 
-               mutex_unlock(&OCFS2_I(inode)->ip_unaligned_aio);
+               if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
        }
 
        ocfs2_iocb_clear_rw_locked(iocb);
index dd59599b022d5ab26dffd82807d048cac170a154..65f10fb82ee475c3267ac9385c528247d2ebd696 100644 (file)
@@ -102,4 +102,9 @@ enum ocfs2_iocb_lock_bits {
 #define ocfs2_iocb_is_unaligned_aio(iocb) \
        test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
 
+#define OCFS2_IOEND_WQ_HASH_SZ 37
+#define ocfs2_ioend_wq(v)   (&ocfs2__ioend_wq[((unsigned long)(v)) %\
+                                           OCFS2_IOEND_WQ_HASH_SZ])
+extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 #endif /* OCFS2_FILE_H */
index cdd30c04537e3e347d2522e56882de5d6eb19787..cbb2ccdb326a590b7c8bcb400999d2c329feac76 100644 (file)
@@ -2074,6 +2074,13 @@ out:
        return ret;
 }
 
+static void ocfs2_aiodio_wait(struct inode *inode)
+{
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
+
+       wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0));
+}
+
 static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
 {
        int blockmask = inode->i_sb->s_blocksize - 1;
@@ -2378,8 +2385,10 @@ relock:
                 * Wait on previous unaligned aio to complete before
                 * proceeding.
                 */
-               mutex_lock(&OCFS2_I(inode)->ip_unaligned_aio);
-               /* Mark the iocb as needing an unlock in ocfs2_dio_end_io */
+               ocfs2_aiodio_wait(inode);
+
+               /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */
+               atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio);
                ocfs2_iocb_set_unaligned_aio(iocb);
        }
 
@@ -2452,7 +2461,7 @@ relock:
 no_sync:
        if (unaligned_dio) {
                ocfs2_iocb_clear_unaligned_aio(iocb);
-               mutex_unlock(&OCFS2_I(inode)->ip_unaligned_aio);
+               atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio);
        }
 
 out:
index 5e86b247c821ce8434dfa5c9d5fe59798a8cde86..c8723c65792d792feab9201f23f53b5cbf6c8b1e 100644 (file)
@@ -44,7 +44,7 @@ struct ocfs2_inode_info
        struct rw_semaphore             ip_xattr_sem;
 
        /* Number of outstanding AIO's which are not page aligned */
-       struct mutex                    ip_unaligned_aio;
+       atomic_t                        ip_unaligned_aio;
 
        /* These fields are protected by ip_lock */
        spinlock_t                      ip_lock;
index a8004a6ca2661d5aadcf42bc7c5f5e23eada0479..a52344583c8def3a5a53a684ec9e65f6d1a096f9 100644 (file)
@@ -1594,9 +1594,14 @@ static int ocfs2_show_options(struct seq_file *s, struct dentry *root)
        return 0;
 }
 
+wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 static int __init ocfs2_init(void)
 {
-       int status;
+       int status, i;
+
+       for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++)
+               init_waitqueue_head(&ocfs2__ioend_wq[i]);
 
        ocfs2_print_version();
        status = init_ocfs2_uptodate_cache();
@@ -1740,7 +1745,7 @@ static void ocfs2_inode_init_once(void *data)
        ocfs2_extent_map_init(&oi->vfs_inode);
        INIT_LIST_HEAD(&oi->ip_io_markers);
        oi->ip_dir_start_lookup = 0;
-       mutex_init(&oi->ip_unaligned_aio);
+       atomic_set(&oi->ip_unaligned_aio, 0);
        init_rwsem(&oi->ip_alloc_sem);
        init_rwsem(&oi->ip_xattr_sem);
        mutex_init(&oi->ip_io_mutex);