* [tip:locking/urgent 1/1] kernel/futex/core.c:1870:21: sparse: sparse: cast removes address space '__percpu' of expression
@ 2026-08-15 23:37 kernel test robot
0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-08-15 23:37 UTC (permalink / raw)
To: Hyunwoo Kim; +Cc: oe-kbuild-all, linux-kernel, x86, Peter Zijlstra
tree: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/urgent
head: 4f664e37fe72ab21426d2d74fcbcf7399e8fc52c
commit: 4f664e37fe72ab21426d2d74fcbcf7399e8fc52c [1/1] futex: Fix race on the initial mm->futex.phash.ref allocation
config: riscv-randconfig-r134-20260816 (https://download.01.org/0day-ci/archive/20260816/202608160702.gsnEjcvu-lkp@intel.com/config)
compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 844a18e753e822736c9805ab779144b647a2c186)
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260816/202608160702.gsnEjcvu-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608160702.gsnEjcvu-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
WARNING: invalid argument to '-march': '_zacas_zabha'
kernel/futex/core.c:536:38: sparse: sparse: cast removes address space '__user' of expression
kernel/futex/core.c:536:51: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] [usertype] __user *naddr @@ got void * @@
kernel/futex/core.c:536:51: sparse: expected unsigned int [noderef] [usertype] __user *naddr
kernel/futex/core.c:536:51: sparse: got void *
kernel/futex/core.c:552:38: sparse: sparse: cast removes address space '__user' of expression
kernel/futex/core.c:552:51: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] [usertype] __user *naddr @@ got void * @@
kernel/futex/core.c:552:51: sparse: expected unsigned int [noderef] [usertype] __user *naddr
kernel/futex/core.c:552:51: sparse: got void *
>> kernel/futex/core.c:1870:21: sparse: sparse: cast removes address space '__percpu' of expression
vim +/__percpu +1870 kernel/futex/core.c
1836
1837 static int futex_hash_allocate(unsigned int hash_slots, unsigned int flags)
1838 {
1839 struct mm_struct *mm = current->mm;
1840 struct futex_private_hash *fph;
1841 bool custom = flags & FH_CUSTOM;
1842 int i;
1843
1844 if (hash_slots && (hash_slots == 1 || !is_power_of_2(hash_slots)))
1845 return -EINVAL;
1846
1847 /*
1848 * Once we've disabled the global hash there is no way back.
1849 */
1850 scoped_guard(rcu) {
1851 fph = rcu_dereference(mm->futex.phash.hash);
1852 if (fph && !fph->hash_mask) {
1853 if (custom)
1854 return -EBUSY;
1855 return 0;
1856 }
1857 }
1858
1859 if (!mm->futex.phash.ref) {
1860 unsigned int __percpu *ref = alloc_percpu(unsigned int);
1861
1862 if (!ref)
1863 return -ENOMEM;
1864
1865 /*
1866 * Tasks sharing the mm can run this concurrently, so take the
1867 * initial reference before publishing the counter.
1868 */
1869 this_cpu_inc(*ref); /* 0 -> 1 */
> 1870 if (cmpxchg(&mm->futex.phash.ref, NULL, ref))
1871 free_percpu(ref);
1872 }
1873
1874 fph = kvzalloc(struct_size(fph, queues, hash_slots),
1875 GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1876 if (!fph)
1877 return -ENOMEM;
1878
1879 fph->hash_mask = hash_slots ? hash_slots - 1 : 0;
1880 fph->custom = custom;
1881 fph->mm = mm;
1882
1883 for (i = 0; i < hash_slots; i++)
1884 futex_hash_bucket_init(&fph->queues[i]);
1885
1886 if (custom) {
1887 /*
1888 * Only let prctl() wait / retry; don't unduly delay clone().
1889 */
1890 again:
1891 wait_var_event(mm, futex_pivot_pending(mm));
1892 }
1893
1894 scoped_guard(mutex, &mm->futex.phash.lock) {
1895 struct futex_private_hash *free __free(kvfree) = NULL;
1896 struct futex_private_hash *cur, *new;
1897
1898 cur = rcu_dereference_protected(mm->futex.phash.hash,
1899 lockdep_is_held(&mm->futex.phash.lock));
1900 new = mm->futex.phash.hash_new;
1901 mm->futex.phash.hash_new = NULL;
1902
1903 if (fph) {
1904 if (cur && !cur->hash_mask) {
1905 /*
1906 * If two threads simultaneously request the global
1907 * hash then the first one performs the switch,
1908 * the second one returns here.
1909 */
1910 free = fph;
1911 mm->futex.phash.hash_new = new;
1912 return -EBUSY;
1913 }
1914 if (cur && !new) {
1915 /*
1916 * If we have an existing hash, but do not yet have
1917 * allocated a replacement hash, drop the initial
1918 * reference on the existing hash.
1919 */
1920 futex_ref_drop(cur);
1921 }
1922
1923 if (new) {
1924 /*
1925 * Two updates raced; throw out the lesser one.
1926 */
1927 if (futex_hash_less(new, fph)) {
1928 free = new;
1929 new = fph;
1930 } else {
1931 free = fph;
1932 }
1933 } else {
1934 new = fph;
1935 }
1936 fph = NULL;
1937 }
1938
1939 if (new) {
1940 /*
1941 * Will set mm->futex.phash.new_hash on failure;
1942 * futex_private_hash_get() will try again.
1943 */
1944 if (!__futex_pivot_hash(mm, new) && custom)
1945 goto again;
1946 }
1947 }
1948 return 0;
1949 }
1950
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-15 23:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-15 23:37 [tip:locking/urgent 1/1] kernel/futex/core.c:1870:21: sparse: sparse: cast removes address space '__percpu' of expression kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.