The principle function for freeing pages is __free_pages_ok(). It should not be called directly, instead the function __free_pages() should be used which does some simple checks first. See Figure 6.4 for its call graph.
When a buddy is freed, Linux tries to coalesce the buddies together immediately if possible. This is not the best method as the worst case scenario will have many coalescing followed by the immediate splitting of the same blocks[#!vahalia96!#]. At time of writing, work is taking place on implementing a lazy buddy coalescing scheme[#!barkley89!#].
To detect if if the buddies can be merged or not, Linux checks the bit from
the free_areamap to determine the state of the buddy. As
the buddy has just been freed, it is that at least one is definitely
free because a buddy has just been freed. If after toggling the bit it is 0,
then the buddies can be merged.
Calculating the address is a well known concept [#!knuth68!#]. Because the
allocations are always in blocks of size 2, the address of the block,
or at least its offset within zone_mem_map will also be a
power of 2
. The end result is that there will always be at least k
number of zeros to the right of the address. To get the address of the buddy,
the kth bit from the right is examined. If it is 0, then the buddy
will have this bit flipped. To get this bit, Linux creates a mask
which is calculated as
The mask we are interested in is
Linux takes a shortcut in calculating this by noting that
Once the buddy is merged, it is removed for the free list and the newly coalesced pair moves to the next higher order to see if it may also be merged.