| #!/bin/sh -e |
| |
| CHUNK_HDR_SIZE=32 |
| CHUNK_MIN_ALLOC=8 |
| |
| ALLOCATOR_START=0x400008000000 # Hex addr |
| ALLOCATOR_SIZE=134217728 |
| |
| SSH="ssh root@127.0.0.1 -p 2222" |
| DEBUGFS="/sys/kernel/debug/" |
| BC=$(which bc) |
| |
| calc() |
| { |
| echo "$@" | $BC |
| } |
| |
| dec_to_hex() |
| { |
| printf "%x\n" $1 |
| } |
| |
| hex_to_dec() |
| { |
| printf "%d\n" $1 |
| } |
| |
| alloc() |
| { |
| $SSH "echo $1 > $DEBUGFS/hyp_alloc" |
| } |
| |
| free() |
| { |
| local addr=$(calc $(hex_to_dec $ALLOCATOR_START)+$1) |
| |
| $SSH "echo $(dec_to_hex $addr) > $DEBUGFS/hyp_free" |
| } |
| |
| reclaim() |
| { |
| $SSH "echo $(calc $ALLOCATOR_SIZE/4096) > $DEBUGFS/hyp_reclaim" |
| } |
| |
| dump() |
| { |
| $SSH "cat /sys//kernel/debug/dump_hyp_allocator" |
| } |
| |
| log_and_die() |
| { |
| echo "ERROR: $@" |
| dump |
| exit 1 |
| } |
| |
| test_end() |
| { |
| DUMP=$(dump) |
| |
| [ -z $DUMP ] || log_and_die "Allocator not empty" |
| } |
| |
| run() |
| { |
| echo "Run $1...." |
| eval $1 |
| test_end |
| echo ".... Passed" |
| } |
| |
| test_allocator_bounds() |
| { |
| alloc $(calc $ALLOCATOR_SIZE-$CHUNK_HDR_SIZE) |
| alloc 48 || true ## expected to fail |
| free $CHUNK_HDR_SIZE |
| reclaim |
| alloc $ALLOCATOR_SIZE || true |
| } |
| |
| test_discontiguous_mapped_regions() |
| { |
| alloc 8192 # Also tests the min distance to the page start |
| alloc 48 |
| free $CHUNK_HDR_SIZE |
| reclaim |
| free $(calc 8192+$CHUNK_HDR_SIZE+8+$CHUNK_HDR_SIZE) |
| reclaim |
| } |
| |
| test_no_reclaimable_pages() |
| { |
| alloc 4096 # Also tests the min distance to the page start |
| alloc 48 |
| free $CHUNK_HDR_SIZE |
| reclaim # Should not reclaim anything |
| free $(calc 4096+$CHUNK_HDR_SIZE+8+$CHUNK_HDR_SIZE) |
| reclaim |
| } |
| |
| test_recycle_split() |
| { |
| alloc 4096 |
| alloc 48 |
| free $CHUNK_HDR_SIZE |
| alloc 2048 # Split the first chunk |
| alloc 2016 # no split due to the distance with the page start |
| free $CHUNK_HDR_SIZE |
| alloc 2040 # no split due to distance with the following chunk |
| free $(calc 4096+$CHUNK_HDR_SIZE+8+$CHUNK_HDR_SIZE) |
| free $(calc 2048+$CHUNK_HDR_SIZE+$CHUNK_HDR_SIZE) |
| free $CHUNK_HDR_SIZE |
| reclaim |
| } |
| |
| test_merge_updown() |
| { |
| alloc 48 |
| alloc 48 |
| alloc 48 |
| free $CHUNK_HDR_SIZE |
| free $CHUNK_HDR_SIZE+48+$CHUNK_HDR_SIZE+48+$CHUNK_HDR_SIZE |
| free $CHUNK_HDR_SIZE+48+$CHUNK_HDR_SIZE |
| reclaim |
| } |
| |
| test_aligned_chunks() |
| { |
| alloc $(calc 4096-$CHUNK_HDR_SIZE) # chunk1 |
| alloc $(calc "2*4096-$CHUNK_HDR_SIZE") # chunk2 |
| alloc 64 # chunk3 |
| free 4096+$CHUNK_HDR_SIZE # free chunk2 |
| reclaim # Should reclaim only one page from chunk2 |
| alloc 64 # Should be the new chunk2 |
| free 4096+$CHUNK_HDR_SIZE # free chunk2 |
| free $CHUNK_HDR_SIZE |
| free "3*4096+$CHUNK_HDR_SIZE" |
| reclaim |
| } |
| |
| run test_allocator_bounds |
| run test_discontiguous_mapped_regions |
| run test_no_reclaimable_pages |
| run test_recycle_split |
| run test_merge_updown |
| run test_aligned_chunks |