All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: zwu.kernel@gmail.com
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org,
	linuxram@linux.vnet.ibm.com, viro@zeniv.linux.org.uk,
	cmm@us.ibm.com, tytso@mit.edu, marco.stornelli@gmail.com,
	stroetmann@ontolinux.com, diegocg@gmail.com, chris@csamuel.org,
	Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Subject: Re: [RFC v2 01/10] vfs: introduce private rb structures
Date: Tue, 25 Sep 2012 17:37:29 +1000	[thread overview]
Message-ID: <20120925073729.GA29154@dastard> (raw)
In-Reply-To: <1348404995-14372-2-git-send-email-zwu.kernel@gmail.com>

On Sun, Sep 23, 2012 at 08:56:26PM +0800, zwu.kernel@gmail.com wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> 
>   One root structure hot_info is defined, is hooked
> up in super_block, and will be used to hold rb trees
> root, hash list root and some other information, etc.
>   Adds hot_inode_tree struct to keep track of
> frequently accessed files, and be keyed by {inode, offset}.
> Trees contain hot_inode_items representing those files
> and ranges.
>   Having these trees means that vfs can quickly determine the
> temperature of some data by doing some calculations on the
> hot_freq_data struct that hangs off of the tree item.
>   Define two items hot_inode_item and hot_range_item,
> one of them represents one tracked file
> to keep track of its access frequency and the tree of
> ranges in this file, while the latter represents
> a file range of one inode.
>   Each of the two structures contains a hot_freq_data
> struct with its frequency of access metrics (number of
> {reads, writes}, last {read,write} time, frequency of
> {reads,writes}).
>   Also, each hot_inode_item contains one hot_range_tree
> struct which is keyed by {inode, offset, length}
> and used to keep track of all the ranges in this file.
> 
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>

Just a coupl eof minor formatting things first up - I'll have more
comments as I get deeper into the series.

....
> +/*
> + * Initialize the inode tree. Should be called for each new inode
> + * access or other user of the hot_inode interface.
> + */
> +static void hot_rb_inode_tree_init(struct hot_inode_tree *tree)

The names of these are a bit clunky. You probably don't need the
"_rb_" in the function name. i.e. hot_inode_tree_init() is
sufficient, and if we every want to change in the tree type we don't
have to rename every single function...

