lkml.org 
[lkml]   [1998]   [Aug]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 2.1.114 VFS code 5x slower than 2.0.33?!? (patch attached)
    Michael L. Galbraith wrote:

    > I tried ls -l from the test directory with ktracer and a 1048576 entry
    > trace buffer. It fills the buffer, so it's only the last (nearly) 1000000
    > function calls.
    >
    > echo > /proc/trace;(/bin/ls -l > /dev/null);dotrace > trace2
    >
    > A profile of that looks like..
    >
    > TIME% USECS-TOTAL AVG-USECS CALLS ADDRESS FUNCTION
    > 0.0612% 1522.31 4.73 322 c01355f3 d_lookup
    > 0.0777% 1935.03 0.52 3747 c01491a7 inode_getblk
    > 0.0833% 2074.79 3.29 630 c0125d9f __get_free_pages
    > 0.0934% 2324.23 0.38 6164 c012ae0a __brelse
    > 0.0976% 2428.45 0.39 6161 c012a77b getblk
    > 0.0979% 2438.01 0.40 6169 c0129fa4 get_hash_table
    > 0.0989% 2462.22 0.66 3747 c01495e3 ext2_getblk
    > 0.1045% 2600.19 0.42 6168 c012aac1 set_writetime
    > 0.1482% 3688.33 3.36 1097 c0125c7b free_pages
    > 0.1810% 4506.08 85.02 53 c01f3602 ___copy_user
    > 0.2510% 6247.79 32.88 190 c01f3527 __memcpy_g
    > 0.2733% 6803.21 1.07 6385 c012ab17 refile_buffer
    > 0.2967% 7385.19 55.95 132 c0136243 find_inode
    > 0.5184% 12903.88 2.02 6384 c0129f4b find_buffer
    > 0.8341% 20763.10 943.78 22 c0113d7b add_timer
    > 0.8640% 21506.21 51.95 414 c01f34a2 ___zero_chunk
    > 2.9761% 74083.18 3704.16 20 c0111753 do_check_pgt_cache
    > 6.9174% 172194.28 242.53 710 c011e8bd put_page
    > 23.8479% 593640.59 827.95 717 c010a976 ret_from_sys_call
    > 24.7294% 615583.22 1905.83 323 c010c107 do_IRQ
    > 36.0331% 896962.98 0.92 976587 c014721c ext2_check_dir_entry
    > 1048556 entries; 2777969.43 total usecs; 10.39% idle.

    Hi Mike,

    I rewrote ext2_check_dir_entry to move the error handling out-of-line, and
    thought you might be interested in profiling to see whether it helps at all.

    Even if ext2_check_dir_entry doesn't account for the long elapsed times, it
    should still be worthwhile to speed it up a bit, as your profiling results
    indicate that it does get called a lot.

    Regards,
    Bill





    --- linux-2.1.115/fs/ext2/dir.c.old Wed May 20 13:08:35 1998
    +++ linux-2.1.115/fs/ext2/dir.c Sat Aug 8 11:08:20 1998
    @@ -79,27 +79,48 @@
    struct buffer_head * bh,
    unsigned long offset)
    {
    - const char * error_msg = NULL;
    + struct super_block *sb;
    + const char * error_msg;

    if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(1))
    - error_msg = "rec_len is smaller than minimal";
    - else if (le16_to_cpu(de->rec_len) % 4 != 0)
    - error_msg = "rec_len % 4 != 0";
    - else if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
    - error_msg = "rec_len is too small for name_len";
    - else if (dir && ((char *) de - bh->b_data) + le16_to_cpu(de->rec_len) >
    - dir->i_sb->s_blocksize)
    - error_msg = "directory entry across blocks";
    - else if (dir && le32_to_cpu(de->inode) > le32_to_cpu(dir->i_sb->u.ext2_sb.s_es->s_inodes_count))
    - error_msg = "inode out of bounds";
    + goto out_too_small;
    + if (le16_to_cpu(de->rec_len) % 4 != 0)
    + goto out_not_four;
    + if (le16_to_cpu(de->rec_len) < EXT2_DIR_REC_LEN(de->name_len))
    + goto out_namelen;
    + if (!dir)
    + goto out_OK;
    + sb = dir->i_sb;
    + if (((char *) de - bh->b_data) + le16_to_cpu(de->rec_len) > sb->s_blocksize)
    + goto out_cross;
    + if (le32_to_cpu(de->inode) <= le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count)) {
    + out_OK:
    + return 1;
    + }

    - if (error_msg != NULL)
    - ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
    - "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
    - dir->i_ino, error_msg, offset,
    - (unsigned long) le32_to_cpu(de->inode),
    - le16_to_cpu(de->rec_len), de->name_len);
    - return error_msg == NULL ? 1 : 0;
    + /*
    + * Error exits
    + */
    + error_msg = "inode out of bounds";
    + goto out_error;
    +out_too_small:
    + error_msg = "rec_len is smaller than minimal";
    + goto out_error;
    +out_not_four:
    + error_msg = "rec_len % 4 != 0";
    + goto out_error;
    +out_namelen:
    + error_msg = "rec_len is too small for name_len";
    + goto out_error;
    +out_cross:
    + error_msg = "directory entry across blocks";
    +out_error:
    + ext2_error (dir->i_sb, function, "bad entry in directory #%lu: %s - "
    + "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
    + dir->i_ino, error_msg, offset,
    + (unsigned long) le32_to_cpu(de->inode),
    + le16_to_cpu(de->rec_len), de->name_len);
    + return 0;
    }

    static int ext2_readdir(struct file * filp,
    \
     
     \ /
      Last update: 2005-03-22 13:43    [W:0.029 / U:1.296 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site