CC: [email protected] CC: [email protected] TO: Peter Zijlstra <[email protected]> CC: "André Almeida" <[email protected]>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: ee1703cda8dc777e937dec172da55beaf1a74919 commit: a046f1a0d3e320cfee6bdac336416a537f49e7c6 futex: Split out wait/wake date: 6 weeks ago :::::: branch date: 4 hours ago :::::: commit date: 6 weeks ago config: m68k-randconfig-m031-20211117 (attached as .config) compiler: m68k-linux-gcc (GCC) 11.2.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <[email protected]> Reported-by: Dan Carpenter <[email protected]> smatch warnings: kernel/futex/waitwake.c:281 futex_wake_op() warn: bitwise AND condition is false here kernel/futex/waitwake.c:417 futex_wait_setup() warn: bitwise AND condition is false here vim +281 kernel/futex/waitwake.c a046f1a0d3e320 Peter Zijlstra 2021-09-23 233 a046f1a0d3e320 Peter Zijlstra 2021-09-23 234 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 235 * Wake up all waiters hashed on the physical page that is mapped a046f1a0d3e320 Peter Zijlstra 2021-09-23 236 * to this virtual address: a046f1a0d3e320 Peter Zijlstra 2021-09-23 237 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 238 int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, a046f1a0d3e320 Peter Zijlstra 2021-09-23 239 int nr_wake, int nr_wake2, int op) a046f1a0d3e320 Peter Zijlstra 2021-09-23 240 { a046f1a0d3e320 Peter Zijlstra 2021-09-23 241 union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; a046f1a0d3e320 Peter Zijlstra 2021-09-23 242 struct futex_hash_bucket *hb1, *hb2; a046f1a0d3e320 Peter Zijlstra 2021-09-23 243 struct futex_q *this, *next; a046f1a0d3e320 Peter Zijlstra 2021-09-23 244 int ret, op_ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 245 DEFINE_WAKE_Q(wake_q); a046f1a0d3e320 Peter Zijlstra 2021-09-23 246 a046f1a0d3e320 Peter Zijlstra 2021-09-23 247 retry: a046f1a0d3e320 Peter Zijlstra 2021-09-23 248 ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, FUTEX_READ); a046f1a0d3e320 Peter Zijlstra 2021-09-23 249 if (unlikely(ret != 0)) a046f1a0d3e320 Peter Zijlstra 2021-09-23 250 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 251 ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, FUTEX_WRITE); a046f1a0d3e320 Peter Zijlstra 2021-09-23 252 if (unlikely(ret != 0)) a046f1a0d3e320 Peter Zijlstra 2021-09-23 253 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 254 a046f1a0d3e320 Peter Zijlstra 2021-09-23 255 hb1 = futex_hash(&key1); a046f1a0d3e320 Peter Zijlstra 2021-09-23 256 hb2 = futex_hash(&key2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 257 a046f1a0d3e320 Peter Zijlstra 2021-09-23 258 retry_private: a046f1a0d3e320 Peter Zijlstra 2021-09-23 259 double_lock_hb(hb1, hb2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 260 op_ret = futex_atomic_op_inuser(op, uaddr2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 261 if (unlikely(op_ret < 0)) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 262 double_unlock_hb(hb1, hb2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 263 a046f1a0d3e320 Peter Zijlstra 2021-09-23 264 if (!IS_ENABLED(CONFIG_MMU) || a046f1a0d3e320 Peter Zijlstra 2021-09-23 265 unlikely(op_ret != -EFAULT && op_ret != -EAGAIN)) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 266 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 267 * we don't get EFAULT from MMU faults if we don't have a046f1a0d3e320 Peter Zijlstra 2021-09-23 268 * an MMU, but we might get them from range checking a046f1a0d3e320 Peter Zijlstra 2021-09-23 269 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 270 ret = op_ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 271 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 272 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 273 a046f1a0d3e320 Peter Zijlstra 2021-09-23 274 if (op_ret == -EFAULT) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 275 ret = fault_in_user_writeable(uaddr2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 276 if (ret) a046f1a0d3e320 Peter Zijlstra 2021-09-23 277 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 278 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 279 a046f1a0d3e320 Peter Zijlstra 2021-09-23 280 cond_resched(); a046f1a0d3e320 Peter Zijlstra 2021-09-23 @281 if (!(flags & FLAGS_SHARED)) a046f1a0d3e320 Peter Zijlstra 2021-09-23 282 goto retry_private; a046f1a0d3e320 Peter Zijlstra 2021-09-23 283 goto retry; a046f1a0d3e320 Peter Zijlstra 2021-09-23 284 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 285 a046f1a0d3e320 Peter Zijlstra 2021-09-23 286 plist_for_each_entry_safe(this, next, &hb1->chain, list) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 287 if (futex_match (&this->key, &key1)) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 288 if (this->pi_state || this->rt_waiter) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 289 ret = -EINVAL; a046f1a0d3e320 Peter Zijlstra 2021-09-23 290 goto out_unlock; a046f1a0d3e320 Peter Zijlstra 2021-09-23 291 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 292 futex_wake_mark(&wake_q, this); a046f1a0d3e320 Peter Zijlstra 2021-09-23 293 if (++ret >= nr_wake) a046f1a0d3e320 Peter Zijlstra 2021-09-23 294 break; a046f1a0d3e320 Peter Zijlstra 2021-09-23 295 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 296 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 297 a046f1a0d3e320 Peter Zijlstra 2021-09-23 298 if (op_ret > 0) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 299 op_ret = 0; a046f1a0d3e320 Peter Zijlstra 2021-09-23 300 plist_for_each_entry_safe(this, next, &hb2->chain, list) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 301 if (futex_match (&this->key, &key2)) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 302 if (this->pi_state || this->rt_waiter) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 303 ret = -EINVAL; a046f1a0d3e320 Peter Zijlstra 2021-09-23 304 goto out_unlock; a046f1a0d3e320 Peter Zijlstra 2021-09-23 305 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 306 futex_wake_mark(&wake_q, this); a046f1a0d3e320 Peter Zijlstra 2021-09-23 307 if (++op_ret >= nr_wake2) a046f1a0d3e320 Peter Zijlstra 2021-09-23 308 break; a046f1a0d3e320 Peter Zijlstra 2021-09-23 309 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 310 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 311 ret += op_ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 312 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 313 a046f1a0d3e320 Peter Zijlstra 2021-09-23 314 out_unlock: a046f1a0d3e320 Peter Zijlstra 2021-09-23 315 double_unlock_hb(hb1, hb2); a046f1a0d3e320 Peter Zijlstra 2021-09-23 316 wake_up_q(&wake_q); a046f1a0d3e320 Peter Zijlstra 2021-09-23 317 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 318 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 319 a046f1a0d3e320 Peter Zijlstra 2021-09-23 320 static long futex_wait_restart(struct restart_block *restart); a046f1a0d3e320 Peter Zijlstra 2021-09-23 321 a046f1a0d3e320 Peter Zijlstra 2021-09-23 322 /** a046f1a0d3e320 Peter Zijlstra 2021-09-23 323 * futex_wait_queue() - futex_queue() and wait for wakeup, timeout, or signal a046f1a0d3e320 Peter Zijlstra 2021-09-23 324 * @hb: the futex hash bucket, must be locked by the caller a046f1a0d3e320 Peter Zijlstra 2021-09-23 325 * @q: the futex_q to queue up on a046f1a0d3e320 Peter Zijlstra 2021-09-23 326 * @timeout: the prepared hrtimer_sleeper, or null for no timeout a046f1a0d3e320 Peter Zijlstra 2021-09-23 327 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 328 void futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q, a046f1a0d3e320 Peter Zijlstra 2021-09-23 329 struct hrtimer_sleeper *timeout) a046f1a0d3e320 Peter Zijlstra 2021-09-23 330 { a046f1a0d3e320 Peter Zijlstra 2021-09-23 331 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 332 * The task state is guaranteed to be set before another task can a046f1a0d3e320 Peter Zijlstra 2021-09-23 333 * wake it. set_current_state() is implemented using smp_store_mb() and a046f1a0d3e320 Peter Zijlstra 2021-09-23 334 * futex_queue() calls spin_unlock() upon completion, both serializing a046f1a0d3e320 Peter Zijlstra 2021-09-23 335 * access to the hash list and forcing another memory barrier. a046f1a0d3e320 Peter Zijlstra 2021-09-23 336 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 337 set_current_state(TASK_INTERRUPTIBLE); a046f1a0d3e320 Peter Zijlstra 2021-09-23 338 futex_queue(q, hb); a046f1a0d3e320 Peter Zijlstra 2021-09-23 339 a046f1a0d3e320 Peter Zijlstra 2021-09-23 340 /* Arm the timer */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 341 if (timeout) a046f1a0d3e320 Peter Zijlstra 2021-09-23 342 hrtimer_sleeper_start_expires(timeout, HRTIMER_MODE_ABS); a046f1a0d3e320 Peter Zijlstra 2021-09-23 343 a046f1a0d3e320 Peter Zijlstra 2021-09-23 344 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 345 * If we have been removed from the hash list, then another task a046f1a0d3e320 Peter Zijlstra 2021-09-23 346 * has tried to wake us, and we can skip the call to schedule(). a046f1a0d3e320 Peter Zijlstra 2021-09-23 347 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 348 if (likely(!plist_node_empty(&q->list))) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 349 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 350 * If the timer has already expired, current will already be a046f1a0d3e320 Peter Zijlstra 2021-09-23 351 * flagged for rescheduling. Only call schedule if there a046f1a0d3e320 Peter Zijlstra 2021-09-23 352 * is no timeout, or if it has yet to expire. a046f1a0d3e320 Peter Zijlstra 2021-09-23 353 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 354 if (!timeout || timeout->task) a046f1a0d3e320 Peter Zijlstra 2021-09-23 355 freezable_schedule(); a046f1a0d3e320 Peter Zijlstra 2021-09-23 356 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 357 __set_current_state(TASK_RUNNING); a046f1a0d3e320 Peter Zijlstra 2021-09-23 358 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 359 a046f1a0d3e320 Peter Zijlstra 2021-09-23 360 /** a046f1a0d3e320 Peter Zijlstra 2021-09-23 361 * futex_wait_setup() - Prepare to wait on a futex a046f1a0d3e320 Peter Zijlstra 2021-09-23 362 * @uaddr: the futex userspace address a046f1a0d3e320 Peter Zijlstra 2021-09-23 363 * @val: the expected value a046f1a0d3e320 Peter Zijlstra 2021-09-23 364 * @flags: futex flags (FLAGS_SHARED, etc.) a046f1a0d3e320 Peter Zijlstra 2021-09-23 365 * @q: the associated futex_q a046f1a0d3e320 Peter Zijlstra 2021-09-23 366 * @hb: storage for hash_bucket pointer to be returned to caller a046f1a0d3e320 Peter Zijlstra 2021-09-23 367 * a046f1a0d3e320 Peter Zijlstra 2021-09-23 368 * Setup the futex_q and locate the hash_bucket. Get the futex value and a046f1a0d3e320 Peter Zijlstra 2021-09-23 369 * compare it with the expected value. Handle atomic faults internally. a046f1a0d3e320 Peter Zijlstra 2021-09-23 370 * Return with the hb lock held on success, and unlocked on failure. a046f1a0d3e320 Peter Zijlstra 2021-09-23 371 * a046f1a0d3e320 Peter Zijlstra 2021-09-23 372 * Return: a046f1a0d3e320 Peter Zijlstra 2021-09-23 373 * - 0 - uaddr contains val and hb has been locked; a046f1a0d3e320 Peter Zijlstra 2021-09-23 374 * - <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked a046f1a0d3e320 Peter Zijlstra 2021-09-23 375 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 376 int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, a046f1a0d3e320 Peter Zijlstra 2021-09-23 377 struct futex_q *q, struct futex_hash_bucket **hb) a046f1a0d3e320 Peter Zijlstra 2021-09-23 378 { a046f1a0d3e320 Peter Zijlstra 2021-09-23 379 u32 uval; a046f1a0d3e320 Peter Zijlstra 2021-09-23 380 int ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 381 a046f1a0d3e320 Peter Zijlstra 2021-09-23 382 /* a046f1a0d3e320 Peter Zijlstra 2021-09-23 383 * Access the page AFTER the hash-bucket is locked. a046f1a0d3e320 Peter Zijlstra 2021-09-23 384 * Order is important: a046f1a0d3e320 Peter Zijlstra 2021-09-23 385 * a046f1a0d3e320 Peter Zijlstra 2021-09-23 386 * Userspace waiter: val = var; if (cond(val)) futex_wait(&var, val); a046f1a0d3e320 Peter Zijlstra 2021-09-23 387 * Userspace waker: if (cond(var)) { var = new; futex_wake(&var); } a046f1a0d3e320 Peter Zijlstra 2021-09-23 388 * a046f1a0d3e320 Peter Zijlstra 2021-09-23 389 * The basic logical guarantee of a futex is that it blocks ONLY a046f1a0d3e320 Peter Zijlstra 2021-09-23 390 * if cond(var) is known to be true at the time of blocking, for a046f1a0d3e320 Peter Zijlstra 2021-09-23 391 * any cond. If we locked the hash-bucket after testing *uaddr, that a046f1a0d3e320 Peter Zijlstra 2021-09-23 392 * would open a race condition where we could block indefinitely with a046f1a0d3e320 Peter Zijlstra 2021-09-23 393 * cond(var) false, which would violate the guarantee. a046f1a0d3e320 Peter Zijlstra 2021-09-23 394 * a046f1a0d3e320 Peter Zijlstra 2021-09-23 395 * On the other hand, we insert q and release the hash-bucket only a046f1a0d3e320 Peter Zijlstra 2021-09-23 396 * after testing *uaddr. This guarantees that futex_wait() will NOT a046f1a0d3e320 Peter Zijlstra 2021-09-23 397 * absorb a wakeup if *uaddr does not match the desired values a046f1a0d3e320 Peter Zijlstra 2021-09-23 398 * while the syscall executes. a046f1a0d3e320 Peter Zijlstra 2021-09-23 399 */ a046f1a0d3e320 Peter Zijlstra 2021-09-23 400 retry: a046f1a0d3e320 Peter Zijlstra 2021-09-23 401 ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, FUTEX_READ); a046f1a0d3e320 Peter Zijlstra 2021-09-23 402 if (unlikely(ret != 0)) a046f1a0d3e320 Peter Zijlstra 2021-09-23 403 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 404 a046f1a0d3e320 Peter Zijlstra 2021-09-23 405 retry_private: a046f1a0d3e320 Peter Zijlstra 2021-09-23 406 *hb = futex_q_lock(q); a046f1a0d3e320 Peter Zijlstra 2021-09-23 407 a046f1a0d3e320 Peter Zijlstra 2021-09-23 408 ret = futex_get_value_locked(&uval, uaddr); a046f1a0d3e320 Peter Zijlstra 2021-09-23 409 a046f1a0d3e320 Peter Zijlstra 2021-09-23 410 if (ret) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 411 futex_q_unlock(*hb); a046f1a0d3e320 Peter Zijlstra 2021-09-23 412 a046f1a0d3e320 Peter Zijlstra 2021-09-23 413 ret = get_user(uval, uaddr); a046f1a0d3e320 Peter Zijlstra 2021-09-23 414 if (ret) a046f1a0d3e320 Peter Zijlstra 2021-09-23 415 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 416 a046f1a0d3e320 Peter Zijlstra 2021-09-23 @417 if (!(flags & FLAGS_SHARED)) a046f1a0d3e320 Peter Zijlstra 2021-09-23 418 goto retry_private; a046f1a0d3e320 Peter Zijlstra 2021-09-23 419 a046f1a0d3e320 Peter Zijlstra 2021-09-23 420 goto retry; a046f1a0d3e320 Peter Zijlstra 2021-09-23 421 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 422 a046f1a0d3e320 Peter Zijlstra 2021-09-23 423 if (uval != val) { a046f1a0d3e320 Peter Zijlstra 2021-09-23 424 futex_q_unlock(*hb); a046f1a0d3e320 Peter Zijlstra 2021-09-23 425 ret = -EWOULDBLOCK; a046f1a0d3e320 Peter Zijlstra 2021-09-23 426 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 427 a046f1a0d3e320 Peter Zijlstra 2021-09-23 428 return ret; a046f1a0d3e320 Peter Zijlstra 2021-09-23 429 } a046f1a0d3e320 Peter Zijlstra 2021-09-23 430 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/[email protected]
.config.gz
Description: application/gzip
_______________________________________________ kbuild mailing list -- [email protected] To unsubscribe send an email to [email protected]