.....
> +/*
> + * Initialize a new hot_inode_item structure. The new structure is
> + * returned with a reference count of one and needs to be
> + * freed using free_inode_item()
> + */
> +void hot_rb_inode_item_init(void *_item)
> +{

The usual naming convention for slab initialiser functions is to use
a suffix of "_once" to indicate it is only ever called once per
slab object instantiation, not every time the object is allocated
fom the slab. See, for example, inode_init_once() and
inode_init_always().

so, that would make this function hot_inode_item_init_once().

....
> +/* init hot_inode_item and hot_range_item kmem cache */
> +static int __init hot_rb_item_cache_init(void)
> +{
> +	hot_inode_item_cache = kmem_cache_create("hot_inode_item",
> +			sizeof(struct hot_inode_item), 0,
> +			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
> +			hot_rb_inode_item_init);
> +	if (!hot_inode_item_cache)
> +		goto inode_err;
> +
> +	hot_range_item_cache = kmem_cache_create("hot_range_item",
> +					sizeof(struct hot_range_item), 0,
> +					SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
> +					hot_rb_range_item_init);
> +	if (!hot_range_item_cache)
> +		goto range_err;
> +
> +	return 0;
> +
> +range_err:
> +	kmem_cache_destroy(hot_inode_item_cache);
> +inode_err:
> +	return -ENOMEM;
> +}
> +
> +/*
> + * Initialize kmem cache for hot_inode_item
> + * and hot_range_item
> + */
> +void __init hot_track_cache_init(void)
> +{
> +	if (hot_rb_item_cache_init())
> +		return;

No real need to have a hot_rb_item_cache_init() function here - just
open code it all in the hot_track_cache_init() function.

> +}
> diff --git a/fs/hot_tracking.h b/fs/hot_tracking.h
> new file mode 100644
> index 0000000..269b67a
> --- /dev/null
> +++ b/fs/hot_tracking.h
> @@ -0,0 +1,27 @@
> +/*
> + * fs/hot_tracking.h
> + *
> + * Copyright (C) 2012 IBM Corp. All rights reserved.
> + * Written by Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> + *            Ben Chociej <bchociej@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License v2 as published by the Free Software Foundation.
> + */
> +
> +#ifndef __HOT_TRACKING__
> +#define __HOT_TRACKING__
> +
> +#include <linux/rbtree.h>
> +#include <linux/hot_tracking.h>
> +
> +/* values for hot_freq_data flags */
> +/* freq data struct is for an inode */
> +#define FREQ_DATA_TYPE_INODE (1 << 0)
> +/* freq data struct is for a range */
> +#define FREQ_DATA_TYPE_RANGE (1 << 1)

The comments are redundant - the name of the object documents it's
use sufficiently.  ie.

/* values for hot_freq_data flags */
#define FREQ_DATA_TYPE_INODE (1 << 0)
#define FREQ_DATA_TYPE_RANGE (1 << 1)

is just fine by itself.

....
> +/* A frequency data struct holds values that are used to
> + * determine temperature of files and file ranges. These structs
> + * are members of hot_inode_item and hot_range_item
> + */

/*
 * This is a
 * multiline comment. ;)
 */

> +struct hot_freq_data {
> +	struct timespec last_read_time;
> +	struct timespec last_write_time;
> +	u32 nr_reads;
> +	u32 nr_writes;
> +	u64 avg_delta_reads;
> +	u64 avg_delta_writes;
> +	u8 flags;
> +	u32 last_temperature;

may as well make the flags a u32 - the compiler will ues that much
space anyway as it aligned the u32 last_temperature variable after
it.

> +};
> +
> +/* An item representing an inode and its access frequency */
> +struct hot_inode_item {
> +	/* node for hot_inode_tree rb_tree */
> +	struct rb_node rb_node;
> +	/* tree of ranges in this inode */
> +	struct hot_range_tree hot_range_tree;
> +	/* frequency data for this inode */
> +	struct hot_freq_data hot_freq_data;
> +	/* inode number, copied from inode */
> +	unsigned long i_ino;
> +	/* used to check for errors in ref counting */
> +	u8 in_tree;
> +	/* protects hot_freq_data, i_no, in_tree */
> +	spinlock_t lock;
> +	/* prevents kfree */
> +	struct kref refs;

It's hard to see the code in the commentsi, and some of comments are
redundant.. It's easier to read if you do this:

struct hot_inode_item {
	struct rb_node node;			/* hot_inode_tree index */
	struct hot_range_tree hot_range_tree;	/* tree of ranges */
	struct hot_freq_data hot_freq_data;	/* frequency data */
	unsigned long i_ino;			/* inode number from inode */
	u8 in_tree;				/* ref counting check */
	spinlock_t lock;			/* protects object data */
	struct kref refs;			/* prevents kfree */
}

Also: 
	- i_ino really needs to be a 64 bit quantity as some
	  filesystems can use 64 bit inode numbers even on 32
	  bit systems (e.g. XFS).
	- in_tree can be u32 or a flags field if it is boolean. if
	  it is just debug, then maybe it can be removed whenteh
	  code is ready for commit.

> +};
> +
> +/*
> + * An item representing a range inside of an inode whose frequency
> + * is being tracked
> + */
> +struct hot_range_item {
> +	/* node for hot_range_tree rb_tree */
> +	struct rb_node rb_node;
> +	/* frequency data for this range */
> +	struct hot_freq_data hot_freq_data;
> +	/* the hot_inode_item associated with this hot_range_item */
> +	struct hot_inode_item *hot_inode;
> +	/* starting offset of this range */
> +	u64 start;
> +	/* length of this range */
> +	u64 len;

What units?
	u64 start;	/* start offset in bytes */
	u64 len		/* length in bytes */

> +	/* used to check for errors in ref counting */
> +	u8 in_tree;
> +	/* protects hot_freq_data, start, len, and in_tree */
> +	spinlock_t lock;
> +	/* prevents kfree */
> +	struct kref refs;
> +};
> +
> +struct hot_info {
> +	/* red-black tree that keeps track of fs-wide hot data */
> +	struct hot_inode_tree hot_inode_tree;
> +};

The comment is redundant...

Cheers,

Dave.

-- 
Dave Chinner
david@fromorbit.com

  reply	other threads:[~2012-09-25  7:42 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-23 12:56 [RFC v2 00/10] vfs: hot data tracking zwu.kernel
2012-09-23 12:56 ` [RFC v2 01/10] vfs: introduce private rb structures zwu.kernel
2012-09-25  7:37   ` Dave Chinner [this message]
2012-09-25  7:57     ` Zhi Yong Wu
2012-09-25  8:00     ` Zhi Yong Wu
2012-09-25 10:20   ` Ram Pai
2012-09-26  3:20     ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 02/10] vfs: add support for updating access frequency zwu.kernel
2012-09-25  9:17   ` Dave Chinner
2012-09-26  2:53     ` Zhi Yong Wu
2012-09-27  2:19       ` Dave Chinner
2012-09-27  2:30         ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 03/10] vfs: add one new mount option '-o hottrack' zwu.kernel
2012-09-25  9:28   ` Dave Chinner
2012-09-26  2:56     ` Zhi Yong Wu
2012-09-27  2:20       ` Dave Chinner
2012-09-27  2:30         ` Zhi Yong Wu
2012-09-27  5:25     ` Zhi Yong Wu
2012-09-27  7:05       ` Dave Chinner
2012-09-27  7:21         ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 04/10] vfs: add init and exit support zwu.kernel
2012-09-27  2:27   ` Dave Chinner
2012-09-23 12:56 ` [RFC v2 05/10] vfs: introduce one hash table zwu.kernel
2012-09-25  9:54   ` Ram Pai
2012-09-26  4:08     ` Zhi Yong Wu
2012-09-27  3:43   ` Dave Chinner
2012-09-27  6:23     ` Zhi Yong Wu
2012-09-27  6:57       ` Dave Chinner
2012-09-27  7:10         ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 06/10] vfs: enable hot data tracking zwu.kernel
2012-09-27  3:54   ` Dave Chinner
2012-09-27  6:28     ` Zhi Yong Wu
2012-09-27  6:59       ` Dave Chinner
2012-09-27  7:12         ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 07/10] vfs: fork one kthread to update data temperature zwu.kernel
2012-09-27  4:03   ` Dave Chinner
2012-09-27  6:54     ` Zhi Yong Wu
2012-09-27  7:01       ` Dave Chinner
2012-09-27  7:19         ` Zhi Yong Wu
2012-09-23 12:56 ` [RFC v2 08/10] vfs: add 3 new ioctl interfaces zwu.kernel
2012-09-23 12:56 ` [RFC v2 09/10] vfs: add debugfs support zwu.kernel
2012-09-23 12:56 ` [RFC v2 10/10] vfs: add documentation zwu.kernel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120925073729.GA29154@dastard \
    --to=david@fromorbit.com \
    --cc=chris@csamuel.org \
    --cc=cmm@us.ibm.com \
    --cc=diegocg@gmail.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxram@linux.vnet.ibm.com \
    --cc=marco.stornelli@gmail.com \
    --cc=stroetmann@ontolinux.com \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wuzhy@linux.vnet.ibm.com \
    --cc=zwu.kernel@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.