]> git.pld-linux.org Git - packages/mysql.git/blame - mysql-innodb_split_buf_pool_mutex.patch
- needs gcc4 to build, be sure detect is ok
[packages/mysql.git] / mysql-innodb_split_buf_pool_mutex.patch
CommitLineData
d4e9320e
AM
1# name : innodb_split_buf_pool_mutex.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
7023c87b
ER
8diff -ruN a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c
9--- a/storage/innodb_plugin/btr/btr0cur.c 2010-08-04 02:24:19.000000000 +0900
10+++ b/storage/innodb_plugin/btr/btr0cur.c 2010-08-27 16:11:40.593021205 +0900
11@@ -3764,7 +3764,8 @@
d4e9320e
AM
12
13 mtr_commit(mtr);
14
7023c87b
ER
15- buf_pool_mutex_enter();
16+ //buf_pool_mutex_enter();
17+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
18 mutex_enter(&block->mutex);
19
20 /* Only free the block if it is still allocated to
7023c87b 21@@ -3775,17 +3776,22 @@
d4e9320e
AM
22 && buf_block_get_space(block) == space
23 && buf_block_get_page_no(block) == page_no) {
24
25- if (buf_LRU_free_block(&block->page, all, NULL)
26+ if (buf_LRU_free_block(&block->page, all, NULL, TRUE)
27 != BUF_LRU_FREED
28- && all && block->page.zip.data) {
29+ && all && block->page.zip.data
30+ /* Now, buf_LRU_free_block() may release mutex temporarily */
31+ && buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
32+ && buf_block_get_space(block) == space
33+ && buf_block_get_page_no(block) == page_no) {
34 /* Attempt to deallocate the uncompressed page
35 if the whole block cannot be deallocted. */
36
37- buf_LRU_free_block(&block->page, FALSE, NULL);
38+ buf_LRU_free_block(&block->page, FALSE, NULL, TRUE);
39 }
40 }
41
7023c87b
ER
42- buf_pool_mutex_exit();
43+ //buf_pool_mutex_exit();
44+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
45 mutex_exit(&block->mutex);
46 }
47
7023c87b
ER
48diff -ruN a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c
49--- a/storage/innodb_plugin/btr/btr0sea.c 2010-08-27 16:11:12.151975789 +0900
50+++ b/storage/innodb_plugin/btr/btr0sea.c 2010-08-27 16:11:40.593021205 +0900
51@@ -1199,7 +1199,7 @@
d4e9320e
AM
52 ulint* offsets;
53
54 rw_lock_x_lock(&btr_search_latch);
7023c87b
ER
55- buf_pool_mutex_enter();
56+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
57
58 table = btr_search_sys->hash_index;
59
7023c87b
ER
60@@ -1285,7 +1285,7 @@
61 bpage = UT_LIST_GET_PREV(LRU, bpage);
d4e9320e
AM
62 }
63
7023c87b
ER
64- buf_pool_mutex_exit();
65+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
66 rw_lock_x_unlock(&btr_search_latch);
67
68 if (UNIV_LIKELY_NULL(heap)) {
7023c87b 69@@ -1878,7 +1878,8 @@
d4e9320e
AM
70 rec_offs_init(offsets_);
71
72 rw_lock_x_lock(&btr_search_latch);
7023c87b
ER
73- buf_pool_mutex_enter();
74+ //buf_pool_mutex_enter();
75+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
76
77 cell_count = hash_get_n_cells(btr_search_sys->hash_index);
78
7023c87b 79@@ -1886,11 +1887,13 @@
d4e9320e
AM
80 /* We release btr_search_latch every once in a while to
81 give other queries a chance to run. */
82 if ((i != 0) && ((i % chunk_size) == 0)) {
7023c87b
ER
83- buf_pool_mutex_exit();
84+ //buf_pool_mutex_exit();
85+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
86 rw_lock_x_unlock(&btr_search_latch);
87 os_thread_yield();
88 rw_lock_x_lock(&btr_search_latch);
7023c87b
ER
89- buf_pool_mutex_enter();
90+ //buf_pool_mutex_enter();
91+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
92 }
93
94 node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
7023c87b 95@@ -1997,11 +2000,13 @@
d4e9320e
AM
96 /* We release btr_search_latch every once in a while to
97 give other queries a chance to run. */
98 if (i != 0) {
7023c87b
ER
99- buf_pool_mutex_exit();
100+ //buf_pool_mutex_exit();
101+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
102 rw_lock_x_unlock(&btr_search_latch);
103 os_thread_yield();
104 rw_lock_x_lock(&btr_search_latch);
7023c87b
ER
105- buf_pool_mutex_enter();
106+ //buf_pool_mutex_enter();
107+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
108 }
109
110 if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
7023c87b 111@@ -2009,7 +2014,8 @@
d4e9320e
AM
112 }
113 }
114
7023c87b
ER
115- buf_pool_mutex_exit();
116+ //buf_pool_mutex_exit();
117+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
118 rw_lock_x_unlock(&btr_search_latch);
119 if (UNIV_LIKELY_NULL(heap)) {
120 mem_heap_free(heap);
7023c87b
ER
121diff -ruN a/storage/innodb_plugin/buf/buf0buddy.c b/storage/innodb_plugin/buf/buf0buddy.c
122--- a/storage/innodb_plugin/buf/buf0buddy.c 2010-08-27 15:54:59.015990108 +0900
123+++ b/storage/innodb_plugin/buf/buf0buddy.c 2010-08-27 16:11:40.596022762 +0900
124@@ -82,10 +82,11 @@
d4e9320e
AM
125 if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
126 #endif /* UNIV_DEBUG_VALGRIND */
127
7023c87b
ER
128- ut_ad(buf_pool_mutex_own());
129+ //ut_ad(buf_pool_mutex_own());
130+ ut_ad(mutex_own(&zip_free_mutex));
d4e9320e
AM
131 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
132 ut_ad(buf_pool->zip_free[i].start != bpage);
133- UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
134+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
135
136 #ifdef UNIV_DEBUG_VALGRIND
137 if (b) UNIV_MEM_FREE(b, BUF_BUDDY_LOW << i);
7023c87b
ER
138@@ -103,8 +104,8 @@
139 ulint i) /*!< in: index of buf_pool->zip_free[] */
d4e9320e
AM
140 {
141 #ifdef UNIV_DEBUG_VALGRIND
142- buf_page_t* prev = UT_LIST_GET_PREV(list, bpage);
143- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
144+ buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
145+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
146
147 if (prev) UNIV_MEM_VALID(prev, BUF_BUDDY_LOW << i);
148 if (next) UNIV_MEM_VALID(next, BUF_BUDDY_LOW << i);
7023c87b 149@@ -113,9 +114,10 @@
d4e9320e
AM
150 ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
151 #endif /* UNIV_DEBUG_VALGRIND */
152
7023c87b
ER
153- ut_ad(buf_pool_mutex_own());
154+ //ut_ad(buf_pool_mutex_own());
155+ ut_ad(mutex_own(&zip_free_mutex));
d4e9320e
AM
156 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
157- UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
158+ UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
159
160 #ifdef UNIV_DEBUG_VALGRIND
161 if (prev) UNIV_MEM_FREE(prev, BUF_BUDDY_LOW << i);
7023c87b 162@@ -134,12 +136,13 @@
d4e9320e
AM
163 {
164 buf_page_t* bpage;
165
7023c87b
ER
166- ut_ad(buf_pool_mutex_own());
167+ //ut_ad(buf_pool_mutex_own());
168+ ut_ad(mutex_own(&zip_free_mutex));
d4e9320e
AM
169 ut_a(i < BUF_BUDDY_SIZES);
170
171 #ifndef UNIV_DEBUG_VALGRIND
172 /* Valgrind would complain about accessing free memory. */
173- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
174+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
175 ut_ad(buf_page_get_state(ut_list_node_313)
176 == BUF_BLOCK_ZIP_FREE)));
177 #endif /* !UNIV_DEBUG_VALGRIND */
7023c87b
ER
178@@ -182,16 +185,19 @@
179 void
d4e9320e
AM
180 buf_buddy_block_free(
181 /*=================*/
7023c87b
ER
182- void* buf) /*!< in: buffer frame to deallocate */
183+ void* buf, /*!< in: buffer frame to deallocate */
184+ ibool have_page_hash_mutex)
d4e9320e
AM
185 {
186 const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
187 buf_page_t* bpage;
188 buf_block_t* block;
189
7023c87b
ER
190- ut_ad(buf_pool_mutex_own());
191+ //ut_ad(buf_pool_mutex_own());
192 ut_ad(!mutex_own(&buf_pool_zip_mutex));
d4e9320e
AM
193 ut_a(!ut_align_offset(buf, UNIV_PAGE_SIZE));
194
7023c87b 195+ mutex_enter(&zip_hash_mutex);
d4e9320e
AM
196+
197 HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
198 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
199 && bpage->in_zip_hash && !bpage->in_page_hash),
7023c87b 200@@ -203,12 +209,14 @@
d4e9320e
AM
201 ut_d(bpage->in_zip_hash = FALSE);
202 HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
203
7023c87b 204+ mutex_exit(&zip_hash_mutex);
d4e9320e
AM
205+
206 ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
207 UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
208
209 block = (buf_block_t*) bpage;
210 mutex_enter(&block->mutex);
211- buf_LRU_block_free_non_file_page(block);
212+ buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
213 mutex_exit(&block->mutex);
214
7023c87b
ER
215 ut_ad(buf_buddy_n_frames > 0);
216@@ -224,7 +232,7 @@
217 buf_block_t* block) /*!< in: buffer frame to allocate */
d4e9320e 218 {
d4e9320e 219 const ulint fold = BUF_POOL_ZIP_FOLD(block);
7023c87b
ER
220- ut_ad(buf_pool_mutex_own());
221+ //ut_ad(buf_pool_mutex_own());
222 ut_ad(!mutex_own(&buf_pool_zip_mutex));
d4e9320e
AM
223 ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
224
7023c87b 225@@ -236,7 +244,10 @@
d4e9320e
AM
226 ut_ad(!block->page.in_page_hash);
227 ut_ad(!block->page.in_zip_hash);
228 ut_d(block->page.in_zip_hash = TRUE);
229+
7023c87b 230+ mutex_enter(&zip_hash_mutex);
d4e9320e 231 HASH_INSERT(buf_page_t, hash, buf_pool->zip_hash, fold, &block->page);
7023c87b 232+ mutex_exit(&zip_hash_mutex);
d4e9320e 233
7023c87b 234 ut_d(buf_buddy_n_frames++);
d4e9320e 235 }
7023c87b 236@@ -270,7 +281,7 @@
d4e9320e
AM
237 bpage->state = BUF_BLOCK_ZIP_FREE;
238 #ifndef UNIV_DEBUG_VALGRIND
239 /* Valgrind would complain about accessing free memory. */
240- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
241+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
242 ut_ad(buf_page_get_state(
243 ut_list_node_313)
244 == BUF_BLOCK_ZIP_FREE)));
7023c87b
ER
245@@ -292,24 +303,28 @@
246 /*================*/
247 ulint i, /*!< in: index of buf_pool->zip_free[],
248 or BUF_BUDDY_SIZES */
249- ibool* lru) /*!< in: pointer to a variable that will be assigned
250+ ibool* lru, /*!< in: pointer to a variable that will be assigned
251 TRUE if storage was allocated from the LRU list
252 and buf_pool_mutex was temporarily released,
253 or NULL if the LRU list should not be used */
254+ ibool have_page_hash_mutex)
d4e9320e
AM
255 {
256 buf_block_t* block;
257
7023c87b
ER
258- ut_ad(buf_pool_mutex_own());
259+ //ut_ad(buf_pool_mutex_own());
260 ut_ad(!mutex_own(&buf_pool_zip_mutex));
d4e9320e
AM
261
262 if (i < BUF_BUDDY_SIZES) {
263 /* Try to allocate from the buddy system. */
7023c87b
ER
264+ mutex_enter(&zip_free_mutex);
265 block = buf_buddy_alloc_zip(i);
d4e9320e
AM
266
267 if (block) {
7023c87b 268
d4e9320e
AM
269 goto func_exit;
270 }
7023c87b
ER
271+
272+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
273 }
274
275 /* Try allocating from the buf_pool->free list. */
7023c87b 276@@ -326,18 +341,29 @@
d4e9320e
AM
277 }
278
279 /* Try replacing an uncompressed page in the buffer pool. */
7023c87b
ER
280- buf_pool_mutex_exit();
281+ //buf_pool_mutex_exit();
282+ mutex_exit(&LRU_list_mutex);
d4e9320e 283+ if (have_page_hash_mutex) {
7023c87b 284+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e 285+ }
7023c87b 286 block = buf_LRU_get_free_block(0);
d4e9320e 287 *lru = TRUE;
7023c87b
ER
288- buf_pool_mutex_enter();
289+ //buf_pool_mutex_enter();
290+ mutex_enter(&LRU_list_mutex);
d4e9320e 291+ if (have_page_hash_mutex) {
7023c87b 292+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
293+ }
294
295 alloc_big:
296 buf_buddy_block_register(block);
297
7023c87b
ER
298+ mutex_enter(&zip_free_mutex);
299 block = buf_buddy_alloc_from(block->frame, i, BUF_BUDDY_SIZES);
d4e9320e
AM
300
301 func_exit:
7023c87b
ER
302 buf_buddy_stat[i].used++;
303+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
304+
305 return(block);
306 }
307
7023c87b
ER
308@@ -353,7 +379,10 @@
309 {
d4e9320e 310 buf_page_t* b;
d4e9320e 311
7023c87b
ER
312- ut_ad(buf_pool_mutex_own());
313+ //ut_ad(buf_pool_mutex_own());
d4e9320e 314+#ifdef UNIV_SYNC_DEBUG
7023c87b 315+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
d4e9320e
AM
316+#endif
317
318 switch (buf_page_get_state(bpage)) {
319 case BUF_BLOCK_ZIP_FREE:
7023c87b 320@@ -362,7 +391,7 @@
d4e9320e
AM
321 case BUF_BLOCK_FILE_PAGE:
322 case BUF_BLOCK_MEMORY:
323 case BUF_BLOCK_REMOVE_HASH:
324- ut_error;
325+ /* ut_error; */ /* optimistic */
326 case BUF_BLOCK_ZIP_DIRTY:
327 /* Cannot relocate dirty pages. */
328 return(FALSE);
7023c87b 329@@ -372,9 +401,17 @@
d4e9320e
AM
330 }
331
7023c87b
ER
332 mutex_enter(&buf_pool_zip_mutex);
333+ mutex_enter(&zip_free_mutex);
d4e9320e
AM
334
335 if (!buf_page_can_relocate(bpage)) {
7023c87b
ER
336 mutex_exit(&buf_pool_zip_mutex);
337+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
338+ return(FALSE);
339+ }
340+
7023c87b
ER
341+ if (bpage != buf_page_hash_get(bpage->space, bpage->offset)) {
342+ mutex_exit(&buf_pool_zip_mutex);
343+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
344 return(FALSE);
345 }
346
7023c87b 347@@ -382,18 +419,21 @@
d4e9320e
AM
348 ut_d(bpage->state = BUF_BLOCK_ZIP_FREE);
349
350 /* relocate buf_pool->zip_clean */
351- b = UT_LIST_GET_PREV(list, dpage);
352- UT_LIST_REMOVE(list, buf_pool->zip_clean, dpage);
7023c87b 353+ mutex_enter(&flush_list_mutex);
d4e9320e
AM
354+ b = UT_LIST_GET_PREV(zip_list, dpage);
355+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, dpage);
356
357 if (b) {
358- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, dpage);
359+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, dpage);
360 } else {
361- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, dpage);
362+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, dpage);
363 }
7023c87b 364+ mutex_exit(&flush_list_mutex);
d4e9320e
AM
365
366 UNIV_MEM_INVALID(bpage, sizeof *bpage);
367
7023c87b
ER
368 mutex_exit(&buf_pool_zip_mutex);
369+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
370 return(TRUE);
371 }
372
7023c87b
ER
373@@ -406,13 +446,15 @@
374 /*===============*/
375 void* src, /*!< in: block to relocate */
376 void* dst, /*!< in: free block to relocate to */
377- ulint i) /*!< in: index of buf_pool->zip_free[] */
378+ ulint i, /*!< in: index of buf_pool->zip_free[] */
379+ ibool have_page_hash_mutex)
d4e9320e
AM
380 {
381 buf_page_t* bpage;
382 const ulint size = BUF_BUDDY_LOW << i;
383 ullint usec = ut_time_us(NULL);
384
7023c87b
ER
385- ut_ad(buf_pool_mutex_own());
386+ //ut_ad(buf_pool_mutex_own());
387+ ut_ad(mutex_own(&zip_free_mutex));
388 ut_ad(!mutex_own(&buf_pool_zip_mutex));
d4e9320e
AM
389 ut_ad(!ut_align_offset(src, size));
390 ut_ad(!ut_align_offset(dst, size));
7023c87b 391@@ -434,6 +476,12 @@
d4e9320e
AM
392 /* This is a compressed page. */
393 mutex_t* mutex;
394
395+ if (!have_page_hash_mutex) {
7023c87b
ER
396+ mutex_exit(&zip_free_mutex);
397+ mutex_enter(&LRU_list_mutex);
398+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
399+ }
400+
401 /* The src block may be split into smaller blocks,
402 some of which may be free. Thus, the
403 mach_read_from_4() calls below may attempt to read
7023c87b 404@@ -458,6 +506,11 @@
d4e9320e
AM
405 added to buf_pool->page_hash yet. Obviously,
406 it cannot be relocated. */
407
408+ if (!have_page_hash_mutex) {
7023c87b
ER
409+ mutex_enter(&zip_free_mutex);
410+ mutex_exit(&LRU_list_mutex);
411+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
412+ }
413 return(FALSE);
414 }
415
7023c87b 416@@ -467,18 +520,27 @@
d4e9320e
AM
417 For the sake of simplicity, give up. */
418 ut_ad(page_zip_get_size(&bpage->zip) < size);
419
420+ if (!have_page_hash_mutex) {
7023c87b
ER
421+ mutex_enter(&zip_free_mutex);
422+ mutex_exit(&LRU_list_mutex);
423+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
424+ }
425 return(FALSE);
426 }
427
428+ /* To keep latch order */
429+ if (have_page_hash_mutex)
7023c87b 430+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
431+
432 /* The block must have been allocated, but it may
433 contain uninitialized data. */
434 UNIV_MEM_ASSERT_W(src, size);
435
436- mutex = buf_page_get_mutex(bpage);
437+ mutex = buf_page_get_mutex_enter(bpage);
438
439- mutex_enter(mutex);
7023c87b 440+ mutex_enter(&zip_free_mutex);
d4e9320e
AM
441
442- if (buf_page_can_relocate(bpage)) {
443+ if (mutex && buf_page_can_relocate(bpage)) {
444 /* Relocate the compressed page. */
445 ut_a(bpage->zip.data == src);
446 memcpy(dst, src, size);
7023c87b 447@@ -493,10 +555,22 @@
d4e9320e
AM
448 buddy_stat->relocated_usec
449 += ut_time_us(NULL) - usec;
450 }
451+
452+ if (!have_page_hash_mutex) {
7023c87b
ER
453+ mutex_exit(&LRU_list_mutex);
454+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
455+ }
456 return(TRUE);
457 }
458
459- mutex_exit(mutex);
460+ if (!have_page_hash_mutex) {
7023c87b
ER
461+ mutex_exit(&LRU_list_mutex);
462+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
463+ }
464+
465+ if (mutex) {
466+ mutex_exit(mutex);
467+ }
468 } else if (i == buf_buddy_get_slot(sizeof(buf_page_t))) {
469 /* This must be a buf_page_t object. */
470 #if UNIV_WORD_SIZE == 4
7023c87b 471@@ -505,10 +579,31 @@
d4e9320e
AM
472 about uninitialized pad bytes. */
473 UNIV_MEM_ASSERT_RW(src, size);
474 #endif
475+
7023c87b 476+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
477+
478+ if (!have_page_hash_mutex) {
7023c87b
ER
479+ mutex_enter(&LRU_list_mutex);
480+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
481+ }
482+
483 if (buf_buddy_relocate_block(src, dst)) {
7023c87b 484+ mutex_enter(&zip_free_mutex);
d4e9320e
AM
485+
486+ if (!have_page_hash_mutex) {
7023c87b
ER
487+ mutex_exit(&LRU_list_mutex);
488+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
489+ }
490
491 goto success;
492 }
493+
7023c87b 494+ mutex_enter(&zip_free_mutex);
d4e9320e
AM
495+
496+ if (!have_page_hash_mutex) {
7023c87b
ER
497+ mutex_exit(&LRU_list_mutex);
498+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
499+ }
500 }
501
502 return(FALSE);
7023c87b
ER
503@@ -522,13 +617,15 @@
504 /*===============*/
505 void* buf, /*!< in: block to be freed, must not be
506 pointed to by the buffer pool */
507- ulint i) /*!< in: index of buf_pool->zip_free[],
508+ ulint i, /*!< in: index of buf_pool->zip_free[],
509 or BUF_BUDDY_SIZES */
510+ ibool have_page_hash_mutex)
d4e9320e
AM
511 {
512 buf_page_t* bpage;
513 buf_page_t* buddy;
514
7023c87b
ER
515- ut_ad(buf_pool_mutex_own());
516+ //ut_ad(buf_pool_mutex_own());
517+ ut_ad(mutex_own(&zip_free_mutex));
518 ut_ad(!mutex_own(&buf_pool_zip_mutex));
d4e9320e 519 ut_ad(i <= BUF_BUDDY_SIZES);
7023c87b
ER
520 ut_ad(buf_buddy_stat[i].used > 0);
521@@ -539,7 +636,9 @@
d4e9320e
AM
522 ut_d(((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE);
523
524 if (i == BUF_BUDDY_SIZES) {
7023c87b
ER
525- buf_buddy_block_free(buf);
526+ mutex_exit(&zip_free_mutex);
527+ buf_buddy_block_free(buf, have_page_hash_mutex);
528+ mutex_enter(&zip_free_mutex);
d4e9320e
AM
529 return;
530 }
531
7023c87b 532@@ -584,7 +683,7 @@
d4e9320e
AM
533 ut_a(bpage != buf);
534
535 {
536- buf_page_t* next = UT_LIST_GET_NEXT(list, bpage);
537+ buf_page_t* next = UT_LIST_GET_NEXT(zip_list, bpage);
538 UNIV_MEM_ASSERT_AND_FREE(bpage, BUF_BUDDY_LOW << i);
539 bpage = next;
540 }
7023c87b 541@@ -593,13 +692,13 @@
d4e9320e
AM
542 #ifndef UNIV_DEBUG_VALGRIND
543 buddy_nonfree:
544 /* Valgrind would complain about accessing free memory. */
545- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
546+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
547 ut_ad(buf_page_get_state(ut_list_node_313)
548 == BUF_BLOCK_ZIP_FREE)));
549 #endif /* UNIV_DEBUG_VALGRIND */
550
551 /* The buddy is not free. Is there a free block of this size? */
552- bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
553+ bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
554
555 if (bpage) {
556 /* Remove the block from the free list, because a successful
7023c87b
ER
557@@ -609,7 +708,7 @@
558 buf_buddy_remove_from_free(bpage, i);
d4e9320e
AM
559
560 /* Try to relocate the buddy of buf to the free block. */
7023c87b
ER
561- if (buf_buddy_relocate(buddy, bpage, i)) {
562+ if (buf_buddy_relocate(buddy, bpage, i, have_page_hash_mutex)) {
d4e9320e
AM
563
564 ut_d(buddy->state = BUF_BLOCK_ZIP_FREE);
565 goto buddy_free2;
7023c87b 566@@ -629,14 +728,14 @@
d4e9320e
AM
567
568 (Parts of the buddy can be free in
569 buf_pool->zip_free[j] with j < i.) */
570- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i],
571+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
572 ut_ad(buf_page_get_state(
573 ut_list_node_313)
574 == BUF_BLOCK_ZIP_FREE
575 && ut_list_node_313 != buddy)));
576 #endif /* !UNIV_DEBUG_VALGRIND */
577
7023c87b
ER
578- if (buf_buddy_relocate(buddy, buf, i)) {
579+ if (buf_buddy_relocate(buddy, buf, i, have_page_hash_mutex)) {
d4e9320e
AM
580
581 buf = bpage;
582 UNIV_MEM_VALID(bpage, BUF_BUDDY_LOW << i);
7023c87b
ER
583diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
584--- a/storage/innodb_plugin/buf/buf0buf.c 2010-08-27 15:55:39.385322978 +0900
585+++ b/storage/innodb_plugin/buf/buf0buf.c 2010-08-27 16:11:40.603021006 +0900
586@@ -251,6 +251,12 @@
587 /** mutex protecting the buffer pool struct and control blocks, except the
588 read-write lock in them */
589 UNIV_INTERN mutex_t buf_pool_mutex;
590+UNIV_INTERN mutex_t LRU_list_mutex;
591+UNIV_INTERN mutex_t flush_list_mutex;
592+UNIV_INTERN rw_lock_t page_hash_latch;
593+UNIV_INTERN mutex_t free_list_mutex;
594+UNIV_INTERN mutex_t zip_free_mutex;
595+UNIV_INTERN mutex_t zip_hash_mutex;
596 /** mutex protecting the control blocks of compressed-only pages
597 (of type buf_page_t, not buf_block_t) */
598 UNIV_INTERN mutex_t buf_pool_zip_mutex;
599@@ -661,9 +667,9 @@
d4e9320e
AM
600 block->page.in_zip_hash = FALSE;
601 block->page.in_flush_list = FALSE;
602 block->page.in_free_list = FALSE;
603- block->in_unzip_LRU_list = FALSE;
604 #endif /* UNIV_DEBUG */
605 block->page.in_LRU_list = FALSE;
606+ block->in_unzip_LRU_list = FALSE;
607 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
608 block->n_pointers = 0;
609 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
7023c87b 610@@ -748,8 +754,10 @@
d4e9320e
AM
611 memset(block->frame, '\0', UNIV_PAGE_SIZE);
612 #endif
613 /* Add the block to the free list */
614- UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page));
7023c87b 615+ mutex_enter(&free_list_mutex);
d4e9320e 616+ UT_LIST_ADD_LAST(free, buf_pool->free, (&block->page));
d4e9320e 617 ut_d(block->page.in_free_list = TRUE);
7023c87b 618+ mutex_exit(&free_list_mutex);
d4e9320e
AM
619
620 block++;
7023c87b
ER
621 frame += UNIV_PAGE_SIZE;
622@@ -774,7 +782,7 @@
623 ulint i;
624
625 ut_ad(buf_pool);
626- ut_ad(buf_pool_mutex_own());
627+ //ut_ad(buf_pool_mutex_own());
628
629 block = chunk->blocks;
630
631@@ -826,7 +834,7 @@
632 ulint i;
633
634 ut_ad(buf_pool);
635- ut_ad(buf_pool_mutex_own());
636+ //ut_ad(buf_pool_mutex_own()); /*optimistic...*/
637
638 block = chunk->blocks;
639
640@@ -878,7 +886,7 @@
641 ulint i;
d4e9320e
AM
642
643 ut_ad(buf_pool);
7023c87b
ER
644- ut_ad(buf_pool_mutex_own());
645+ ut_ad(buf_pool_mutex_own()); /* but we need all mutex here */
646
647 block = chunk->blocks;
d4e9320e 648
7023c87b 649@@ -904,7 +912,7 @@
d4e9320e
AM
650 buf_block_t* block;
651 const buf_block_t* block_end;
652
7023c87b
ER
653- ut_ad(buf_pool_mutex_own());
654+ ut_ad(buf_pool_mutex_own()); /* but we need all mutex here */
d4e9320e
AM
655
656 block_end = chunk->blocks + chunk->size;
657
7023c87b 658@@ -916,8 +924,10 @@
d4e9320e
AM
659 ut_ad(!block->in_unzip_LRU_list);
660 ut_ad(!block->page.in_flush_list);
661 /* Remove the block from the free list. */
7023c87b 662+ mutex_enter(&free_list_mutex);
d4e9320e
AM
663 ut_ad(block->page.in_free_list);
664- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
665+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
7023c87b 666+ mutex_exit(&free_list_mutex);
d4e9320e
AM
667
668 /* Free the latches. */
669 mutex_free(&block->mutex);
7023c87b
ER
670@@ -947,8 +957,17 @@
671 /* 1. Initialize general fields
d4e9320e 672 ------------------------------- */
7023c87b
ER
673 mutex_create(&buf_pool_mutex, SYNC_BUF_POOL);
674+ mutex_create(&LRU_list_mutex, SYNC_BUF_LRU_LIST);
675+ mutex_create(&flush_list_mutex, SYNC_BUF_FLUSH_LIST);
676+ rw_lock_create(&page_hash_latch, SYNC_BUF_PAGE_HASH);
677+ mutex_create(&free_list_mutex, SYNC_BUF_FREE_LIST);
678+ mutex_create(&zip_free_mutex, SYNC_BUF_ZIP_FREE);
679+ mutex_create(&zip_hash_mutex, SYNC_BUF_ZIP_HASH);
680+
681 mutex_create(&buf_pool_zip_mutex, SYNC_BUF_BLOCK);
682
683+ mutex_enter(&LRU_list_mutex);
684+ rw_lock_x_lock(&page_hash_latch);
685 buf_pool_mutex_enter();
d4e9320e 686
7023c87b
ER
687 buf_pool->n_chunks = 1;
688@@ -983,6 +1002,8 @@
689 --------------------------- */
d4e9320e
AM
690 /* All fields are initialized by mem_zalloc(). */
691
7023c87b
ER
692+ mutex_exit(&LRU_list_mutex);
693+ rw_lock_x_unlock(&page_hash_latch);
694 buf_pool_mutex_exit();
d4e9320e 695
7023c87b
ER
696 btr_search_sys_create(buf_pool->curr_size
697@@ -1120,7 +1141,11 @@
698 buf_page_t* b;
d4e9320e 699 ulint fold;
d4e9320e 700
7023c87b
ER
701- ut_ad(buf_pool_mutex_own());
702+ //ut_ad(buf_pool_mutex_own());
703+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e 704+#ifdef UNIV_SYNC_DEBUG
7023c87b 705+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
d4e9320e
AM
706+#endif
707 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
708 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
709 ut_a(bpage->buf_fix_count == 0);
7023c87b 710@@ -1204,7 +1229,8 @@
d4e9320e
AM
711
712 try_again:
713 btr_search_disable(); /* Empty the adaptive hash index again */
7023c87b
ER
714- buf_pool_mutex_enter();
715+ //buf_pool_mutex_enter();
716+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
717
718 shrink_again:
719 if (buf_pool->n_chunks <= 1) {
7023c87b 720@@ -1275,7 +1301,7 @@
d4e9320e
AM
721
722 buf_LRU_make_block_old(&block->page);
723 dirty++;
724- } else if (buf_LRU_free_block(&block->page, TRUE, NULL)
725+ } else if (buf_LRU_free_block(&block->page, TRUE, NULL, FALSE)
726 != BUF_LRU_FREED) {
727 nonfree++;
728 }
7023c87b 729@@ -1283,7 +1309,8 @@
d4e9320e
AM
730 mutex_exit(&block->mutex);
731 }
732
7023c87b
ER
733- buf_pool_mutex_exit();
734+ //buf_pool_mutex_exit();
735+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
736
737 /* Request for a flush of the chunk if it helps.
738 Do not flush if there are non-free blocks, since
7023c87b 739@@ -1332,7 +1359,8 @@
d4e9320e 740 func_done:
7023c87b 741 srv_buf_pool_old_size = srv_buf_pool_size;
d4e9320e 742 func_exit:
7023c87b
ER
743- buf_pool_mutex_exit();
744+ //buf_pool_mutex_exit();
745+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
746 btr_search_enable();
747 }
748
7023c87b 749@@ -1350,7 +1378,11 @@
d4e9320e 750 hash_table_t* zip_hash;
7023c87b 751 buf_page_t* b;
d4e9320e 752
7023c87b
ER
753- buf_pool_mutex_enter();
754+ //buf_pool_mutex_enter();
755+ mutex_enter(&LRU_list_mutex);
756+ rw_lock_x_lock(&page_hash_latch);
757+ mutex_enter(&flush_list_mutex);
758+
d4e9320e
AM
759
760 /* Free, create, and populate the hash table. */
761 hash_table_free(buf_pool->page_hash);
7023c87b 762@@ -1392,7 +1424,7 @@
d4e9320e
AM
763 in buf_pool->flush_list. */
764
d4e9320e
AM
765 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
766- b = UT_LIST_GET_NEXT(list, b)) {
767+ b = UT_LIST_GET_NEXT(zip_list, b)) {
768 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
769 ut_ad(!b->in_flush_list);
770 ut_ad(b->in_LRU_list);
7023c87b 771@@ -1404,7 +1436,7 @@
d4e9320e 772 }
d4e9320e 773
d4e9320e
AM
774 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
775- b = UT_LIST_GET_NEXT(list, b)) {
776+ b = UT_LIST_GET_NEXT(flush_list, b)) {
777 ut_ad(b->in_flush_list);
778 ut_ad(b->in_LRU_list);
779 ut_ad(b->in_page_hash);
7023c87b 780@@ -1430,7 +1462,10 @@
d4e9320e 781 }
d4e9320e
AM
782 }
783
7023c87b
ER
784- buf_pool_mutex_exit();
785+ //buf_pool_mutex_exit();
786+ mutex_exit(&LRU_list_mutex);
787+ rw_lock_x_unlock(&page_hash_latch);
788+ mutex_exit(&flush_list_mutex);
d4e9320e
AM
789 }
790
7023c87b
ER
791 /********************************************************************//**
792@@ -1440,17 +1475,20 @@
793 buf_pool_resize(void)
794 /*=================*/
d4e9320e 795 {
7023c87b
ER
796- buf_pool_mutex_enter();
797+ //buf_pool_mutex_enter();
798+ mutex_enter(&LRU_list_mutex);
d4e9320e 799
7023c87b 800 if (srv_buf_pool_old_size == srv_buf_pool_size) {
d4e9320e 801
7023c87b
ER
802- buf_pool_mutex_exit();
803+ //buf_pool_mutex_exit();
804+ mutex_exit(&LRU_list_mutex);
805 return;
d4e9320e
AM
806 }
807
7023c87b 808 if (srv_buf_pool_curr_size + 1048576 > srv_buf_pool_size) {
d4e9320e 809
7023c87b
ER
810- buf_pool_mutex_exit();
811+ //buf_pool_mutex_exit();
812+ mutex_exit(&LRU_list_mutex);
d4e9320e 813
7023c87b
ER
814 /* Disable adaptive hash indexes and empty the index
815 in order to free up memory in the buffer pool chunks. */
816@@ -1484,7 +1522,8 @@
817 }
d4e9320e 818
7023c87b
ER
819 srv_buf_pool_old_size = srv_buf_pool_size;
820- buf_pool_mutex_exit();
821+ //buf_pool_mutex_exit();
822+ mutex_exit(&LRU_list_mutex);
823 }
d4e9320e 824
7023c87b
ER
825 buf_pool_page_hash_rebuild();
826@@ -1500,13 +1539,15 @@
827 /*================*/
828 buf_page_t* bpage) /*!< in: buffer block of a file page */
d4e9320e 829 {
7023c87b
ER
830- buf_pool_mutex_enter();
831+ //buf_pool_mutex_enter();
832+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
833
834 ut_a(buf_page_in_file(bpage));
835
836 buf_LRU_make_block_young(bpage);
837
7023c87b
ER
838- buf_pool_mutex_exit();
839+ //buf_pool_mutex_exit();
840+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
841 }
842
843 /********************************************************************//**
7023c87b 844@@ -1528,14 +1569,20 @@
d4e9320e
AM
845 ut_a(buf_page_in_file(bpage));
846
847 if (buf_page_peek_if_too_old(bpage)) {
7023c87b
ER
848- buf_pool_mutex_enter();
849+ //buf_pool_mutex_enter();
850+ mutex_enter(&LRU_list_mutex);
d4e9320e 851 buf_LRU_make_block_young(bpage);
7023c87b
ER
852- buf_pool_mutex_exit();
853+ //buf_pool_mutex_exit();
854+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
855 } else if (!access_time) {
856 ulint time_ms = ut_time_ms();
7023c87b 857- buf_pool_mutex_enter();
d4e9320e 858+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
7023c87b 859+ //buf_pool_mutex_enter();
d4e9320e
AM
860+ if (block_mutex) {
861 buf_page_set_accessed(bpage, time_ms);
7023c87b 862- buf_pool_mutex_exit();
d4e9320e
AM
863+ mutex_exit(block_mutex);
864+ }
7023c87b 865+ //buf_pool_mutex_exit();
d4e9320e
AM
866 }
867 }
868
7023c87b
ER
869@@ -1551,7 +1598,8 @@
870 {
d4e9320e 871 buf_block_t* block;
d4e9320e 872
7023c87b
ER
873- buf_pool_mutex_enter();
874+ //buf_pool_mutex_enter();
875+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 876
7023c87b 877 block = (buf_block_t*) buf_page_hash_get(space, offset);
d4e9320e 878
7023c87b 879@@ -1559,7 +1607,8 @@
d4e9320e
AM
880 block->check_index_page_at_flush = FALSE;
881 }
882
7023c87b
ER
883- buf_pool_mutex_exit();
884+ //buf_pool_mutex_exit();
885+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
886 }
887
888 /********************************************************************//**
7023c87b
ER
889@@ -1577,7 +1626,8 @@
890 buf_block_t* block;
d4e9320e 891 ibool is_hashed;
d4e9320e 892
7023c87b
ER
893- buf_pool_mutex_enter();
894+ //buf_pool_mutex_enter();
895+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 896
7023c87b 897 block = (buf_block_t*) buf_page_hash_get(space, offset);
d4e9320e 898
7023c87b 899@@ -1587,7 +1637,8 @@
d4e9320e
AM
900 is_hashed = block->is_hashed;
901 }
902
7023c87b
ER
903- buf_pool_mutex_exit();
904+ //buf_pool_mutex_exit();
905+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
906
907 return(is_hashed);
908 }
7023c87b
ER
909@@ -1608,7 +1659,8 @@
910 {
d4e9320e 911 buf_page_t* bpage;
d4e9320e 912
7023c87b
ER
913- buf_pool_mutex_enter();
914+ //buf_pool_mutex_enter();
915+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 916
7023c87b 917 bpage = buf_page_hash_get(space, offset);
d4e9320e 918
7023c87b 919@@ -1616,7 +1668,8 @@
d4e9320e
AM
920 bpage->file_page_was_freed = TRUE;
921 }
922
7023c87b
ER
923- buf_pool_mutex_exit();
924+ //buf_pool_mutex_exit();
925+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
926
927 return(bpage);
928 }
7023c87b
ER
929@@ -1636,7 +1689,8 @@
930 {
d4e9320e 931 buf_page_t* bpage;
d4e9320e 932
7023c87b
ER
933- buf_pool_mutex_enter();
934+ //buf_pool_mutex_enter();
935+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 936
7023c87b 937 bpage = buf_page_hash_get(space, offset);
d4e9320e 938
7023c87b 939@@ -1644,7 +1698,8 @@
d4e9320e
AM
940 bpage->file_page_was_freed = FALSE;
941 }
942
7023c87b
ER
943- buf_pool_mutex_exit();
944+ //buf_pool_mutex_exit();
945+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
946
947 return(bpage);
948 }
7023c87b 949@@ -1678,8 +1733,9 @@
d4e9320e
AM
950 buf_pool->stat.n_page_gets++;
951
952 for (;;) {
7023c87b
ER
953- buf_pool_mutex_enter();
954+ //buf_pool_mutex_enter();
d4e9320e 955 lookup:
7023c87b
ER
956+ rw_lock_s_lock(&page_hash_latch);
957 bpage = buf_page_hash_get(space, offset);
d4e9320e 958 if (bpage) {
7023c87b
ER
959 break;
960@@ -1687,7 +1743,8 @@
d4e9320e
AM
961
962 /* Page not in buf_pool: needs to be read from file */
963
7023c87b
ER
964- buf_pool_mutex_exit();
965+ //buf_pool_mutex_exit();
966+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
967
968 buf_read_page(space, zip_size, offset);
969
7023c87b 970@@ -1699,29 +1756,34 @@
d4e9320e
AM
971 if (UNIV_UNLIKELY(!bpage->zip.data)) {
972 /* There is no compressed page. */
973 err_exit:
7023c87b
ER
974- buf_pool_mutex_exit();
975+ //buf_pool_mutex_exit();
976+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
977 return(NULL);
978 }
979
980+ block_mutex = buf_page_get_mutex_enter(bpage);
981+
7023c87b 982+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e 983+
d4e9320e 984 switch (buf_page_get_state(bpage)) {
7023c87b
ER
985 case BUF_BLOCK_NOT_USED:
986 case BUF_BLOCK_READY_FOR_USE:
d4e9320e
AM
987 case BUF_BLOCK_MEMORY:
988 case BUF_BLOCK_REMOVE_HASH:
989 case BUF_BLOCK_ZIP_FREE:
990+ if (block_mutex)
991+ mutex_exit(block_mutex);
992 break;
993 case BUF_BLOCK_ZIP_PAGE:
994 case BUF_BLOCK_ZIP_DIRTY:
7023c87b 995- block_mutex = &buf_pool_zip_mutex;
d4e9320e 996- mutex_enter(block_mutex);
7023c87b 997+ ut_a(block_mutex == &buf_pool_zip_mutex);
d4e9320e
AM
998 bpage->buf_fix_count++;
999 goto got_block;
1000 case BUF_BLOCK_FILE_PAGE:
1001- block_mutex = &((buf_block_t*) bpage)->mutex;
1002- mutex_enter(block_mutex);
1003+ ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
1004
1005 /* Discard the uncompressed page frame if possible. */
1006- if (buf_LRU_free_block(bpage, FALSE, NULL)
1007+ if (buf_LRU_free_block(bpage, FALSE, NULL, FALSE)
1008 == BUF_LRU_FREED) {
1009
1010 mutex_exit(block_mutex);
7023c87b 1011@@ -1740,7 +1802,7 @@
d4e9320e
AM
1012 must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
1013 access_time = buf_page_is_accessed(bpage);
1014
7023c87b
ER
1015- buf_pool_mutex_exit();
1016+ //buf_pool_mutex_exit();
d4e9320e
AM
1017
1018 mutex_exit(block_mutex);
1019
7023c87b
ER
1020@@ -1995,7 +2057,7 @@
1021 const buf_block_t* block) /*!< in: pointer to block,
1022 not dereferenced */
d4e9320e 1023 {
7023c87b
ER
1024- ut_ad(buf_pool_mutex_own());
1025+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
1026
1027 if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
1028 /* The pointer should be aligned. */
7023c87b 1029@@ -2029,6 +2091,7 @@
d4e9320e
AM
1030 ulint fix_type;
1031 ibool must_read;
1032 ulint retries = 0;
7023c87b 1033+ mutex_t* block_mutex;
d4e9320e
AM
1034
1035 ut_ad(mtr);
7023c87b
ER
1036 ut_ad(mtr->state == MTR_ACTIVE);
1037@@ -2046,9 +2109,11 @@
1038 buf_pool->stat.n_page_gets++;
d4e9320e
AM
1039 loop:
1040 block = guess;
7023c87b
ER
1041- buf_pool_mutex_enter();
1042+ //buf_pool_mutex_enter();
d4e9320e
AM
1043
1044 if (block) {
1045+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1046+
1047 /* If the guess is a compressed page descriptor that
1048 has been allocated by buf_buddy_alloc(), it may have
1049 been invalidated by buf_buddy_relocate(). In that
7023c87b 1050@@ -2057,11 +2122,15 @@
d4e9320e
AM
1051 the guess may be pointing to a buffer pool chunk that
1052 has been released when resizing the buffer pool. */
1053
7023c87b 1054- if (!buf_block_is_uncompressed(block)
d4e9320e
AM
1055+ if (!block_mutex) {
1056+ block = guess = NULL;
7023c87b 1057+ } else if (!buf_block_is_uncompressed(block)
d4e9320e
AM
1058 || offset != block->page.offset
1059 || space != block->page.space
1060 || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
1061
1062+ mutex_exit(block_mutex);
1063+
1064 block = guess = NULL;
1065 } else {
1066 ut_ad(!block->page.in_zip_hash);
7023c87b 1067@@ -2070,14 +2139,20 @@
d4e9320e
AM
1068 }
1069
1070 if (block == NULL) {
7023c87b
ER
1071+ rw_lock_s_lock(&page_hash_latch);
1072 block = (buf_block_t*) buf_page_hash_get(space, offset);
d4e9320e
AM
1073+ if (block) {
1074+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1075+ ut_a(block_mutex);
1076+ }
7023c87b 1077+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
1078 }
1079
1080 loop2:
7023c87b
ER
1081 if (block == NULL) {
1082 /* Page not in buf_pool: needs to be read from file */
d4e9320e 1083
7023c87b
ER
1084- buf_pool_mutex_exit();
1085+ //buf_pool_mutex_exit();
d4e9320e 1086
7023c87b
ER
1087 if (mode == BUF_GET_IF_IN_POOL) {
1088
1089@@ -2120,7 +2195,8 @@
d4e9320e 1090
7023c87b
ER
1091 if (must_read && mode == BUF_GET_IF_IN_POOL) {
1092 /* The page is only being read to buffer */
1093- buf_pool_mutex_exit();
1094+ //buf_pool_mutex_exit();
d4e9320e
AM
1095+ mutex_exit(block_mutex);
1096
1097 return(NULL);
1098 }
7023c87b 1099@@ -2130,38 +2206,50 @@
d4e9320e
AM
1100 ibool success;
1101
1102 case BUF_BLOCK_FILE_PAGE:
7023c87b 1103+ if (block_mutex == &buf_pool_zip_mutex) {
d4e9320e
AM
1104+ /* it is wrong mutex... */
1105+ mutex_exit(block_mutex);
1106+ goto loop;
1107+ }
1108 break;
1109
1110 case BUF_BLOCK_ZIP_PAGE:
1111 case BUF_BLOCK_ZIP_DIRTY:
7023c87b 1112+ ut_ad(block_mutex == &buf_pool_zip_mutex);
d4e9320e
AM
1113 bpage = &block->page;
1114 /* Protect bpage->buf_fix_count. */
7023c87b
ER
1115- mutex_enter(&buf_pool_zip_mutex);
1116+ /* Already proteced here. */
1117+ //mutex_enter(&buf_pool_zip_mutex);
d4e9320e
AM
1118
1119 if (bpage->buf_fix_count
1120 || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
1121 /* This condition often occurs when the buffer
1122 is not buffer-fixed, but I/O-fixed by
1123 buf_page_init_for_read(). */
7023c87b
ER
1124- mutex_exit(&buf_pool_zip_mutex);
1125+ //mutex_exit(&buf_pool_zip_mutex);
d4e9320e
AM
1126 wait_until_unfixed:
1127 /* The block is buffer-fixed or I/O-fixed.
1128 Try again later. */
7023c87b
ER
1129- buf_pool_mutex_exit();
1130+ //buf_pool_mutex_exit();
d4e9320e
AM
1131+ mutex_exit(block_mutex);
1132 os_thread_sleep(WAIT_FOR_READ);
7023c87b 1133
d4e9320e
AM
1134 goto loop;
1135 }
1136
1137 /* Allocate an uncompressed page. */
7023c87b
ER
1138- buf_pool_mutex_exit();
1139- mutex_exit(&buf_pool_zip_mutex);
1140+ //buf_pool_mutex_exit();
1141+ //mutex_exit(&buf_pool_zip_mutex);
d4e9320e
AM
1142+ mutex_exit(block_mutex);
1143
7023c87b 1144 block = buf_LRU_get_free_block(0);
d4e9320e
AM
1145 ut_a(block);
1146+ block_mutex = &block->mutex;
1147
7023c87b 1148- buf_pool_mutex_enter();
d4e9320e 1149- mutex_enter(&block->mutex);
7023c87b
ER
1150+ //buf_pool_mutex_enter();
1151+ mutex_enter(&LRU_list_mutex);
1152+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
1153+ mutex_enter(block_mutex);
1154
1155 {
7023c87b
ER
1156 buf_page_t* hash_bpage
1157@@ -2172,35 +2260,49 @@
1158 while buf_pool_mutex was released.
d4e9320e
AM
1159 Free the block that was allocated. */
1160
1161- buf_LRU_block_free_non_file_page(block);
1162- mutex_exit(&block->mutex);
1163+ buf_LRU_block_free_non_file_page(block, TRUE);
1164+ mutex_exit(block_mutex);
1165
1166 block = (buf_block_t*) hash_bpage;
1167+ if (block) {
1168+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
1169+ ut_a(block_mutex);
1170+ }
7023c87b
ER
1171+ rw_lock_x_unlock(&page_hash_latch);
1172+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1173 goto loop2;
1174 }
1175 }
1176
7023c87b 1177+ mutex_enter(&buf_pool_zip_mutex);
d4e9320e
AM
1178+
1179 if (UNIV_UNLIKELY
1180 (bpage->buf_fix_count
1181 || buf_page_get_io_fix(bpage) != BUF_IO_NONE)) {
1182
7023c87b 1183+ mutex_exit(&buf_pool_zip_mutex);
d4e9320e 1184 /* The block was buffer-fixed or I/O-fixed
7023c87b 1185 while buf_pool_mutex was not held by this thread.
d4e9320e
AM
1186 Free the block that was allocated and try again.
1187 This should be extremely unlikely. */
1188
1189- buf_LRU_block_free_non_file_page(block);
1190- mutex_exit(&block->mutex);
1191+ buf_LRU_block_free_non_file_page(block, TRUE);
1192+ //mutex_exit(&block->mutex);
1193
7023c87b
ER
1194+ rw_lock_x_unlock(&page_hash_latch);
1195+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1196 goto wait_until_unfixed;
1197 }
1198
1199 /* Move the compressed page from bpage to block,
1200 and uncompress it. */
1201
7023c87b
ER
1202- mutex_enter(&buf_pool_zip_mutex);
1203+ mutex_enter(&flush_list_mutex);
1204
d4e9320e
AM
1205 buf_relocate(bpage, &block->page);
1206+
7023c87b 1207+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1208+
1209 buf_block_init_low(block);
1210 block->lock_hash_val = lock_rec_hash(space, offset);
1211
7023c87b 1212@@ -2209,7 +2311,7 @@
d4e9320e
AM
1213
1214 if (buf_page_get_state(&block->page)
1215 == BUF_BLOCK_ZIP_PAGE) {
1216- UT_LIST_REMOVE(list, buf_pool->zip_clean,
1217+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean,
1218 &block->page);
1219 ut_ad(!block->page.in_flush_list);
1220 } else {
7023c87b
ER
1221@@ -2218,6 +2320,8 @@
1222 &block->page);
1223 }
1224
1225+ mutex_exit(&flush_list_mutex);
1226+
1227 /* Buffer-fix, I/O-fix, and X-latch the block
1228 for the duration of the decompression.
1229 Also add the block to the unzip_LRU list. */
1230@@ -2226,19 +2330,24 @@
d4e9320e
AM
1231 /* Insert at the front of unzip_LRU list */
1232 buf_unzip_LRU_add_block(block, FALSE);
1233
7023c87b 1234+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1235+
1236 block->page.buf_fix_count = 1;
1237 buf_block_set_io_fix(block, BUF_IO_READ);
1238 rw_lock_x_lock_func(&block->lock, 0, file, line);
1239
1240 UNIV_MEM_INVALID(bpage, sizeof *bpage);
1241
1242- mutex_exit(&block->mutex);
1243+ mutex_exit(block_mutex);
7023c87b 1244 mutex_exit(&buf_pool_zip_mutex);
d4e9320e 1245+
7023c87b 1246+ mutex_enter(&buf_pool_mutex);
d4e9320e 1247 buf_pool->n_pend_unzip++;
7023c87b 1248+ mutex_exit(&buf_pool_mutex);
d4e9320e 1249
7023c87b
ER
1250- buf_buddy_free(bpage, sizeof *bpage);
1251+ buf_buddy_free(bpage, sizeof *bpage, FALSE);
d4e9320e 1252
7023c87b
ER
1253- buf_pool_mutex_exit();
1254+ //buf_pool_mutex_exit();
d4e9320e
AM
1255
1256 /* Decompress the page and apply buffered operations
7023c87b
ER
1257 while not holding buf_pool_mutex or block->mutex. */
1258@@ -2251,12 +2360,15 @@
d4e9320e
AM
1259 }
1260
1261 /* Unfix and unlatch the block. */
7023c87b 1262- buf_pool_mutex_enter();
d4e9320e 1263- mutex_enter(&block->mutex);
7023c87b 1264+ //buf_pool_mutex_enter();
d4e9320e
AM
1265+ block_mutex = &block->mutex;
1266+ mutex_enter(block_mutex);
1267 block->page.buf_fix_count--;
1268 buf_block_set_io_fix(block, BUF_IO_NONE);
1269- mutex_exit(&block->mutex);
1270+
7023c87b 1271+ mutex_enter(&buf_pool_mutex);
d4e9320e 1272 buf_pool->n_pend_unzip--;
7023c87b 1273+ mutex_exit(&buf_pool_mutex);
d4e9320e 1274 rw_lock_x_unlock(&block->lock);
d4e9320e 1275 break;
7023c87b
ER
1276
1277@@ -2271,7 +2383,7 @@
d4e9320e
AM
1278
1279 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1280
1281- mutex_enter(&block->mutex);
1282+ //mutex_enter(&block->mutex);
1283 #if UNIV_WORD_SIZE == 4
1284 /* On 32-bit systems, there is no padding in buf_page_t. On
1285 other systems, Valgrind could complain about uninitialized pad
7023c87b 1286@@ -2305,13 +2417,14 @@
d4e9320e
AM
1287
1288 buf_block_buf_fix_inc(block, file, line);
1289
1290- mutex_exit(&block->mutex);
1291+ //mutex_exit(&block->mutex);
1292
1293 /* Check if this is the first access to the page */
1294
1295 access_time = buf_page_is_accessed(&block->page);
1296
7023c87b
ER
1297- buf_pool_mutex_exit();
1298+ //buf_pool_mutex_exit();
d4e9320e
AM
1299+ mutex_exit(block_mutex);
1300
1301 buf_page_set_accessed_make_young(&block->page, access_time);
1302
7023c87b
ER
1303@@ -2539,9 +2652,11 @@
1304 mutex_exit(&block->mutex);
d4e9320e
AM
1305
1306 if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
7023c87b
ER
1307- buf_pool_mutex_enter();
1308+ //buf_pool_mutex_enter();
1309+ mutex_enter(&LRU_list_mutex);
d4e9320e 1310 buf_LRU_make_block_young(&block->page);
7023c87b
ER
1311- buf_pool_mutex_exit();
1312+ //buf_pool_mutex_exit();
1313+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1314 } else if (!buf_page_is_accessed(&block->page)) {
1315 /* Above, we do a dirty read on purpose, to avoid
1316 mutex contention. The field buf_page_t::access_time
7023c87b 1317@@ -2549,9 +2664,11 @@
d4e9320e
AM
1318 field must be protected by mutex, however. */
1319 ulint time_ms = ut_time_ms();
1320
7023c87b
ER
1321- buf_pool_mutex_enter();
1322+ //buf_pool_mutex_enter();
d4e9320e
AM
1323+ mutex_enter(&block->mutex);
1324 buf_page_set_accessed(&block->page, time_ms);
7023c87b
ER
1325- buf_pool_mutex_exit();
1326+ //buf_pool_mutex_exit();
d4e9320e
AM
1327+ mutex_exit(&block->mutex);
1328 }
1329
1330 ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
7023c87b 1331@@ -2617,16 +2734,19 @@
d4e9320e
AM
1332 ut_ad(mtr);
1333 ut_ad(mtr->state == MTR_ACTIVE);
1334
7023c87b
ER
1335- buf_pool_mutex_enter();
1336+ //buf_pool_mutex_enter();
1337+ rw_lock_s_lock(&page_hash_latch);
1338 block = buf_block_hash_get(space_id, page_no);
d4e9320e 1339
7023c87b
ER
1340 if (!block) {
1341- buf_pool_mutex_exit();
1342+ //buf_pool_mutex_exit();
1343+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
1344 return(NULL);
1345 }
1346
d4e9320e 1347 mutex_enter(&block->mutex);
7023c87b
ER
1348- buf_pool_mutex_exit();
1349+ //buf_pool_mutex_exit();
1350+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
1351
1352 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1353 ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
7023c87b
ER
1354@@ -2713,7 +2833,10 @@
1355 {
d4e9320e 1356 buf_page_t* hash_page;
d4e9320e 1357
7023c87b
ER
1358- ut_ad(buf_pool_mutex_own());
1359+ //ut_ad(buf_pool_mutex_own());
d4e9320e 1360+#ifdef UNIV_SYNC_DEBUG
7023c87b 1361+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
d4e9320e
AM
1362+#endif
1363 ut_ad(mutex_own(&(block->mutex)));
1364 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
1365
7023c87b 1366@@ -2746,7 +2869,8 @@
d4e9320e
AM
1367 (const void*) hash_page, (const void*) block);
1368 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1369 mutex_exit(&block->mutex);
7023c87b
ER
1370- buf_pool_mutex_exit();
1371+ //buf_pool_mutex_exit();
1372+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1373 buf_print();
1374 buf_LRU_print();
1375 buf_validate();
7023c87b
ER
1376@@ -2825,16 +2949,24 @@
1377 ut_ad(block);
1378 }
d4e9320e 1379
7023c87b
ER
1380- buf_pool_mutex_enter();
1381+ //buf_pool_mutex_enter();
1382+ mutex_enter(&LRU_list_mutex);
1383+ rw_lock_x_lock(&page_hash_latch);
d4e9320e 1384
7023c87b
ER
1385 if (buf_page_hash_get(space, offset)) {
1386 /* The page is already in the buffer pool. */
d4e9320e
AM
1387 err_exit:
1388 if (block) {
1389 mutex_enter(&block->mutex);
1390- buf_LRU_block_free_non_file_page(block);
7023c87b
ER
1391+ mutex_exit(&LRU_list_mutex);
1392+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1393+ buf_LRU_block_free_non_file_page(block, FALSE);
1394 mutex_exit(&block->mutex);
1395 }
1396+ else {
7023c87b
ER
1397+ mutex_exit(&LRU_list_mutex);
1398+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1399+ }
1400
1401 bpage = NULL;
1402 goto func_exit;
7023c87b
ER
1403@@ -2854,6 +2986,8 @@
1404 mutex_enter(&block->mutex);
1405 buf_page_init(space, offset, block);
d4e9320e 1406
7023c87b 1407+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1408+
1409 /* The block must be put to the LRU list, to the old blocks */
1410 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
1411
7023c87b 1412@@ -2881,7 +3015,7 @@
d4e9320e
AM
1413 been added to buf_pool->LRU and
1414 buf_pool->page_hash. */
1415 mutex_exit(&block->mutex);
7023c87b
ER
1416- data = buf_buddy_alloc(zip_size, &lru);
1417+ data = buf_buddy_alloc(zip_size, &lru, FALSE);
d4e9320e
AM
1418 mutex_enter(&block->mutex);
1419 block->page.zip.data = data;
1420
7023c87b 1421@@ -2894,6 +3028,7 @@
d4e9320e
AM
1422 buf_unzip_LRU_add_block(block, TRUE);
1423 }
1424
7023c87b 1425+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1426 mutex_exit(&block->mutex);
1427 } else {
1428 /* Defer buf_buddy_alloc() until after the block has
7023c87b 1429@@ -2905,8 +3040,8 @@
d4e9320e
AM
1430 control block (bpage), in order to avoid the
1431 invocation of buf_buddy_relocate_block() on
1432 uninitialized data. */
7023c87b
ER
1433- data = buf_buddy_alloc(zip_size, &lru);
1434- bpage = buf_buddy_alloc(sizeof *bpage, &lru);
1435+ data = buf_buddy_alloc(zip_size, &lru, TRUE);
1436+ bpage = buf_buddy_alloc(sizeof *bpage, &lru, TRUE);
1437
1438 /* If buf_buddy_alloc() allocated storage from the LRU list,
1439 it released and reacquired buf_pool_mutex. Thus, we must
1440@@ -2915,8 +3050,11 @@
1441 && UNIV_LIKELY_NULL(buf_page_hash_get(space, offset))) {
1442
1443 /* The block was added by some other thread. */
1444- buf_buddy_free(bpage, sizeof *bpage);
1445- buf_buddy_free(data, zip_size);
1446+ buf_buddy_free(bpage, sizeof *bpage, TRUE);
1447+ buf_buddy_free(data, zip_size, TRUE);
d4e9320e 1448+
7023c87b
ER
1449+ mutex_exit(&LRU_list_mutex);
1450+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e 1451
7023c87b
ER
1452 bpage = NULL;
1453 goto func_exit;
1454@@ -2946,18 +3084,26 @@
1455 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
1456 buf_page_address_fold(space, offset), bpage);
d4e9320e 1457
7023c87b 1458+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1459+
1460 /* The block must be put to the LRU list, to the old blocks */
1461 buf_LRU_add_block(bpage, TRUE/* to old blocks */);
7023c87b 1462+ mutex_enter(&flush_list_mutex);
d4e9320e 1463 buf_LRU_insert_zip_clean(bpage);
7023c87b 1464+ mutex_exit(&flush_list_mutex);
d4e9320e 1465+
7023c87b
ER
1466+ mutex_exit(&LRU_list_mutex);
1467
d4e9320e
AM
1468 buf_page_set_io_fix(bpage, BUF_IO_READ);
1469
7023c87b 1470 mutex_exit(&buf_pool_zip_mutex);
d4e9320e
AM
1471 }
1472
7023c87b 1473+ mutex_enter(&buf_pool_mutex);
d4e9320e 1474 buf_pool->n_pend_reads++;
7023c87b
ER
1475+ mutex_exit(&buf_pool_mutex);
1476 func_exit:
1477- buf_pool_mutex_exit();
1478+ //buf_pool_mutex_exit();
d4e9320e
AM
1479
1480 if (mode == BUF_READ_IBUF_PAGES_ONLY) {
1481
7023c87b 1482@@ -2995,7 +3141,9 @@
d4e9320e 1483
7023c87b 1484 free_block = buf_LRU_get_free_block(0);
d4e9320e 1485
7023c87b
ER
1486- buf_pool_mutex_enter();
1487+ //buf_pool_mutex_enter();
1488+ mutex_enter(&LRU_list_mutex);
1489+ rw_lock_x_lock(&page_hash_latch);
d4e9320e 1490
7023c87b
ER
1491 block = (buf_block_t*) buf_page_hash_get(space, offset);
1492
1493@@ -3008,7 +3156,9 @@
d4e9320e
AM
1494 #endif /* UNIV_DEBUG_FILE_ACCESSES */
1495
1496 /* Page can be found in buf_pool */
7023c87b
ER
1497- buf_pool_mutex_exit();
1498+ //buf_pool_mutex_exit();
1499+ mutex_exit(&LRU_list_mutex);
1500+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1501
1502 buf_block_free(free_block);
1503
7023c87b 1504@@ -3030,6 +3180,7 @@
d4e9320e
AM
1505 mutex_enter(&block->mutex);
1506
7023c87b
ER
1507 buf_page_init(space, offset, block);
1508+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1509
1510 /* The block must be put to the LRU list */
1511 buf_LRU_add_block(&block->page, FALSE);
7023c87b
ER
1512@@ -3056,7 +3207,7 @@
1513 the reacquisition of buf_pool_mutex. We also must
d4e9320e
AM
1514 defer this operation until after the block descriptor
1515 has been added to buf_pool->LRU and buf_pool->page_hash. */
7023c87b
ER
1516- data = buf_buddy_alloc(zip_size, &lru);
1517+ data = buf_buddy_alloc(zip_size, &lru, FALSE);
d4e9320e
AM
1518 mutex_enter(&block->mutex);
1519 block->page.zip.data = data;
1520
7023c87b 1521@@ -3074,7 +3225,8 @@
d4e9320e
AM
1522
1523 buf_page_set_accessed(&block->page, time_ms);
1524
7023c87b
ER
1525- buf_pool_mutex_exit();
1526+ //buf_pool_mutex_exit();
1527+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1528
1529 mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
1530
7023c87b
ER
1531@@ -3124,6 +3276,8 @@
1532 enum buf_io_fix io_type;
d4e9320e
AM
1533 const ibool uncompressed = (buf_page_get_state(bpage)
1534 == BUF_BLOCK_FILE_PAGE);
7023c87b 1535+ enum buf_flush flush_type;
d4e9320e
AM
1536+ mutex_t* block_mutex;
1537
1538 ut_a(buf_page_in_file(bpage));
1539
7023c87b 1540@@ -3257,8 +3411,17 @@
d4e9320e
AM
1541 }
1542 }
1543
7023c87b
ER
1544- buf_pool_mutex_enter();
1545- mutex_enter(buf_page_get_mutex(bpage));
1546+ //buf_pool_mutex_enter();
1547+ if (io_type == BUF_IO_WRITE) {
1548+ flush_type = buf_page_get_flush_type(bpage);
d4e9320e 1549+ /* to keep consistency at buf_LRU_insert_zip_clean() */
7023c87b
ER
1550+ //if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
1551+ mutex_enter(&LRU_list_mutex);
1552+ //}
d4e9320e 1553+ }
d4e9320e
AM
1554+ block_mutex = buf_page_get_mutex_enter(bpage);
1555+ ut_a(block_mutex);
7023c87b 1556+ mutex_enter(&buf_pool_mutex);
d4e9320e
AM
1557
1558 #ifdef UNIV_IBUF_COUNT_DEBUG
1559 if (io_type == BUF_IO_WRITE || uncompressed) {
7023c87b 1560@@ -3298,6 +3461,11 @@
d4e9320e
AM
1561
1562 buf_flush_write_complete(bpage);
1563
7023c87b
ER
1564+ /* to keep consistency at buf_LRU_insert_zip_clean() */
1565+ //if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
1566+ mutex_exit(&LRU_list_mutex);
1567+ //}
d4e9320e
AM
1568+
1569 if (uncompressed) {
1570 rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
1571 BUF_IO_WRITE);
7023c87b 1572@@ -3320,8 +3488,9 @@
d4e9320e
AM
1573 }
1574 #endif /* UNIV_DEBUG */
1575
1576- mutex_exit(buf_page_get_mutex(bpage));
7023c87b
ER
1577- buf_pool_mutex_exit();
1578+ mutex_exit(&buf_pool_mutex);
d4e9320e 1579+ mutex_exit(block_mutex);
7023c87b 1580+ //buf_pool_mutex_exit();
d4e9320e
AM
1581 }
1582
1583 /*********************************************************************//**
7023c87b
ER
1584@@ -3368,7 +3537,8 @@
1585 freed = buf_LRU_search_and_free_block(100);
d4e9320e
AM
1586 }
1587
7023c87b
ER
1588- buf_pool_mutex_enter();
1589+ //buf_pool_mutex_enter();
1590+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
1591
1592 ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
1593 ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
7023c87b 1594@@ -3381,7 +3551,8 @@
d4e9320e 1595 memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
7023c87b 1596 buf_refresh_io_stats();
d4e9320e 1597
7023c87b
ER
1598- buf_pool_mutex_exit();
1599+ //buf_pool_mutex_exit();
1600+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
1601 }
1602
7023c87b
ER
1603 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1604@@ -3406,7 +3577,10 @@
d4e9320e
AM
1605
1606 ut_ad(buf_pool);
1607
7023c87b
ER
1608- buf_pool_mutex_enter();
1609+ //buf_pool_mutex_enter();
1610+ mutex_enter(&LRU_list_mutex);
1611+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
1612+ /* for keep the new latch order, it cannot validate correctly... */
1613
1614 chunk = buf_pool->chunks;
1615
7023c87b 1616@@ -3505,7 +3679,7 @@
d4e9320e
AM
1617 /* Check clean compressed-only blocks. */
1618
1619 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1620- b = UT_LIST_GET_NEXT(list, b)) {
1621+ b = UT_LIST_GET_NEXT(zip_list, b)) {
1622 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1623 switch (buf_page_get_io_fix(b)) {
1624 case BUF_IO_NONE:
7023c87b 1625@@ -3530,8 +3704,9 @@
d4e9320e 1626
7023c87b
ER
1627 /* Check dirty compressed-only blocks. */
1628
1629+ mutex_enter(&flush_list_mutex);
d4e9320e
AM
1630 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1631- b = UT_LIST_GET_NEXT(list, b)) {
1632+ b = UT_LIST_GET_NEXT(flush_list, b)) {
1633 ut_ad(b->in_flush_list);
7023c87b
ER
1634
1635 switch (buf_page_get_state(b)) {
1636@@ -3576,6 +3751,7 @@
1637 }
1638 ut_a(buf_page_hash_get(b->space, b->offset) == b);
1639 }
1640+ mutex_exit(&flush_list_mutex);
1641
1642 mutex_exit(&buf_pool_zip_mutex);
1643
1644@@ -3587,19 +3763,27 @@
d4e9320e
AM
1645 }
1646
1647 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
7023c87b 1648+ /* because of latching order with block->mutex, we cannot get free_list_mutex before that */
d4e9320e
AM
1649+/*
1650 if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
1651 fprintf(stderr, "Free list len %lu, free blocks %lu\n",
1652 (ulong) UT_LIST_GET_LEN(buf_pool->free),
7023c87b
ER
1653 (ulong) n_free);
1654 ut_error;
1655 }
1656+*/
1657+ /* because of latching order with block->mutex, we cannot get flush_list_mutex before that */
1658+/*
1659 ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush);
1660
d4e9320e
AM
1661 ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
1662 ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
1663 ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
1664+*/
1665
7023c87b
ER
1666- buf_pool_mutex_exit();
1667+ //buf_pool_mutex_exit();
1668+ mutex_exit(&LRU_list_mutex);
1669+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
1670
1671 ut_a(buf_LRU_validate());
7023c87b
ER
1672 ut_a(buf_flush_validate());
1673@@ -3633,7 +3817,10 @@
1674 index_ids = mem_alloc(sizeof(dulint) * size);
d4e9320e
AM
1675 counts = mem_alloc(sizeof(ulint) * size);
1676
7023c87b
ER
1677- buf_pool_mutex_enter();
1678+ //buf_pool_mutex_enter();
1679+ mutex_enter(&LRU_list_mutex);
1680+ mutex_enter(&free_list_mutex);
1681+ mutex_enter(&flush_list_mutex);
d4e9320e
AM
1682
1683 fprintf(stderr,
7023c87b
ER
1684 "buf_pool size %lu\n"
1685@@ -3700,7 +3887,10 @@
d4e9320e
AM
1686 }
1687 }
1688
7023c87b
ER
1689- buf_pool_mutex_exit();
1690+ //buf_pool_mutex_exit();
1691+ mutex_exit(&LRU_list_mutex);
1692+ mutex_exit(&free_list_mutex);
1693+ mutex_exit(&flush_list_mutex);
d4e9320e
AM
1694
1695 for (i = 0; i < n_found; i++) {
1696 index = dict_index_get_if_in_cache(index_ids[i]);
7023c87b
ER
1697@@ -3739,7 +3929,7 @@
1698 ulint i;
d4e9320e
AM
1699 ulint fixed_pages_number = 0;
1700
7023c87b
ER
1701- buf_pool_mutex_enter();
1702+ //buf_pool_mutex_enter();
d4e9320e
AM
1703
1704 chunk = buf_pool->chunks;
1705
7023c87b 1706@@ -3773,7 +3963,7 @@
d4e9320e
AM
1707 /* Traverse the lists of clean and dirty compressed-only blocks. */
1708
1709 for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
1710- b = UT_LIST_GET_NEXT(list, b)) {
1711+ b = UT_LIST_GET_NEXT(zip_list, b)) {
1712 ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
1713 ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
1714
7023c87b
ER
1715@@ -3783,8 +3973,9 @@
1716 }
1717 }
d4e9320e 1718
7023c87b 1719+ mutex_enter(&flush_list_mutex);
d4e9320e
AM
1720 for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
1721- b = UT_LIST_GET_NEXT(list, b)) {
1722+ b = UT_LIST_GET_NEXT(flush_list, b)) {
1723 ut_ad(b->in_flush_list);
1724
1725 switch (buf_page_get_state(b)) {
7023c87b
ER
1726@@ -3807,9 +3998,10 @@
1727 break;
1728 }
1729 }
1730+ mutex_exit(&flush_list_mutex);
d4e9320e 1731
7023c87b
ER
1732 mutex_exit(&buf_pool_zip_mutex);
1733- buf_pool_mutex_exit();
1734+ //buf_pool_mutex_exit();
d4e9320e
AM
1735
1736 return(fixed_pages_number);
1737 }
7023c87b 1738@@ -3867,7 +4059,11 @@
d4e9320e
AM
1739
1740 ut_ad(buf_pool);
1741
7023c87b
ER
1742- buf_pool_mutex_enter();
1743+ //buf_pool_mutex_enter();
1744+ mutex_enter(&LRU_list_mutex);
1745+ mutex_enter(&free_list_mutex);
1746+ mutex_enter(&buf_pool_mutex);
1747+ mutex_enter(&flush_list_mutex);
d4e9320e 1748
7023c87b
ER
1749 fprintf(file,
1750 "Buffer pool size %lu\n"
1751@@ -3966,7 +4162,11 @@
d4e9320e
AM
1752 buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
1753
7023c87b
ER
1754 buf_refresh_io_stats();
1755- buf_pool_mutex_exit();
1756+ //buf_pool_mutex_exit();
1757+ mutex_exit(&LRU_list_mutex);
1758+ mutex_exit(&free_list_mutex);
1759+ mutex_exit(&buf_pool_mutex);
1760+ mutex_exit(&flush_list_mutex);
d4e9320e
AM
1761 }
1762
7023c87b
ER
1763 /**********************************************************************//**
1764@@ -3993,7 +4193,7 @@
1765
1766 ut_ad(buf_pool);
1767
1768- buf_pool_mutex_enter();
1769+ //buf_pool_mutex_enter(); /* optimistic */
1770
1771 chunk = buf_pool->chunks;
1772
1773@@ -4010,7 +4210,7 @@
1774 }
1775 }
1776
1777- buf_pool_mutex_exit();
1778+ //buf_pool_mutex_exit(); /* optimistic */
1779
1780 return(TRUE);
1781 }
1782@@ -4026,7 +4226,8 @@
1783 {
1784 ibool ret;
1785
1786- buf_pool_mutex_enter();
1787+ //buf_pool_mutex_enter();
1788+ mutex_enter(&buf_pool_mutex);
1789
1790 if (buf_pool->n_pend_reads + buf_pool->n_flush[BUF_FLUSH_LRU]
1791 + buf_pool->n_flush[BUF_FLUSH_LIST]
1792@@ -4036,7 +4237,8 @@
1793 ret = TRUE;
1794 }
1795
1796- buf_pool_mutex_exit();
1797+ //buf_pool_mutex_exit();
1798+ mutex_exit(&buf_pool_mutex);
1799
1800 return(ret);
1801 }
1802@@ -4051,11 +4253,13 @@
d4e9320e
AM
1803 {
1804 ulint len;
1805
7023c87b
ER
1806- buf_pool_mutex_enter();
1807+ //buf_pool_mutex_enter();
1808+ mutex_enter(&free_list_mutex);
d4e9320e
AM
1809
1810 len = UT_LIST_GET_LEN(buf_pool->free);
1811
7023c87b
ER
1812- buf_pool_mutex_exit();
1813+ //buf_pool_mutex_exit();
1814+ mutex_exit(&free_list_mutex);
d4e9320e
AM
1815
1816 return(len);
1817 }
7023c87b
ER
1818diff -ruN a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c
1819--- a/storage/innodb_plugin/buf/buf0flu.c 2010-08-27 15:54:59.022021357 +0900
1820+++ b/storage/innodb_plugin/buf/buf0flu.c 2010-08-27 16:11:40.607020890 +0900
1821@@ -102,7 +102,8 @@
1822 const ib_rbt_node_t* c_node;
1823 const ib_rbt_node_t* p_node;
1824
1825- ut_ad(buf_pool_mutex_own());
1826+ //ut_ad(buf_pool_mutex_own());
1827+ ut_ad(mutex_own(&flush_list_mutex));
1828
1829 /* Insert this buffer into the rbt. */
1830 c_node = rbt_insert(buf_pool->flush_rbt, &bpage, &bpage);
1831@@ -132,7 +133,8 @@
1832 ibool ret = FALSE;
1833 #endif /* UNIV_DEBUG */
1834
1835- ut_ad(buf_pool_mutex_own());
1836+ //ut_ad(buf_pool_mutex_own());
1837+ ut_ad(mutex_own(&flush_list_mutex));
1838 #ifdef UNIV_DEBUG
1839 ret =
1840 #endif /* UNIV_DEBUG */
1841@@ -199,12 +201,14 @@
1842 buf_flush_init_flush_rbt(void)
1843 /*==========================*/
1844 {
1845- buf_pool_mutex_enter();
1846+ //buf_pool_mutex_enter();
1847+ mutex_enter(&flush_list_mutex);
1848
1849 /* Create red black tree for speedy insertions in flush list. */
1850 buf_pool->flush_rbt = rbt_create(sizeof(buf_page_t*),
1851 buf_flush_block_cmp);
1852- buf_pool_mutex_exit();
1853+ //buf_pool_mutex_exit();
1854+ mutex_exit(&flush_list_mutex);
1855 }
1856
1857 /********************************************************************//**
1858@@ -214,7 +218,8 @@
1859 buf_flush_free_flush_rbt(void)
1860 /*==========================*/
1861 {
1862- buf_pool_mutex_enter();
1863+ //buf_pool_mutex_enter();
1864+ mutex_enter(&flush_list_mutex);
1865
1866 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1867 ut_a(buf_flush_validate_low());
1868@@ -223,7 +228,8 @@
1869 rbt_free(buf_pool->flush_rbt);
1870 buf_pool->flush_rbt = NULL;
1871
1872- buf_pool_mutex_exit();
1873+ //buf_pool_mutex_exit();
1874+ mutex_exit(&flush_list_mutex);
1875 }
d4e9320e 1876
7023c87b
ER
1877 /********************************************************************//**
1878@@ -234,7 +240,9 @@
1879 /*=============================*/
1880 buf_block_t* block) /*!< in/out: block which is modified */
1881 {
1882- ut_ad(buf_pool_mutex_own());
1883+ //ut_ad(buf_pool_mutex_own());
1884+ ut_ad(mutex_own(&block->mutex));
1885+ ut_ad(mutex_own(&flush_list_mutex));
1886 ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL)
1887 || (UT_LIST_GET_FIRST(buf_pool->flush_list)->oldest_modification
1888 <= block->page.oldest_modification));
1889@@ -252,7 +260,7 @@
1890 ut_ad(!block->page.in_zip_hash);
1891 ut_ad(!block->page.in_flush_list);
d4e9320e 1892 ut_d(block->page.in_flush_list = TRUE);
d4e9320e
AM
1893- UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1894+ UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1895
1896 #ifdef UNIV_DEBUG_VALGRIND
1897 {
7023c87b
ER
1898@@ -283,7 +291,9 @@
1899 buf_page_t* prev_b;
1900 buf_page_t* b;
1901
1902- ut_ad(buf_pool_mutex_own());
1903+ //ut_ad(buf_pool_mutex_own());
1904+ ut_ad(mutex_own(&block->mutex));
1905+ ut_ad(mutex_own(&flush_list_mutex));
1906 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1907
1908 ut_ad(block->page.in_LRU_list);
1909@@ -324,14 +334,14 @@
d4e9320e
AM
1910 > block->page.oldest_modification) {
1911 ut_ad(b->in_flush_list);
1912 prev_b = b;
1913- b = UT_LIST_GET_NEXT(list, b);
1914+ b = UT_LIST_GET_NEXT(flush_list, b);
1915 }
1916 }
1917
1918 if (prev_b == NULL) {
1919- UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
1920+ UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
1921 } else {
1922- UT_LIST_INSERT_AFTER(list, buf_pool->flush_list,
1923+ UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list,
1924 prev_b, &block->page);
1925 }
1926
7023c87b
ER
1927@@ -352,7 +362,7 @@
1928 buf_page_in_file(bpage) and in the LRU list */
1929 {
1930 //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
1931- //ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1932+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
7023c87b 1933 //ut_ad(bpage->in_LRU_list); /* optimistic use */
d4e9320e
AM
1934
1935 if (UNIV_LIKELY(bpage->in_LRU_list && buf_page_in_file(bpage))) {
7023c87b
ER
1936@@ -387,12 +397,12 @@
1937 buf_page_in_file(bpage) */
d4e9320e
AM
1938 enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
1939 {
d4e9320e 1940- ut_a(buf_page_in_file(bpage));
7023c87b 1941- ut_ad(buf_pool_mutex_own());
d4e9320e 1942+ //ut_a(buf_page_in_file(bpage));
7023c87b 1943+ //ut_ad(buf_pool_mutex_own()); /*optimistic...*/
d4e9320e
AM
1944 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1945 ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);
1946
1947- if (bpage->oldest_modification != 0
1948+ if (buf_page_in_file(bpage) && bpage->oldest_modification != 0
1949 && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
1950 ut_ad(bpage->in_flush_list);
1951
7023c87b
ER
1952@@ -421,8 +431,11 @@
1953 /*=============*/
1954 buf_page_t* bpage) /*!< in: pointer to the block in question */
d4e9320e 1955 {
7023c87b
ER
1956- ut_ad(buf_pool_mutex_own());
1957+ //ut_ad(buf_pool_mutex_own());
d4e9320e 1958 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
7023c87b
ER
1959+
1960+ mutex_enter(&flush_list_mutex);
1961+
d4e9320e
AM
1962 ut_ad(bpage->in_flush_list);
1963
7023c87b
ER
1964 switch (buf_page_get_state(bpage)) {
1965@@ -433,15 +446,16 @@
1966 case BUF_BLOCK_READY_FOR_USE:
1967 case BUF_BLOCK_MEMORY:
1968 case BUF_BLOCK_REMOVE_HASH:
1969+ mutex_exit(&flush_list_mutex);
1970 ut_error;
d4e9320e
AM
1971 return;
1972 case BUF_BLOCK_ZIP_DIRTY:
1973 buf_page_set_state(bpage, BUF_BLOCK_ZIP_PAGE);
1974- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
1975+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
1976 buf_LRU_insert_zip_clean(bpage);
1977 break;
1978 case BUF_BLOCK_FILE_PAGE:
1979- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
1980+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
1981 break;
1982 }
1983
7023c87b
ER
1984@@ -456,8 +470,9 @@
1985
1986 bpage->oldest_modification = 0;
1987
1988- ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
1989+ ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
1990 ut_ad(ut_list_node_313->in_flush_list)));
1991+ mutex_exit(&flush_list_mutex);
1992 }
1993
1994 /********************************************************************//**
1995@@ -474,7 +489,8 @@
1996 buf_page_t* prev;
1997 buf_page_t* prev_b = NULL;
1998
1999- ut_ad(buf_pool_mutex_own());
2000+ //ut_ad(buf_pool_mutex_own());
2001+ ut_ad(mutex_own(&flush_list_mutex));
d4e9320e 2002
7023c87b 2003 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
d4e9320e 2004
7023c87b 2005@@ -492,18 +508,18 @@
d4e9320e
AM
2006 because we assert on in_flush_list in comparison function. */
2007 ut_d(bpage->in_flush_list = FALSE);
2008
2009- prev = UT_LIST_GET_PREV(list, bpage);
2010- UT_LIST_REMOVE(list, buf_pool->flush_list, bpage);
2011+ prev = UT_LIST_GET_PREV(flush_list, bpage);
2012+ UT_LIST_REMOVE(flush_list, buf_pool->flush_list, bpage);
2013
2014 if (prev) {
2015 ut_ad(prev->in_flush_list);
2016 UT_LIST_INSERT_AFTER(
2017- list,
2018+ flush_list,
2019 buf_pool->flush_list,
2020 prev, dpage);
2021 } else {
2022 UT_LIST_ADD_FIRST(
2023- list,
2024+ flush_list,
2025 buf_pool->flush_list,
2026 dpage);
2027 }
7023c87b 2028@@ -977,7 +993,9 @@
d4e9320e
AM
2029 io_fixed and oldest_modification != 0. Thus, it cannot be
2030 relocated in the buffer pool or removed from flush_list or
2031 LRU_list. */
7023c87b
ER
2032- ut_ad(!buf_pool_mutex_own());
2033+ //ut_ad(!buf_pool_mutex_own());
2034+ ut_ad(!mutex_own(&LRU_list_mutex));
2035+ ut_ad(!mutex_own(&flush_list_mutex));
d4e9320e
AM
2036 ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
2037 ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
7023c87b
ER
2038 ut_ad(bpage->oldest_modification != 0);
2039@@ -1137,12 +1155,19 @@
d4e9320e
AM
2040 ibool is_uncompressed;
2041
2042 ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
7023c87b
ER
2043- ut_ad(buf_pool_mutex_own());
2044+ //ut_ad(buf_pool_mutex_own());
d4e9320e 2045+#ifdef UNIV_SYNC_DEBUG
7023c87b
ER
2046+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
2047+ || rw_lock_own(&page_hash_latch, RW_LOCK_SHARED));
d4e9320e
AM
2048+#endif
2049 ut_ad(buf_page_in_file(bpage));
2050
2051 block_mutex = buf_page_get_mutex(bpage);
2052 ut_ad(mutex_own(block_mutex));
2053
7023c87b
ER
2054+ mutex_enter(&buf_pool_mutex);
2055+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
2056+
2057 ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
2058
2059 buf_page_set_io_fix(bpage, BUF_IO_WRITE);
7023c87b
ER
2060@@ -1173,7 +1198,8 @@
2061 }
d4e9320e 2062
7023c87b
ER
2063 mutex_exit(block_mutex);
2064- buf_pool_mutex_exit();
2065+ //buf_pool_mutex_exit();
2066+ mutex_exit(&buf_pool_mutex);
d4e9320e 2067
7023c87b
ER
2068 /* Even though bpage is not protected by any mutex at
2069 this point, it is safe to access bpage, because it is
2070@@ -1210,7 +1236,8 @@
2071 immediately. */
d4e9320e 2072
7023c87b
ER
2073 mutex_exit(block_mutex);
2074- buf_pool_mutex_exit();
2075+ //buf_pool_mutex_exit();
2076+ mutex_exit(&buf_pool_mutex);
2077 break;
d4e9320e 2078
7023c87b
ER
2079 default:
2080@@ -1275,7 +1302,8 @@
2081 high = fil_space_get_size(space);
2082 }
d4e9320e 2083
7023c87b
ER
2084- buf_pool_mutex_enter();
2085+ //buf_pool_mutex_enter();
2086+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 2087
7023c87b
ER
2088 for (i = low; i < high; i++) {
2089
2090@@ -1294,11 +1322,9 @@
d4e9320e
AM
2091 if (flush_type != BUF_FLUSH_LRU
2092 || i == offset
2093 || buf_page_is_old(bpage)) {
2094- mutex_t* block_mutex = buf_page_get_mutex(bpage);
7023c87b
ER
2095-
2096- mutex_enter(block_mutex);
d4e9320e
AM
2097+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2098
d4e9320e
AM
2099- if (buf_flush_ready_for_flush(bpage, flush_type)
2100+ if (block_mutex && buf_flush_ready_for_flush(bpage, flush_type)
2101 && (i == offset || !bpage->buf_fix_count)) {
2102 /* We only try to flush those
7023c87b
ER
2103 neighbors != offset where the buf fix count is
2104@@ -1312,14 +1338,16 @@
2105 ut_ad(!mutex_own(block_mutex));
d4e9320e 2106 count++;
7023c87b
ER
2107
2108- buf_pool_mutex_enter();
d4e9320e 2109- } else {
7023c87b
ER
2110+ //buf_pool_mutex_enter();
2111+ rw_lock_s_lock(&page_hash_latch);
d4e9320e
AM
2112+ } else if (block_mutex) {
2113 mutex_exit(block_mutex);
2114 }
2115 }
d4e9320e
AM
2116 }
2117
7023c87b
ER
2118- buf_pool_mutex_exit();
2119+ //buf_pool_mutex_exit();
2120+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e 2121
7023c87b
ER
2122 return(count);
2123 }
2124@@ -1350,9 +1378,11 @@
2125 min_n), otherwise ignored */
2126 {
2127 buf_page_t* bpage;
2128+ buf_page_t* prev_bpage = NULL;
2129 ulint page_count = 0;
2130 ulint space;
2131 ulint offset;
2132+ ulint remaining = 0;
2133
2134 ut_ad((flush_type == BUF_FLUSH_LRU)
2135 || (flush_type == BUF_FLUSH_LIST));
2136@@ -1360,20 +1390,28 @@
2137 ut_ad((flush_type != BUF_FLUSH_LIST)
2138 || sync_thread_levels_empty_gen(TRUE));
2139 #endif /* UNIV_SYNC_DEBUG */
2140- buf_pool_mutex_enter();
2141+ //buf_pool_mutex_enter();
2142+ mutex_enter(&buf_pool_mutex);
d4e9320e 2143
7023c87b
ER
2144 if ((buf_pool->n_flush[flush_type] > 0)
2145 || (buf_pool->init_flush[flush_type] == TRUE)) {
d4e9320e 2146
7023c87b 2147 /* There is already a flush batch of the same type running */
d4e9320e 2148
7023c87b
ER
2149- buf_pool_mutex_exit();
2150+ //buf_pool_mutex_exit();
2151+ mutex_exit(&buf_pool_mutex);
d4e9320e 2152
7023c87b
ER
2153 return(ULINT_UNDEFINED);
2154 }
d4e9320e 2155
7023c87b 2156 buf_pool->init_flush[flush_type] = TRUE;
d4e9320e 2157
7023c87b
ER
2158+ mutex_exit(&buf_pool_mutex);
2159+
2160+ if (flush_type == BUF_FLUSH_LRU) {
2161+ mutex_enter(&LRU_list_mutex);
2162+ }
2163+
2164 for (;;) {
2165 flush_next:
2166 /* If we have flushed enough, leave the loop */
2167@@ -1390,7 +1428,13 @@
2168 } else {
2169 ut_ad(flush_type == BUF_FLUSH_LIST);
d4e9320e 2170
7023c87b
ER
2171+ mutex_enter(&flush_list_mutex);
2172+ remaining = UT_LIST_GET_LEN(buf_pool->flush_list);
2173 bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
2174+ if (bpage) {
2175+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2176+ }
2177+ mutex_exit(&flush_list_mutex);
2178 if (!bpage
2179 || bpage->oldest_modification >= lsn_limit) {
2180 /* We have flushed enough */
2181@@ -1407,26 +1451,35 @@
2182 function a pointer to a block in the list! */
d4e9320e 2183
7023c87b
ER
2184 do {
2185- mutex_t*block_mutex = buf_page_get_mutex(bpage);
2186+ mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
2187 ibool ready;
d4e9320e 2188
7023c87b
ER
2189- ut_a(buf_page_in_file(bpage));
2190+ //ut_a(buf_page_in_file(bpage));
d4e9320e 2191
7023c87b
ER
2192- mutex_enter(block_mutex);
2193- ready = buf_flush_ready_for_flush(bpage, flush_type);
2194- mutex_exit(block_mutex);
2195+ if (block_mutex) {
2196+ ready = buf_flush_ready_for_flush(bpage, flush_type);
2197+ mutex_exit(block_mutex);
2198+ } else {
2199+ ready = FALSE;
2200+ }
d4e9320e 2201
7023c87b
ER
2202 if (ready) {
2203 space = buf_page_get_space(bpage);
2204 offset = buf_page_get_page_no(bpage);
d4e9320e 2205
7023c87b
ER
2206- buf_pool_mutex_exit();
2207+ //buf_pool_mutex_exit();
2208+ if (flush_type == BUF_FLUSH_LRU) {
2209+ mutex_exit(&LRU_list_mutex);
2210+ }
d4e9320e 2211
7023c87b
ER
2212 /* Try to flush also all the neighbors */
2213 page_count += buf_flush_try_neighbors(
2214 space, offset, flush_type, srv_flush_neighbor_pages);
d4e9320e 2215
7023c87b
ER
2216- buf_pool_mutex_enter();
2217+ //buf_pool_mutex_enter();
2218+ if (flush_type == BUF_FLUSH_LRU) {
2219+ mutex_enter(&LRU_list_mutex);
2220+ }
2221 goto flush_next;
d4e9320e 2222
7023c87b
ER
2223 } else if (flush_type == BUF_FLUSH_LRU) {
2224@@ -1434,16 +1487,35 @@
2225 } else {
2226 ut_ad(flush_type == BUF_FLUSH_LIST);
2227
2228- bpage = UT_LIST_GET_PREV(list, bpage);
2229- ut_ad(!bpage || bpage->in_flush_list);
2230+ mutex_enter(&flush_list_mutex);
2231+ bpage = UT_LIST_GET_PREV(flush_list, bpage);
2232+ //ut_ad(!bpage || bpage->in_flush_list); /* optimistic */
2233+ if (bpage != prev_bpage) {
2234+ /* the search may warp.. retrying */
2235+ bpage = NULL;
2236+ }
2237+ if (bpage) {
2238+ prev_bpage = UT_LIST_GET_PREV(flush_list, bpage);
2239+ }
2240+ mutex_exit(&flush_list_mutex);
2241+ remaining--;
d4e9320e 2242 }
7023c87b 2243 } while (bpage != NULL);
d4e9320e 2244
7023c87b
ER
2245+ if (remaining)
2246+ goto flush_next;
2247+
2248 /* If we could not find anything to flush, leave the loop */
d4e9320e 2249
7023c87b
ER
2250 break;
2251 }
d4e9320e 2252
7023c87b
ER
2253+ if (flush_type == BUF_FLUSH_LRU) {
2254+ mutex_exit(&LRU_list_mutex);
2255+ }
2256+
2257+ mutex_enter(&buf_pool_mutex);
2258+
2259 buf_pool->init_flush[flush_type] = FALSE;
d4e9320e 2260
7023c87b
ER
2261 if (buf_pool->n_flush[flush_type] == 0) {
2262@@ -1453,7 +1525,8 @@
2263 os_event_set(buf_pool->no_flush[flush_type]);
d4e9320e
AM
2264 }
2265
7023c87b
ER
2266- buf_pool_mutex_exit();
2267+ //buf_pool_mutex_exit();
2268+ mutex_exit(&buf_pool_mutex);
d4e9320e
AM
2269
2270 buf_flush_buffered_writes();
2271
7023c87b 2272@@ -1514,7 +1587,7 @@
d4e9320e 2273 retry:
7023c87b 2274 //buf_pool_mutex_enter();
d4e9320e 2275 if (have_LRU_mutex)
7023c87b
ER
2276- buf_pool_mutex_enter();
2277+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
2278
2279 n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
2280
7023c87b 2281@@ -1531,15 +1604,15 @@
d4e9320e
AM
2282 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2283 continue;
2284 }
2285- block_mutex = buf_page_get_mutex(bpage);
2286-
2287- mutex_enter(block_mutex);
2288+ block_mutex = buf_page_get_mutex_enter(bpage);
2289
2290- if (buf_flush_ready_for_replace(bpage)) {
2291+ if (block_mutex && buf_flush_ready_for_replace(bpage)) {
2292 n_replaceable++;
2293 }
2294
2295- mutex_exit(block_mutex);
2296+ if (block_mutex) {
2297+ mutex_exit(block_mutex);
2298+ }
2299
2300 distance++;
2301
7023c87b 2302@@ -1548,7 +1621,7 @@
d4e9320e 2303
7023c87b 2304 //buf_pool_mutex_exit();
d4e9320e 2305 if (have_LRU_mutex)
7023c87b
ER
2306- buf_pool_mutex_exit();
2307+ mutex_exit(&LRU_list_mutex);
d4e9320e 2308
7023c87b 2309 if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
d4e9320e 2310
7023c87b
ER
2311@@ -1715,7 +1788,7 @@
2312 buf_page_t* bpage;
2313 const ib_rbt_node_t* rnode = NULL;
d4e9320e
AM
2314
2315- UT_LIST_VALIDATE(list, buf_page_t, buf_pool->flush_list,
2316+ UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
2317 ut_ad(ut_list_node_313->in_flush_list));
2318
2319 bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
7023c87b
ER
2320@@ -1730,7 +1803,7 @@
2321 while (bpage != NULL) {
2322 const ib_uint64_t om = bpage->oldest_modification;
2323 ut_ad(bpage->in_flush_list);
2324- ut_a(buf_page_in_file(bpage));
2325+ //ut_a(buf_page_in_file(bpage)); /* optimistic */
2326 ut_a(om > 0);
2327
2328 if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
2329@@ -1742,7 +1815,7 @@
d4e9320e
AM
2330 rnode = rbt_next(buf_pool->flush_rbt, rnode);
2331 }
2332
2333- bpage = UT_LIST_GET_NEXT(list, bpage);
2334+ bpage = UT_LIST_GET_NEXT(flush_list, bpage);
2335
2336 ut_a(!bpage || om >= bpage->oldest_modification);
2337 }
7023c87b
ER
2338@@ -1764,11 +1837,13 @@
2339 {
2340 ibool ret;
2341
2342- buf_pool_mutex_enter();
2343+ //buf_pool_mutex_enter();
2344+ mutex_enter(&flush_list_mutex);
2345
2346 ret = buf_flush_validate_low();
2347
2348- buf_pool_mutex_exit();
2349+ //buf_pool_mutex_exit();
2350+ mutex_exit(&flush_list_mutex);
2351
2352 return(ret);
2353 }
2354diff -ruN a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
2355--- a/storage/innodb_plugin/buf/buf0lru.c 2010-08-27 15:54:59.025058614 +0900
2356+++ b/storage/innodb_plugin/buf/buf0lru.c 2010-08-27 16:11:40.611021077 +0900
2357@@ -145,8 +145,9 @@
d4e9320e
AM
2358 void
2359 buf_LRU_block_free_hashed_page(
2360 /*===========================*/
2361- buf_block_t* block); /*!< in: block, must contain a file page and
2362+ buf_block_t* block, /*!< in: block, must contain a file page and
2363 be in a state where it can be freed */
2364+ ibool have_page_hash_mutex);
2365
2366 /******************************************************************//**
2367 Determines if the unzip_LRU list should be used for evicting a victim
7023c87b
ER
2368@@ -154,16 +155,21 @@
2369 @return TRUE if should use unzip_LRU */
2370 UNIV_INLINE
d4e9320e 2371 ibool
7023c87b
ER
2372-buf_LRU_evict_from_unzip_LRU(void)
2373+buf_LRU_evict_from_unzip_LRU(
d4e9320e 2374+ ibool have_LRU_mutex)
7023c87b 2375 /*==============================*/
d4e9320e
AM
2376 {
2377 ulint io_avg;
2378 ulint unzip_avg;
2379
7023c87b
ER
2380- ut_ad(buf_pool_mutex_own());
2381+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
2382
2383+ if (!have_LRU_mutex)
7023c87b 2384+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
2385 /* If the unzip_LRU list is empty, we can only use the LRU. */
2386 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0) {
2387+ if (!have_LRU_mutex)
7023c87b 2388+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2389 return(FALSE);
2390 }
2391
7023c87b 2392@@ -172,14 +178,20 @@
d4e9320e
AM
2393 decompressed pages in the buffer pool. */
2394 if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
2395 <= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
2396+ if (!have_LRU_mutex)
7023c87b 2397+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2398 return(FALSE);
2399 }
2400
2401 /* If eviction hasn't started yet, we assume by default
2402 that a workload is disk bound. */
2403 if (buf_pool->freed_page_clock == 0) {
2404+ if (!have_LRU_mutex)
7023c87b 2405+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2406 return(TRUE);
2407 }
2408+ if (!have_LRU_mutex)
7023c87b 2409+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2410
2411 /* Calculate the average over past intervals, and add the values
2412 of the current interval. */
7023c87b 2413@@ -245,19 +257,23 @@
d4e9320e 2414
7023c87b
ER
2415 page_arr = ut_malloc(sizeof(ulint)
2416 * BUF_LRU_DROP_SEARCH_HASH_SIZE);
2417- buf_pool_mutex_enter();
2418+ //buf_pool_mutex_enter();
2419+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
2420
2421 scan_again:
2422 num_entries = 0;
2423 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2424
2425 while (bpage != NULL) {
2426- mutex_t* block_mutex = buf_page_get_mutex(bpage);
2427+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2428 buf_page_t* prev_bpage;
2429
2430- mutex_enter(block_mutex);
2431 prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
2432
2433+ if (!block_mutex) {
2434+ goto next_page;
2435+ }
2436+
2437 ut_a(buf_page_in_file(bpage));
2438
2439 if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
7023c87b
ER
2440@@ -285,12 +301,14 @@
2441 }
2442 /* Array full. We release the buf_pool_mutex to
d4e9320e 2443 obey the latching order. */
7023c87b
ER
2444- buf_pool_mutex_exit();
2445+ //buf_pool_mutex_exit();
2446+ mutex_exit(&LRU_list_mutex);
d4e9320e 2447
7023c87b
ER
2448 buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
2449 num_entries);
d4e9320e 2450 num_entries = 0;
7023c87b
ER
2451- buf_pool_mutex_enter();
2452+ //buf_pool_mutex_enter();
2453+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
2454 } else {
2455 mutex_exit(block_mutex);
2456 }
7023c87b 2457@@ -315,7 +333,8 @@
d4e9320e
AM
2458 }
2459 }
2460
7023c87b
ER
2461- buf_pool_mutex_exit();
2462+ //buf_pool_mutex_exit();
2463+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2464
2465 /* Drop any remaining batch of search hashed pages. */
2466 buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
7023c87b
ER
2467@@ -343,7 +362,9 @@
2468 buf_LRU_drop_page_hash_for_tablespace(id);
d4e9320e
AM
2469
2470 scan_again:
7023c87b
ER
2471- buf_pool_mutex_enter();
2472+ //buf_pool_mutex_enter();
2473+ mutex_enter(&LRU_list_mutex);
2474+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
2475
2476 all_freed = TRUE;
2477
7023c87b 2478@@ -371,8 +392,16 @@
d4e9320e
AM
2479
2480 all_freed = FALSE;
2481 } else {
2482- mutex_t* block_mutex = buf_page_get_mutex(bpage);
2483- mutex_enter(block_mutex);
2484+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
2485+
2486+ if (!block_mutex) {
2487+ /* It may be impossible case...
2488+ Something wrong, so will be scan_again */
2489+
2490+ all_freed = FALSE;
2491+
2492+ goto next_page_no_mutex;
2493+ }
2494
2495 if (bpage->buf_fix_count > 0) {
2496
7023c87b 2497@@ -431,7 +460,9 @@
d4e9320e
AM
2498 ulint page_no;
2499 ulint zip_size;
2500
7023c87b
ER
2501- buf_pool_mutex_exit();
2502+ //buf_pool_mutex_exit();
2503+ mutex_exit(&LRU_list_mutex);
2504+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
2505
2506 zip_size = buf_page_get_zip_size(bpage);
2507 page_no = buf_page_get_page_no(bpage);
7023c87b 2508@@ -456,7 +487,7 @@
d4e9320e
AM
2509 if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
2510 != BUF_BLOCK_ZIP_FREE) {
2511 buf_LRU_block_free_hashed_page((buf_block_t*)
2512- bpage);
2513+ bpage, TRUE);
2514 } else {
2515 /* The block_mutex should have been
2516 released by buf_LRU_block_remove_hashed_page()
7023c87b 2517@@ -488,7 +519,9 @@
d4e9320e
AM
2518 bpage = prev_bpage;
2519 }
2520
7023c87b
ER
2521- buf_pool_mutex_exit();
2522+ //buf_pool_mutex_exit();
2523+ mutex_exit(&LRU_list_mutex);
2524+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
2525
2526 if (!all_freed) {
2527 os_thread_sleep(20000);
7023c87b
ER
2528@@ -507,7 +540,9 @@
2529 {
d4e9320e 2530 buf_page_t* b;
d4e9320e 2531
7023c87b
ER
2532- ut_ad(buf_pool_mutex_own());
2533+ //ut_ad(buf_pool_mutex_own());
2534+ ut_ad(mutex_own(&LRU_list_mutex));
2535+ ut_ad(mutex_own(&flush_list_mutex));
d4e9320e
AM
2536 ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
2537
2538 /* Find the first successor of bpage in the LRU list
7023c87b 2539@@ -515,17 +550,17 @@
d4e9320e
AM
2540 b = bpage;
2541 do {
2542 b = UT_LIST_GET_NEXT(LRU, b);
2543- } while (b && buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE);
2544+ } while (b && (buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE || !b->in_LRU_list));
2545
2546 /* Insert bpage before b, i.e., after the predecessor of b. */
2547 if (b) {
2548- b = UT_LIST_GET_PREV(list, b);
2549+ b = UT_LIST_GET_PREV(zip_list, b);
2550 }
2551
2552 if (b) {
2553- UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, bpage);
2554+ UT_LIST_INSERT_AFTER(zip_list, buf_pool->zip_clean, b, bpage);
2555 } else {
2556- UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
2557+ UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_clean, bpage);
2558 }
2559 }
2560
7023c87b
ER
2561@@ -537,16 +572,17 @@
2562 ibool
d4e9320e
AM
2563 buf_LRU_free_from_unzip_LRU_list(
2564 /*=============================*/
7023c87b
ER
2565- ulint n_iterations) /*!< in: how many times this has been called
2566+ ulint n_iterations, /*!< in: how many times this has been called
2567 repeatedly without result: a high value means
2568 that we should search farther; we will search
2569 n_iterations / 5 of the unzip_LRU list,
2570 or nothing if n_iterations >= 5 */
2571+ ibool have_LRU_mutex)
d4e9320e
AM
2572 {
2573 buf_block_t* block;
2574 ulint distance;
2575
7023c87b
ER
2576- ut_ad(buf_pool_mutex_own());
2577+ //ut_ad(buf_pool_mutex_own()); /* optimistic */
d4e9320e
AM
2578
2579 /* Theoratically it should be much easier to find a victim
2580 from unzip_LRU as we can choose even a dirty block (as we'll
7023c87b 2581@@ -556,7 +592,7 @@
d4e9320e
AM
2582 if we have done five iterations so far. */
2583
2584 if (UNIV_UNLIKELY(n_iterations >= 5)
7023c87b
ER
2585- || !buf_LRU_evict_from_unzip_LRU()) {
2586+ || !buf_LRU_evict_from_unzip_LRU(have_LRU_mutex)) {
d4e9320e
AM
2587
2588 return(FALSE);
2589 }
7023c87b 2590@@ -564,18 +600,25 @@
d4e9320e
AM
2591 distance = 100 + (n_iterations
2592 * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
2593
2594+restart:
2595 for (block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
2596 UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
2597 block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
2598
2599 enum buf_lru_free_block_status freed;
2600
2601+ mutex_enter(&block->mutex);
2602+ if (!block->in_unzip_LRU_list || !block->page.in_LRU_list
2603+ || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
2604+ mutex_exit(&block->mutex);
2605+ goto restart;
2606+ }
2607+
2608 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
2609 ut_ad(block->in_unzip_LRU_list);
2610 ut_ad(block->page.in_LRU_list);
2611
2612- mutex_enter(&block->mutex);
2613- freed = buf_LRU_free_block(&block->page, FALSE, NULL);
2614+ freed = buf_LRU_free_block(&block->page, FALSE, NULL, have_LRU_mutex);
2615 mutex_exit(&block->mutex);
2616
2617 switch (freed) {
7023c87b
ER
2618@@ -608,20 +651,22 @@
2619 ibool
d4e9320e
AM
2620 buf_LRU_free_from_common_LRU_list(
2621 /*==============================*/
7023c87b
ER
2622- ulint n_iterations) /*!< in: how many times this has been called
2623+ ulint n_iterations, /*!< in: how many times this has been called
d4e9320e
AM
2624 repeatedly without result: a high value means
2625 that we should search farther; if
2626 n_iterations < 10, then we search
2627 n_iterations / 10 * buf_pool->curr_size
2628 pages from the end of the LRU list */
7023c87b 2629+ ibool have_LRU_mutex)
d4e9320e
AM
2630 {
2631 buf_page_t* bpage;
2632 ulint distance;
2633
7023c87b
ER
2634- ut_ad(buf_pool_mutex_own());
2635+ //ut_ad(buf_pool_mutex_own()); /* optimistic */
d4e9320e
AM
2636
2637 distance = 100 + (n_iterations * buf_pool->curr_size) / 10;
2638
2639+restart:
2640 for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
2641 UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
2642 bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
7023c87b 2643@@ -629,14 +674,23 @@
d4e9320e
AM
2644 enum buf_lru_free_block_status freed;
2645 unsigned accessed;
2646 mutex_t* block_mutex
2647- = buf_page_get_mutex(bpage);
2648+ = buf_page_get_mutex_enter(bpage);
2649+
2650+ if (!block_mutex) {
2651+ goto restart;
2652+ }
2653+
2654+ if (!bpage->in_LRU_list
2655+ || !buf_page_in_file(bpage)) {
2656+ mutex_exit(block_mutex);
2657+ goto restart;
2658+ }
2659
2660 ut_ad(buf_page_in_file(bpage));
2661 ut_ad(bpage->in_LRU_list);
2662
2663- mutex_enter(block_mutex);
2664 accessed = buf_page_is_accessed(bpage);
2665- freed = buf_LRU_free_block(bpage, TRUE, NULL);
2666+ freed = buf_LRU_free_block(bpage, TRUE, NULL, have_LRU_mutex);
2667 mutex_exit(block_mutex);
2668
2669 switch (freed) {
7023c87b 2670@@ -685,22 +739,33 @@
d4e9320e
AM
2671 n_iterations / 5 of the unzip_LRU list. */
2672 {
2673 ibool freed = FALSE;
2674+ ibool have_LRU_mutex = FALSE;
7023c87b 2675+
d4e9320e
AM
2676+ if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
2677+ have_LRU_mutex = TRUE;
7023c87b
ER
2678
2679- buf_pool_mutex_enter();
2680+ /* optimistic search... */
2681+ //buf_pool_mutex_enter();
d4e9320e 2682+ if (have_LRU_mutex)
7023c87b 2683+ mutex_enter(&LRU_list_mutex);
d4e9320e 2684
7023c87b
ER
2685- freed = buf_LRU_free_from_unzip_LRU_list(n_iterations);
2686+ freed = buf_LRU_free_from_unzip_LRU_list(n_iterations, have_LRU_mutex);
d4e9320e
AM
2687
2688 if (!freed) {
7023c87b
ER
2689- freed = buf_LRU_free_from_common_LRU_list(n_iterations);
2690+ freed = buf_LRU_free_from_common_LRU_list(n_iterations, have_LRU_mutex);
d4e9320e
AM
2691 }
2692
7023c87b 2693+ mutex_enter(&buf_pool_mutex);
d4e9320e
AM
2694 if (!freed) {
2695 buf_pool->LRU_flush_ended = 0;
2696 } else if (buf_pool->LRU_flush_ended > 0) {
7023c87b 2697 buf_pool->LRU_flush_ended--;
d4e9320e 2698 }
7023c87b 2699+ mutex_exit(&buf_pool_mutex);
d4e9320e 2700
7023c87b
ER
2701- buf_pool_mutex_exit();
2702+ //buf_pool_mutex_exit();
d4e9320e 2703+ if (have_LRU_mutex)
7023c87b 2704+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2705
2706 return(freed);
2707 }
7023c87b
ER
2708@@ -718,18 +783,22 @@
2709 buf_LRU_try_free_flushed_blocks(void)
2710 /*=================================*/
2711 {
2712- buf_pool_mutex_enter();
2713+ //buf_pool_mutex_enter();
2714+ mutex_enter(&buf_pool_mutex);
d4e9320e 2715
7023c87b 2716 while (buf_pool->LRU_flush_ended > 0) {
d4e9320e 2717
7023c87b
ER
2718- buf_pool_mutex_exit();
2719+ //buf_pool_mutex_exit();
2720+ mutex_exit(&buf_pool_mutex);
d4e9320e 2721
7023c87b 2722 buf_LRU_search_and_free_block(1);
d4e9320e 2723
7023c87b
ER
2724- buf_pool_mutex_enter();
2725+ //buf_pool_mutex_enter();
2726+ mutex_enter(&buf_pool_mutex);
d4e9320e
AM
2727 }
2728
7023c87b
ER
2729- buf_pool_mutex_exit();
2730+ //buf_pool_mutex_exit();
2731+ mutex_exit(&buf_pool_mutex);
2732 }
2733
2734 /******************************************************************//**
2735@@ -744,7 +813,9 @@
2736 {
2737 ibool ret = FALSE;
2738
2739- buf_pool_mutex_enter();
2740+ //buf_pool_mutex_enter();
2741+ mutex_enter(&LRU_list_mutex);
2742+ mutex_enter(&free_list_mutex);
2743
2744 if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
2745 + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 4) {
2746@@ -752,7 +823,9 @@
2747 ret = TRUE;
2748 }
2749
2750- buf_pool_mutex_exit();
2751+ //buf_pool_mutex_exit();
2752+ mutex_exit(&LRU_list_mutex);
2753+ mutex_exit(&free_list_mutex);
2754
d4e9320e 2755 return(ret);
7023c87b
ER
2756 }
2757@@ -768,9 +841,10 @@
d4e9320e
AM
2758 {
2759 buf_block_t* block;
2760
7023c87b
ER
2761- ut_ad(buf_pool_mutex_own());
2762+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
2763
2764- block = (buf_block_t*) UT_LIST_GET_FIRST(buf_pool->free);
7023c87b 2765+ mutex_enter(&free_list_mutex);
d4e9320e
AM
2766+ block = (buf_block_t*) UT_LIST_GET_LAST(buf_pool->free);
2767
2768 if (block) {
7023c87b
ER
2769 ut_ad(block->page.in_free_list);
2770@@ -778,7 +852,9 @@
d4e9320e
AM
2771 ut_ad(!block->page.in_flush_list);
2772 ut_ad(!block->page.in_LRU_list);
2773 ut_a(!buf_page_in_file(&block->page));
2774- UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
2775+ UT_LIST_REMOVE(free, buf_pool->free, (&block->page));
2776+
7023c87b 2777+ mutex_exit(&free_list_mutex);
d4e9320e
AM
2778
2779 mutex_enter(&block->mutex);
2780
7023c87b
ER
2781@@ -786,6 +862,8 @@
2782 UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
d4e9320e
AM
2783
2784 mutex_exit(&block->mutex);
2785+ } else {
7023c87b 2786+ mutex_exit(&free_list_mutex);
d4e9320e
AM
2787 }
2788
2789 return(block);
7023c87b 2790@@ -809,7 +887,7 @@
d4e9320e
AM
2791 ibool mon_value_was = FALSE;
2792 ibool started_monitor = FALSE;
2793 loop:
7023c87b
ER
2794- buf_pool_mutex_enter();
2795+ //buf_pool_mutex_enter();
d4e9320e
AM
2796
2797 if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
2798 + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
7023c87b
ER
2799@@ -889,14 +967,16 @@
2800 if (UNIV_UNLIKELY(zip_size)) {
d4e9320e
AM
2801 ibool lru;
2802 page_zip_set_size(&block->page.zip, zip_size);
7023c87b
ER
2803- block->page.zip.data = buf_buddy_alloc(zip_size, &lru);
2804+ mutex_enter(&LRU_list_mutex);
2805+ block->page.zip.data = buf_buddy_alloc(zip_size, &lru, FALSE);
2806+ mutex_exit(&LRU_list_mutex);
d4e9320e
AM
2807 UNIV_MEM_DESC(block->page.zip.data, zip_size, block);
2808 } else {
7023c87b 2809 page_zip_set_size(&block->page.zip, 0);
d4e9320e
AM
2810 block->page.zip.data = NULL;
2811 }
2812
7023c87b
ER
2813- buf_pool_mutex_exit();
2814+ //buf_pool_mutex_exit();
d4e9320e
AM
2815
2816 if (started_monitor) {
2817 srv_print_innodb_monitor = mon_value_was;
7023c87b 2818@@ -908,7 +988,7 @@
d4e9320e
AM
2819 /* If no block was in the free list, search from the end of the LRU
2820 list and try to free a block there */
2821
7023c87b
ER
2822- buf_pool_mutex_exit();
2823+ //buf_pool_mutex_exit();
2824
2825 freed = buf_LRU_search_and_free_block(n_iterations);
2826
2827@@ -957,18 +1037,21 @@
2828
2829 os_aio_simulated_wake_handler_threads();
d4e9320e 2830
7023c87b
ER
2831- buf_pool_mutex_enter();
2832+ //buf_pool_mutex_enter();
2833+ mutex_enter(&buf_pool_mutex);
2834
2835 if (buf_pool->LRU_flush_ended > 0) {
2836 /* We have written pages in an LRU flush. To make the insert
2837 buffer more efficient, we try to move these pages to the free
2838 list. */
2839
2840- buf_pool_mutex_exit();
2841+ //buf_pool_mutex_exit();
2842+ mutex_exit(&buf_pool_mutex);
2843
2844 buf_LRU_try_free_flushed_blocks();
2845 } else {
2846- buf_pool_mutex_exit();
2847+ //buf_pool_mutex_exit();
2848+ mutex_exit(&buf_pool_mutex);
2849 }
d4e9320e 2850
7023c87b
ER
2851 if (n_iterations > 10) {
2852@@ -993,7 +1076,8 @@
d4e9320e
AM
2853 ulint new_len;
2854
2855 ut_a(buf_pool->LRU_old);
7023c87b
ER
2856- ut_ad(buf_pool_mutex_own());
2857+ //ut_ad(buf_pool_mutex_own());
2858+ ut_ad(mutex_own(&LRU_list_mutex));
2859 ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
2860 ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
d4e9320e 2861 #if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
7023c87b 2862@@ -1058,7 +1142,8 @@
d4e9320e
AM
2863 {
2864 buf_page_t* bpage;
2865
7023c87b
ER
2866- ut_ad(buf_pool_mutex_own());
2867+ //ut_ad(buf_pool_mutex_own());
2868+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2869 ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
2870
2871 /* We first initialize all blocks in the LRU list as old and then use
7023c87b 2872@@ -1091,13 +1176,14 @@
d4e9320e
AM
2873 ut_ad(buf_pool);
2874 ut_ad(bpage);
2875 ut_ad(buf_page_in_file(bpage));
7023c87b
ER
2876- ut_ad(buf_pool_mutex_own());
2877+ //ut_ad(buf_pool_mutex_own());
2878+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2879
2880 if (buf_page_belongs_to_unzip_LRU(bpage)) {
2881 buf_block_t* block = (buf_block_t*) bpage;
2882
2883 ut_ad(block->in_unzip_LRU_list);
2884- ut_d(block->in_unzip_LRU_list = FALSE);
2885+ block->in_unzip_LRU_list = FALSE;
2886
2887 UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
2888 }
7023c87b
ER
2889@@ -1113,7 +1199,8 @@
2890 {
d4e9320e
AM
2891 ut_ad(buf_pool);
2892 ut_ad(bpage);
7023c87b
ER
2893- ut_ad(buf_pool_mutex_own());
2894+ //ut_ad(buf_pool_mutex_own());
2895+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2896
2897 ut_a(buf_page_in_file(bpage));
2898
7023c87b
ER
2899@@ -1188,12 +1275,13 @@
2900 {
d4e9320e
AM
2901 ut_ad(buf_pool);
2902 ut_ad(block);
7023c87b
ER
2903- ut_ad(buf_pool_mutex_own());
2904+ //ut_ad(buf_pool_mutex_own());
2905+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2906
2907 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
2908
2909 ut_ad(!block->in_unzip_LRU_list);
2910- ut_d(block->in_unzip_LRU_list = TRUE);
2911+ block->in_unzip_LRU_list = TRUE;
2912
2913 if (old) {
2914 UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
7023c87b
ER
2915@@ -1212,7 +1300,8 @@
2916 {
d4e9320e
AM
2917 ut_ad(buf_pool);
2918 ut_ad(bpage);
7023c87b
ER
2919- ut_ad(buf_pool_mutex_own());
2920+ //ut_ad(buf_pool_mutex_own());
2921+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2922
2923 ut_a(buf_page_in_file(bpage));
2924
7023c87b
ER
2925@@ -1261,7 +1350,8 @@
2926 {
d4e9320e
AM
2927 ut_ad(buf_pool);
2928 ut_ad(bpage);
7023c87b
ER
2929- ut_ad(buf_pool_mutex_own());
2930+ //ut_ad(buf_pool_mutex_own());
2931+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2932
2933 ut_a(buf_page_in_file(bpage));
2934 ut_ad(!bpage->in_LRU_list);
7023c87b
ER
2935@@ -1338,7 +1428,8 @@
2936 /*=====================*/
2937 buf_page_t* bpage) /*!< in: control block */
d4e9320e 2938 {
7023c87b
ER
2939- ut_ad(buf_pool_mutex_own());
2940+ //ut_ad(buf_pool_mutex_own());
2941+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
2942
2943 if (bpage->old) {
2944 buf_pool->stat.n_pages_made_young++;
7023c87b 2945@@ -1380,18 +1471,19 @@
d4e9320e
AM
2946 buf_page_t* bpage, /*!< in: block to be freed */
2947 ibool zip, /*!< in: TRUE if should remove also the
2948 compressed page of an uncompressed page */
2949- ibool* buf_pool_mutex_released)
2950+ ibool* buf_pool_mutex_released,
2951 /*!< in: pointer to a variable that will
2952 be assigned TRUE if buf_pool_mutex
2953 was temporarily released, or NULL */
2954+ ibool have_LRU_mutex)
2955 {
2956 buf_page_t* b = NULL;
d4e9320e
AM
2957 mutex_t* block_mutex = buf_page_get_mutex(bpage);
2958
7023c87b
ER
2959- ut_ad(buf_pool_mutex_own());
2960+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
2961 ut_ad(mutex_own(block_mutex));
2962 ut_ad(buf_page_in_file(bpage));
2963- ut_ad(bpage->in_LRU_list);
2964+ //ut_ad(bpage->in_LRU_list);
2965 ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
2966 #if UNIV_WORD_SIZE == 4
2967 /* On 32-bit systems, there is no padding in buf_page_t. On
7023c87b 2968@@ -1400,7 +1492,7 @@
d4e9320e
AM
2969 UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
2970 #endif
2971
2972- if (!buf_page_can_relocate(bpage)) {
2973+ if (!bpage->in_LRU_list || !block_mutex || !buf_page_can_relocate(bpage)) {
2974
2975 /* Do not free buffer-fixed or I/O-fixed blocks. */
2976 return(BUF_LRU_NOT_FREED);
7023c87b 2977@@ -1432,15 +1524,15 @@
d4e9320e
AM
2978 If it cannot be allocated (without freeing a block
2979 from the LRU list), refuse to free bpage. */
2980 alloc:
7023c87b
ER
2981- buf_pool_mutex_exit_forbid();
2982- b = buf_buddy_alloc(sizeof *b, NULL);
2983- buf_pool_mutex_exit_allow();
2984+ //buf_pool_mutex_exit_forbid();
2985+ b = buf_buddy_alloc(sizeof *b, NULL, FALSE);
2986+ //buf_pool_mutex_exit_allow();
d4e9320e
AM
2987
2988 if (UNIV_UNLIKELY(!b)) {
2989 return(BUF_LRU_CANNOT_RELOCATE);
2990 }
2991
2992- memcpy(b, bpage, sizeof *b);
2993+ //memcpy(b, bpage, sizeof *b);
2994 }
2995
2996 #ifdef UNIV_DEBUG
7023c87b 2997@@ -1451,6 +1543,39 @@
d4e9320e
AM
2998 }
2999 #endif /* UNIV_DEBUG */
3000
3001+ /* not to break latch order, must re-enter block_mutex */
3002+ mutex_exit(block_mutex);
3003+
3004+ if (!have_LRU_mutex)
7023c87b
ER
3005+ mutex_enter(&LRU_list_mutex); /* optimistic */
3006+ rw_lock_x_lock(&page_hash_latch);
d4e9320e
AM
3007+ mutex_enter(block_mutex);
3008+
3009+ /* recheck states of block */
3010+ if (!bpage->in_LRU_list || block_mutex != buf_page_get_mutex(bpage)
3011+ || !buf_page_can_relocate(bpage)) {
3012+not_freed:
3013+ if (b) {
7023c87b 3014+ buf_buddy_free(b, sizeof *b, TRUE);
d4e9320e
AM
3015+ }
3016+ if (!have_LRU_mutex)
7023c87b
ER
3017+ mutex_exit(&LRU_list_mutex);
3018+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
3019+ return(BUF_LRU_NOT_FREED);
3020+ } else if (zip || !bpage->zip.data) {
3021+ if (bpage->oldest_modification)
3022+ goto not_freed;
3023+ } else if (bpage->oldest_modification) {
3024+ if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
3025+ ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_DIRTY);
3026+ goto not_freed;
3027+ }
3028+ }
3029+
3030+ if (b) {
3031+ memcpy(b, bpage, sizeof *b);
3032+ }
3033+
3034 if (buf_LRU_block_remove_hashed_page(bpage, zip)
3035 != BUF_BLOCK_ZIP_FREE) {
3036 ut_a(bpage->buf_fix_count == 0);
7023c87b 3037@@ -1462,6 +1587,10 @@
d4e9320e 3038
7023c87b 3039 ut_a(!buf_page_hash_get(bpage->space, bpage->offset));
d4e9320e
AM
3040
3041+ while (prev_b && !prev_b->in_LRU_list) {
3042+ prev_b = UT_LIST_GET_PREV(LRU, prev_b);
3043+ }
3044+
3045 b->state = b->oldest_modification
3046 ? BUF_BLOCK_ZIP_DIRTY
3047 : BUF_BLOCK_ZIP_PAGE;
7023c87b
ER
3048@@ -1537,12 +1666,14 @@
3049 buf_LRU_add_block_low(b, buf_page_is_old(b));
3050 }
3051
3052+ mutex_enter(&flush_list_mutex);
3053 if (b->state == BUF_BLOCK_ZIP_PAGE) {
3054 buf_LRU_insert_zip_clean(b);
3055 } else {
3056 /* Relocate on buf_pool->flush_list. */
3057 buf_flush_relocate_on_flush_list(bpage, b);
3058 }
3059+ mutex_exit(&flush_list_mutex);
3060
3061 bpage->zip.data = NULL;
3062 page_zip_set_size(&bpage->zip, 0);
3063@@ -1558,7 +1689,9 @@
d4e9320e
AM
3064 *buf_pool_mutex_released = TRUE;
3065 }
3066
7023c87b
ER
3067- buf_pool_mutex_exit();
3068+ //buf_pool_mutex_exit();
3069+ mutex_exit(&LRU_list_mutex);
3070+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
3071 mutex_exit(block_mutex);
3072
3073 /* Remove possible adaptive hash index on the page.
7023c87b 3074@@ -1590,7 +1723,9 @@
d4e9320e
AM
3075 : BUF_NO_CHECKSUM_MAGIC);
3076 }
3077
7023c87b
ER
3078- buf_pool_mutex_enter();
3079+ //buf_pool_mutex_enter();
d4e9320e 3080+ if (have_LRU_mutex)
7023c87b 3081+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
3082 mutex_enter(block_mutex);
3083
3084 if (b) {
7023c87b
ER
3085@@ -1600,13 +1735,17 @@
3086 mutex_exit(&buf_pool_zip_mutex);
d4e9320e
AM
3087 }
3088
3089- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
3090+ buf_LRU_block_free_hashed_page((buf_block_t*) bpage, FALSE);
3091 } else {
3092 /* The block_mutex should have been released by
3093 buf_LRU_block_remove_hashed_page() when it returns
3094 BUF_BLOCK_ZIP_FREE. */
7023c87b 3095 ut_ad(block_mutex == &buf_pool_zip_mutex);
d4e9320e
AM
3096 mutex_enter(block_mutex);
3097+
3098+ if (!have_LRU_mutex)
7023c87b
ER
3099+ mutex_exit(&LRU_list_mutex);
3100+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
3101 }
3102
3103 return(BUF_LRU_FREED);
7023c87b 3104@@ -1618,12 +1757,13 @@
d4e9320e
AM
3105 void
3106 buf_LRU_block_free_non_file_page(
3107 /*=============================*/
3108- buf_block_t* block) /*!< in: block, must not contain a file page */
3109+ buf_block_t* block, /*!< in: block, must not contain a file page */
3110+ ibool have_page_hash_mutex)
3111 {
7023c87b 3112 void* data;
d4e9320e
AM
3113
3114 ut_ad(block);
7023c87b
ER
3115- ut_ad(buf_pool_mutex_own());
3116+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
3117 ut_ad(mutex_own(&block->mutex));
3118
3119 switch (buf_block_get_state(block)) {
7023c87b 3120@@ -1657,15 +1797,17 @@
d4e9320e
AM
3121 if (data) {
3122 block->page.zip.data = NULL;
3123 mutex_exit(&block->mutex);
7023c87b
ER
3124- buf_pool_mutex_exit_forbid();
3125- buf_buddy_free(data, page_zip_get_size(&block->page.zip));
3126- buf_pool_mutex_exit_allow();
3127+ //buf_pool_mutex_exit_forbid();
3128+ buf_buddy_free(data, page_zip_get_size(&block->page.zip), have_page_hash_mutex);
3129+ //buf_pool_mutex_exit_allow();
d4e9320e
AM
3130 mutex_enter(&block->mutex);
3131 page_zip_set_size(&block->page.zip, 0);
3132 }
3133
3134- UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
7023c87b 3135+ mutex_enter(&free_list_mutex);
d4e9320e
AM
3136+ UT_LIST_ADD_FIRST(free, buf_pool->free, (&block->page));
3137 ut_d(block->page.in_free_list = TRUE);
7023c87b 3138+ mutex_exit(&free_list_mutex);
d4e9320e
AM
3139
3140 UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
3141 }
7023c87b
ER
3142@@ -1692,7 +1834,11 @@
3143 {
3144 const buf_page_t* hashed_bpage;
d4e9320e 3145 ut_ad(bpage);
7023c87b
ER
3146- ut_ad(buf_pool_mutex_own());
3147+ //ut_ad(buf_pool_mutex_own());
3148+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e 3149+#ifdef UNIV_SYNC_DEBUG
7023c87b 3150+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX));
d4e9320e
AM
3151+#endif
3152 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3153
3154 ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
7023c87b 3155@@ -1798,7 +1944,9 @@
d4e9320e
AM
3156
3157 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
3158 mutex_exit(buf_page_get_mutex(bpage));
7023c87b
ER
3159- buf_pool_mutex_exit();
3160+ //buf_pool_mutex_exit();
3161+ mutex_exit(&LRU_list_mutex);
3162+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
3163 buf_print();
3164 buf_LRU_print();
3165 buf_validate();
7023c87b 3166@@ -1821,14 +1969,14 @@
d4e9320e
AM
3167 ut_a(bpage->zip.data);
3168 ut_a(buf_page_get_zip_size(bpage));
3169
3170- UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
3171+ UT_LIST_REMOVE(zip_list, buf_pool->zip_clean, bpage);
3172
7023c87b
ER
3173 mutex_exit(&buf_pool_zip_mutex);
3174- buf_pool_mutex_exit_forbid();
3175+ //buf_pool_mutex_exit_forbid();
3176 buf_buddy_free(bpage->zip.data,
3177- page_zip_get_size(&bpage->zip));
3178- buf_buddy_free(bpage, sizeof(*bpage));
3179- buf_pool_mutex_exit_allow();
3180+ page_zip_get_size(&bpage->zip), TRUE);
3181+ buf_buddy_free(bpage, sizeof(*bpage), TRUE);
3182+ //buf_pool_mutex_exit_allow();
d4e9320e
AM
3183 UNIV_MEM_UNDESC(bpage);
3184 return(BUF_BLOCK_ZIP_FREE);
7023c87b
ER
3185
3186@@ -1850,9 +1998,9 @@
d4e9320e
AM
3187 ut_ad(!bpage->in_flush_list);
3188 ut_ad(!bpage->in_LRU_list);
3189 mutex_exit(&((buf_block_t*) bpage)->mutex);
7023c87b
ER
3190- buf_pool_mutex_exit_forbid();
3191- buf_buddy_free(data, page_zip_get_size(&bpage->zip));
3192- buf_pool_mutex_exit_allow();
3193+ //buf_pool_mutex_exit_forbid();
3194+ buf_buddy_free(data, page_zip_get_size(&bpage->zip), TRUE);
3195+ //buf_pool_mutex_exit_allow();
d4e9320e
AM
3196 mutex_enter(&((buf_block_t*) bpage)->mutex);
3197 page_zip_set_size(&bpage->zip, 0);
3198 }
7023c87b 3199@@ -1878,15 +2026,16 @@
d4e9320e
AM
3200 void
3201 buf_LRU_block_free_hashed_page(
3202 /*===========================*/
3203- buf_block_t* block) /*!< in: block, must contain a file page and
3204+ buf_block_t* block, /*!< in: block, must contain a file page and
3205 be in a state where it can be freed */
3206+ ibool have_page_hash_mutex)
3207 {
7023c87b
ER
3208- ut_ad(buf_pool_mutex_own());
3209+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
3210 ut_ad(mutex_own(&block->mutex));
3211
3212 buf_block_set_state(block, BUF_BLOCK_MEMORY);
3213
3214- buf_LRU_block_free_non_file_page(block);
3215+ buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
3216 }
3217
3218 /**********************************************************************//**
7023c87b 3219@@ -1912,7 +2061,8 @@
d4e9320e
AM
3220 }
3221
3222 if (adjust) {
7023c87b
ER
3223- buf_pool_mutex_enter();
3224+ //buf_pool_mutex_enter();
3225+ mutex_enter(&LRU_list_mutex);
d4e9320e 3226
7023c87b
ER
3227 if (ratio != buf_LRU_old_ratio) {
3228 buf_LRU_old_ratio = ratio;
3229@@ -1923,7 +2073,8 @@
d4e9320e
AM
3230 }
3231 }
3232
7023c87b
ER
3233- buf_pool_mutex_exit();
3234+ //buf_pool_mutex_exit();
3235+ mutex_exit(&LRU_list_mutex);
d4e9320e 3236 } else {
7023c87b 3237 buf_LRU_old_ratio = ratio;
d4e9320e 3238 }
7023c87b
ER
3239@@ -1948,7 +2099,8 @@
3240 goto func_exit;
3241 }
3242
3243- buf_pool_mutex_enter();
3244+ //buf_pool_mutex_enter();
3245+ mutex_enter(&buf_pool_mutex);
3246
3247 /* Update the index. */
3248 item = &buf_LRU_stat_arr[buf_LRU_stat_arr_ind];
3249@@ -1962,7 +2114,8 @@
3250 /* Put current entry in the array. */
3251 memcpy(item, &buf_LRU_stat_cur, sizeof *item);
3252
3253- buf_pool_mutex_exit();
3254+ //buf_pool_mutex_exit();
3255+ mutex_exit(&buf_pool_mutex);
3256
3257 func_exit:
3258 /* Clear the current entry. */
3259@@ -1984,7 +2137,8 @@
d4e9320e
AM
3260 ulint new_len;
3261
3262 ut_ad(buf_pool);
7023c87b
ER
3263- buf_pool_mutex_enter();
3264+ //buf_pool_mutex_enter();
3265+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
3266
3267 if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
3268
7023c87b 3269@@ -2044,16 +2198,22 @@
d4e9320e
AM
3270
3271 ut_a(buf_pool->LRU_old_len == old_len);
3272
3273- UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
7023c87b
ER
3274+ mutex_exit(&LRU_list_mutex);
3275+ mutex_enter(&free_list_mutex);
d4e9320e
AM
3276+
3277+ UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
3278 ut_ad(ut_list_node_313->in_free_list));
3279
3280 for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
3281 bpage != NULL;
3282- bpage = UT_LIST_GET_NEXT(list, bpage)) {
3283+ bpage = UT_LIST_GET_NEXT(free, bpage)) {
3284
3285 ut_a(buf_page_get_state(bpage) == BUF_BLOCK_NOT_USED);
3286 }
3287
7023c87b
ER
3288+ mutex_exit(&free_list_mutex);
3289+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
3290+
3291 UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
3292 ut_ad(ut_list_node_313->in_unzip_LRU_list
3293 && ut_list_node_313->page.in_LRU_list));
7023c87b 3294@@ -2067,7 +2227,8 @@
d4e9320e
AM
3295 ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
3296 }
3297
7023c87b
ER
3298- buf_pool_mutex_exit();
3299+ //buf_pool_mutex_exit();
3300+ mutex_exit(&LRU_list_mutex);
3301 return(TRUE);
d4e9320e 3302 }
7023c87b
ER
3303 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
3304@@ -2083,7 +2244,8 @@
d4e9320e
AM
3305 const buf_page_t* bpage;
3306
3307 ut_ad(buf_pool);
7023c87b
ER
3308- buf_pool_mutex_enter();
3309+ //buf_pool_mutex_enter();
3310+ mutex_enter(&LRU_list_mutex);
d4e9320e
AM
3311
3312 bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
3313
7023c87b 3314@@ -2140,6 +2302,7 @@
d4e9320e
AM
3315 bpage = UT_LIST_GET_NEXT(LRU, bpage);
3316 }
3317
7023c87b
ER
3318- buf_pool_mutex_exit();
3319+ //buf_pool_mutex_exit();
3320+ mutex_exit(&LRU_list_mutex);
d4e9320e 3321 }
7023c87b
ER
3322 #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
3323diff -ruN a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c
3324--- a/storage/innodb_plugin/buf/buf0rea.c 2010-08-27 15:54:59.027059378 +0900
3325+++ b/storage/innodb_plugin/buf/buf0rea.c 2010-08-27 16:11:40.614021339 +0900
3326@@ -290,10 +290,12 @@
d4e9320e 3327
7023c87b
ER
3328 tablespace_version = fil_space_get_version(space);
3329
3330- buf_pool_mutex_enter();
3331+ //buf_pool_mutex_enter();
3332+ mutex_enter(&buf_pool_mutex);
3333
3334 if (high > fil_space_get_size(space)) {
3335- buf_pool_mutex_exit();
3336+ //buf_pool_mutex_exit();
3337+ mutex_exit(&buf_pool_mutex);
3338 /* The area is not whole, return */
3339
3340 return(0);
3341@@ -301,10 +303,12 @@
3342
3343 if (buf_pool->n_pend_reads
3344 > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
3345- buf_pool_mutex_exit();
3346+ //buf_pool_mutex_exit();
3347+ mutex_exit(&buf_pool_mutex);
d4e9320e
AM
3348
3349 return(0);
3350 }
7023c87b 3351+ mutex_exit(&buf_pool_mutex);
d4e9320e
AM
3352
3353 /* Check that almost all pages in the area have been accessed; if
3354 offset == low, the accesses must be in a descending order, otherwise,
7023c87b 3355@@ -323,6 +327,7 @@
d4e9320e
AM
3356
3357 fail_count = 0;
3358
7023c87b 3359+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 3360 for (i = low; i < high; i++) {
7023c87b 3361 bpage = buf_page_hash_get(space, i);
d4e9320e 3362
7023c87b 3363@@ -350,7 +355,8 @@
d4e9320e
AM
3364
3365 if (fail_count > threshold) {
3366 /* Too many failures: return */
7023c87b
ER
3367- buf_pool_mutex_exit();
3368+ //buf_pool_mutex_exit();
3369+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
3370 return(0);
3371 }
3372
7023c87b
ER
3373@@ -365,7 +371,8 @@
3374 bpage = buf_page_hash_get(space, offset);
d4e9320e
AM
3375
3376 if (bpage == NULL) {
7023c87b
ER
3377- buf_pool_mutex_exit();
3378+ //buf_pool_mutex_exit();
3379+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
3380
3381 return(0);
3382 }
7023c87b 3383@@ -391,7 +398,8 @@
d4e9320e
AM
3384 pred_offset = fil_page_get_prev(frame);
3385 succ_offset = fil_page_get_next(frame);
3386
7023c87b
ER
3387- buf_pool_mutex_exit();
3388+ //buf_pool_mutex_exit();
3389+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
3390
3391 if ((offset == low) && (succ_offset == offset + 1)) {
3392
7023c87b
ER
3393diff -ruN a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc
3394--- a/storage/innodb_plugin/handler/i_s.cc 2010-08-27 15:59:21.753412068 +0900
3395+++ b/storage/innodb_plugin/handler/i_s.cc 2010-08-27 16:11:40.617020805 +0900
3396@@ -2230,7 +2230,8 @@
3397
3398 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
3399
3400- buf_pool_mutex_enter();
3401+ //buf_pool_mutex_enter();
3402+ mutex_enter(&zip_free_mutex);
3403
3404 for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
3405 buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[x];
3406@@ -2256,7 +2257,8 @@
d4e9320e 3407 }
7023c87b 3408 }
d4e9320e 3409
7023c87b
ER
3410- buf_pool_mutex_exit();
3411+ //buf_pool_mutex_exit();
3412+ mutex_exit(&zip_free_mutex);
3413 DBUG_RETURN(status);
3414 }
d4e9320e 3415
7023c87b
ER
3416diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
3417--- a/storage/innodb_plugin/handler/innodb_patch_info.h 2010-08-27 16:11:12.167183642 +0900
3418+++ b/storage/innodb_plugin/handler/innodb_patch_info.h 2010-08-27 16:11:40.614990183 +0900
3419@@ -33,5 +33,6 @@
d4e9320e
AM
3420 {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
3421 {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
3422 {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
3423+{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
3424 {NULL, NULL, NULL, NULL}
3425 };
7023c87b
ER
3426diff -ruN a/storage/innodb_plugin/include/buf0buddy.h b/storage/innodb_plugin/include/buf0buddy.h
3427--- a/storage/innodb_plugin/include/buf0buddy.h 2010-08-04 02:24:19.000000000 +0900
3428+++ b/storage/innodb_plugin/include/buf0buddy.h 2010-08-27 16:11:40.618988049 +0900
3429@@ -49,10 +49,11 @@
3430 buf_buddy_alloc(
3431 /*============*/
d4e9320e
AM
3432 ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3433- ibool* lru) /*!< in: pointer to a variable that will be assigned
3434+ ibool* lru, /*!< in: pointer to a variable that will be assigned
3435 TRUE if storage was allocated from the LRU list
7023c87b 3436 and buf_pool_mutex was temporarily released,
d4e9320e
AM
3437 or NULL if the LRU list should not be used */
3438+ ibool have_page_hash_mutex)
3439 __attribute__((malloc));
3440
3441 /**********************************************************************//**
7023c87b
ER
3442@@ -63,7 +64,8 @@
3443 /*===========*/
d4e9320e
AM
3444 void* buf, /*!< in: block to be freed, must not be
3445 pointed to by the buffer pool */
3446- ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */
3447+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3448+ ibool have_page_hash_mutex)
3449 __attribute__((nonnull));
3450
7023c87b
ER
3451 /** Statistics of buddy blocks of a given size. */
3452diff -ruN a/storage/innodb_plugin/include/buf0buddy.ic b/storage/innodb_plugin/include/buf0buddy.ic
3453--- a/storage/innodb_plugin/include/buf0buddy.ic 2010-08-04 02:24:19.000000000 +0900
3454+++ b/storage/innodb_plugin/include/buf0buddy.ic 2010-08-27 16:11:40.619989772 +0900
3455@@ -44,10 +44,11 @@
3456 /*================*/
d4e9320e
AM
3457 ulint i, /*!< in: index of buf_pool->zip_free[],
3458 or BUF_BUDDY_SIZES */
3459- ibool* lru) /*!< in: pointer to a variable that will be assigned
3460+ ibool* lru, /*!< in: pointer to a variable that will be assigned
3461 TRUE if storage was allocated from the LRU list
7023c87b 3462 and buf_pool_mutex was temporarily released,
d4e9320e
AM
3463 or NULL if the LRU list should not be used */
3464+ ibool have_page_hash_mutex)
3465 __attribute__((malloc));
3466
3467 /**********************************************************************//**
7023c87b
ER
3468@@ -58,8 +59,9 @@
3469 /*===============*/
3470 void* buf, /*!< in: block to be freed, must not be
3471 pointed to by the buffer pool */
3472- ulint i) /*!< in: index of buf_pool->zip_free[],
3473+ ulint i, /*!< in: index of buf_pool->zip_free[],
3474 or BUF_BUDDY_SIZES */
3475+ ibool have_page_hash_mutex)
d4e9320e
AM
3476 __attribute__((nonnull));
3477
3478 /**********************************************************************//**
7023c87b
ER
3479@@ -96,14 +98,15 @@
3480 buf_buddy_alloc(
3481 /*============*/
3482 ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3483- ibool* lru) /*!< in: pointer to a variable that will be assigned
3484+ ibool* lru, /*!< in: pointer to a variable that will be assigned
3485 TRUE if storage was allocated from the LRU list
3486 and buf_pool_mutex was temporarily released,
3487 or NULL if the LRU list should not be used */
3488+ ibool have_page_hash_mutex)
d4e9320e 3489 {
7023c87b
ER
3490- ut_ad(buf_pool_mutex_own());
3491+ //ut_ad(buf_pool_mutex_own());
d4e9320e 3492
7023c87b
ER
3493- return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru));
3494+ return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
d4e9320e
AM
3495 }
3496
3497 /**********************************************************************//**
7023c87b
ER
3498@@ -114,11 +117,24 @@
3499 /*===========*/
3500 void* buf, /*!< in: block to be freed, must not be
3501 pointed to by the buffer pool */
3502- ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */
3503+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
3504+ ibool have_page_hash_mutex)
d4e9320e 3505 {
7023c87b
ER
3506- ut_ad(buf_pool_mutex_own());
3507+ //ut_ad(buf_pool_mutex_own());
3508
3509- buf_buddy_free_low(buf, buf_buddy_get_slot(size));
d4e9320e 3510+ if (!have_page_hash_mutex) {
7023c87b
ER
3511+ mutex_enter(&LRU_list_mutex);
3512+ rw_lock_x_lock(&page_hash_latch);
d4e9320e 3513+ }
7023c87b
ER
3514+
3515+ mutex_enter(&zip_free_mutex);
3516+ buf_buddy_free_low(buf, buf_buddy_get_slot(size), TRUE);
3517+ mutex_exit(&zip_free_mutex);
d4e9320e
AM
3518+
3519+ if (!have_page_hash_mutex) {
7023c87b
ER
3520+ mutex_exit(&LRU_list_mutex);
3521+ rw_lock_x_unlock(&page_hash_latch);
d4e9320e
AM
3522+ }
3523 }
3524
3525 #ifdef UNIV_MATERIALIZE
7023c87b
ER
3526diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
3527--- a/storage/innodb_plugin/include/buf0buf.h 2010-08-27 15:55:39.399063353 +0900
3528+++ b/storage/innodb_plugin/include/buf0buf.h 2010-08-27 16:11:40.622020552 +0900
3529@@ -713,6 +713,15 @@
d4e9320e
AM
3530 const buf_page_t* bpage) /*!< in: pointer to control block */
3531 __attribute__((pure));
3532
3533+/*************************************************************************
3534+Gets the mutex of a block and enter the mutex with consistency. */
3535+UNIV_INLINE
3536+mutex_t*
3537+buf_page_get_mutex_enter(
3538+/*=========================*/
3539+ const buf_page_t* bpage) /*!< in: pointer to control block */
3540+ __attribute__((pure));
3541+
3542 /*********************************************************************//**
3543 Get the flush type of a page.
3544 @return flush type */
7023c87b 3545@@ -1066,7 +1075,7 @@
d4e9320e
AM
3546 All these are protected by buf_pool_mutex. */
3547 /* @{ */
3548
3549- UT_LIST_NODE_T(buf_page_t) list;
3550+ /* UT_LIST_NODE_T(buf_page_t) list; */
3551 /*!< based on state, this is a
7023c87b
ER
3552 list node, protected only by
3553 buf_pool_mutex, in one of the
3554@@ -1086,6 +1095,10 @@
d4e9320e
AM
3555 BUF_BLOCK_REMOVE_HASH or
3556 BUF_BLOCK_READY_IN_USE. */
3557
3558+ /* resplit for optimistic use */
3559+ UT_LIST_NODE_T(buf_page_t) free;
3560+ UT_LIST_NODE_T(buf_page_t) flush_list;
3561+ UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
3562 #ifdef UNIV_DEBUG
3563 ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
7023c87b
ER
3564 when buf_pool_mutex is free, the
3565@@ -1166,11 +1179,11 @@
d4e9320e
AM
3566 a block is in the unzip_LRU list
3567 if page.state == BUF_BLOCK_FILE_PAGE
3568 and page.zip.data != NULL */
3569-#ifdef UNIV_DEBUG
3570+//#ifdef UNIV_DEBUG
3571 ibool in_unzip_LRU_list;/*!< TRUE if the page is in the
3572 decompressed LRU list;
3573 used in debugging */
3574-#endif /* UNIV_DEBUG */
3575+//#endif /* UNIV_DEBUG */
3576 mutex_t mutex; /*!< mutex protecting this block:
3577 state (also protected by the buffer
3578 pool mutex), io_fix, buf_fix_count,
7023c87b
ER
3579@@ -1446,6 +1459,12 @@
3580 /** mutex protecting the buffer pool struct and control blocks, except the
3581 read-write lock in them */
3582 extern mutex_t buf_pool_mutex;
3583+extern mutex_t LRU_list_mutex;
3584+extern mutex_t flush_list_mutex;
3585+extern rw_lock_t page_hash_latch;
3586+extern mutex_t free_list_mutex;
3587+extern mutex_t zip_free_mutex;
3588+extern mutex_t zip_hash_mutex;
3589 /** mutex protecting the control blocks of compressed-only pages
3590 (of type buf_page_t, not buf_block_t) */
3591 extern mutex_t buf_pool_zip_mutex;
3592diff -ruN a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
3593--- a/storage/innodb_plugin/include/buf0buf.ic 2010-08-04 02:24:19.000000000 +0900
3594+++ b/storage/innodb_plugin/include/buf0buf.ic 2010-08-27 16:11:40.624990413 +0900
3595@@ -121,7 +121,9 @@
3596 buf_page_t* bpage;
3597 ib_uint64_t lsn;
3598
3599- buf_pool_mutex_enter();
3600+try_again:
3601+ //buf_pool_mutex_enter();
3602+ mutex_enter(&flush_list_mutex);
3603
3604 bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
3605
3606@@ -130,9 +132,14 @@
3607 } else {
3608 ut_ad(bpage->in_flush_list);
3609 lsn = bpage->oldest_modification;
3610+ if (lsn == 0) {
3611+ mutex_exit(&flush_list_mutex);
3612+ goto try_again;
3613+ }
3614 }
3615
3616- buf_pool_mutex_exit();
3617+ //buf_pool_mutex_exit();
3618+ mutex_exit(&flush_list_mutex);
3619
3620 /* The returned answer may be out of date: the flush_list can
3621 change after the mutex has been released. */
3622@@ -252,7 +259,7 @@
d4e9320e
AM
3623 case BUF_BLOCK_ZIP_FREE:
3624 /* This is a free page in buf_pool->zip_free[].
3625 Such pages should only be accessed by the buddy allocator. */
3626- ut_error;
3627+ /* ut_error; */ /* optimistic */
3628 break;
3629 case BUF_BLOCK_ZIP_PAGE:
3630 case BUF_BLOCK_ZIP_DIRTY:
7023c87b 3631@@ -295,7 +302,7 @@
d4e9320e 3632 {
d4e9320e
AM
3633 switch (buf_page_get_state(bpage)) {
3634 case BUF_BLOCK_ZIP_FREE:
3635- ut_error;
3636+ /* ut_error; */ /* optimistic */
3637 return(NULL);
3638 case BUF_BLOCK_ZIP_PAGE:
3639 case BUF_BLOCK_ZIP_DIRTY:
7023c87b 3640@@ -305,6 +312,28 @@
d4e9320e
AM
3641 }
3642 }
3643
3644+/*************************************************************************
3645+Gets the mutex of a block and enter the mutex with consistency. */
3646+UNIV_INLINE
3647+mutex_t*
3648+buf_page_get_mutex_enter(
3649+/*=========================*/
3650+ const buf_page_t* bpage) /*!< in: pointer to control block */
3651+{
3652+ mutex_t* block_mutex;
3653+
3654+ while(1) {
3655+ block_mutex = buf_page_get_mutex(bpage);
3656+ if (!block_mutex)
3657+ return block_mutex;
3658+
3659+ mutex_enter(block_mutex);
3660+ if (block_mutex == buf_page_get_mutex(bpage))
3661+ return block_mutex;
3662+ mutex_exit(block_mutex);
3663+ }
3664+}
3665+
3666 /*********************************************************************//**
3667 Get the flush type of a page.
3668 @return flush type */
7023c87b
ER
3669@@ -400,7 +429,7 @@
3670 buf_page_t* bpage, /*!< in/out: control block */
d4e9320e
AM
3671 enum buf_io_fix io_fix) /*!< in: io_fix state */
3672 {
7023c87b
ER
3673- ut_ad(buf_pool_mutex_own());
3674+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
3675 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3676
7023c87b
ER
3677 bpage->io_fix = io_fix;
3678@@ -428,12 +457,13 @@
3679 /*==================*/
d4e9320e
AM
3680 const buf_page_t* bpage) /*!< control block being relocated */
3681 {
7023c87b
ER
3682- ut_ad(buf_pool_mutex_own());
3683+ //ut_ad(buf_pool_mutex_own());
d4e9320e
AM
3684 ut_ad(mutex_own(buf_page_get_mutex(bpage)));
3685 ut_ad(buf_page_in_file(bpage));
3686- ut_ad(bpage->in_LRU_list);
7023c87b 3687+ /* optimistic */
d4e9320e
AM
3688+ //ut_ad(bpage->in_LRU_list);
3689
3690- return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
3691+ return(bpage->in_LRU_list && bpage->io_fix == BUF_IO_NONE
3692 && bpage->buf_fix_count == 0);
3693 }
3694
7023c87b 3695@@ -447,7 +477,7 @@
d4e9320e
AM
3696 const buf_page_t* bpage) /*!< in: control block */
3697 {
d4e9320e 3698 ut_ad(buf_page_in_file(bpage));
7023c87b
ER
3699- ut_ad(buf_pool_mutex_own());
3700+ //ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
d4e9320e 3701
7023c87b
ER
3702 return(bpage->old);
3703 }
3704@@ -462,7 +492,8 @@
3705 ibool old) /*!< in: old */
3706 {
d4e9320e 3707 ut_a(buf_page_in_file(bpage));
7023c87b
ER
3708- ut_ad(buf_pool_mutex_own());
3709+ //ut_ad(buf_pool_mutex_own());
3710+ ut_ad(mutex_own(&LRU_list_mutex));
d4e9320e
AM
3711 ut_ad(bpage->in_LRU_list);
3712
3713 #ifdef UNIV_LRU_DEBUG
7023c87b 3714@@ -509,7 +540,8 @@
d4e9320e
AM
3715 ulint time_ms) /*!< in: ut_time_ms() */
3716 {
d4e9320e 3717 ut_a(buf_page_in_file(bpage));
7023c87b
ER
3718- ut_ad(buf_pool_mutex_own());
3719+ //ut_ad(buf_pool_mutex_own());
3720+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
d4e9320e
AM
3721
3722 if (!bpage->access_time) {
7023c87b
ER
3723 /* Make this the time of the first access. */
3724@@ -741,17 +773,17 @@
d4e9320e
AM
3725 /*===========*/
3726 buf_block_t* block) /*!< in, own: block to be freed */
3727 {
7023c87b
ER
3728- buf_pool_mutex_enter();
3729+ //buf_pool_mutex_enter();
d4e9320e
AM
3730
3731 mutex_enter(&block->mutex);
3732
3733 ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
3734
3735- buf_LRU_block_free_non_file_page(block);
3736+ buf_LRU_block_free_non_file_page(block, FALSE);
3737
3738 mutex_exit(&block->mutex);
3739
7023c87b
ER
3740- buf_pool_mutex_exit();
3741+ //buf_pool_mutex_exit();
d4e9320e
AM
3742 }
3743 #endif /* !UNIV_HOTBACKUP */
3744
7023c87b 3745@@ -799,17 +831,17 @@
d4e9320e
AM
3746 page frame */
3747 {
3748 ib_uint64_t lsn;
3749- mutex_t* block_mutex = buf_page_get_mutex(bpage);
d4e9320e
AM
3750+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
3751
7023c87b
ER
3752- mutex_enter(block_mutex);
3753-
d4e9320e
AM
3754- if (buf_page_in_file(bpage)) {
3755+ if (block_mutex && buf_page_in_file(bpage)) {
3756 lsn = bpage->newest_modification;
3757 } else {
3758 lsn = 0;
3759 }
3760
3761- mutex_exit(block_mutex);
3762+ if (block_mutex) {
3763+ mutex_exit(block_mutex);
3764+ }
3765
3766 return(lsn);
3767 }
7023c87b
ER
3768@@ -825,7 +857,7 @@
3769 buf_block_t* block) /*!< in: block */
3770 {
d4e9320e 3771 #ifdef UNIV_SYNC_DEBUG
7023c87b
ER
3772- ut_ad((buf_pool_mutex_own()
3773+ ut_ad((mutex_own(&LRU_list_mutex)
d4e9320e
AM
3774 && (block->page.buf_fix_count == 0))
3775 || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
3776 #endif /* UNIV_SYNC_DEBUG */
7023c87b
ER
3777@@ -917,7 +949,11 @@
3778 ulint fold;
d4e9320e
AM
3779
3780 ut_ad(buf_pool);
7023c87b
ER
3781- ut_ad(buf_pool_mutex_own());
3782+ //ut_ad(buf_pool_mutex_own());
d4e9320e 3783+#ifdef UNIV_SYNC_DEBUG
7023c87b
ER
3784+ ut_ad(rw_lock_own(&page_hash_latch, RW_LOCK_EX)
3785+ || rw_lock_own(&page_hash_latch, RW_LOCK_SHARED));
d4e9320e 3786+#endif
d4e9320e
AM
3787
3788 /* Look for the page in the hash table */
7023c87b
ER
3789
3790@@ -972,11 +1008,13 @@
3791 {
d4e9320e 3792 const buf_page_t* bpage;
d4e9320e 3793
7023c87b
ER
3794- buf_pool_mutex_enter();
3795+ //buf_pool_mutex_enter();
3796+ rw_lock_s_lock(&page_hash_latch);
d4e9320e 3797
7023c87b 3798 bpage = buf_page_hash_get(space, offset);
d4e9320e 3799
7023c87b
ER
3800- buf_pool_mutex_exit();
3801+ //buf_pool_mutex_exit();
3802+ rw_lock_s_unlock(&page_hash_latch);
d4e9320e
AM
3803
3804 return(bpage != NULL);
3805 }
7023c87b
ER
3806@@ -1038,11 +1076,14 @@
3807 ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
3808 ut_a(block->page.buf_fix_count > 0);
3809
3810+ /* buf_flush_note_modification() should be called before this function. */
3811+/*
3812 if (rw_latch == RW_X_LATCH && mtr->modifications) {
3813 buf_pool_mutex_enter();
3814 buf_flush_note_modification(block, mtr);
3815 buf_pool_mutex_exit();
d4e9320e 3816 }
d4e9320e 3817+*/
7023c87b
ER
3818
3819 mutex_enter(&block->mutex);
3820
3821diff -ruN a/storage/innodb_plugin/include/buf0flu.ic b/storage/innodb_plugin/include/buf0flu.ic
3822--- a/storage/innodb_plugin/include/buf0flu.ic 2010-08-04 02:24:19.000000000 +0900
3823+++ b/storage/innodb_plugin/include/buf0flu.ic 2010-08-27 16:11:40.625993554 +0900
3824@@ -55,13 +55,23 @@
3825 buf_block_t* block, /*!< in: block which is modified */
3826 mtr_t* mtr) /*!< in: mtr */
3827 {
3828+ ibool use_LRU_mutex = FALSE;
d4e9320e 3829+
7023c87b
ER
3830+ if (UT_LIST_GET_LEN(buf_pool->unzip_LRU))
3831+ use_LRU_mutex = TRUE;
d4e9320e 3832+
7023c87b
ER
3833+ if (use_LRU_mutex)
3834+ mutex_enter(&LRU_list_mutex);
d4e9320e 3835+
7023c87b
ER
3836+ mutex_enter(&block->mutex);
3837+
3838 ut_ad(block);
3839 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
3840 ut_ad(block->page.buf_fix_count > 0);
3841 #ifdef UNIV_SYNC_DEBUG
3842 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
3843 #endif /* UNIV_SYNC_DEBUG */
3844- ut_ad(buf_pool_mutex_own());
3845+ //ut_ad(buf_pool_mutex_own());
3846
3847 ut_ad(mtr->start_lsn != 0);
3848 ut_ad(mtr->modifications);
3849@@ -70,16 +80,23 @@
3850 block->page.newest_modification = mtr->end_lsn;
3851
3852 if (!block->page.oldest_modification) {
3853+ mutex_enter(&flush_list_mutex);
3854
3855 block->page.oldest_modification = mtr->start_lsn;
3856 ut_ad(block->page.oldest_modification != 0);
3857
3858 buf_flush_insert_into_flush_list(block);
3859+ mutex_exit(&flush_list_mutex);
3860 } else {
3861 ut_ad(block->page.oldest_modification <= mtr->start_lsn);
3862 }
3863
3864+ mutex_exit(&block->mutex);
d4e9320e 3865+
7023c87b 3866 ++srv_buf_pool_write_requests;
d4e9320e 3867+
7023c87b
ER
3868+ if (use_LRU_mutex)
3869+ mutex_exit(&LRU_list_mutex);
3870 }
3871
3872 /********************************************************************//**
3873@@ -94,6 +111,16 @@
3874 ib_uint64_t end_lsn) /*!< in: end lsn of the last mtr in the
3875 set of mtr's */
3876 {
3877+ ibool use_LRU_mutex = FALSE;
3878+
3879+ if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
3880+ use_LRU_mutex = TRUE;
3881+
3882+ if (use_LRU_mutex)
3883+ mutex_enter(&LRU_list_mutex);
3884+
3885+ mutex_enter(&(block->mutex));
3886+
3887 ut_ad(block);
3888 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
3889 ut_ad(block->page.buf_fix_count > 0);
3890@@ -101,23 +128,28 @@
3891 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
3892 #endif /* UNIV_SYNC_DEBUG */
3893
3894- buf_pool_mutex_enter();
3895+ //buf_pool_mutex_enter();
3896
3897 ut_ad(block->page.newest_modification <= end_lsn);
3898
3899 block->page.newest_modification = end_lsn;
3900
3901 if (!block->page.oldest_modification) {
3902+ mutex_enter(&flush_list_mutex);
3903
3904 block->page.oldest_modification = start_lsn;
3905
3906 ut_ad(block->page.oldest_modification != 0);
3907
3908 buf_flush_insert_sorted_into_flush_list(block);
3909+ mutex_exit(&flush_list_mutex);
3910 } else {
3911 ut_ad(block->page.oldest_modification <= start_lsn);
3912 }
3913
3914- buf_pool_mutex_exit();
3915+ //buf_pool_mutex_exit();
3916+ if (use_LRU_mutex)
3917+ mutex_exit(&LRU_list_mutex);
3918+ mutex_exit(&(block->mutex));
3919 }
d4e9320e 3920 #endif /* !UNIV_HOTBACKUP */
7023c87b
ER
3921diff -ruN a/storage/innodb_plugin/include/buf0lru.h b/storage/innodb_plugin/include/buf0lru.h
3922--- a/storage/innodb_plugin/include/buf0lru.h 2010-08-04 02:24:19.000000000 +0900
3923+++ b/storage/innodb_plugin/include/buf0lru.h 2010-08-27 16:11:40.627990038 +0900
3924@@ -112,10 +112,11 @@
d4e9320e
AM
3925 buf_page_t* bpage, /*!< in: block to be freed */
3926 ibool zip, /*!< in: TRUE if should remove also the
3927 compressed page of an uncompressed page */
3928- ibool* buf_pool_mutex_released);
3929+ ibool* buf_pool_mutex_released,
3930 /*!< in: pointer to a variable that will
7023c87b 3931 be assigned TRUE if buf_pool_mutex
d4e9320e
AM
3932 was temporarily released, or NULL */
3933+ ibool have_LRU_mutex);
3934 /******************************************************************//**
3935 Try to free a replaceable block.
3936 @return TRUE if found and freed */
7023c87b 3937@@ -157,7 +158,8 @@
d4e9320e
AM
3938 void
3939 buf_LRU_block_free_non_file_page(
3940 /*=============================*/
3941- buf_block_t* block); /*!< in: block, must not contain a file page */
3942+ buf_block_t* block, /*!< in: block, must not contain a file page */
3943+ ibool have_page_hash_mutex);
3944 /******************************************************************//**
3945 Adds a block to the LRU list. */
3946 UNIV_INTERN
7023c87b
ER
3947diff -ruN a/storage/innodb_plugin/include/sync0sync.h b/storage/innodb_plugin/include/sync0sync.h
3948--- a/storage/innodb_plugin/include/sync0sync.h 2010-08-04 02:24:19.000000000 +0900
3949+++ b/storage/innodb_plugin/include/sync0sync.h 2010-08-27 16:11:40.628990180 +0900
3950@@ -487,8 +487,14 @@
d4e9320e
AM
3951 SYNC_SEARCH_SYS, as memory allocation
3952 can call routines there! Otherwise
3953 the level is SYNC_MEM_HASH. */
7023c87b
ER
3954+#define SYNC_BUF_LRU_LIST 157
3955+#define SYNC_BUF_PAGE_HASH 156
3956+#define SYNC_BUF_BLOCK 155
3957+#define SYNC_BUF_FREE_LIST 153
3958+#define SYNC_BUF_ZIP_FREE 152
3959+#define SYNC_BUF_ZIP_HASH 151
3960 #define SYNC_BUF_POOL 150
3961-#define SYNC_BUF_BLOCK 149
3962+#define SYNC_BUF_FLUSH_LIST 149
d4e9320e
AM
3963 #define SYNC_DOUBLEWRITE 140
3964 #define SYNC_ANY_LATCH 135
7023c87b
ER
3965 #define SYNC_THR_LOCAL 133
3966@@ -519,7 +525,7 @@
d4e9320e
AM
3967 os_fast_mutex; /*!< We use this OS mutex in place of lock_word
3968 when atomic operations are not enabled */
3969 #endif
3970- ulint waiters; /*!< This ulint is set to 1 if there are (or
3971+ volatile ulint waiters; /*!< This ulint is set to 1 if there are (or
3972 may be) threads waiting in the global wait
3973 array for this mutex to be released.
3974 Otherwise, this is 0. */
7023c87b
ER
3975diff -ruN a/storage/innodb_plugin/mtr/mtr0mtr.c b/storage/innodb_plugin/mtr/mtr0mtr.c
3976--- a/storage/innodb_plugin/mtr/mtr0mtr.c 2010-08-04 02:24:20.000000000 +0900
3977+++ b/storage/innodb_plugin/mtr/mtr0mtr.c 2010-08-27 16:11:40.631020912 +0900
3978@@ -105,6 +105,38 @@
3979 }
3980 }
3981
3982+UNIV_INLINE
3983+void
3984+mtr_memo_note_modification_all(
3985+/*===========================*/
3986+ mtr_t* mtr) /* in: mtr */
3987+{
3988+ mtr_memo_slot_t* slot;
3989+ dyn_array_t* memo;
3990+ ulint offset;
3991+
3992+ ut_ad(mtr);
3993+ ut_ad(mtr->magic_n == MTR_MAGIC_N);
3994+ ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
3995+ commit */
3996+ ut_ad(mtr->modifications);
3997+
3998+ memo = &(mtr->memo);
3999+
4000+ offset = dyn_array_get_data_size(memo);
4001+
4002+ while (offset > 0) {
4003+ offset -= sizeof(mtr_memo_slot_t);
4004+ slot = dyn_array_get_element(memo, offset);
4005+
4006+ if (UNIV_LIKELY(slot->object != NULL) &&
4007+ slot->type == MTR_MEMO_PAGE_X_FIX) {
4008+ buf_flush_note_modification(
4009+ (buf_block_t*)slot->object, mtr);
4010+ }
4011+ }
4012+}
4013+
4014 /************************************************************//**
4015 Writes the contents of a mini-transaction log, if any, to the database log. */
4016 static
4017@@ -188,6 +220,8 @@
4018
4019 if (write_log) {
4020 mtr_log_reserve_and_write(mtr);
4021+
4022+ mtr_memo_note_modification_all(mtr);
4023 }
4024
4025 /* We first update the modification info to buffer pages, and only
4026@@ -198,11 +232,13 @@
4027 required when we insert modified buffer pages in to the flush list
4028 which must be sorted on oldest_modification. */
4029
4030- mtr_memo_pop_all(mtr);
4031-
4032 if (write_log) {
4033 log_release();
4034 }
4035+
4036+ /* All unlocking has been moved here, after log_sys mutex release. */
4037+ mtr_memo_pop_all(mtr);
4038+
4039 #endif /* !UNIV_HOTBACKUP */
4040
4041 ut_d(mtr->state = MTR_COMMITTED);
4042@@ -273,6 +309,12 @@
4043 slot = dyn_array_get_element(memo, offset);
4044
4045 if ((object == slot->object) && (type == slot->type)) {
4046+ if (mtr->modifications &&
4047+ UNIV_LIKELY(slot->object != NULL) &&
4048+ slot->type == MTR_MEMO_PAGE_X_FIX) {
4049+ buf_flush_note_modification(
4050+ (buf_block_t*)slot->object, mtr);
4051+ }
4052
4053 mtr_memo_slot_release(mtr, slot);
4054
4055diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
4056--- a/storage/innodb_plugin/srv/srv0srv.c 2010-08-27 16:11:12.194989878 +0900
4057+++ b/storage/innodb_plugin/srv/srv0srv.c 2010-08-27 16:11:40.634022489 +0900
4058@@ -2829,7 +2829,7 @@
4059
4060 mutex_exit(&(log_sys->mutex));
4061
4062- buf_pool_mutex_enter();
4063+ mutex_enter(&flush_list_mutex);
4064
4065 level = 0;
4066 bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
4067@@ -2851,7 +2851,7 @@
4068 bpl = 0;
d4e9320e 4069 }
7023c87b
ER
4070
4071- buf_pool_mutex_exit();
4072+ mutex_exit(&flush_list_mutex);
4073
4074 if (!srv_use_doublewrite_buf) {
4075 /* flush is faster than when doublewrite */
4076diff -ruN a/storage/innodb_plugin/sync/sync0sync.c b/storage/innodb_plugin/sync/sync0sync.c
4077--- a/storage/innodb_plugin/sync/sync0sync.c 2010-08-04 02:24:20.000000000 +0900
4078+++ b/storage/innodb_plugin/sync/sync0sync.c 2010-08-27 16:11:40.636021261 +0900
4079@@ -254,7 +254,7 @@
d4e9320e
AM
4080 mutex->lock_word = 0;
4081 #endif
4082 mutex->event = os_event_create(NULL);
4083- mutex_set_waiters(mutex, 0);
4084+ mutex->waiters = 0;
4085 #ifdef UNIV_DEBUG
4086 mutex->magic_n = MUTEX_MAGIC_N;
4087 #endif /* UNIV_DEBUG */
7023c87b 4088@@ -432,6 +432,15 @@
d4e9320e
AM
4089 mutex_t* mutex, /*!< in: mutex */
4090 ulint n) /*!< in: value to set */
4091 {
4092+#ifdef INNODB_RW_LOCKS_USE_ATOMICS
4093+ ut_ad(mutex);
4094+
4095+ if (n) {
4096+ os_compare_and_swap_ulint(&mutex->waiters, 0, 1);
4097+ } else {
4098+ os_compare_and_swap_ulint(&mutex->waiters, 1, 0);
4099+ }
4100+#else
4101 volatile ulint* ptr; /* declared volatile to ensure that
4102 the value is stored to memory */
4103 ut_ad(mutex);
7023c87b 4104@@ -440,6 +449,7 @@
d4e9320e
AM
4105
4106 *ptr = n; /* Here we assume that the write of a single
4107 word in memory is atomic */
4108+#endif
4109 }
4110
4111 /******************************************************************//**
7023c87b
ER
4112@@ -1153,6 +1163,12 @@
4113 case SYNC_TRX_SYS_HEADER:
4114 case SYNC_FILE_FORMAT_TAG:
4115 case SYNC_DOUBLEWRITE:
d4e9320e 4116+ case SYNC_BUF_LRU_LIST:
7023c87b 4117+ case SYNC_BUF_FLUSH_LIST:
d4e9320e
AM
4118+ case SYNC_BUF_PAGE_HASH:
4119+ case SYNC_BUF_FREE_LIST:
4120+ case SYNC_BUF_ZIP_FREE:
4121+ case SYNC_BUF_ZIP_HASH:
4122 case SYNC_BUF_POOL:
7023c87b
ER
4123 case SYNC_SEARCH_SYS:
4124 case SYNC_SEARCH_SYS_CONF:
4125@@ -1181,7 +1197,7 @@
d4e9320e
AM
4126 buffer block (block->mutex or buf_pool_zip_mutex). */
4127 if (!sync_thread_levels_g(array, level, FALSE)) {
4128 ut_a(sync_thread_levels_g(array, level - 1, TRUE));
4129- ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
7023c87b 4130+ ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
d4e9320e
AM
4131 }
4132 break;
4133 case SYNC_REC_LOCK:
This page took 0.655646 seconds and 4 git commands to generate.