Commit 0d83304c7e7bd3b05be90281b3a47841bc8f057a

Authored by Akinobu Mita
Committed by Linus Torvalds
1 parent 8111d1b552

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