diff options
Diffstat (limited to 'tools/testing/radix-tree/regression1.c')
-rw-r--r-- | tools/testing/radix-tree/regression1.c | 58 |
1 files changed, 19 insertions, 39 deletions
diff --git a/tools/testing/radix-tree/regression1.c b/tools/testing/radix-tree/regression1.c index 0aece092f40e..b4a4a7168986 100644 --- a/tools/testing/radix-tree/regression1.c +++ b/tools/testing/radix-tree/regression1.c | |||
@@ -53,12 +53,12 @@ struct page { | |||
53 | unsigned long index; | 53 | unsigned long index; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct page *page_alloc(void) | 56 | static struct page *page_alloc(int index) |
57 | { | 57 | { |
58 | struct page *p; | 58 | struct page *p; |
59 | p = malloc(sizeof(struct page)); | 59 | p = malloc(sizeof(struct page)); |
60 | p->count = 1; | 60 | p->count = 1; |
61 | p->index = 1; | 61 | p->index = index; |
62 | pthread_mutex_init(&p->lock, NULL); | 62 | pthread_mutex_init(&p->lock, NULL); |
63 | 63 | ||
64 | return p; | 64 | return p; |
@@ -80,53 +80,33 @@ static void page_free(struct page *p) | |||
80 | static unsigned find_get_pages(unsigned long start, | 80 | static unsigned find_get_pages(unsigned long start, |
81 | unsigned int nr_pages, struct page **pages) | 81 | unsigned int nr_pages, struct page **pages) |
82 | { | 82 | { |
83 | unsigned int i; | 83 | XA_STATE(xas, &mt_tree, start); |
84 | unsigned int ret; | 84 | struct page *page; |
85 | unsigned int nr_found; | 85 | unsigned int ret = 0; |
86 | 86 | ||
87 | rcu_read_lock(); | 87 | rcu_read_lock(); |
88 | restart: | 88 | xas_for_each(&xas, page, ULONG_MAX) { |
89 | nr_found = radix_tree_gang_lookup_slot(&mt_tree, | 89 | if (xas_retry(&xas, page)) |
90 | (void ***)pages, NULL, start, nr_pages); | ||
91 | ret = 0; | ||
92 | for (i = 0; i < nr_found; i++) { | ||
93 | struct page *page; | ||
94 | repeat: | ||
95 | page = radix_tree_deref_slot((void **)pages[i]); | ||
96 | if (unlikely(!page)) | ||
97 | continue; | 90 | continue; |
98 | 91 | ||
99 | if (radix_tree_exception(page)) { | ||
100 | if (radix_tree_deref_retry(page)) { | ||
101 | /* | ||
102 | * Transient condition which can only trigger | ||
103 | * when entry at index 0 moves out of or back | ||
104 | * to root: none yet gotten, safe to restart. | ||
105 | */ | ||
106 | assert((start | i) == 0); | ||
107 | goto restart; | ||
108 | } | ||
109 | /* | ||
110 | * No exceptional entries are inserted in this test. | ||
111 | */ | ||
112 | assert(0); | ||
113 | } | ||
114 | |||
115 | pthread_mutex_lock(&page->lock); | 92 | pthread_mutex_lock(&page->lock); |
116 | if (!page->count) { | 93 | if (!page->count) |
117 | pthread_mutex_unlock(&page->lock); | 94 | goto unlock; |
118 | goto repeat; | 95 | |
119 | } | ||
120 | /* don't actually update page refcount */ | 96 | /* don't actually update page refcount */ |
121 | pthread_mutex_unlock(&page->lock); | 97 | pthread_mutex_unlock(&page->lock); |
122 | 98 | ||
123 | /* Has the page moved? */ | 99 | /* Has the page moved? */ |
124 | if (unlikely(page != *((void **)pages[i]))) { | 100 | if (unlikely(page != xas_reload(&xas))) |
125 | goto repeat; | 101 | goto put_page; |
126 | } | ||
127 | 102 | ||
128 | pages[ret] = page; | 103 | pages[ret] = page; |
129 | ret++; | 104 | ret++; |
105 | continue; | ||
106 | unlock: | ||
107 | pthread_mutex_unlock(&page->lock); | ||
108 | put_page: | ||
109 | xas_reset(&xas); | ||
130 | } | 110 | } |
131 | rcu_read_unlock(); | 111 | rcu_read_unlock(); |
132 | return ret; | 112 | return ret; |
@@ -145,12 +125,12 @@ static void *regression1_fn(void *arg) | |||
145 | for (j = 0; j < 1000000; j++) { | 125 | for (j = 0; j < 1000000; j++) { |
146 | struct page *p; | 126 | struct page *p; |
147 | 127 | ||
148 | p = page_alloc(); | 128 | p = page_alloc(0); |
149 | pthread_mutex_lock(&mt_lock); | 129 | pthread_mutex_lock(&mt_lock); |
150 | radix_tree_insert(&mt_tree, 0, p); | 130 | radix_tree_insert(&mt_tree, 0, p); |
151 | pthread_mutex_unlock(&mt_lock); | 131 | pthread_mutex_unlock(&mt_lock); |
152 | 132 | ||
153 | p = page_alloc(); | 133 | p = page_alloc(1); |
154 | pthread_mutex_lock(&mt_lock); | 134 | pthread_mutex_lock(&mt_lock); |
155 | radix_tree_insert(&mt_tree, 1, p); | 135 | radix_tree_insert(&mt_tree, 1, p); |
156 | pthread_mutex_unlock(&mt_lock); | 136 | pthread_mutex_unlock(&mt_lock); |