Re: 2.1.114 VFS code 5x slower than 2.0.33?!? (patch attached)

Bill Hawes (whawes@transmeta.com)
Mon, 10 Aug 1998 10:38:31 -0700


This is a multi-part message in MIME format.
--------------905C2E33323D42EE265B666E
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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

--------------905C2E33323D42EE265B666E
Content-Type: text/plain; charset=us-ascii; name="fs_ext2dir115-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="fs_ext2dir115-patch"

--- 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,

--------------905C2E33323D42EE265B666E--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html