Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memblock tests: add tests for memblock_trim_memory

Add tests for memblock_trim_memory() for the following scenarios:
- all regions aligned
- one unaligned region that is smaller than the alignment
- one unaligned region that is unaligned at the base
- one unaligned region that is unaligned at the end

Reviewed-by: Shaoqin Huang <shaoqin.huang@intel.com>
Signed-off-by: Rebecca Mckeever <remckee0@gmail.com>
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Link: https://lore.kernel.org/r/0e5f55154a3b66581e04ba3717978795cbc08a5b.1661578349.git.remckee0@gmail.com

authored by

Rebecca Mckeever and committed by
Mike Rapoport
dcd45ad2 a541c6d4

+223
+223
tools/testing/memblock/tests/basic_api.c
··· 8 8 #define FUNC_RESERVE "memblock_reserve" 9 9 #define FUNC_REMOVE "memblock_remove" 10 10 #define FUNC_FREE "memblock_free" 11 + #define FUNC_TRIM "memblock_trim_memory" 11 12 12 13 static int memblock_initialization_check(void) 13 14 { ··· 1724 1723 return 0; 1725 1724 } 1726 1725 1726 + /* 1727 + * A test that tries to trim memory when both ends of the memory region are 1728 + * aligned. Expect that the memory will not be trimmed. Expect the counter to 1729 + * not be updated. 1730 + */ 1731 + static int memblock_trim_memory_aligned_check(void) 1732 + { 1733 + struct memblock_region *rgn; 1734 + const phys_addr_t alignment = SMP_CACHE_BYTES; 1735 + 1736 + rgn = &memblock.memory.regions[0]; 1737 + 1738 + struct region r = { 1739 + .base = alignment, 1740 + .size = alignment * 4 1741 + }; 1742 + 1743 + PREFIX_PUSH(); 1744 + 1745 + reset_memblock_regions(); 1746 + memblock_add(r.base, r.size); 1747 + memblock_trim_memory(alignment); 1748 + 1749 + ASSERT_EQ(rgn->base, r.base); 1750 + ASSERT_EQ(rgn->size, r.size); 1751 + 1752 + ASSERT_EQ(memblock.memory.cnt, 1); 1753 + 1754 + test_pass_pop(); 1755 + 1756 + return 0; 1757 + } 1758 + 1759 + /* 1760 + * A test that tries to trim memory when there are two available regions, r1 and 1761 + * r2. Region r1 is aligned on both ends and region r2 is unaligned on one end 1762 + * and smaller than the alignment: 1763 + * 1764 + * alignment 1765 + * |--------| 1766 + * | +-----------------+ +------+ | 1767 + * | | r1 | | r2 | | 1768 + * +--------+-----------------+--------+------+---+ 1769 + * ^ ^ ^ ^ ^ 1770 + * |________|________|________| | 1771 + * | Unaligned address 1772 + * Aligned addresses 1773 + * 1774 + * Expect that r1 will not be trimmed and r2 will be removed. Expect the 1775 + * counter to be updated. 1776 + */ 1777 + static int memblock_trim_memory_too_small_check(void) 1778 + { 1779 + struct memblock_region *rgn; 1780 + const phys_addr_t alignment = SMP_CACHE_BYTES; 1781 + 1782 + rgn = &memblock.memory.regions[0]; 1783 + 1784 + struct region r1 = { 1785 + .base = alignment, 1786 + .size = alignment * 2 1787 + }; 1788 + struct region r2 = { 1789 + .base = alignment * 4, 1790 + .size = alignment - SZ_2 1791 + }; 1792 + 1793 + PREFIX_PUSH(); 1794 + 1795 + reset_memblock_regions(); 1796 + memblock_add(r1.base, r1.size); 1797 + memblock_add(r2.base, r2.size); 1798 + memblock_trim_memory(alignment); 1799 + 1800 + ASSERT_EQ(rgn->base, r1.base); 1801 + ASSERT_EQ(rgn->size, r1.size); 1802 + 1803 + ASSERT_EQ(memblock.memory.cnt, 1); 1804 + 1805 + test_pass_pop(); 1806 + 1807 + return 0; 1808 + } 1809 + 1810 + /* 1811 + * A test that tries to trim memory when there are two available regions, r1 and 1812 + * r2. Region r1 is aligned on both ends and region r2 is unaligned at the base 1813 + * and aligned at the end: 1814 + * 1815 + * Unaligned address 1816 + * | 1817 + * v 1818 + * | +-----------------+ +---------------+ | 1819 + * | | r1 | | r2 | | 1820 + * +--------+-----------------+----------+---------------+---+ 1821 + * ^ ^ ^ ^ ^ ^ 1822 + * |________|________|________|________|________| 1823 + * | 1824 + * Aligned addresses 1825 + * 1826 + * Expect that r1 will not be trimmed and r2 will be trimmed at the base. 1827 + * Expect the counter to not be updated. 1828 + */ 1829 + static int memblock_trim_memory_unaligned_base_check(void) 1830 + { 1831 + struct memblock_region *rgn1, *rgn2; 1832 + const phys_addr_t alignment = SMP_CACHE_BYTES; 1833 + phys_addr_t offset = SZ_2; 1834 + phys_addr_t new_r2_base, new_r2_size; 1835 + 1836 + rgn1 = &memblock.memory.regions[0]; 1837 + rgn2 = &memblock.memory.regions[1]; 1838 + 1839 + struct region r1 = { 1840 + .base = alignment, 1841 + .size = alignment * 2 1842 + }; 1843 + struct region r2 = { 1844 + .base = alignment * 4 + offset, 1845 + .size = alignment * 2 - offset 1846 + }; 1847 + 1848 + PREFIX_PUSH(); 1849 + 1850 + new_r2_base = r2.base + (alignment - offset); 1851 + new_r2_size = r2.size - (alignment - offset); 1852 + 1853 + reset_memblock_regions(); 1854 + memblock_add(r1.base, r1.size); 1855 + memblock_add(r2.base, r2.size); 1856 + memblock_trim_memory(alignment); 1857 + 1858 + ASSERT_EQ(rgn1->base, r1.base); 1859 + ASSERT_EQ(rgn1->size, r1.size); 1860 + 1861 + ASSERT_EQ(rgn2->base, new_r2_base); 1862 + ASSERT_EQ(rgn2->size, new_r2_size); 1863 + 1864 + ASSERT_EQ(memblock.memory.cnt, 2); 1865 + 1866 + test_pass_pop(); 1867 + 1868 + return 0; 1869 + } 1870 + 1871 + /* 1872 + * A test that tries to trim memory when there are two available regions, r1 and 1873 + * r2. Region r1 is aligned on both ends and region r2 is aligned at the base 1874 + * and unaligned at the end: 1875 + * 1876 + * Unaligned address 1877 + * | 1878 + * v 1879 + * | +-----------------+ +---------------+ | 1880 + * | | r1 | | r2 | | 1881 + * +--------+-----------------+--------+---------------+---+ 1882 + * ^ ^ ^ ^ ^ ^ 1883 + * |________|________|________|________|________| 1884 + * | 1885 + * Aligned addresses 1886 + * 1887 + * Expect that r1 will not be trimmed and r2 will be trimmed at the end. 1888 + * Expect the counter to not be updated. 1889 + */ 1890 + static int memblock_trim_memory_unaligned_end_check(void) 1891 + { 1892 + struct memblock_region *rgn1, *rgn2; 1893 + const phys_addr_t alignment = SMP_CACHE_BYTES; 1894 + phys_addr_t offset = SZ_2; 1895 + phys_addr_t new_r2_size; 1896 + 1897 + rgn1 = &memblock.memory.regions[0]; 1898 + rgn2 = &memblock.memory.regions[1]; 1899 + 1900 + struct region r1 = { 1901 + .base = alignment, 1902 + .size = alignment * 2 1903 + }; 1904 + struct region r2 = { 1905 + .base = alignment * 4, 1906 + .size = alignment * 2 - offset 1907 + }; 1908 + 1909 + PREFIX_PUSH(); 1910 + 1911 + new_r2_size = r2.size - (alignment - offset); 1912 + 1913 + reset_memblock_regions(); 1914 + memblock_add(r1.base, r1.size); 1915 + memblock_add(r2.base, r2.size); 1916 + memblock_trim_memory(alignment); 1917 + 1918 + ASSERT_EQ(rgn1->base, r1.base); 1919 + ASSERT_EQ(rgn1->size, r1.size); 1920 + 1921 + ASSERT_EQ(rgn2->base, r2.base); 1922 + ASSERT_EQ(rgn2->size, new_r2_size); 1923 + 1924 + ASSERT_EQ(memblock.memory.cnt, 2); 1925 + 1926 + test_pass_pop(); 1927 + 1928 + return 0; 1929 + } 1930 + 1931 + static int memblock_trim_memory_checks(void) 1932 + { 1933 + prefix_reset(); 1934 + prefix_push(FUNC_TRIM); 1935 + test_print("Running %s tests...\n", FUNC_TRIM); 1936 + 1937 + memblock_trim_memory_aligned_check(); 1938 + memblock_trim_memory_too_small_check(); 1939 + memblock_trim_memory_unaligned_base_check(); 1940 + memblock_trim_memory_unaligned_end_check(); 1941 + 1942 + prefix_pop(); 1943 + 1944 + return 0; 1945 + } 1946 + 1727 1947 int memblock_basic_checks(void) 1728 1948 { 1729 1949 memblock_initialization_check(); ··· 1953 1731 memblock_remove_checks(); 1954 1732 memblock_free_checks(); 1955 1733 memblock_bottom_up_checks(); 1734 + memblock_trim_memory_checks(); 1956 1735 1957 1736 return 0; 1958 1737 }