Commit 0d83304c7e7bd3b05be90281b3a47841bc8f057a
Committed by
Linus Torvalds
1 parent
8111d1b552
Exists in
master
and in
7 other branches
pm: hibernation: simplify memory bitmap
This patch simplifies the memory bitmap manipulations. - remove the member size in struct bm_block It is not necessary for struct bm_block to have the number of bit chunks that can be calculated by using end_pfn and start_pfn. - use find_next_bit() for memory_bm_next_pfn No need to invent the bitmap library only for the memory bitmap. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 21 additions and 67 deletions Side-by-side Diff
kernel/power/snapshot.c
... | ... | @@ -205,8 +205,7 @@ |
205 | 205 | * objects. The main list's elements are of type struct zone_bitmap |
206 | 206 | * and each of them corresonds to one zone. For each zone bitmap |
207 | 207 | * object there is a list of objects of type struct bm_block that |
208 | - * represent each blocks of bit chunks in which information is | |
209 | - * stored. | |
208 | + * represent each blocks of bitmap in which information is stored. | |
210 | 209 | * |
211 | 210 | * struct memory_bitmap contains a pointer to the main list of zone |
212 | 211 | * bitmap objects, a struct bm_position used for browsing the bitmap, |
213 | 212 | |
214 | 213 | |
215 | 214 | |
... | ... | @@ -224,26 +223,27 @@ |
224 | 223 | * pfns that correspond to the start and end of the represented zone. |
225 | 224 | * |
226 | 225 | * struct bm_block contains a pointer to the memory page in which |
227 | - * information is stored (in the form of a block of bit chunks | |
228 | - * of type unsigned long each). It also contains the pfns that | |
229 | - * correspond to the start and end of the represented memory area and | |
230 | - * the number of bit chunks in the block. | |
226 | + * information is stored (in the form of a block of bitmap) | |
227 | + * It also contains the pfns that correspond to the start and end of | |
228 | + * the represented memory area. | |
231 | 229 | */ |
232 | 230 | |
233 | 231 | #define BM_END_OF_MAP (~0UL) |
234 | 232 | |
235 | -#define BM_CHUNKS_PER_BLOCK (PAGE_SIZE / sizeof(long)) | |
236 | -#define BM_BITS_PER_CHUNK (sizeof(long) << 3) | |
237 | 233 | #define BM_BITS_PER_BLOCK (PAGE_SIZE << 3) |
238 | 234 | |
239 | 235 | struct bm_block { |
240 | 236 | struct bm_block *next; /* next element of the list */ |
241 | 237 | unsigned long start_pfn; /* pfn represented by the first bit */ |
242 | 238 | unsigned long end_pfn; /* pfn represented by the last bit plus 1 */ |
243 | - unsigned int size; /* number of bit chunks */ | |
244 | - unsigned long *data; /* chunks of bits representing pages */ | |
239 | + unsigned long *data; /* bitmap representing pages */ | |
245 | 240 | }; |
246 | 241 | |
242 | +static inline unsigned long bm_block_bits(struct bm_block *bb) | |
243 | +{ | |
244 | + return bb->end_pfn - bb->start_pfn; | |
245 | +} | |
246 | + | |
247 | 247 | struct zone_bitmap { |
248 | 248 | struct zone_bitmap *next; /* next element of the list */ |
249 | 249 | unsigned long start_pfn; /* minimal pfn in this zone */ |
... | ... | @@ -257,7 +257,6 @@ |
257 | 257 | struct bm_position { |
258 | 258 | struct zone_bitmap *zone_bm; |
259 | 259 | struct bm_block *block; |
260 | - int chunk; | |
261 | 260 | int bit; |
262 | 261 | }; |
263 | 262 | |
... | ... | @@ -272,12 +271,6 @@ |
272 | 271 | |
273 | 272 | /* Functions that operate on memory bitmaps */ |
274 | 273 | |
275 | -static inline void memory_bm_reset_chunk(struct memory_bitmap *bm) | |
276 | -{ | |
277 | - bm->cur.chunk = 0; | |
278 | - bm->cur.bit = -1; | |
279 | -} | |
280 | - | |
281 | 274 | static void memory_bm_position_reset(struct memory_bitmap *bm) |
282 | 275 | { |
283 | 276 | struct zone_bitmap *zone_bm; |
... | ... | @@ -285,7 +278,7 @@ |
285 | 278 | zone_bm = bm->zone_bm_list; |
286 | 279 | bm->cur.zone_bm = zone_bm; |
287 | 280 | bm->cur.block = zone_bm->bm_blocks; |
288 | - memory_bm_reset_chunk(bm); | |
281 | + bm->cur.bit = 0; | |
289 | 282 | } |
290 | 283 | |
291 | 284 | static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free); |
292 | 285 | |
... | ... | @@ -394,12 +387,10 @@ |
394 | 387 | bb->start_pfn = pfn; |
395 | 388 | if (nr >= BM_BITS_PER_BLOCK) { |
396 | 389 | pfn += BM_BITS_PER_BLOCK; |
397 | - bb->size = BM_CHUNKS_PER_BLOCK; | |
398 | 390 | nr -= BM_BITS_PER_BLOCK; |
399 | 391 | } else { |
400 | 392 | /* This is executed only once in the loop */ |
401 | 393 | pfn += nr; |
402 | - bb->size = DIV_ROUND_UP(nr, BM_BITS_PER_CHUNK); | |
403 | 394 | } |
404 | 395 | bb->end_pfn = pfn; |
405 | 396 | bb = bb->next; |
... | ... | @@ -478,8 +469,8 @@ |
478 | 469 | } |
479 | 470 | zone_bm->cur_block = bb; |
480 | 471 | pfn -= bb->start_pfn; |
481 | - *bit_nr = pfn % BM_BITS_PER_CHUNK; | |
482 | - *addr = bb->data + pfn / BM_BITS_PER_CHUNK; | |
472 | + *bit_nr = pfn; | |
473 | + *addr = bb->data; | |
483 | 474 | return 0; |
484 | 475 | } |
485 | 476 | |
... | ... | @@ -528,36 +519,6 @@ |
528 | 519 | return test_bit(bit, addr); |
529 | 520 | } |
530 | 521 | |
531 | -/* Two auxiliary functions for memory_bm_next_pfn */ | |
532 | - | |
533 | -/* Find the first set bit in the given chunk, if there is one */ | |
534 | - | |
535 | -static inline int next_bit_in_chunk(int bit, unsigned long *chunk_p) | |
536 | -{ | |
537 | - bit++; | |
538 | - while (bit < BM_BITS_PER_CHUNK) { | |
539 | - if (test_bit(bit, chunk_p)) | |
540 | - return bit; | |
541 | - | |
542 | - bit++; | |
543 | - } | |
544 | - return -1; | |
545 | -} | |
546 | - | |
547 | -/* Find a chunk containing some bits set in given block of bits */ | |
548 | - | |
549 | -static inline int next_chunk_in_block(int n, struct bm_block *bb) | |
550 | -{ | |
551 | - n++; | |
552 | - while (n < bb->size) { | |
553 | - if (bb->data[n]) | |
554 | - return n; | |
555 | - | |
556 | - n++; | |
557 | - } | |
558 | - return -1; | |
559 | -} | |
560 | - | |
561 | 522 | /** |
562 | 523 | * memory_bm_next_pfn - find the pfn that corresponds to the next set bit |
563 | 524 | * in the bitmap @bm. If the pfn cannot be found, BM_END_OF_MAP is |
564 | 525 | |
565 | 526 | |
566 | 527 | |
567 | 528 | |
568 | 529 | |
569 | 530 | |
... | ... | @@ -571,40 +532,33 @@ |
571 | 532 | { |
572 | 533 | struct zone_bitmap *zone_bm; |
573 | 534 | struct bm_block *bb; |
574 | - int chunk; | |
575 | 535 | int bit; |
576 | 536 | |
577 | 537 | do { |
578 | 538 | bb = bm->cur.block; |
579 | 539 | do { |
580 | - chunk = bm->cur.chunk; | |
581 | 540 | bit = bm->cur.bit; |
582 | - do { | |
583 | - bit = next_bit_in_chunk(bit, bb->data + chunk); | |
584 | - if (bit >= 0) | |
585 | - goto Return_pfn; | |
541 | + bit = find_next_bit(bb->data, bm_block_bits(bb), bit); | |
542 | + if (bit < bm_block_bits(bb)) | |
543 | + goto Return_pfn; | |
586 | 544 | |
587 | - chunk = next_chunk_in_block(chunk, bb); | |
588 | - bit = -1; | |
589 | - } while (chunk >= 0); | |
590 | 545 | bb = bb->next; |
591 | 546 | bm->cur.block = bb; |
592 | - memory_bm_reset_chunk(bm); | |
547 | + bm->cur.bit = 0; | |
593 | 548 | } while (bb); |
594 | 549 | zone_bm = bm->cur.zone_bm->next; |
595 | 550 | if (zone_bm) { |
596 | 551 | bm->cur.zone_bm = zone_bm; |
597 | 552 | bm->cur.block = zone_bm->bm_blocks; |
598 | - memory_bm_reset_chunk(bm); | |
553 | + bm->cur.bit = 0; | |
599 | 554 | } |
600 | 555 | } while (zone_bm); |
601 | 556 | memory_bm_position_reset(bm); |
602 | 557 | return BM_END_OF_MAP; |
603 | 558 | |
604 | 559 | Return_pfn: |
605 | - bm->cur.chunk = chunk; | |
606 | - bm->cur.bit = bit; | |
607 | - return bb->start_pfn + chunk * BM_BITS_PER_CHUNK + bit; | |
560 | + bm->cur.bit = bit + 1; | |
561 | + return bb->start_pfn + bit; | |
608 | 562 | } |
609 | 563 | |
610 | 564 | /** |