All of lore.kernel.org
 help / color / mirror / Atom feed
* (unknown), 
@ 2010-06-16 16:33 ` Jan Kara
  0 siblings, 0 replies; 30+ messages in thread
From: Jan Kara @ 2010-06-16 16:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: linux-mm, Andrew Morton, npiggin

  Hello,

  here is the fourth version of the writeback livelock avoidance patches
for data integrity writes. To quickly summarize the idea: we tag dirty
pages at the beginning of write_cache_pages with a new TOWRITE tag and
then write only tagged pages to avoid parallel writers to livelock us.
See changelogs of the patches for more details.
  I have tested the patches with fsx and a test program I wrote which
checks that if we crash after fsync, the data is indeed on disk.
  If there are no more concerns, can these patches get merged?

								Honza

  Changes since last version:
- tagging function was changed to stop after given amount of pages to
  avoid keeping tree_lock and irqs disabled for too long
- changed names and updated comments as Andrew suggested
- measured memory impact and reported it in the changelog

  Things suggested but not changed (I want to avoid going in circles ;):
- use tagging also for WB_SYNC_NONE writeback - there's problem with an
  interaction with wbc->nr_to_write. If we tag all dirty pages, we can
  spend too much time tagging when we write only a few pages in the end
  because of nr_to_write. If we tag only say nr_to_write pages, we may
  not have enough pages tagged because some pages are written out by
  someone else and so we would have to restart and tagging would become
  essentially useless. So my option is - switch to tagging for WB_SYNC_NONE
  writeback if we can get rid of nr_to_write. But that's a story for
  a different patch set.
- implement function for clearing several tags (TOWRITE, DIRTY) at once
  - IMHO not worth it because we would save only conversion of page index
  to radix tree offsets. The rest would have to be separate anyways. And
  the interface would be incosistent as well...
- use __lookup_tag to implement radix_tree_range_tag_if_tagged - doesn't
  quite work because __lookup_tag returns only leaf nodes so we'd have to
  implement tree traversal anyways to tag also internal nodes.

^ permalink raw reply	[flat|nested] 30+ messages in thread
* [PATCH 0/2 v5] Livelock avoidance for data integrity writes
@ 2010-06-24 13:57 Jan Kara
  2010-06-24 13:57 ` [PATCH 1/2] radix-tree: Implement function radix_tree_range_tag_if_tagged Jan Kara
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Kara @ 2010-06-24 13:57 UTC (permalink / raw)
  To: Andrew Morton; +Cc: inux-fsdevel, linux-mm, npiggin, david


  Hi,

  this is an update of my patches to implement livelock avoidance for data
integrity writes using page tagging. There are some minor changes against
the previous versions:
  * fixed some whitespace problems spotted checkpatch
  * added WARN_ON_ONCE to catch a problem if radix_tree_range_tag_if_tagged
    tags more pages than we asked
  * fixed radix_tree_range_tag_if_tagged to tag at most as many pages as
    we asked (it could tag one page more).

  The patch now passed also XFSQA for XFS (well, several tests failed - like
192, 195, 228 ... - but they don't seem to be related - they are atime test,
ctime test, file alignment test, ...). Also the radix tree code passed through
10000 iterations of the following test I've implemented in Andrew's rtth:

