コード例 #1
0
ファイル: tag_check.c プロジェクト: yejerry/linux
static void
__simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
{
    unsigned long first = 0;
    int ret;

    item_check_absent(tree, index);
    assert(item_tag_get(tree, index, tag) == 0);

    item_insert(tree, index);
    assert(item_tag_get(tree, index, tag) == 0);
    item_tag_set(tree, index, tag);
    ret = item_tag_get(tree, index, tag);
    assert(ret != 0);
    ret = radix_tree_range_tag_if_tagged(tree, &first, ~0UL, 10, tag, !tag);
    assert(ret == 1);
    ret = item_tag_get(tree, index, !tag);
    assert(ret != 0);
    ret = item_delete(tree, index);
    assert(ret != 0);
    item_insert(tree, index);
    ret = item_tag_get(tree, index, tag);
    assert(ret == 0);
    ret = item_delete(tree, index);
    assert(ret != 0);
    ret = item_delete(tree, index);
    assert(ret == 0);
}
コード例 #2
0
void tag_pages_for_writeback(struct address_space *mapping,
			     pgoff_t start, pgoff_t end)
{
	unsigned long tagged;

	do {
		spin_lock_irq(&mapping->tree_lock);
		tagged = radix_tree_range_tag_if_tagged(&mapping->page_tree,
				&start, end, WRITEBACK_TAG_BATCH,
				PAGECACHE_TAG_DIRTY, PAGECACHE_TAG_TOWRITE);
		spin_unlock_irq(&mapping->tree_lock);
		WARN_ON_ONCE(tagged > WRITEBACK_TAG_BATCH);
		cond_resched();
	} while (tagged >= WRITEBACK_TAG_BATCH);
}
コード例 #3
0
/*
 * We tag pages in batches of WRITEBACK_TAG_BATCH to reduce tree_lock latency.
 */
void tag_pages_for_writeback(struct address_space *mapping,
			     pgoff_t start, pgoff_t end)
{
#define WRITEBACK_TAG_BATCH 4096
	unsigned long tagged;

	do {
		spin_lock_irq(&mapping->tree_lock);
		tagged = radix_tree_range_tag_if_tagged(&mapping->page_tree,
				&start, end, WRITEBACK_TAG_BATCH,
				PAGECACHE_TAG_DIRTY, PAGECACHE_TAG_TOWRITE);
		spin_unlock_irq(&mapping->tree_lock);
		WARN_ON_ONCE(tagged > WRITEBACK_TAG_BATCH);
		cond_resched();
		/* We check 'start' to handle wrapping when end == ~0UL */
	} while (tagged >= WRITEBACK_TAG_BATCH && start);
}
コード例 #4
0
ファイル: regression2.c プロジェクト: 020gzh/linux
void regression2_test(void)
{
	int i;
	struct page *p;
	int max_slots = RADIX_TREE_MAP_SIZE;
	unsigned long int start, end;
	struct page *pages[1];

	printf("running regression test 2 (should take milliseconds)\n");
	/* 0. */
	for (i = 0; i <= max_slots - 1; i++) {
		p = page_alloc();
		radix_tree_insert(&mt_tree, i, p);
	}
	radix_tree_tag_set(&mt_tree, max_slots - 1, PAGECACHE_TAG_DIRTY);

	/* 1. */
	start = 0;
	end = max_slots - 2;
	radix_tree_range_tag_if_tagged(&mt_tree, &start, end, 1,
				PAGECACHE_TAG_DIRTY, PAGECACHE_TAG_TOWRITE);

	/* 2. */
	p = page_alloc();
	radix_tree_insert(&mt_tree, max_slots, p);

	/* 3. */
	radix_tree_tag_clear(&mt_tree, max_slots - 1, PAGECACHE_TAG_DIRTY);

	/* 4. */
	for (i = max_slots - 1; i >= 0; i--)
		radix_tree_delete(&mt_tree, i);

	/* 5. */
	// NOTE: start should not be 0 because radix_tree_gang_lookup_tag_slot
	//       can return.
	start = 1;
	end = max_slots - 2;
	radix_tree_gang_lookup_tag_slot(&mt_tree, (void ***)pages, start, end,
		PAGECACHE_TAG_TOWRITE);

	/* We remove all the remained nodes */
	radix_tree_delete(&mt_tree, max_slots);

	printf("regression test 2, done\n");
}
コード例 #5
0
ファイル: tag_check.c プロジェクト: yejerry/linux
static void single_check(void)
{
    struct item *items[BATCH];
    RADIX_TREE(tree, GFP_KERNEL);
    int ret;
    unsigned long first = 0;

    item_insert(&tree, 0);
    item_tag_set(&tree, 0, 0);
    ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0);
    assert(ret == 1);
    ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 1, BATCH, 0);
    assert(ret == 0);
    verify_tag_consistency(&tree, 0);
    verify_tag_consistency(&tree, 1);
    ret = radix_tree_range_tag_if_tagged(&tree, &first, 10, 10, 0, 1);
    assert(ret == 1);
    ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 1);
    assert(ret == 1);
    item_kill_tree(&tree);
}
コード例 #6
0
ファイル: main.c プロジェクト: 020gzh/linux
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, 2);
	} 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);
	verify_tag_consistency(&tree, 0);
	verify_tag_consistency(&tree, 1);
	verify_tag_consistency(&tree, 2);
//	printf("\n");
	item_kill_tree(&tree);
}