On Saturday, 5 of July 2008, Akinobu Mita wrote: > 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. Thanks for doing this change, it looks OK. I haven't have the time to test it yet, but once it's been tested, I'll push it to Andrew for merging. I'll fold patch 1/2 into this one. Thanks, Rafael > Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx> > Cc: Pavel Machek <pavel@xxxxxxx> > Cc: Rafael J. Wysocki <rjw@xxxxxxx> > Cc: linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx > --- > kernel/power/snapshot.c | 84 ++++++++++-------------------------------------- > 1 file changed, 19 insertions(+), 65 deletions(-) > > Index: 2.6-git/kernel/power/snapshot.c > =================================================================== > --- 2.6-git.orig/kernel/power/snapshot.c > +++ 2.6-git/kernel/power/snapshot.c > @@ -205,8 +205,7 @@ static void chain_free(struct chain_allo > * objects. The main list's elements are of type struct zone_bitmap > * and each of them corresonds to one zone. For each zone bitmap > * object there is a list of objects of type struct bm_block that > - * represent each blocks of bit chunks in which information is > - * stored. > + * represent each blocks of bitmap in which information is stored. > * > * struct memory_bitmap contains a pointer to the main list of zone > * bitmap objects, a struct bm_position used for browsing the bitmap, > @@ -224,26 +223,27 @@ static void chain_free(struct chain_allo > * pfns that correspond to the start and end of the represented zone. > * > * struct bm_block contains a pointer to the memory page in which > - * information is stored (in the form of a block of bit chunks > - * of type unsigned long each). It also contains the pfns that > - * correspond to the start and end of the represented memory area and > - * the number of bit chunks in the block. > + * information is stored (in the form of a block of bitmap) > + * It also contains the pfns that correspond to the start and end of > + * the represented memory area. > */ > > #define BM_END_OF_MAP (~0UL) > > -#define BM_CHUNKS_PER_BLOCK (PAGE_SIZE / sizeof(long)) > -#define BM_BITS_PER_CHUNK (sizeof(long) << 3) > #define BM_BITS_PER_BLOCK (PAGE_SIZE << 3) > > struct bm_block { > struct bm_block *next; /* next element of the list */ > unsigned long start_pfn; /* pfn represented by the first bit */ > unsigned long end_pfn; /* pfn represented by the last bit plus 1 */ > - unsigned int size; /* number of bit chunks */ > - unsigned long *data; /* chunks of bits representing pages */ > + unsigned long *data; /* bitmap representing pages */ > }; > > +static inline unsigned long bm_block_bits(struct bm_block *bb) > +{ > + return bb->end_pfn - bb->start_pfn; > +} > + > struct zone_bitmap { > struct zone_bitmap *next; /* next element of the list */ > unsigned long start_pfn; /* minimal pfn in this zone */ > @@ -257,7 +257,6 @@ struct zone_bitmap { > struct bm_position { > struct zone_bitmap *zone_bm; > struct bm_block *block; > - int chunk; > int bit; > }; > > @@ -272,12 +271,6 @@ struct memory_bitmap { > > /* Functions that operate on memory bitmaps */ > > -static inline void memory_bm_reset_chunk(struct memory_bitmap *bm) > -{ > - bm->cur.chunk = 0; > - bm->cur.bit = -1; > -} > - > static void memory_bm_position_reset(struct memory_bitmap *bm) > { > struct zone_bitmap *zone_bm; > @@ -285,7 +278,7 @@ static void memory_bm_position_reset(str > zone_bm = bm->zone_bm_list; > bm->cur.zone_bm = zone_bm; > bm->cur.block = zone_bm->bm_blocks; > - memory_bm_reset_chunk(bm); > + bm->cur.bit = 0; > } > > static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free); > @@ -394,12 +387,10 @@ memory_bm_create(struct memory_bitmap *b > bb->start_pfn = pfn; > if (nr >= BM_BITS_PER_BLOCK) { > pfn += BM_BITS_PER_BLOCK; > - bb->size = BM_CHUNKS_PER_BLOCK; > nr -= BM_BITS_PER_BLOCK; > } else { > /* This is executed only once in the loop */ > pfn += nr; > - bb->size = DIV_ROUND_UP(nr, BM_BITS_PER_CHUNK); > } > bb->end_pfn = pfn; > bb = bb->next; > @@ -528,36 +519,6 @@ static int memory_bm_test_bit(struct mem > return test_bit(bit, addr); > } > > -/* Two auxiliary functions for memory_bm_next_pfn */ > - > -/* Find the first set bit in the given chunk, if there is one */ > - > -static inline int next_bit_in_chunk(int bit, unsigned long *chunk_p) > -{ > - bit++; > - while (bit < BM_BITS_PER_CHUNK) { > - if (test_bit(bit, chunk_p)) > - return bit; > - > - bit++; > - } > - return -1; > -} > - > -/* Find a chunk containing some bits set in given block of bits */ > - > -static inline int next_chunk_in_block(int n, struct bm_block *bb) > -{ > - n++; > - while (n < bb->size) { > - if (bb->data[n]) > - return n; > - > - n++; > - } > - return -1; > -} > - > /** > * memory_bm_next_pfn - find the pfn that corresponds to the next set bit > * in the bitmap @bm. If the pfn cannot be found, BM_END_OF_MAP is > @@ -571,40 +532,33 @@ static unsigned long memory_bm_next_pfn( > { > struct zone_bitmap *zone_bm; > struct bm_block *bb; > - int chunk; > int bit; > > do { > bb = bm->cur.block; > do { > - chunk = bm->cur.chunk; > bit = bm->cur.bit; > - do { > - bit = next_bit_in_chunk(bit, bb->data + chunk); > - if (bit >= 0) > - goto Return_pfn; > - > - chunk = next_chunk_in_block(chunk, bb); > - bit = -1; > - } while (chunk >= 0); > + bit = find_next_bit(bb->data, bm_block_bits(bb), bit); > + if (bit < bm_block_bits(bb)) > + goto Return_pfn; > + > bb = bb->next; > bm->cur.block = bb; > - memory_bm_reset_chunk(bm); > + bm->cur.bit = 0; > } while (bb); > zone_bm = bm->cur.zone_bm->next; > if (zone_bm) { > bm->cur.zone_bm = zone_bm; > bm->cur.block = zone_bm->bm_blocks; > - memory_bm_reset_chunk(bm); > + bm->cur.bit = 0; > } > } while (zone_bm); > memory_bm_position_reset(bm); > return BM_END_OF_MAP; > > Return_pfn: > - bm->cur.chunk = chunk; > - bm->cur.bit = bit; > - return bb->start_pfn + chunk * BM_BITS_PER_CHUNK + bit; > + bm->cur.bit = bit + 1; > + return bb->start_pfn + bit; > } > > /** > > _______________________________________________ linux-pm mailing list linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/linux-pm