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.

mm/madvise: deduplicate madvise_do_behavior() skip case handlings

The logic for checking if a given madvise() request for a single memory
range can skip real work, namely madvise_do_behavior(), is duplicated in
do_madvise() and vector_madvise(). Split out the logic to a function and
reuse it.

Link: https://lkml.kernel.org/r/20250312164750.59215-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: David Hildenbrand <david@redhat.com>
Cc: Liam R. Howlett <howlett@gmail.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

SeongJae Park and committed by
Andrew Morton
0a6ffacb f4a578d3

+34 -23
+34 -23
mm/madvise.c
··· 1640 1640 return true; 1641 1641 } 1642 1642 1643 + /* 1644 + * madvise_should_skip() - Return if the request is invalid or nothing. 1645 + * @start: Start address of madvise-requested address range. 1646 + * @len_in: Length of madvise-requested address range. 1647 + * @behavior: Requested madvise behavor. 1648 + * @err: Pointer to store an error code from the check. 1649 + * 1650 + * If the specified behaviour is invalid or nothing would occur, we skip the 1651 + * operation. This function returns true in the cases, otherwise false. In 1652 + * the former case we store an error on @err. 1653 + */ 1654 + static bool madvise_should_skip(unsigned long start, size_t len_in, 1655 + int behavior, int *err) 1656 + { 1657 + if (!is_valid_madvise(start, len_in, behavior)) { 1658 + *err = -EINVAL; 1659 + return true; 1660 + } 1661 + if (start + PAGE_ALIGN(len_in) == start) { 1662 + *err = 0; 1663 + return true; 1664 + } 1665 + return false; 1666 + } 1667 + 1643 1668 static bool is_madvise_populate(int behavior) 1644 1669 { 1645 1670 switch (behavior) { ··· 1772 1747 */ 1773 1748 int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior) 1774 1749 { 1775 - unsigned long end; 1776 1750 int error; 1777 - size_t len; 1778 1751 1779 - if (!is_valid_madvise(start, len_in, behavior)) 1780 - return -EINVAL; 1781 - 1782 - len = PAGE_ALIGN(len_in); 1783 - end = start + len; 1784 - 1785 - if (end == start) 1786 - return 0; 1787 - 1752 + if (madvise_should_skip(start, len_in, behavior, &error)) 1753 + return error; 1788 1754 error = madvise_lock(mm, behavior); 1789 1755 if (error) 1790 1756 return error; 1791 - error = madvise_do_behavior(mm, start, len_in, len, behavior); 1757 + error = madvise_do_behavior(mm, start, len_in, PAGE_ALIGN(len_in), 1758 + behavior); 1792 1759 madvise_unlock(mm, behavior); 1793 1760 1794 1761 return error; ··· 1807 1790 while (iov_iter_count(iter)) { 1808 1791 unsigned long start = (unsigned long)iter_iov_addr(iter); 1809 1792 size_t len_in = iter_iov_len(iter); 1810 - size_t len; 1793 + int error; 1811 1794 1812 - if (!is_valid_madvise(start, len_in, behavior)) { 1813 - ret = -EINVAL; 1814 - break; 1815 - } 1816 - 1817 - len = PAGE_ALIGN(len_in); 1818 - if (start + len == start) 1819 - ret = 0; 1795 + if (madvise_should_skip(start, len_in, behavior, &error)) 1796 + ret = error; 1820 1797 else 1821 - ret = madvise_do_behavior(mm, start, len_in, len, 1822 - behavior); 1798 + ret = madvise_do_behavior(mm, start, len_in, 1799 + PAGE_ALIGN(len_in), behavior); 1823 1800 /* 1824 1801 * An madvise operation is attempting to restart the syscall, 1825 1802 * but we cannot proceed as it would not be correct to repeat