From: Andrew Morton <akpm@linux-foundation.org>
To: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@kernel.org, npiggin@suse.de, david@fromorbit.com,
linux-mm@kvack.org
Subject: Re: [PATCH 1/2] radix-tree: Implement function radix_tree_gang_tag_if_tagged
Date: Wed, 9 Jun 2010 16:30:45 -0700 [thread overview]
Message-ID: <20100609163045.797ae621.akpm@linux-foundation.org> (raw)
In-Reply-To: <1275676854-15461-2-git-send-email-jack@suse.cz>
On Fri, 4 Jun 2010 20:40:53 +0200
Jan Kara <jack@suse.cz> wrote:
> Implement function for setting one tag if another tag is set
> for each item in given range.
>
>
> ...
>
> /**
> + * radix_tree_gang_tag_if_tagged - for each item in given range set given
> + * tag if item has another tag set
> + * @root: radix tree root
> + * @first_index: starting index of a range to scan
> + * @last_index: last index of a range to scan
> + * @iftag: tag index to test
> + * @settag: tag index to set if tested tag is set
> + *
> + * This function scans range of radix tree from first_index to last_index.
> + * For each item in the range if iftag is set, the function sets also
> + * settag.
> + *
> + * The function returns number of leaves where the tag was set.
> + */
> +unsigned long radix_tree_gang_tag_if_tagged(struct radix_tree_root *root,
> + unsigned long first_index, unsigned long last_index,
> + unsigned int iftag, unsigned int settag)
This is kind of a misuse of the term "gang".
First we had radix_tree_lookup(), which returned a single page.
That was a bit inefficient, so then we added radix_tree_gang_lookup(),
which retuned a "gang" of pages.
But radix_tree_gang_tag_if_tagged() doesn't return a gang of anything
(it has no `void **results' argument).
radix_tree_range_tag_if_tagged()?
> +{
> + unsigned int height = root->height, shift;
> + unsigned long tagged = 0, index = first_index;
> + struct radix_tree_node *open_slots[height], *slot;
> +
> + last_index = min(last_index, radix_tree_maxindex(height));
> + if (first_index > last_index)
> + return 0;
> + if (!root_tag_get(root, iftag))
> + return 0;
> + if (height == 0) {
> + root_tag_set(root, settag);
> + return 1;
> + }
> +
> + shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
> + slot = radix_tree_indirect_to_ptr(root->rnode);
> +
> + for (;;) {
> + int offset;
> +
> + offset = (index >> shift) & RADIX_TREE_MAP_MASK;
> + if (!slot->slots[offset])
> + goto next;
> + if (!tag_get(slot, iftag, offset))
> + goto next;
> + tag_set(slot, settag, offset);
> + if (height == 1) {
> + tagged++;
> + goto next;
> + }
> + /* Go down one level */
> + height--;
> + shift -= RADIX_TREE_MAP_SHIFT;
> + open_slots[height] = slot;
> + slot = slot->slots[offset];
> + continue;
> +next:
> + /* Go to next item at level determined by 'shift' */
> + index = ((index >> shift) + 1) << shift;
> + if (index > last_index)
> + break;
> + while (((index >> shift) & RADIX_TREE_MAP_MASK) == 0) {
> + /*
> + * We've fully scanned this node. Go up. Because
> + * last_index is guaranteed to be in the tree, what
> + * we do below cannot wander astray.
> + */
> + slot = open_slots[height];
> + height++;
> + shift += RADIX_TREE_MAP_SHIFT;
> + }
> + }
> + /*
> + * The iftag must have been set somewhere because otherwise
> + * we would return immediated at the beginning of the function
> + */
> + root_tag_set(root, settag);
> +
> + return tagged;
> +}
> +EXPORT_SYMBOL(radix_tree_gang_tag_if_tagged);
Wouldn't this be a lot simpler if it used __lookup_tag()? Along the
lines of
do {
slot *slots[N];
n = __lookup_tag(.., slots, ...);
for (i = 0; i < n; i++)
tag_set(slots[i], ...);
} while (something);
?
That's still one cache miss per slot and misses on the slots will
preponderate, so the performance won't be much different.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2010-06-09 23:30 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-04 18:40 [PATCH 0/2 RFC v3] Livelock avoidance for data integrity writeback Jan Kara
2010-06-04 18:40 ` [PATCH 1/2] radix-tree: Implement function radix_tree_gang_tag_if_tagged Jan Kara
2010-06-09 23:30 ` Andrew Morton [this message]
2010-06-10 12:28 ` Jan Kara
2010-06-04 18:40 ` [PATCH 2/2] mm: Implement writeback livelock avoidance using page tagging Jan Kara
2010-06-09 23:41 ` Andrew Morton
2010-06-10 12:31 ` Jan Kara
2010-06-09 23:45 ` Andrew Morton
2010-06-10 12:42 ` Jan Kara
-- strict thread matches above, loose matches on Subject: below --
2010-06-04 18:47 [PATCH 0/2 RFC v3] Livelock avoidance for data integrity writeback Jan Kara
2010-06-04 18:47 ` [PATCH 1/2] radix-tree: Implement function radix_tree_gang_tag_if_tagged Jan Kara
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=20100609163045.797ae621.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=david@fromorbit.com \
--cc=jack@suse.cz \
--cc=linux-fsdevel@kernel.org \
--cc=linux-mm@kvack.org \
--cc=npiggin@suse.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).