void copy_tag_check(void)
{
        RADIX_TREE(tree, GFP_KERNEL);
        unsigned long idx[ITEMS];
        unsigned long start, end, count = 0, tagged, cur, tmp;
        int i;

//      printf("generating radix tree indices...\n");
        start = rand();
        end = rand();
        if (start > end && (rand() % 10)) {
                cur = start;
                start = end;
                end = cur;
        }
        /* Specifically create items around the start and the end of the range
         * with high probability to check for off by one errors */
        cur = rand();
        if (cur & 1) {
                item_insert(&tree, start);
                if (cur & 2) {
                        if (start <= end)
                                count++;
                        item_tag_set(&tree, start, 0);
                }
        }
        if (cur & 4) {
                item_insert(&tree, start-1);
               if (cur & 8)
                        item_tag_set(&tree, start-1, 0);
        }
        if (cur & 16) {
                item_insert(&tree, end);
                if (cur & 32) {
                        if (start <= end)
                                count++;
                        item_tag_set(&tree, end, 0);
                }
        }
        if (cur & 64) {
                item_insert(&tree, end+1);
                if (cur & 128)
                        item_tag_set(&tree, end+1, 0);
        }

        for (i = 0; i < ITEMS; i++) {
                do {
                        idx[i] = rand();
                } while (item_lookup(&tree, idx[i]));

                item_insert(&tree, idx[i]);
                if (rand() & 1) {
                        item_tag_set(&tree, idx[i], 0);
                        if (idx[i] >= start && idx[i] <= end)
                                count++;
                }
/*              if (i % 1000 == 0)
                        putchar('.'); */
        }

//      printf("\ncopying tags...\n");
        cur = start;
        tagged = radix_tree_range_tag_if_tagged(&tree, &cur, end, ITEMS, 0, 1);

//      printf("checking copied tags\n");
        assert(tagged == count);
        check_copied_tags(&tree, start, end, idx, ITEMS, 0, 1);

        /* Copy tags in several rounds */
//      printf("\ncopying tags...\n");
        cur = start;
        do {
                tmp = rand() % (count/10+2);
                tagged = radix_tree_range_tag_if_tagged(&tree, &cur, end, tmp, 0
        } while (tmp == tagged);

//      printf("%lu %lu %lu\n", tagged, tmp, count);
//      printf("checking copied tags\n");
        check_copied_tags(&tree, start, end, idx, ITEMS, 0, 2);
        assert(tagged < tmp);
//      printf("\n");
        item_kill_tree(&tree);
}

								Honza

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

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2010-06-24 13:58 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-16 16:33 (unknown), Jan Kara
2010-06-16 16:33 ` Jan Kara
2010-06-16 16:33 ` [PATCH 1/2] radix-tree: Implement function radix_tree_range_tag_if_tagged Jan Kara
2010-06-16 16:33   ` Jan Kara
2010-06-18 22:18   ` Andrew Morton
2010-06-21 12:09     ` Nick Piggin
2010-06-21 12:09       ` Nick Piggin
2010-06-21 22:43       ` Jan Kara
2010-06-21 22:43         ` Jan Kara
2010-06-23 13:42       ` Jan Kara
2010-06-23 13:42         ` Jan Kara
2010-06-16 16:33 ` [PATCH 2/2] mm: Implement writeback livelock avoidance using page tagging Jan Kara
2010-06-16 16:33   ` Jan Kara
2010-06-18 22:21   ` Andrew Morton
2010-06-21 12:42     ` Jan Kara
2010-06-21 12:42       ` Jan Kara
2010-06-16 22:15 ` your mail Dave Chinner
2010-06-17  7:43   ` [PATCH 0/2 v4] Writeback livelock avoidance for data integrity writes Jan Kara
2010-06-17  7:43     ` Jan Kara
2010-06-18  6:11     ` Dave Chinner
2010-06-18  7:01       ` Nick Piggin
2010-06-18  7:01         ` Nick Piggin
2010-06-17  9:11 ` Jan Kara
2010-06-17  9:11   ` Jan Kara
2010-06-22  2:59 ` your mail Wu Fengguang
2010-06-22  2:59   ` Wu Fengguang
2010-06-22 13:54   ` Jan Kara
2010-06-22 13:54     ` Jan Kara
2010-06-22 14:12     ` Wu Fengguang
2010-06-24 13:57 [PATCH 0/2 v5] Livelock avoidance for data integrity writes Jan Kara
2010-06-24 13:57 ` [PATCH 1/2] radix-tree: Implement function radix_tree_range_tag_if_tagged Jan Kara

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.