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.

selftests: ntsync: Add some tests for wakeup signaling with WINESYNC_IOC_WAIT_ANY.

Test contended "wait-for-any" waits, to make sure that scheduling and wakeup
logic works correctly.

Signed-off-by: Elizabeth Figura <zfigura@codeweavers.com>
Link: https://lore.kernel.org/r/20241213193511.457338-21-zfigura@codeweavers.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Elizabeth Figura and committed by
Greg Kroah-Hartman
f2327985 d168f689

+143
+143
tools/testing/selftests/drivers/ntsync/ntsync.c
··· 532 532 close(fd); 533 533 } 534 534 535 + struct wake_args { 536 + int fd; 537 + int obj; 538 + }; 539 + 540 + struct wait_args { 541 + int fd; 542 + unsigned long request; 543 + struct ntsync_wait_args *args; 544 + int ret; 545 + int err; 546 + }; 547 + 548 + static void *wait_thread(void *arg) 549 + { 550 + struct wait_args *args = arg; 551 + 552 + args->ret = ioctl(args->fd, args->request, args->args); 553 + args->err = errno; 554 + return NULL; 555 + } 556 + 557 + static __u64 get_abs_timeout(unsigned int ms) 558 + { 559 + struct timespec timeout; 560 + clock_gettime(CLOCK_MONOTONIC, &timeout); 561 + return (timeout.tv_sec * 1000000000) + timeout.tv_nsec + (ms * 1000000); 562 + } 563 + 564 + static int wait_for_thread(pthread_t thread, unsigned int ms) 565 + { 566 + struct timespec timeout; 567 + 568 + clock_gettime(CLOCK_REALTIME, &timeout); 569 + timeout.tv_nsec += ms * 1000000; 570 + timeout.tv_sec += (timeout.tv_nsec / 1000000000); 571 + timeout.tv_nsec %= 1000000000; 572 + return pthread_timedjoin_np(thread, NULL, &timeout); 573 + } 574 + 575 + TEST(wake_any) 576 + { 577 + struct ntsync_mutex_args mutex_args = {0}; 578 + struct ntsync_wait_args wait_args = {0}; 579 + struct ntsync_sem_args sem_args = {0}; 580 + struct wait_args thread_args; 581 + int objs[2], fd, ret; 582 + __u32 count, index; 583 + pthread_t thread; 584 + 585 + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); 586 + ASSERT_LE(0, fd); 587 + 588 + sem_args.count = 0; 589 + sem_args.max = 3; 590 + objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); 591 + EXPECT_LE(0, objs[0]); 592 + 593 + mutex_args.owner = 123; 594 + mutex_args.count = 1; 595 + objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); 596 + EXPECT_LE(0, objs[1]); 597 + 598 + /* test waking the semaphore */ 599 + 600 + wait_args.timeout = get_abs_timeout(1000); 601 + wait_args.objs = (uintptr_t)objs; 602 + wait_args.count = 2; 603 + wait_args.owner = 456; 604 + wait_args.index = 0xdeadbeef; 605 + thread_args.fd = fd; 606 + thread_args.args = &wait_args; 607 + thread_args.request = NTSYNC_IOC_WAIT_ANY; 608 + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); 609 + EXPECT_EQ(0, ret); 610 + 611 + ret = wait_for_thread(thread, 100); 612 + EXPECT_EQ(ETIMEDOUT, ret); 613 + 614 + count = 1; 615 + ret = release_sem(objs[0], &count); 616 + EXPECT_EQ(0, ret); 617 + EXPECT_EQ(0, count); 618 + check_sem_state(objs[0], 0, 3); 619 + 620 + ret = wait_for_thread(thread, 100); 621 + EXPECT_EQ(0, ret); 622 + EXPECT_EQ(0, thread_args.ret); 623 + EXPECT_EQ(0, wait_args.index); 624 + 625 + /* test waking the mutex */ 626 + 627 + /* first grab it again for owner 123 */ 628 + ret = wait_any(fd, 1, &objs[1], 123, &index); 629 + EXPECT_EQ(0, ret); 630 + EXPECT_EQ(0, index); 631 + 632 + wait_args.timeout = get_abs_timeout(1000); 633 + wait_args.owner = 456; 634 + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); 635 + EXPECT_EQ(0, ret); 636 + 637 + ret = wait_for_thread(thread, 100); 638 + EXPECT_EQ(ETIMEDOUT, ret); 639 + 640 + ret = unlock_mutex(objs[1], 123, &count); 641 + EXPECT_EQ(0, ret); 642 + EXPECT_EQ(2, count); 643 + 644 + ret = pthread_tryjoin_np(thread, NULL); 645 + EXPECT_EQ(EBUSY, ret); 646 + 647 + ret = unlock_mutex(objs[1], 123, &count); 648 + EXPECT_EQ(0, ret); 649 + EXPECT_EQ(1, mutex_args.count); 650 + check_mutex_state(objs[1], 1, 456); 651 + 652 + ret = wait_for_thread(thread, 100); 653 + EXPECT_EQ(0, ret); 654 + EXPECT_EQ(0, thread_args.ret); 655 + EXPECT_EQ(1, wait_args.index); 656 + 657 + /* delete an object while it's being waited on */ 658 + 659 + wait_args.timeout = get_abs_timeout(200); 660 + wait_args.owner = 123; 661 + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); 662 + EXPECT_EQ(0, ret); 663 + 664 + ret = wait_for_thread(thread, 100); 665 + EXPECT_EQ(ETIMEDOUT, ret); 666 + 667 + close(objs[0]); 668 + close(objs[1]); 669 + 670 + ret = wait_for_thread(thread, 200); 671 + EXPECT_EQ(0, ret); 672 + EXPECT_EQ(-1, thread_args.ret); 673 + EXPECT_EQ(ETIMEDOUT, thread_args.err); 674 + 675 + close(fd); 676 + } 677 + 535 678 TEST_HARNESS_MAIN