From patchwork Mon Dec 9 18:58:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849506 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C6421A9B52; Mon, 9 Dec 2024 19:03:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771003; cv=none; b=G9oF4CdI0jeWg++sxJzKVhK/zuI8r0hfsJbzNBDsepusvCSCAbJQeTFSziwKY7kx3y52AtCQlriTvJLanfTR1Udd8kHCLLRBxGOc6aurhsqzSu2Sfr5T70qFNGchnh0b5RCKENHm4h+AJ4FlR7Y6b4iEGP6OqyN/shgSXkK2Kwg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771003; c=relaxed/simple; bh=2uYVO1VRtIY6WYhZsMHHl59EjRHy2djXZYIJsvPoIqo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YFwLJqe1R711eYJWp4cwaGF/fzBNE+TqBUKnv07FLvVyrOsGh/FvniUcg7RcFUo3bRvks8hmniJKuQxLGcvDNOIH6DTEOxYPT1r4WvKChkZ2B1bcKjpIx/2VgyCvRQg4dDJvhQPWFVEX3awu1Z7n6GdgxcHLZ04Z/g5cJFiHm/Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=aSxs3sQ1; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="aSxs3sQ1" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=MztNwuC9SO5j1bGDs8fQm0MrbEZZV1l+TeU5kSOtjag=; b=aSxs3sQ1b8DiSOcp8geniaPN3x bhT03crEcEoBQmDUVK0tjTl+qroRPZh7m7fZHgc7TAs1vFnVYK1SR7CjEVcDRS/3cb/SzXezzPX5a pUaO0XzXkktq411u80cH/Z7OJDC7uN9HTXgfgNKVOMqLbIK04XKaqQYlNbAErWJmXMzFohiNjlCUS Xkb1fzjvXJshwxFgSQ8VIDts5ipT+/byhtjfWbYLazfrZCPvSN2cswEu8EFAWgF82ZQ8k+4phK63C UlR9Je1pAe4MTZy8U+cBM9j1ehwkKnhsNnGLAMt/NRqoEep9fU+nacpHUwDPmhCaSCSS1THFX6EhH Ip2j+n4Q==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyX-001Gd5-15; Mon, 09 Dec 2024 12:59:21 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 01/28] ntsync: Introduce NTSYNC_IOC_WAIT_ANY. Date: Mon, 9 Dec 2024 12:58:37 -0600 Message-ID: <20241209185904.507350-2-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to part of the functionality of the NT syscall NtWaitForMultipleObjects(). Specifically, it implements the behaviour where the third argument (wait_any) is TRUE, and it does not handle alertable waits. Those features have been split out into separate patches to ease review. This patch therefore implements the wait/wake infrastructure which comprises the core of ntsync's functionality. NTSYNC_IOC_WAIT_ANY is a vectored wait function similar to poll(). Unlike poll(), it "consumes" objects when they are signaled. For semaphores, this means decreasing one from the internal counter. At most one object can be consumed by this function. This wait/wake model is fundamentally different from that used anywhere else in the kernel, and for that reason ntsync does not use any existing infrastructure, such as futexes, kernel mutexes or semaphores, or wait_event(). Up to 64 objects can be waited on at once. As soon as one is signaled, the object with the lowest index is consumed, and that index is returned via the "index" field. A timeout is supported. The timeout is passed as a u64 nanosecond value, which represents absolute time measured against either the MONOTONIC or REALTIME clock (controlled by the flags argument). If U64_MAX is passed, the ioctl waits indefinitely. This ioctl validates that all objects belong to the relevant device. This is not necessary for any technical reason related to NTSYNC_IOC_WAIT_ANY, but will be necessary for NTSYNC_IOC_WAIT_ALL introduced in the following patch. Some padding fields are added for alignment and for fields which will be added in future patches (split out to ease review). Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 245 ++++++++++++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 14 +++ 2 files changed, 259 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 4954553b7baa..2bfe5299f25b 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -6,11 +6,16 @@ */ #include +#include #include #include +#include +#include #include #include #include +#include +#include #include #include #include @@ -30,6 +35,8 @@ enum ntsync_type { * * Both rely on struct file for reference counting. Individual * ntsync_obj objects take a reference to the device when created. + * Wait operations take a reference to each object being waited on for + * the duration of the wait. */ struct ntsync_obj { @@ -47,12 +54,55 @@ struct ntsync_obj { __u32 max; } sem; } u; + + struct list_head any_waiters; +}; + +struct ntsync_q_entry { + struct list_head node; + struct ntsync_q *q; + struct ntsync_obj *obj; + __u32 index; +}; + +struct ntsync_q { + struct task_struct *task; + + /* + * Protected via atomic_try_cmpxchg(). Only the thread that wins the + * compare-and-swap may actually change object states and wake this + * task. + */ + atomic_t signaled; + + __u32 count; + struct ntsync_q_entry entries[]; }; struct ntsync_device { struct file *file; }; +static void try_wake_any_sem(struct ntsync_obj *sem) +{ + struct ntsync_q_entry *entry; + + lockdep_assert_held(&sem->lock); + + list_for_each_entry(entry, &sem->any_waiters, node) { + struct ntsync_q *q = entry->q; + int signaled = -1; + + if (!sem->u.sem.count) + break; + + if (atomic_try_cmpxchg(&q->signaled, &signaled, entry->index)) { + sem->u.sem.count--; + wake_up_process(q->task); + } + } +} + /* * Actually change the semaphore state, returning -EOVERFLOW if it is made * invalid. @@ -88,6 +138,8 @@ static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp) prev_count = sem->u.sem.count; ret = post_sem_state(sem, args); + if (!ret) + try_wake_any_sem(sem); spin_unlock(&sem->lock); @@ -140,6 +192,7 @@ static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev, obj->dev = dev; get_file(dev->file); spin_lock_init(&obj->lock); + INIT_LIST_HEAD(&obj->any_waiters); return obj; } @@ -190,6 +243,196 @@ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp) return put_user(fd, &user_args->sem); } +static struct ntsync_obj *get_obj(struct ntsync_device *dev, int fd) +{ + struct file *file = fget(fd); + struct ntsync_obj *obj; + + if (!file) + return NULL; + + if (file->f_op != &ntsync_obj_fops) { + fput(file); + return NULL; + } + + obj = file->private_data; + if (obj->dev != dev) { + fput(file); + return NULL; + } + + return obj; +} + +static void put_obj(struct ntsync_obj *obj) +{ + fput(obj->file); +} + +static int ntsync_schedule(const struct ntsync_q *q, const struct ntsync_wait_args *args) +{ + ktime_t timeout = ns_to_ktime(args->timeout); + clockid_t clock = CLOCK_MONOTONIC; + ktime_t *timeout_ptr; + int ret = 0; + + timeout_ptr = (args->timeout == U64_MAX ? NULL : &timeout); + + if (args->flags & NTSYNC_WAIT_REALTIME) + clock = CLOCK_REALTIME; + + do { + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + set_current_state(TASK_INTERRUPTIBLE); + if (atomic_read(&q->signaled) != -1) { + ret = 0; + break; + } + ret = schedule_hrtimeout_range_clock(timeout_ptr, 0, HRTIMER_MODE_ABS, clock); + } while (ret < 0); + __set_current_state(TASK_RUNNING); + + return ret; +} + +/* + * Allocate and initialize the ntsync_q structure, but do not queue us yet. + */ +static int setup_wait(struct ntsync_device *dev, + const struct ntsync_wait_args *args, + struct ntsync_q **ret_q) +{ + const __u32 count = args->count; + int fds[NTSYNC_MAX_WAIT_COUNT]; + struct ntsync_q *q; + __u32 i, j; + + if (args->pad[0] || args->pad[1] || args->pad[2] || (args->flags & ~NTSYNC_WAIT_REALTIME)) + return -EINVAL; + + if (args->count > NTSYNC_MAX_WAIT_COUNT) + return -EINVAL; + + if (copy_from_user(fds, u64_to_user_ptr(args->objs), + array_size(count, sizeof(*fds)))) + return -EFAULT; + + q = kmalloc(struct_size(q, entries, count), GFP_KERNEL); + if (!q) + return -ENOMEM; + q->task = current; + atomic_set(&q->signaled, -1); + q->count = count; + + for (i = 0; i < count; i++) { + struct ntsync_q_entry *entry = &q->entries[i]; + struct ntsync_obj *obj = get_obj(dev, fds[i]); + + if (!obj) + goto err; + + entry->obj = obj; + entry->q = q; + entry->index = i; + } + + *ret_q = q; + return 0; + +err: + for (j = 0; j < i; j++) + put_obj(q->entries[j].obj); + kfree(q); + return -EINVAL; +} + +static void try_wake_any_obj(struct ntsync_obj *obj) +{ + switch (obj->type) { + case NTSYNC_TYPE_SEM: + try_wake_any_sem(obj); + break; + } +} + +static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) +{ + struct ntsync_wait_args args; + struct ntsync_q *q; + int signaled; + __u32 i; + int ret; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + + ret = setup_wait(dev, &args, &q); + if (ret < 0) + return ret; + + /* queue ourselves */ + + for (i = 0; i < args.count; i++) { + struct ntsync_q_entry *entry = &q->entries[i]; + struct ntsync_obj *obj = entry->obj; + + spin_lock(&obj->lock); + list_add_tail(&entry->node, &obj->any_waiters); + spin_unlock(&obj->lock); + } + + /* check if we are already signaled */ + + for (i = 0; i < args.count; i++) { + struct ntsync_obj *obj = q->entries[i].obj; + + if (atomic_read(&q->signaled) != -1) + break; + + spin_lock(&obj->lock); + try_wake_any_obj(obj); + spin_unlock(&obj->lock); + } + + /* sleep */ + + ret = ntsync_schedule(q, &args); + + /* and finally, unqueue */ + + for (i = 0; i < args.count; i++) { + struct ntsync_q_entry *entry = &q->entries[i]; + struct ntsync_obj *obj = entry->obj; + + spin_lock(&obj->lock); + list_del(&entry->node); + spin_unlock(&obj->lock); + + put_obj(obj); + } + + signaled = atomic_read(&q->signaled); + if (signaled != -1) { + struct ntsync_wait_args __user *user_args = argp; + + /* even if we caught a signal, we need to communicate success */ + ret = 0; + + if (put_user(signaled, &user_args->index)) + ret = -EFAULT; + } else if (!ret) { + ret = -ETIMEDOUT; + } + + kfree(q); + return ret; +} + static int ntsync_char_open(struct inode *inode, struct file *file) { struct ntsync_device *dev; @@ -221,6 +464,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case NTSYNC_IOC_CREATE_SEM: return ntsync_create_sem(dev, argp); + case NTSYNC_IOC_WAIT_ANY: + return ntsync_wait_any(dev, argp); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index dcfa38fdc93c..edc12c7a10dc 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -16,7 +16,21 @@ struct ntsync_sem_args { __u32 max; }; +#define NTSYNC_WAIT_REALTIME 0x1 + +struct ntsync_wait_args { + __u64 timeout; + __u64 objs; + __u32 count; + __u32 index; + __u32 flags; + __u32 pad[3]; +}; + +#define NTSYNC_MAX_WAIT_COUNT 64 + #define NTSYNC_IOC_CREATE_SEM _IOWR('N', 0x80, struct ntsync_sem_args) +#define NTSYNC_IOC_WAIT_ANY _IOWR('N', 0x82, struct ntsync_wait_args) #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) From patchwork Mon Dec 9 18:58:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848513 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAAC91AA1DB; Mon, 9 Dec 2024 19:03:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771006; cv=none; b=q9ekrhFroH5qyGcYqDXcAwb6bhKi2OhhYTwOFgnR8ODdCB7QsDdLArnHd2iTkZuRdss6AVYGyf4ZW1Dn6z4CVs7qFy0Ve9pEJ0VarFn6PElgTjGHLyNHvhu7VZ16cbYA7t53HGWwdGLbdMjo8f8E6Wk9i9SkR6BhDSnK0ZQw3d0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771006; c=relaxed/simple; bh=jLrTrPwg0pMwT9Jh7sxhVdIa46vdElR9UPVWqBvqBDg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QvWnH7cavmwNtfuMsN2oRA0Z5EDnczKpEQrLlPCzFdZG5TLI7X3JI7Oxf/t12vt/sUokqMjt12UiDWNVL4skkw557+3lHxbiY+q9cOwQllinK5O8fBV2XpSQKNYiuSGPeGmmhmjWJxDk5pPAgRy9gHKC8UeHJIaIj1N7M1Sz3kw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=ZMoCFFUh; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="ZMoCFFUh" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=12a/aKLQ+0yD09myLum/AmqIrEsfZM5XVES09R83JhU=; b=ZMoCFFUhlXBey/NpzX53ibIv4S UCVUTGyB8FGHZbZl+Sg0L0EamdyW5E1FKsImnL8NPV6al0ckKYtx4nS7c4d8sw/8YJ/sGfDZ7D2V7 MLbVCSa6st3PoaUPRDVO7o+Rvg6NXsNguC6hDA1coVbBAZazGrr4kAChyBow7C9OomtnFAc7hiq5M 0cVKkRtEVMGiyL5+nNrRvNDquhmMpYQdMEqKdwxE/fE9WS2D86Ar2q8Hz2x15QrMRgiK8sICCeaPt Kc9+pRivKCq8a40dWL7G3CoZT1PIK/f26Alcuzyz0TFlt0aRk1idOhamuxTAy5L7AEQ8zPX1paVV2 LTbgeEpw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyX-001Gd5-2q; Mon, 09 Dec 2024 12:59:22 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 02/28] ntsync: Introduce NTSYNC_IOC_WAIT_ALL. Date: Mon, 9 Dec 2024 12:58:38 -0600 Message-ID: <20241209185904.507350-3-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This is similar to NTSYNC_IOC_WAIT_ANY, but waits until all of the objects are simultaneously signaled, and then acquires all of them as a single atomic operation. Because acquisition of multiple objects is atomic, some complex locking is required. We cannot simply spin-lock multiple objects simultaneously, as that may disable preƫmption for a problematically long time. Instead, modifying any object which may be involved in a wait-all operation takes a device-wide sleeping mutex, "wait_all_lock", instead of the normal object spinlock. Because wait-for-all is a rare operation, in order to optimize wait-for-any, this lock is only taken when necessary. "all_hint" is used to mark objects which are involved in a wait-for-all operation, and if an object is not, only its spinlock is taken. The locking scheme used here was written by Peter Zijlstra. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 334 ++++++++++++++++++++++++++++++++++-- include/uapi/linux/ntsync.h | 1 + 2 files changed, 322 insertions(+), 13 deletions(-) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 2bfe5299f25b..0f4da571fa33 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ enum ntsync_type { struct ntsync_obj { spinlock_t lock; + int dev_locked; enum ntsync_type type; @@ -55,7 +57,30 @@ struct ntsync_obj { } sem; } u; + /* + * any_waiters is protected by the object lock, but all_waiters is + * protected by the device wait_all_lock. + */ struct list_head any_waiters; + struct list_head all_waiters; + + /* + * Hint describing how many tasks are queued on this object in a + * wait-all operation. + * + * Any time we do a wake, we may need to wake "all" waiters as well as + * "any" waiters. In order to atomically wake "all" waiters, we must + * lock all of the objects, and that means grabbing the wait_all_lock + * below (and, due to lock ordering rules, before locking this object). + * However, wait-all is a rare operation, and grabbing the wait-all + * lock for every wake would create unnecessary contention. + * Therefore we first check whether all_hint is zero, and, if it is, + * we skip trying to wake "all" waiters. + * + * Since wait requests must originate from user-space threads, we're + * limited here by PID_MAX_LIMIT, so there's no risk of overflow. + */ + atomic_t all_hint; }; struct ntsync_q_entry { @@ -75,19 +100,198 @@ struct ntsync_q { */ atomic_t signaled; + bool all; __u32 count; struct ntsync_q_entry entries[]; }; struct ntsync_device { + /* + * Wait-all operations must atomically grab all objects, and be totally + * ordered with respect to each other and wait-any operations. + * If one thread is trying to acquire several objects, another thread + * cannot touch the object at the same time. + * + * This device-wide lock is used to serialize wait-for-all + * operations, and operations on an object that is involved in a + * wait-for-all. + */ + struct mutex wait_all_lock; + struct file *file; }; +/* + * Single objects are locked using obj->lock. + * + * Multiple objects are 'locked' while holding dev->wait_all_lock. + * In this case however, individual objects are not locked by holding + * obj->lock, but by setting obj->dev_locked. + * + * This means that in order to lock a single object, the sequence is slightly + * more complicated than usual. Specifically it needs to check obj->dev_locked + * after acquiring obj->lock, if set, it needs to drop the lock and acquire + * dev->wait_all_lock in order to serialize against the multi-object operation. + */ + +static void dev_lock_obj(struct ntsync_device *dev, struct ntsync_obj *obj) +{ + lockdep_assert_held(&dev->wait_all_lock); + lockdep_assert(obj->dev == dev); + spin_lock(&obj->lock); + /* + * By setting obj->dev_locked inside obj->lock, it is ensured that + * anyone holding obj->lock must see the value. + */ + obj->dev_locked = 1; + spin_unlock(&obj->lock); +} + +static void dev_unlock_obj(struct ntsync_device *dev, struct ntsync_obj *obj) +{ + lockdep_assert_held(&dev->wait_all_lock); + lockdep_assert(obj->dev == dev); + spin_lock(&obj->lock); + obj->dev_locked = 0; + spin_unlock(&obj->lock); +} + +static void obj_lock(struct ntsync_obj *obj) +{ + struct ntsync_device *dev = obj->dev; + + for (;;) { + spin_lock(&obj->lock); + if (likely(!obj->dev_locked)) + break; + + spin_unlock(&obj->lock); + mutex_lock(&dev->wait_all_lock); + spin_lock(&obj->lock); + /* + * obj->dev_locked should be set and released under the same + * wait_all_lock section, since we now own this lock, it should + * be clear. + */ + lockdep_assert(!obj->dev_locked); + spin_unlock(&obj->lock); + mutex_unlock(&dev->wait_all_lock); + } +} + +static void obj_unlock(struct ntsync_obj *obj) +{ + spin_unlock(&obj->lock); +} + +static bool ntsync_lock_obj(struct ntsync_device *dev, struct ntsync_obj *obj) +{ + bool all; + + obj_lock(obj); + all = atomic_read(&obj->all_hint); + if (unlikely(all)) { + obj_unlock(obj); + mutex_lock(&dev->wait_all_lock); + dev_lock_obj(dev, obj); + } + + return all; +} + +static void ntsync_unlock_obj(struct ntsync_device *dev, struct ntsync_obj *obj, bool all) +{ + if (all) { + dev_unlock_obj(dev, obj); + mutex_unlock(&dev->wait_all_lock); + } else { + obj_unlock(obj); + } +} + +#define ntsync_assert_held(obj) \ + lockdep_assert((lockdep_is_held(&(obj)->lock) != LOCK_STATE_NOT_HELD) || \ + ((lockdep_is_held(&(obj)->dev->wait_all_lock) != LOCK_STATE_NOT_HELD) && \ + (obj)->dev_locked)) + +static bool is_signaled(struct ntsync_obj *obj) +{ + ntsync_assert_held(obj); + + switch (obj->type) { + case NTSYNC_TYPE_SEM: + return !!obj->u.sem.count; + } + + WARN(1, "bad object type %#x\n", obj->type); + return false; +} + +/* + * "locked_obj" is an optional pointer to an object which is already locked and + * should not be locked again. This is necessary so that changing an object's + * state and waking it can be a single atomic operation. + */ +static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q, + struct ntsync_obj *locked_obj) +{ + __u32 count = q->count; + bool can_wake = true; + int signaled = -1; + __u32 i; + + lockdep_assert_held(&dev->wait_all_lock); + if (locked_obj) + lockdep_assert(locked_obj->dev_locked); + + for (i = 0; i < count; i++) { + if (q->entries[i].obj != locked_obj) + dev_lock_obj(dev, q->entries[i].obj); + } + + for (i = 0; i < count; i++) { + if (!is_signaled(q->entries[i].obj)) { + can_wake = false; + break; + } + } + + if (can_wake && atomic_try_cmpxchg(&q->signaled, &signaled, 0)) { + for (i = 0; i < count; i++) { + struct ntsync_obj *obj = q->entries[i].obj; + + switch (obj->type) { + case NTSYNC_TYPE_SEM: + obj->u.sem.count--; + break; + } + } + wake_up_process(q->task); + } + + for (i = 0; i < count; i++) { + if (q->entries[i].obj != locked_obj) + dev_unlock_obj(dev, q->entries[i].obj); + } +} + +static void try_wake_all_obj(struct ntsync_device *dev, struct ntsync_obj *obj) +{ + struct ntsync_q_entry *entry; + + lockdep_assert_held(&dev->wait_all_lock); + lockdep_assert(obj->dev_locked); + + list_for_each_entry(entry, &obj->all_waiters, node) + try_wake_all(dev, entry->q, obj); +} + static void try_wake_any_sem(struct ntsync_obj *sem) { struct ntsync_q_entry *entry; - lockdep_assert_held(&sem->lock); + ntsync_assert_held(sem); + lockdep_assert(sem->type == NTSYNC_TYPE_SEM); list_for_each_entry(entry, &sem->any_waiters, node) { struct ntsync_q *q = entry->q; @@ -111,7 +315,7 @@ static int post_sem_state(struct ntsync_obj *sem, __u32 count) { __u32 sum; - lockdep_assert_held(&sem->lock); + ntsync_assert_held(sem); if (check_add_overflow(sem->u.sem.count, count, &sum) || sum > sem->u.sem.max) @@ -123,9 +327,11 @@ static int post_sem_state(struct ntsync_obj *sem, __u32 count) static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp) { + struct ntsync_device *dev = sem->dev; __u32 __user *user_args = argp; __u32 prev_count; __u32 args; + bool all; int ret; if (copy_from_user(&args, argp, sizeof(args))) @@ -134,14 +340,17 @@ static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp) if (sem->type != NTSYNC_TYPE_SEM) return -EINVAL; - spin_lock(&sem->lock); + all = ntsync_lock_obj(dev, sem); prev_count = sem->u.sem.count; ret = post_sem_state(sem, args); - if (!ret) + if (!ret) { + if (all) + try_wake_all_obj(dev, sem); try_wake_any_sem(sem); + } - spin_unlock(&sem->lock); + ntsync_unlock_obj(dev, sem, all); if (!ret && put_user(prev_count, user_args)) ret = -EFAULT; @@ -193,6 +402,8 @@ static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev, get_file(dev->file); spin_lock_init(&obj->lock); INIT_LIST_HEAD(&obj->any_waiters); + INIT_LIST_HEAD(&obj->all_waiters); + atomic_set(&obj->all_hint, 0); return obj; } @@ -304,7 +515,7 @@ static int ntsync_schedule(const struct ntsync_q *q, const struct ntsync_wait_ar * Allocate and initialize the ntsync_q structure, but do not queue us yet. */ static int setup_wait(struct ntsync_device *dev, - const struct ntsync_wait_args *args, + const struct ntsync_wait_args *args, bool all, struct ntsync_q **ret_q) { const __u32 count = args->count; @@ -327,6 +538,7 @@ static int setup_wait(struct ntsync_device *dev, return -ENOMEM; q->task = current; atomic_set(&q->signaled, -1); + q->all = all; q->count = count; for (i = 0; i < count; i++) { @@ -336,6 +548,16 @@ static int setup_wait(struct ntsync_device *dev, if (!obj) goto err; + if (all) { + /* Check that the objects are all distinct. */ + for (j = 0; j < i; j++) { + if (obj == q->entries[j].obj) { + put_obj(obj); + goto err; + } + } + } + entry->obj = obj; entry->q = q; entry->index = i; @@ -365,13 +587,14 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) struct ntsync_wait_args args; struct ntsync_q *q; int signaled; + bool all; __u32 i; int ret; if (copy_from_user(&args, argp, sizeof(args))) return -EFAULT; - ret = setup_wait(dev, &args, &q); + ret = setup_wait(dev, &args, false, &q); if (ret < 0) return ret; @@ -381,9 +604,9 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) struct ntsync_q_entry *entry = &q->entries[i]; struct ntsync_obj *obj = entry->obj; - spin_lock(&obj->lock); + all = ntsync_lock_obj(dev, obj); list_add_tail(&entry->node, &obj->any_waiters); - spin_unlock(&obj->lock); + ntsync_unlock_obj(dev, obj, all); } /* check if we are already signaled */ @@ -394,9 +617,9 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) if (atomic_read(&q->signaled) != -1) break; - spin_lock(&obj->lock); + all = ntsync_lock_obj(dev, obj); try_wake_any_obj(obj); - spin_unlock(&obj->lock); + ntsync_unlock_obj(dev, obj, all); } /* sleep */ @@ -409,9 +632,9 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) struct ntsync_q_entry *entry = &q->entries[i]; struct ntsync_obj *obj = entry->obj; - spin_lock(&obj->lock); + all = ntsync_lock_obj(dev, obj); list_del(&entry->node); - spin_unlock(&obj->lock); + ntsync_unlock_obj(dev, obj, all); put_obj(obj); } @@ -433,6 +656,87 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) return ret; } +static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp) +{ + struct ntsync_wait_args args; + struct ntsync_q *q; + int signaled; + __u32 i; + int ret; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + + ret = setup_wait(dev, &args, true, &q); + if (ret < 0) + return ret; + + /* queue ourselves */ + + mutex_lock(&dev->wait_all_lock); + + for (i = 0; i < args.count; i++) { + struct ntsync_q_entry *entry = &q->entries[i]; + struct ntsync_obj *obj = entry->obj; + + atomic_inc(&obj->all_hint); + + /* + * obj->all_waiters is protected by dev->wait_all_lock rather + * than obj->lock, so there is no need to acquire obj->lock + * here. + */ + list_add_tail(&entry->node, &obj->all_waiters); + } + + /* check if we are already signaled */ + + try_wake_all(dev, q, NULL); + + mutex_unlock(&dev->wait_all_lock); + + /* sleep */ + + ret = ntsync_schedule(q, &args); + + /* and finally, unqueue */ + + mutex_lock(&dev->wait_all_lock); + + for (i = 0; i < args.count; i++) { + struct ntsync_q_entry *entry = &q->entries[i]; + struct ntsync_obj *obj = entry->obj; + + /* + * obj->all_waiters is protected by dev->wait_all_lock rather + * than obj->lock, so there is no need to acquire it here. + */ + list_del(&entry->node); + + atomic_dec(&obj->all_hint); + + put_obj(obj); + } + + mutex_unlock(&dev->wait_all_lock); + + signaled = atomic_read(&q->signaled); + if (signaled != -1) { + struct ntsync_wait_args __user *user_args = argp; + + /* even if we caught a signal, we need to communicate success */ + ret = 0; + + if (put_user(signaled, &user_args->index)) + ret = -EFAULT; + } else if (!ret) { + ret = -ETIMEDOUT; + } + + kfree(q); + return ret; +} + static int ntsync_char_open(struct inode *inode, struct file *file) { struct ntsync_device *dev; @@ -441,6 +745,8 @@ static int ntsync_char_open(struct inode *inode, struct file *file) if (!dev) return -ENOMEM; + mutex_init(&dev->wait_all_lock); + file->private_data = dev; dev->file = file; return nonseekable_open(inode, file); @@ -464,6 +770,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case NTSYNC_IOC_CREATE_SEM: return ntsync_create_sem(dev, argp); + case NTSYNC_IOC_WAIT_ALL: + return ntsync_wait_all(dev, argp); case NTSYNC_IOC_WAIT_ANY: return ntsync_wait_any(dev, argp); default: diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index edc12c7a10dc..addf187b1573 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -31,6 +31,7 @@ struct ntsync_wait_args { #define NTSYNC_IOC_CREATE_SEM _IOWR('N', 0x80, struct ntsync_sem_args) #define NTSYNC_IOC_WAIT_ANY _IOWR('N', 0x82, struct ntsync_wait_args) +#define NTSYNC_IOC_WAIT_ALL _IOWR('N', 0x83, struct ntsync_wait_args) #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) From patchwork Mon Dec 9 18:58:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848515 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D48E19EEBD; Mon, 9 Dec 2024 19:03:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770992; cv=none; b=ABpSpVIRxADkCNbHMN68wGU2HaFWbkqAfEA0z8XUJQ2QBbZ/e5QW2PMEpKDg78OOww8zQ1Upf4w/5fe/qY4CXfh9NxQx99NFcp7+RkpMEPupUnW/FCGrGcg7zWeYnQMKp0wbGCENP4tAxfX0bjO9NbBSVGdmEP3tGVCRRzk/MjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770992; c=relaxed/simple; bh=cb66V+as2dtg11ZepZuG+P+2i30nRAGI6mzTBhnTPXA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kxh40kzz7B4/bV2c11pwsBhWpGwDorsdP5AEa8m8bc3fKAwYDHclxHWQONKdbWkyXbU4JsNxhsL8k7+gCc0OsZtj3DJLxs9I3OFPx35SY0KHWlo8ngcw0BR6Zo8KLlOB0s8VFIyn2cvD2bP6TnQsPem3ABwTyxAZbrK99nsiUaY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=YoYD28m+; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="YoYD28m+" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=dxkbSXM8+NdWh2nFtUMzBGZ7TbW5+CQh4cSgojs2gxI=; b=YoYD28m+ITVR0ID16a0s5ziDNj C2r92jaJxOYrUCfxRgrN5k4RwWqwVxshFCpBhkhKFzv3uBZa7YBo6Qif8yvN2d2E8fUqGo4NnA4nu /gzBtREwXpEzYwRmV+zeoXeoErzVwjB0ZIUalbEFeRBV5KcANT1vxpbadBbHvxZu4w5unoM/r5z6s cw+rW4NHSMwi+EgolbtPm8/MC0FfJVTIg6jrfjn/vo/to3vLhlFa04mKwUkyTX3JkC/w9EUGotpUG OXo2xKqXfbGYY61iVhbzZbKQTV4qvedxP9n+y+CwwcAVmJJaiIu4JWAvU9YCPO4uE7XkhVAwuG0Xt gEYB12Tg==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyY-001Gd5-15; Mon, 09 Dec 2024 12:59:22 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 03/28] ntsync: Introduce NTSYNC_IOC_CREATE_MUTEX. Date: Mon, 9 Dec 2024 12:58:39 -0600 Message-ID: <20241209185904.507350-4-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtCreateMutant(). An NT mutex is recursive, with a 32-bit recursion counter. When acquired via NtWaitForMultipleObjects(), the recursion counter is incremented by one. The OS records the thread which acquired it. The OS records the thread which acquired it. However, in order to keep this driver self-contained, the owning thread ID is managed by user-space, and passed as a parameter to all relevant ioctls. The initial owner and recursion count, if any, are specified when the mutex is created. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 77 +++++++++++++++++++++++++++++++++++-- include/uapi/linux/ntsync.h | 10 ++++- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 0f4da571fa33..30c0bbb442da 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -25,6 +25,7 @@ enum ntsync_type { NTSYNC_TYPE_SEM, + NTSYNC_TYPE_MUTEX, }; /* @@ -55,6 +56,10 @@ struct ntsync_obj { __u32 count; __u32 max; } sem; + struct { + __u32 count; + pid_t owner; + } mutex; } u; /* @@ -92,6 +97,7 @@ struct ntsync_q_entry { struct ntsync_q { struct task_struct *task; + __u32 owner; /* * Protected via atomic_try_cmpxchg(). Only the thread that wins the @@ -214,13 +220,17 @@ static void ntsync_unlock_obj(struct ntsync_device *dev, struct ntsync_obj *obj, ((lockdep_is_held(&(obj)->dev->wait_all_lock) != LOCK_STATE_NOT_HELD) && \ (obj)->dev_locked)) -static bool is_signaled(struct ntsync_obj *obj) +static bool is_signaled(struct ntsync_obj *obj, __u32 owner) { ntsync_assert_held(obj); switch (obj->type) { case NTSYNC_TYPE_SEM: return !!obj->u.sem.count; + case NTSYNC_TYPE_MUTEX: + if (obj->u.mutex.owner && obj->u.mutex.owner != owner) + return false; + return obj->u.mutex.count < UINT_MAX; } WARN(1, "bad object type %#x\n", obj->type); @@ -250,7 +260,7 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q, } for (i = 0; i < count; i++) { - if (!is_signaled(q->entries[i].obj)) { + if (!is_signaled(q->entries[i].obj, q->owner)) { can_wake = false; break; } @@ -264,6 +274,10 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q, case NTSYNC_TYPE_SEM: obj->u.sem.count--; break; + case NTSYNC_TYPE_MUTEX: + obj->u.mutex.count++; + obj->u.mutex.owner = q->owner; + break; } } wake_up_process(q->task); @@ -307,6 +321,30 @@ static void try_wake_any_sem(struct ntsync_obj *sem) } } +static void try_wake_any_mutex(struct ntsync_obj *mutex) +{ + struct ntsync_q_entry *entry; + + ntsync_assert_held(mutex); + lockdep_assert(mutex->type == NTSYNC_TYPE_MUTEX); + + list_for_each_entry(entry, &mutex->any_waiters, node) { + struct ntsync_q *q = entry->q; + int signaled = -1; + + if (mutex->u.mutex.count == UINT_MAX) + break; + if (mutex->u.mutex.owner && mutex->u.mutex.owner != q->owner) + continue; + + if (atomic_try_cmpxchg(&q->signaled, &signaled, entry->index)) { + mutex->u.mutex.count++; + mutex->u.mutex.owner = q->owner; + wake_up_process(q->task); + } + } +} + /* * Actually change the semaphore state, returning -EOVERFLOW if it is made * invalid. @@ -454,6 +492,33 @@ static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp) return put_user(fd, &user_args->sem); } +static int ntsync_create_mutex(struct ntsync_device *dev, void __user *argp) +{ + struct ntsync_mutex_args __user *user_args = argp; + struct ntsync_mutex_args args; + struct ntsync_obj *mutex; + int fd; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + + if (!args.owner != !args.count) + return -EINVAL; + + mutex = ntsync_alloc_obj(dev, NTSYNC_TYPE_MUTEX); + if (!mutex) + return -ENOMEM; + mutex->u.mutex.count = args.count; + mutex->u.mutex.owner = args.owner; + fd = ntsync_obj_get_fd(mutex); + if (fd < 0) { + kfree(mutex); + return fd; + } + + return put_user(fd, &user_args->mutex); +} + static struct ntsync_obj *get_obj(struct ntsync_device *dev, int fd) { struct file *file = fget(fd); @@ -523,7 +588,7 @@ static int setup_wait(struct ntsync_device *dev, struct ntsync_q *q; __u32 i, j; - if (args->pad[0] || args->pad[1] || args->pad[2] || (args->flags & ~NTSYNC_WAIT_REALTIME)) + if (args->pad[0] || args->pad[1] || (args->flags & ~NTSYNC_WAIT_REALTIME)) return -EINVAL; if (args->count > NTSYNC_MAX_WAIT_COUNT) @@ -537,6 +602,7 @@ static int setup_wait(struct ntsync_device *dev, if (!q) return -ENOMEM; q->task = current; + q->owner = args->owner; atomic_set(&q->signaled, -1); q->all = all; q->count = count; @@ -579,6 +645,9 @@ static void try_wake_any_obj(struct ntsync_obj *obj) case NTSYNC_TYPE_SEM: try_wake_any_sem(obj); break; + case NTSYNC_TYPE_MUTEX: + try_wake_any_mutex(obj); + break; } } @@ -768,6 +837,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd, void __user *argp = (void __user *)parm; switch (cmd) { + case NTSYNC_IOC_CREATE_MUTEX: + return ntsync_create_mutex(dev, argp); case NTSYNC_IOC_CREATE_SEM: return ntsync_create_sem(dev, argp); case NTSYNC_IOC_WAIT_ALL: diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index addf187b1573..d5e5a2fbcb4d 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -16,6 +16,12 @@ struct ntsync_sem_args { __u32 max; }; +struct ntsync_mutex_args { + __u32 mutex; + __u32 owner; + __u32 count; +}; + #define NTSYNC_WAIT_REALTIME 0x1 struct ntsync_wait_args { @@ -24,7 +30,8 @@ struct ntsync_wait_args { __u32 count; __u32 index; __u32 flags; - __u32 pad[3]; + __u32 owner; + __u32 pad[2]; }; #define NTSYNC_MAX_WAIT_COUNT 64 @@ -32,6 +39,7 @@ struct ntsync_wait_args { #define NTSYNC_IOC_CREATE_SEM _IOWR('N', 0x80, struct ntsync_sem_args) #define NTSYNC_IOC_WAIT_ANY _IOWR('N', 0x82, struct ntsync_wait_args) #define NTSYNC_IOC_WAIT_ALL _IOWR('N', 0x83, struct ntsync_wait_args) +#define NTSYNC_IOC_CREATE_MUTEX _IOWR('N', 0x84, struct ntsync_sem_args) #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) From patchwork Mon Dec 9 18:58:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849508 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11C2919E994; Mon, 9 Dec 2024 19:03:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770989; cv=none; b=gA97InJh1C9NaLe2BJAvbfwVMonnlpNhUJoN+5sfC/ZYkdAdsLFHBhMth59yhH2yOimy3dPlzUPvOwQKd0XQ8pqvlKNxBo5GP1UAdfRM+EmRz10D18TeANZfyGXR3rwOlSUuQZYjMfWHDT2YpHsknZwzSFwCrULAkEkbqzNPNds= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770989; c=relaxed/simple; bh=GAa18Bd7nhx82olyDjSIwbRvFLAnatHmswpiZ5FPpiQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=awfs9oJfg/fBp+46bfT0WSNX/CHOzTQ7I/w++i/S53WAZK7BBRbgwFhyI46O6sbN+zbdhFd40Y9nMMkOsB6MhT5FQ8S6dktewBDBcgPXzNVNWwK2xJTQ+11wXrLjjuePTgkF2wVhvXIPGqTfmQZnGW/Zu0BA8aXRL3qHsSP3en4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=jpfF5LnA; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="jpfF5LnA" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=eA2+a+04KbrRZRQwWNdZXxbFZIMYyTY06utUL8v2RwI=; b=jpfF5LnAhAIOU6ZZq/IkxFzUse JZwCUsAEq5HYWEuWXtoYwGku64IFhq0DwTnpEloLKZPiSrYC2mkDNEsk2z64pRMUOnfdzXj9/UWmR uImRTdCY5VVD/j6CtFoHc4EIZ7+26pI/+zoJLnozuLJgeI8fw7JhfCp8y/yrfMLa8iq1WT7ilD57G ir6JI+g5O5U3torDk7wGzDVoT2S/Q1KwG264JSF/GA4cL/30JMTqgUU9iqC2pf5dSaOa2mOC/u2cd iHU7LxMA8ZCMCJXT7zmObQaxwJxkQAAcA+Y/1ffcCZdwWhlVJBwMU35Z1K7naL8ZuI/17EbvplPVf cGjsUrgA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyY-001Gd5-1f; Mon, 09 Dec 2024 12:59:22 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 04/28] ntsync: Introduce NTSYNC_IOC_MUTEX_UNLOCK. Date: Mon, 9 Dec 2024 12:58:40 -0600 Message-ID: <20241209185904.507350-5-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtReleaseMutant(). This syscall decrements the mutex's recursion count by one, and returns the previous value. If the mutex is not owned by the current task, the function instead fails and returns -EPERM. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 53 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 54 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 30c0bbb442da..6ed278c17be9 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -396,6 +396,57 @@ static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp) return ret; } +/* + * Actually change the mutex state, returning -EPERM if not the owner. + */ +static int unlock_mutex_state(struct ntsync_obj *mutex, + const struct ntsync_mutex_args *args) +{ + ntsync_assert_held(mutex); + + if (mutex->u.mutex.owner != args->owner) + return -EPERM; + + if (!--mutex->u.mutex.count) + mutex->u.mutex.owner = 0; + return 0; +} + +static int ntsync_mutex_unlock(struct ntsync_obj *mutex, void __user *argp) +{ + struct ntsync_mutex_args __user *user_args = argp; + struct ntsync_device *dev = mutex->dev; + struct ntsync_mutex_args args; + __u32 prev_count; + bool all; + int ret; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + if (!args.owner) + return -EINVAL; + + if (mutex->type != NTSYNC_TYPE_MUTEX) + return -EINVAL; + + all = ntsync_lock_obj(dev, mutex); + + prev_count = mutex->u.mutex.count; + ret = unlock_mutex_state(mutex, &args); + if (!ret) { + if (all) + try_wake_all_obj(dev, mutex); + try_wake_any_mutex(mutex); + } + + ntsync_unlock_obj(dev, mutex, all); + + if (!ret && put_user(prev_count, &user_args->count)) + ret = -EFAULT; + + return ret; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -415,6 +466,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case NTSYNC_IOC_SEM_POST: return ntsync_sem_post(obj, argp); + case NTSYNC_IOC_MUTEX_UNLOCK: + return ntsync_mutex_unlock(obj, argp); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index d5e5a2fbcb4d..a633db34f284 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -42,5 +42,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_CREATE_MUTEX _IOWR('N', 0x84, struct ntsync_sem_args) #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) +#define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('N', 0x85, struct ntsync_mutex_args) #endif From patchwork Mon Dec 9 18:58:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848514 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB9D91A9B45; Mon, 9 Dec 2024 19:03:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771000; cv=none; b=OgfKWBVDIMsYOMKsl9Lhlgxb0AYfZQdEOGmGxFXZX8y5fFkbzkEMPLO0VOJ+wpo1omg89ukUXC3iXz4yiNLqoDdZIagGqKzmKnuTGNrIJvUX2M/+DTIzhNm1+Oa+msLkisKzqVmt7s6JL+bT8CSYVzb5STZrN+3JPKHkrRXGi6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771000; c=relaxed/simple; bh=RjMIMeG6KnVk8HqQ6wwOgtfvSlf5nhwkGOnftj/ll5o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KCFW/YCDrT7U/z7NClvMFB73WPK/aw+VHzKPA3qO3XOhtO8LvYdJjbrLZ5iIIcQebMnhH1yN+8cQ8sQMCddWB2l4peWHYSUnW/qKPmGW9+FDGN6I2jU5Dj/bSD5SggstUxD/NJzrPJLD+V0mfAbWbUV8+91nQ0byp1yXg0719MU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=NFey2SuS; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="NFey2SuS" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=InRezP3YW9qasHnPVT+1MKLKEEmKziLa94eVnmfKD/s=; b=NFey2SuSLSxS6Tiypbv0yntzkk Uzb5HAIgOkBxUMDiCpn3mOKBXS3sS60zixtEs30Wp+psJFjcupchrH3pa6MeiZY/QqyOnKt/LpcNt tnIEZmjiHpUCt0wwyKQdtov10+qsC8l7x1yz79DAZP1EmoAzF3CajHns82BL4qyVxphx1SOyAFevR kNVgLIiTWk4GIMlpp4iSDozZ9Zf8OeFaYOBXHmJ3TI3tUYCgEpOrIqvZufN6Or5AOMdz7h4tKdKuh prtq04W4EaQk5jOwYYFR83pqP6NG5RbP1weuEj+wGKZ5gLodQqkLu7GzKLod5Hml//gUaK/rowJj3 CvO2ncyQ==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyY-001Gd5-2B; Mon, 09 Dec 2024 12:59:22 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 05/28] ntsync: Introduce NTSYNC_IOC_MUTEX_KILL. Date: Mon, 9 Dec 2024 12:58:41 -0600 Message-ID: <20241209185904.507350-6-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This does not correspond to any NT syscall. Rather, when a thread dies, it should be called by the NT emulator for each mutex, with the TID of the dying thread. NT mutexes are robust (in the pthread sense). When an NT thread dies, any mutexes it owned are immediately released. Acquisition of those mutexes by other threads will return a special value indicating that the mutex was abandoned, like EOWNERDEAD returned from pthread_mutex_lock(), and EOWNERDEAD is indeed used here for that purpose. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 61 +++++++++++++++++++++++++++++++++++-- include/uapi/linux/ntsync.h | 1 + 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 6ed278c17be9..0ed864d291a6 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -59,6 +59,7 @@ struct ntsync_obj { struct { __u32 count; pid_t owner; + bool ownerdead; } mutex; } u; @@ -107,6 +108,7 @@ struct ntsync_q { atomic_t signaled; bool all; + bool ownerdead; __u32 count; struct ntsync_q_entry entries[]; }; @@ -275,6 +277,9 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q, obj->u.sem.count--; break; case NTSYNC_TYPE_MUTEX: + if (obj->u.mutex.ownerdead) + q->ownerdead = true; + obj->u.mutex.ownerdead = false; obj->u.mutex.count++; obj->u.mutex.owner = q->owner; break; @@ -338,6 +343,9 @@ static void try_wake_any_mutex(struct ntsync_obj *mutex) continue; if (atomic_try_cmpxchg(&q->signaled, &signaled, entry->index)) { + if (mutex->u.mutex.ownerdead) + q->ownerdead = true; + mutex->u.mutex.ownerdead = false; mutex->u.mutex.count++; mutex->u.mutex.owner = q->owner; wake_up_process(q->task); @@ -447,6 +455,52 @@ static int ntsync_mutex_unlock(struct ntsync_obj *mutex, void __user *argp) return ret; } +/* + * Actually change the mutex state to mark its owner as dead, + * returning -EPERM if not the owner. + */ +static int kill_mutex_state(struct ntsync_obj *mutex, __u32 owner) +{ + ntsync_assert_held(mutex); + + if (mutex->u.mutex.owner != owner) + return -EPERM; + + mutex->u.mutex.ownerdead = true; + mutex->u.mutex.owner = 0; + mutex->u.mutex.count = 0; + return 0; +} + +static int ntsync_mutex_kill(struct ntsync_obj *mutex, void __user *argp) +{ + struct ntsync_device *dev = mutex->dev; + __u32 owner; + bool all; + int ret; + + if (get_user(owner, (__u32 __user *)argp)) + return -EFAULT; + if (!owner) + return -EINVAL; + + if (mutex->type != NTSYNC_TYPE_MUTEX) + return -EINVAL; + + all = ntsync_lock_obj(dev, mutex); + + ret = kill_mutex_state(mutex, owner); + if (!ret) { + if (all) + try_wake_all_obj(dev, mutex); + try_wake_any_mutex(mutex); + } + + ntsync_unlock_obj(dev, mutex, all); + + return ret; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -468,6 +522,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, return ntsync_sem_post(obj, argp); case NTSYNC_IOC_MUTEX_UNLOCK: return ntsync_mutex_unlock(obj, argp); + case NTSYNC_IOC_MUTEX_KILL: + return ntsync_mutex_kill(obj, argp); default: return -ENOIOCTLCMD; } @@ -658,6 +714,7 @@ static int setup_wait(struct ntsync_device *dev, q->owner = args->owner; atomic_set(&q->signaled, -1); q->all = all; + q->ownerdead = false; q->count = count; for (i = 0; i < count; i++) { @@ -766,7 +823,7 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) struct ntsync_wait_args __user *user_args = argp; /* even if we caught a signal, we need to communicate success */ - ret = 0; + ret = q->ownerdead ? -EOWNERDEAD : 0; if (put_user(signaled, &user_args->index)) ret = -EFAULT; @@ -847,7 +904,7 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp) struct ntsync_wait_args __user *user_args = argp; /* even if we caught a signal, we need to communicate success */ - ret = 0; + ret = q->ownerdead ? -EOWNERDEAD : 0; if (put_user(signaled, &user_args->index)) ret = -EFAULT; diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index a633db34f284..d7996180c1d2 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -43,5 +43,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) #define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('N', 0x85, struct ntsync_mutex_args) +#define NTSYNC_IOC_MUTEX_KILL _IOW ('N', 0x86, __u32) #endif From patchwork Mon Dec 9 18:58:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849507 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9617A1A707A; Mon, 9 Dec 2024 19:03:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770995; cv=none; b=Gnfs/Ehi6K+DItMkPWFGIPXJNfFiGk1uzDfgA7BLMhcZmot0WhDrkAeinKGcZUrbD7ge5aGNhUn4cvTRolJjiAw/eKAW/tZJRFlqJAOSynibsLMT1cS3J4AxSLCm6vFryimacSry7tOZuShz6/p+0MDceDGwQueyMHTfSe4QHUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770995; c=relaxed/simple; bh=CSWtZmYdEPGFhBHR00Jti0zhe4Sl3AMpzKwLnC89Cbs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aYHQMo4b7Ppt4KDxsN3QkG5NizjZvFr+EF9NxxHe3zTSHfdTlJ3zc2ibOdjPTXvQmMiS/nMaTRCBENpb+grdwihA5NaJbQ6iRWPpt+CEBpAf+uTgjERMwP0edXdRCRO4c1hhMuobPNO/ygDG6bkkgBjI+8iZ/ntuUqNbcmV9e2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=iaR8KX+p; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="iaR8KX+p" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=SN9QY4qrQDEzA/GyZ+ov1ABljEcCDLyc0yuR+RDikLY=; b=iaR8KX+pTAiTcpKsay91WO9/mM rswAT6SQMlJadz5QUpevtvu6zePqFj+YHOp2kr1AEiRJxwNr1n1vaMTDKwN37SaRXHISMjga+8har +XBsj1h+LXYN+GepNAY69LvNJ7mn2Eik659pP0mshLS7OpuAipK068yq7xsFSNw550B9jBYpFdWLh nE15uf03XC/iYmOIzkwc4L+WVmC3/ZQlAYOPquuQ6s5HPG/ufX0KcoLHA0MeYOF8+LIVWLu4PoZxH n/bNsmdCDNlBMh9tdLKkR0E5pfBC3xCP70pCTkIuH4fBQ1PcmoBgwFTnZ26PJd2/1Q4pspCqeiAYy 9NTq3nMw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyY-001Gd5-2f; Mon, 09 Dec 2024 12:59:23 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 06/28] ntsync: Introduce NTSYNC_IOC_CREATE_EVENT. Date: Mon, 9 Dec 2024 12:58:42 -0600 Message-ID: <20241209185904.507350-7-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This correspond to the NT syscall NtCreateEvent(). An NT event holds a single bit of state denoting whether it is signaled or unsignaled. There are two types of events: manual-reset and automatic-reset. When an automatic-reset event is acquired via a wait function, its state is reset to unsignaled. Manual-reset events are not affected by wait functions. Whether the event is manual-reset, and its initial state, are specified at creation time. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 62 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 7 +++++ 2 files changed, 69 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 0ed864d291a6..ef8949ee2d4b 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -26,6 +26,7 @@ enum ntsync_type { NTSYNC_TYPE_SEM, NTSYNC_TYPE_MUTEX, + NTSYNC_TYPE_EVENT, }; /* @@ -61,6 +62,10 @@ struct ntsync_obj { pid_t owner; bool ownerdead; } mutex; + struct { + bool manual; + bool signaled; + } event; } u; /* @@ -233,6 +238,8 @@ static bool is_signaled(struct ntsync_obj *obj, __u32 owner) if (obj->u.mutex.owner && obj->u.mutex.owner != owner) return false; return obj->u.mutex.count < UINT_MAX; + case NTSYNC_TYPE_EVENT: + return obj->u.event.signaled; } WARN(1, "bad object type %#x\n", obj->type); @@ -283,6 +290,10 @@ static void try_wake_all(struct ntsync_device *dev, struct ntsync_q *q, obj->u.mutex.count++; obj->u.mutex.owner = q->owner; break; + case NTSYNC_TYPE_EVENT: + if (!obj->u.event.manual) + obj->u.event.signaled = false; + break; } } wake_up_process(q->task); @@ -353,6 +364,28 @@ static void try_wake_any_mutex(struct ntsync_obj *mutex) } } +static void try_wake_any_event(struct ntsync_obj *event) +{ + struct ntsync_q_entry *entry; + + ntsync_assert_held(event); + lockdep_assert(event->type == NTSYNC_TYPE_EVENT); + + list_for_each_entry(entry, &event->any_waiters, node) { + struct ntsync_q *q = entry->q; + int signaled = -1; + + if (!event->u.event.signaled) + break; + + if (atomic_try_cmpxchg(&q->signaled, &signaled, entry->index)) { + if (!event->u.event.manual) + event->u.event.signaled = false; + wake_up_process(q->task); + } + } +} + /* * Actually change the semaphore state, returning -EOVERFLOW if it is made * invalid. @@ -628,6 +661,30 @@ static int ntsync_create_mutex(struct ntsync_device *dev, void __user *argp) return put_user(fd, &user_args->mutex); } +static int ntsync_create_event(struct ntsync_device *dev, void __user *argp) +{ + struct ntsync_event_args __user *user_args = argp; + struct ntsync_event_args args; + struct ntsync_obj *event; + int fd; + + if (copy_from_user(&args, argp, sizeof(args))) + return -EFAULT; + + event = ntsync_alloc_obj(dev, NTSYNC_TYPE_EVENT); + if (!event) + return -ENOMEM; + event->u.event.manual = args.manual; + event->u.event.signaled = args.signaled; + fd = ntsync_obj_get_fd(event); + if (fd < 0) { + kfree(event); + return fd; + } + + return put_user(fd, &user_args->event); +} + static struct ntsync_obj *get_obj(struct ntsync_device *dev, int fd) { struct file *file = fget(fd); @@ -758,6 +815,9 @@ static void try_wake_any_obj(struct ntsync_obj *obj) case NTSYNC_TYPE_MUTEX: try_wake_any_mutex(obj); break; + case NTSYNC_TYPE_EVENT: + try_wake_any_event(obj); + break; } } @@ -947,6 +1007,8 @@ static long ntsync_char_ioctl(struct file *file, unsigned int cmd, void __user *argp = (void __user *)parm; switch (cmd) { + case NTSYNC_IOC_CREATE_EVENT: + return ntsync_create_event(dev, argp); case NTSYNC_IOC_CREATE_MUTEX: return ntsync_create_mutex(dev, argp); case NTSYNC_IOC_CREATE_SEM: diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index d7996180c1d2..4c0c4271c7de 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -22,6 +22,12 @@ struct ntsync_mutex_args { __u32 count; }; +struct ntsync_event_args { + __u32 event; + __u32 manual; + __u32 signaled; +}; + #define NTSYNC_WAIT_REALTIME 0x1 struct ntsync_wait_args { @@ -40,6 +46,7 @@ struct ntsync_wait_args { #define NTSYNC_IOC_WAIT_ANY _IOWR('N', 0x82, struct ntsync_wait_args) #define NTSYNC_IOC_WAIT_ALL _IOWR('N', 0x83, struct ntsync_wait_args) #define NTSYNC_IOC_CREATE_MUTEX _IOWR('N', 0x84, struct ntsync_sem_args) +#define NTSYNC_IOC_CREATE_EVENT _IOWR('N', 0x87, struct ntsync_event_args) #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) #define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('N', 0x85, struct ntsync_mutex_args) From patchwork Mon Dec 9 18:58:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848512 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99D741AAA1E; Mon, 9 Dec 2024 19:03:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771012; cv=none; b=CELSaWgdLtA6Y7JaUmZQiLvfg0zdXoFTWi70yQovLl+jzKRvL19dQlf1v9bYBmN2zeuyLzMrdPFyVDmODY7HIGqDZtqOmBIVWeKfN2v+nSdG9Z+sCy7cXzjR9uQg9x5EqSc/EgbDFEZTVceKr0KkgIFmf7mxknCfrc/SiX802u4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771012; c=relaxed/simple; bh=GCclaYD7Lnuw+7ZXZ67vQpIZFd1eu5iixpNSq67pdLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h9gnu9EeFtuKeQzfpXuFTYeYOXSxvHtv5Q7aoDQRCasc2QJfiyXaTaTpLmkMwB8pnWHvZSz1vyuhHoIhufik7YJAcE+CZK/Ec/1vtqm94pmQFpkYdgBqid5Q5SpdCZfxmrH8zHrjwwcTHnOQVTP/kl8LbqUBtJkc7M1TsmUbaUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=U2QCE+6q; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="U2QCE+6q" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=QpEYXS4YpYSMYz8PJzgw6Icn6C0+RwpfhQeNTELXtqw=; b=U2QCE+6qaNm3kXKcxcDCud+pDx hzyWvJEEkqtAM/XbWk3B4zZwRNzl7Jnl+moFmj+0es+cg4pTthS2b3mmI9MpUqUx0nIDfRflgPOcR vhVNXMwZDlA8If5+e4yego9K5tkfyQmArM7fdbgbFUN0juI503WjkGl+sOqa5+4XF4sX2t6RrDC3E xLGh2CCWtY7rR19TmbNMq4LBHPtJJ9vqKaaK4YUgGz0COruHAOnSZLk/ZoswkxzbWeUwFECE3eg7P ZAoOsooJ4hYnvOimO1DdGg0F+W1GfOhk0sBYk2D7b7a5++bQ6JtlAYul7xPozXJuQiGPdGyVxHQ4m iZL00DOg==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyZ-001Gd5-2j; Mon, 09 Dec 2024 12:59:23 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 07/28] ntsync: Introduce NTSYNC_IOC_EVENT_SET. Date: Mon, 9 Dec 2024 12:58:43 -0600 Message-ID: <20241209185904.507350-8-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtSetEvent(). This sets the event to the signaled state, and returns its previous state. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 27 +++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 28 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index ef8949ee2d4b..e46dd795370a 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -534,6 +534,31 @@ static int ntsync_mutex_kill(struct ntsync_obj *mutex, void __user *argp) return ret; } +static int ntsync_event_set(struct ntsync_obj *event, void __user *argp) +{ + struct ntsync_device *dev = event->dev; + __u32 prev_state; + bool all; + + if (event->type != NTSYNC_TYPE_EVENT) + return -EINVAL; + + all = ntsync_lock_obj(dev, event); + + prev_state = event->u.event.signaled; + event->u.event.signaled = true; + if (all) + try_wake_all_obj(dev, event); + try_wake_any_event(event); + + ntsync_unlock_obj(dev, event, all); + + if (put_user(prev_state, (__u32 __user *)argp)) + return -EFAULT; + + return 0; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -557,6 +582,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, return ntsync_mutex_unlock(obj, argp); case NTSYNC_IOC_MUTEX_KILL: return ntsync_mutex_kill(obj, argp); + case NTSYNC_IOC_EVENT_SET: + return ntsync_event_set(obj, argp); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 4c0c4271c7de..36d903521bbe 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -51,5 +51,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_SEM_POST _IOWR('N', 0x81, __u32) #define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('N', 0x85, struct ntsync_mutex_args) #define NTSYNC_IOC_MUTEX_KILL _IOW ('N', 0x86, __u32) +#define NTSYNC_IOC_EVENT_SET _IOR ('N', 0x88, __u32) #endif From patchwork Mon Dec 9 18:58:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849509 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C45E219CC11; Mon, 9 Dec 2024 19:03:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770984; cv=none; b=AkyCZO/KK5ebCvrOPMqaa0iTX6DtDOup+JK35paz+sMRbKtC4ivQLugskysCTIIovy4USOSpaZwHrc2YCgPFJwqrUWzTLzbtxFC4AFMKUoAZ/fcNLRLM1Dh3hPNYsswDr33yr+tMZxAWqMt14yN7nbaKpPvcysmCLJXT1im6XZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770984; c=relaxed/simple; bh=vxXfnHos8ZGQdxrvftHEImXmIlo+QOSkWE3JMqlp5kY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QzZWWlvTJdFncnOp40bPWmbZN6i4j69KabeXYBDwn0h7JmTM3U7vExFZMEtCsIaj9C+QtGgLAR99+NhAiGs2g2yByNyzQ3fO4dXj3UqtwKw3ifYvzUHzrSyiry7r/R+ik3qbQ6VjDHtha6gA2UwUbzHUVY6WPI9BX2hXNbBx/DM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=XWibcmPP; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="XWibcmPP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Ra2mZC+0tmcZOlBPX+RrAk3bBDA6gL8zBbxIVdBXqB8=; b=XWibcmPPRA3ss9kwWnB6EWUs0v Mku8Aw270qjphG2Nl2bCDZZ/wiXTuKs4v6fy1eHW7HffcogtXAcvOWixo2JvmUGCXvdg9c9MawPuw SE1TQSbIo8YnCAQIth3xcYI/S191klAIOOMst+9CxlpEtstXbkM5kbYHgRErMFxx2RHp/95skQ1Ca +15Vd74ziw/UJ/JVfv2zbU3vQ74I8JnOV3D4K5WQqTP2evPF2WNkHlVy9m7IzPOEFRGFNpxA9W0Rk FY+FfWdBhmUzsYi5jAe8nhFzlffdSsckFxehx4NawyLWrQQqH9BDFIgGXDIBGRfz+6oOLzq2fv18y 7iJiApyQ==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiya-001Gd5-13; Mon, 09 Dec 2024 12:59:24 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 08/28] ntsync: Introduce NTSYNC_IOC_EVENT_RESET. Date: Mon, 9 Dec 2024 12:58:44 -0600 Message-ID: <20241209185904.507350-9-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtResetEvent(). This sets the event to the unsignaled state, and returns its previous state. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 24 ++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index e46dd795370a..092133699193 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -559,6 +559,28 @@ static int ntsync_event_set(struct ntsync_obj *event, void __user *argp) return 0; } +static int ntsync_event_reset(struct ntsync_obj *event, void __user *argp) +{ + struct ntsync_device *dev = event->dev; + __u32 prev_state; + bool all; + + if (event->type != NTSYNC_TYPE_EVENT) + return -EINVAL; + + all = ntsync_lock_obj(dev, event); + + prev_state = event->u.event.signaled; + event->u.event.signaled = false; + + ntsync_unlock_obj(dev, event, all); + + if (put_user(prev_state, (__u32 __user *)argp)) + return -EFAULT; + + return 0; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -584,6 +606,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, return ntsync_mutex_kill(obj, argp); case NTSYNC_IOC_EVENT_SET: return ntsync_event_set(obj, argp); + case NTSYNC_IOC_EVENT_RESET: + return ntsync_event_reset(obj, argp); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 36d903521bbe..7fdf79729b20 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -52,5 +52,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_MUTEX_UNLOCK _IOWR('N', 0x85, struct ntsync_mutex_args) #define NTSYNC_IOC_MUTEX_KILL _IOW ('N', 0x86, __u32) #define NTSYNC_IOC_EVENT_SET _IOR ('N', 0x88, __u32) +#define NTSYNC_IOC_EVENT_RESET _IOR ('N', 0x89, __u32) #endif From patchwork Mon Dec 9 18:58:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848517 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C553B19C561; Mon, 9 Dec 2024 19:02:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770978; cv=none; b=qspKqpe109QN/Sm4LYbHPLPHaMW3W1opR8p2fEPmTz4hu9rk4yFheeX46tMzmPpcRcF1l8ATvjt1h2VUeMMqiYJcRgZ0z49M7DobKb0raowVig9Zlfi8xkdlM2pi1HfD0LFErDk7EqoWG4etipoGKbVW3Zas6OkIRBdZm33DseI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770978; c=relaxed/simple; bh=7i5E4uFe34oquEMewE/pLncQW1byrNS5NnsfpLRwUo0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AKU6wNuFJleSRfFmY/dqJzM5TqVpZEt0CSorG1zpq1ZzoPS0jfjCcoLRkcec2SROjmeN7xt0vab7dhPKTF7n3pBcWFh7Svvjs8nnYs7yBRs6jLazZa+baRxDgkeCimUbHFb6VzuUsZvzYqdia7Xt50vg4iJfMmjRkxh4wY/PEU8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=hiYmEJgi; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="hiYmEJgi" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=UpBPK/F1HsD4cQEIcsfdrWRgX1ty6ZDxQwnbUJGmyMA=; b=hiYmEJgi3E9BhoRAHMWzxVx4an RqS+294dbsQtgJXm8kfBuEOrCtunfFefLXVbDwoRTYah2bUv76XScq5mGxeOED/dZuaFuzKGsux9j zkKVmXR157GHmW4XI0DzXr5ZzUT6KKd8Jkb/rm6eOA4tecUWEQgcTepaX/at1ugDQYJUOP/wxVSuw nTM7y/uwZDdKE9pI6SBPpSeHNzclXkWMHyXzg32KoxstNpMAmSoo8H6mmGOAzZKHTjTgsIGYRWUH2 FilzUNuBmGXGH7XmYxWYRf7P6xvMdu7Xr0CWlTjFjkOOhrDPNEisguSl+iCqG07XCnNYVHXH8VESR QAkDAlZA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiya-001Gd5-2M; Mon, 09 Dec 2024 12:59:24 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 09/28] ntsync: Introduce NTSYNC_IOC_EVENT_PULSE. Date: Mon, 9 Dec 2024 12:58:45 -0600 Message-ID: <20241209185904.507350-10-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtPulseEvent(). This wakes up any waiters as if the event had been set, but does not set the event, instead resetting it if it had been signalled. Thus, for a manual-reset event, all waiters are woken, whereas for an auto-reset event, at most one waiter is woken. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 8 ++++++-- include/uapi/linux/ntsync.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 092133699193..6b8352270874 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -534,7 +534,7 @@ static int ntsync_mutex_kill(struct ntsync_obj *mutex, void __user *argp) return ret; } -static int ntsync_event_set(struct ntsync_obj *event, void __user *argp) +static int ntsync_event_set(struct ntsync_obj *event, void __user *argp, bool pulse) { struct ntsync_device *dev = event->dev; __u32 prev_state; @@ -550,6 +550,8 @@ static int ntsync_event_set(struct ntsync_obj *event, void __user *argp) if (all) try_wake_all_obj(dev, event); try_wake_any_event(event); + if (pulse) + event->u.event.signaled = false; ntsync_unlock_obj(dev, event, all); @@ -605,9 +607,11 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, case NTSYNC_IOC_MUTEX_KILL: return ntsync_mutex_kill(obj, argp); case NTSYNC_IOC_EVENT_SET: - return ntsync_event_set(obj, argp); + return ntsync_event_set(obj, argp, false); case NTSYNC_IOC_EVENT_RESET: return ntsync_event_reset(obj, argp); + case NTSYNC_IOC_EVENT_PULSE: + return ntsync_event_set(obj, argp, true); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 7fdf79729b20..5586fadd9bdd 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -53,5 +53,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_MUTEX_KILL _IOW ('N', 0x86, __u32) #define NTSYNC_IOC_EVENT_SET _IOR ('N', 0x88, __u32) #define NTSYNC_IOC_EVENT_RESET _IOR ('N', 0x89, __u32) +#define NTSYNC_IOC_EVENT_PULSE _IOR ('N', 0x8a, __u32) #endif From patchwork Mon Dec 9 18:58:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848516 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EC7D19CCEC; Mon, 9 Dec 2024 19:03:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770986; cv=none; b=PMZKaDyUlEZ6y20ZPDQyR8mpXog4DEdkvhKn0+WoNHK/NTuP/ys36OByiA13Vjw4jwTGU+Wjh2hguQ1FtTTE4l5G4B865Y6VbXQ8OK+hHA672uMJQcnrMefhiJa2FnT+eTbrajkUhVK+ZnstjSVfZbklj8QVuN/zqaJQRg0h9qI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770986; c=relaxed/simple; bh=dt45LmJEiSiP1XR8v8MoEfPn0UTXtfiHExBuAta6jms=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ru8dIk1uoVWxjwTjo05KXu9FSe7cWmvrm+PAWEfej0+3Atyt1cJJcV8kp+3fKvu76OopbjkdTYX4k79ZUgB/nwwvmdMQFRnTcjlpD5bSmQbFTiT8vS3Gc+2EPcrq3zC3hfOfL/+pYQeGCMwR4BW1El6eQZ/cvJVs12WUN7FvDHs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=mBKG3zDR; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="mBKG3zDR" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=SKJGtwUzzUoLxIjVaNdwAGBQ/Tls5kq3VYxfQTvAUCE=; b=mBKG3zDRx3Cte99YBlfx06TugW yO7hWSOCG/3CS8SW6B2I5lBxMd5vC3Byeo/F4smbdaGwe16UWF/lIzMT8qTZ3G+ZbGLYWtArnFyd7 C0uKAtheMfj+t8/61BkEwQZTX+fvE9IVmykAwGTbtg29R6eebbH+hTrqpFj7t/t5Pw7a0diVjIpFR N/sLwZjpr42ReaAEYT/c3lDmsevM0DuLXp2BmsUzyeG+7CGwza93N4+EdOrSP4I3LJUOnxcASjPjO ChrzDi+AxYYG6Kk3ZtMx4CsnDUzQCLypfQUcWzgBfWRZnoNpN891RJC6QlHbKJB+IgA1MjfzilEVH +mAEKy2g==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiya-001Gd5-2q; Mon, 09 Dec 2024 12:59:24 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 10/28] ntsync: Introduce NTSYNC_IOC_SEM_READ. Date: Mon, 9 Dec 2024 12:58:46 -0600 Message-ID: <20241209185904.507350-11-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtQuerySemaphore(). This returns the current count and maximum count of the semaphore. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 26 ++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 27 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 6b8352270874..d6e8a4bde1d0 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -583,6 +583,30 @@ static int ntsync_event_reset(struct ntsync_obj *event, void __user *argp) return 0; } +static int ntsync_sem_read(struct ntsync_obj *sem, void __user *argp) +{ + struct ntsync_sem_args __user *user_args = argp; + struct ntsync_device *dev = sem->dev; + struct ntsync_sem_args args; + bool all; + + if (sem->type != NTSYNC_TYPE_SEM) + return -EINVAL; + + args.sem = 0; + + all = ntsync_lock_obj(dev, sem); + + args.count = sem->u.sem.count; + args.max = sem->u.sem.max; + + ntsync_unlock_obj(dev, sem, all); + + if (copy_to_user(user_args, &args, sizeof(args))) + return -EFAULT; + return 0; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -602,6 +626,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case NTSYNC_IOC_SEM_POST: return ntsync_sem_post(obj, argp); + case NTSYNC_IOC_SEM_READ: + return ntsync_sem_read(obj, argp); case NTSYNC_IOC_MUTEX_UNLOCK: return ntsync_mutex_unlock(obj, argp); case NTSYNC_IOC_MUTEX_KILL: diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 5586fadd9bdd..5e922703686f 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -54,5 +54,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_EVENT_SET _IOR ('N', 0x88, __u32) #define NTSYNC_IOC_EVENT_RESET _IOR ('N', 0x89, __u32) #define NTSYNC_IOC_EVENT_PULSE _IOR ('N', 0x8a, __u32) +#define NTSYNC_IOC_SEM_READ _IOR ('N', 0x8b, struct ntsync_sem_args) #endif From patchwork Mon Dec 9 18:58:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848518 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95A80199939; Mon, 9 Dec 2024 19:02:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770973; cv=none; b=ElBU+7CrlgL9PabnFj7jPtsq/vGXpv2Av9KYC0aVZVRf2mwpr+iedEmmj6HydaWRYAbunGGnc89eMODXbq8e7g2f8aMmAtuQ78pT706kjJIClPlBsQT0gndZeBiW8Z89HXAziGBfCxdRjk/avJGoiCcOGQ/5OzCnZ3x12dp9GyI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770973; c=relaxed/simple; bh=sp6FSdlHM8fF2HY/TPn0ZTbgpJUAdwmTjQm0HETkswg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kID0A64RROtof+q6TCcHKArzUxgjO6yqAOXVB9KTpHWm/XSiBfHM/BbcSauJm6S91P8H8/YS0bijwi7pexOjXwFRaLEdpIZGMKFYJSFsuaynYUzyEfxEQsVNkvvNWbY8FMPMAzE/cROMUnMIy3wBUyScE+Xb6lobV8Ry11w9I64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=ZJJSQIHW; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="ZJJSQIHW" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=r14OW/cQ6BfRX3OgHtXVyjlxZmpfc7UvZouqcnu3iHY=; b=ZJJSQIHW7kzl+ISYs72ZrzeYkI K7rnmXyuangva3etXUnFoxrvgL3W1QTVLpZUn69IEOeVeJNZibOpxtbvQbV1Smpofm9+JWJu9uYI4 XGQvyckwirP9eV6m5u9TB1GGpOI4LPpd+QJmHGYMA7s2XJYmGfhv6S/v2d9bLMhqJE0ExaNk3x5ph cUpZ4KxIPIDqTVPDX7z3UxUGGkoCd27EcNV6zkvqDEb4ZU3Lgl2HInY99d3McKYOf7oM1tIExLQxx kAPTMXz2dXoGT6/LDWw69Us1kddpuEzx7WHrTp8rF3kMEJoJKKJsQTNMXwRij4hBFE4ggEu3UOYeI GDxKGNhw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyb-001Gd5-09; Mon, 09 Dec 2024 12:59:25 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 11/28] ntsync: Introduce NTSYNC_IOC_MUTEX_READ. Date: Mon, 9 Dec 2024 12:58:47 -0600 Message-ID: <20241209185904.507350-12-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtQueryMutant(). This returns the recursion count, owner, and abandoned state of the mutex. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 28 ++++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 29 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index d6e8a4bde1d0..cff2627c1efe 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -607,6 +607,32 @@ static int ntsync_sem_read(struct ntsync_obj *sem, void __user *argp) return 0; } +static int ntsync_mutex_read(struct ntsync_obj *mutex, void __user *argp) +{ + struct ntsync_mutex_args __user *user_args = argp; + struct ntsync_device *dev = mutex->dev; + struct ntsync_mutex_args args; + bool all; + int ret; + + if (mutex->type != NTSYNC_TYPE_MUTEX) + return -EINVAL; + + args.mutex = 0; + + all = ntsync_lock_obj(dev, mutex); + + args.count = mutex->u.mutex.count; + args.owner = mutex->u.mutex.owner; + ret = mutex->u.mutex.ownerdead ? -EOWNERDEAD : 0; + + ntsync_unlock_obj(dev, mutex, all); + + if (copy_to_user(user_args, &args, sizeof(args))) + return -EFAULT; + return ret; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -632,6 +658,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, return ntsync_mutex_unlock(obj, argp); case NTSYNC_IOC_MUTEX_KILL: return ntsync_mutex_kill(obj, argp); + case NTSYNC_IOC_MUTEX_READ: + return ntsync_mutex_read(obj, argp); case NTSYNC_IOC_EVENT_SET: return ntsync_event_set(obj, argp, false); case NTSYNC_IOC_EVENT_RESET: diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 5e922703686f..eced73d08783 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -55,5 +55,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_EVENT_RESET _IOR ('N', 0x89, __u32) #define NTSYNC_IOC_EVENT_PULSE _IOR ('N', 0x8a, __u32) #define NTSYNC_IOC_SEM_READ _IOR ('N', 0x8b, struct ntsync_sem_args) +#define NTSYNC_IOC_MUTEX_READ _IOR ('N', 0x8c, struct ntsync_mutex_args) #endif From patchwork Mon Dec 9 18:58:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849511 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D7F41990AE; Mon, 9 Dec 2024 19:02:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770970; cv=none; b=GseySMlRwxQ6Shzp6S40+kyZWncXSvVtVhE2pAY1SdECq8b6fa6Nkr7CcA/eY9cHjlXznjs89kLBrlX+OaGafEbbgXjtisHXOX+xmmewmkpIwBOkYtmcBuGh/VK8BhCOqx2w51MDyOj+2emlzlwT8YaxjAo/JTAdEaFh5Znvr1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770970; c=relaxed/simple; bh=4yOT8a3cRB0qPmY52n+VNg+UNalreY7d0UFkF/4P5FU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Qv7SHA1z7k7QBaEDAeZPMiXGmOCWIx+vYoD+VVscNAUO6XEr5XWgiQ3fGdlggeas2qWz6oZ/IFEpiCW32fmtc9Qx8kNHDCDuozoqStsoVo4vegLLSbaVFKcMWfWTJWeJQBggq775SK21InenwyWsjCjqWRPE0xD7+azkYiAlymQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=EISCRrI1; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="EISCRrI1" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=oqAQ/CwNvC8HZlzmlY8JFR6LjLHJED15lmj9ttZU4/g=; b=EISCRrI1pnaRvKYeLYpcEKr1tq u+u4lq5yGdcTDf4JSJQkNH5Vulc/ullAl1Rd3UIUaVbPiL7ZGOzqVEIIbU2vNWhEJO2QmUxliG2/J JSdzJirgkkbcGBtMYETS1L/RYx1IIRQprwj8SggQCbv/4rtPlMfifu3lxYlLzrAirISpSrR+SsLFg ANdE3ph3RTV5nLUm94PTUr9T/X6+Q5sW9Q6vbDq1JsSYRsCFaJhh7i5+CYYKiT6j6jTK/R5prWc3b 51t4jju1LrG75QyeYDcJ2cPxePTK9LI2NQJzsyqmNl34GD+iYRamv6D2nHALHSm/ewXfWeNGJJlK+ 77hdUYJA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyb-001Gd5-0f; Mon, 09 Dec 2024 12:59:25 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 12/28] ntsync: Introduce NTSYNC_IOC_EVENT_READ. Date: Mon, 9 Dec 2024 12:58:48 -0600 Message-ID: <20241209185904.507350-13-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This corresponds to the NT syscall NtQueryEvent(). This returns the signaled state of the event and whether it is manual-reset. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 26 ++++++++++++++++++++++++++ include/uapi/linux/ntsync.h | 1 + 2 files changed, 27 insertions(+) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index cff2627c1efe..5a5ee7b6ee92 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -633,6 +633,30 @@ static int ntsync_mutex_read(struct ntsync_obj *mutex, void __user *argp) return ret; } +static int ntsync_event_read(struct ntsync_obj *event, void __user *argp) +{ + struct ntsync_event_args __user *user_args = argp; + struct ntsync_device *dev = event->dev; + struct ntsync_event_args args; + bool all; + + if (event->type != NTSYNC_TYPE_EVENT) + return -EINVAL; + + args.event = 0; + + all = ntsync_lock_obj(dev, event); + + args.manual = event->u.event.manual; + args.signaled = event->u.event.signaled; + + ntsync_unlock_obj(dev, event, all); + + if (copy_to_user(user_args, &args, sizeof(args))) + return -EFAULT; + return 0; +} + static int ntsync_obj_release(struct inode *inode, struct file *file) { struct ntsync_obj *obj = file->private_data; @@ -666,6 +690,8 @@ static long ntsync_obj_ioctl(struct file *file, unsigned int cmd, return ntsync_event_reset(obj, argp); case NTSYNC_IOC_EVENT_PULSE: return ntsync_event_set(obj, argp, true); + case NTSYNC_IOC_EVENT_READ: + return ntsync_event_read(obj, argp); default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index eced73d08783..74abeba832f7 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -56,5 +56,6 @@ struct ntsync_wait_args { #define NTSYNC_IOC_EVENT_PULSE _IOR ('N', 0x8a, __u32) #define NTSYNC_IOC_SEM_READ _IOR ('N', 0x8b, struct ntsync_sem_args) #define NTSYNC_IOC_MUTEX_READ _IOR ('N', 0x8c, struct ntsync_mutex_args) +#define NTSYNC_IOC_EVENT_READ _IOR ('N', 0x8d, struct ntsync_event_args) #endif From patchwork Mon Dec 9 18:58:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848519 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1388F198A01; Mon, 9 Dec 2024 19:02:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770967; cv=none; b=DpHkJ9UanNSJJVVpnMVPaHHtY2sKx+1Cd+57eZxnZnIju+HdFFOFjfvfmjHYEjG7p/X18yXgGnahjtPFp+YfgAcJGmpfpvSSgpTkTrvGt36zNBJCl+AKvqCuMSYjJ150cimUkqPEtVrBH2di22Hfd5RISGO/AQxhHS+IOhii8JU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770967; c=relaxed/simple; bh=FgTY7nxPHkuJZbZmF6H5JuXpcsqITCJKU1p81BIiHrg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D27taT5gadS/RYTJsid//43jYl/jkkwvVC2sxume8ZpVqCsNnxzoSckSCTX9yoizaVtLaf7zHPhkZpZ8q2uTpQnzhDEagVimfiRowTsH9UB2hA4zUoGX9CFkV2jWzRr3f88FPm2LLAH6BSQ8nkkU1oZCO9pxJz5AuHSxdHwQumg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=TvxC9Gok; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="TvxC9Gok" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=rp1DMYnShgGY5Fv/LvCHbD/s0NdGN0Yj6LvMiGhl8B0=; b=TvxC9GokwwLIVFtnQN+wo56PFd rIKBW8lPkUOfx2lielCF7aRXsIu4GZNlD81s1g9QnxAPH2wwARxR4Z2jAa4hANVjzqrcYdyKN6Wsi gF5Tjy+JyfOhHopqo0bN+FsTTTzS9UBoPF+DXtKs8JkWEf45KEQqRmfgUDYZvR8YQR4jr/E+SKZeM gww1HwYOYXBUdfmkH1cgBHzM+Sd0KYTkD5/dTndlRoJZ0My53qWjioQd+XC8arlICNQC2+ip7Ariy QBjy4xpDHndpWB/5WBVR9PJig9rTqOW2XZEUpPk2+B0G7N4R3RD6VlpmLUj3+mrwSQxwrqXrBjjwa zOS/507g==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyb-001Gd5-1A; Mon, 09 Dec 2024 12:59:25 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 13/28] ntsync: Introduce alertable waits. Date: Mon, 9 Dec 2024 12:58:49 -0600 Message-ID: <20241209185904.507350-14-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 NT waits can optionally be made "alertable". This is a special channel for thread wakeup that is mildly similar to SIGIO. A thread has an internal single bit of "alerted" state, and if a thread is alerted while an alertable wait, the wait will return a special value, consume the "alerted" state, and will not consume any of its objects. Alerts are implemented using events; the user-space NT emulator is expected to create an internal ntsync event for each thread and pass that event to wait functions. Signed-off-by: Elizabeth Figura --- drivers/misc/ntsync.c | 70 ++++++++++++++++++++++++++++++++----- include/uapi/linux/ntsync.h | 3 +- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 5a5ee7b6ee92..3fac06270549 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -884,22 +884,29 @@ static int setup_wait(struct ntsync_device *dev, const struct ntsync_wait_args *args, bool all, struct ntsync_q **ret_q) { + int fds[NTSYNC_MAX_WAIT_COUNT + 1]; const __u32 count = args->count; - int fds[NTSYNC_MAX_WAIT_COUNT]; struct ntsync_q *q; + __u32 total_count; __u32 i, j; - if (args->pad[0] || args->pad[1] || (args->flags & ~NTSYNC_WAIT_REALTIME)) + if (args->pad || (args->flags & ~NTSYNC_WAIT_REALTIME)) return -EINVAL; if (args->count > NTSYNC_MAX_WAIT_COUNT) return -EINVAL; + total_count = count; + if (args->alert) + total_count++; + if (copy_from_user(fds, u64_to_user_ptr(args->objs), array_size(count, sizeof(*fds)))) return -EFAULT; + if (args->alert) + fds[count] = args->alert; - q = kmalloc(struct_size(q, entries, count), GFP_KERNEL); + q = kmalloc(struct_size(q, entries, total_count), GFP_KERNEL); if (!q) return -ENOMEM; q->task = current; @@ -909,7 +916,7 @@ static int setup_wait(struct ntsync_device *dev, q->ownerdead = false; q->count = count; - for (i = 0; i < count; i++) { + for (i = 0; i < total_count; i++) { struct ntsync_q_entry *entry = &q->entries[i]; struct ntsync_obj *obj = get_obj(dev, fds[i]); @@ -959,10 +966,10 @@ static void try_wake_any_obj(struct ntsync_obj *obj) static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) { struct ntsync_wait_args args; + __u32 i, total_count; struct ntsync_q *q; int signaled; bool all; - __u32 i; int ret; if (copy_from_user(&args, argp, sizeof(args))) @@ -972,9 +979,13 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) if (ret < 0) return ret; + total_count = args.count; + if (args.alert) + total_count++; + /* queue ourselves */ - for (i = 0; i < args.count; i++) { + for (i = 0; i < total_count; i++) { struct ntsync_q_entry *entry = &q->entries[i]; struct ntsync_obj *obj = entry->obj; @@ -983,9 +994,15 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) ntsync_unlock_obj(dev, obj, all); } - /* check if we are already signaled */ + /* + * Check if we are already signaled. + * + * Note that the API requires that normal objects are checked before + * the alert event. Hence we queue the alert event last, and check + * objects in order. + */ - for (i = 0; i < args.count; i++) { + for (i = 0; i < total_count; i++) { struct ntsync_obj *obj = q->entries[i].obj; if (atomic_read(&q->signaled) != -1) @@ -1002,7 +1019,7 @@ static int ntsync_wait_any(struct ntsync_device *dev, void __user *argp) /* and finally, unqueue */ - for (i = 0; i < args.count; i++) { + for (i = 0; i < total_count; i++) { struct ntsync_q_entry *entry = &q->entries[i]; struct ntsync_obj *obj = entry->obj; @@ -1062,6 +1079,14 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp) */ list_add_tail(&entry->node, &obj->all_waiters); } + if (args.alert) { + struct ntsync_q_entry *entry = &q->entries[args.count]; + struct ntsync_obj *obj = entry->obj; + + dev_lock_obj(dev, obj); + list_add_tail(&entry->node, &obj->any_waiters); + dev_unlock_obj(dev, obj); + } /* check if we are already signaled */ @@ -1069,6 +1094,21 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp) mutex_unlock(&dev->wait_all_lock); + /* + * Check if the alert event is signaled, making sure to do so only + * after checking if the other objects are signaled. + */ + + if (args.alert) { + struct ntsync_obj *obj = q->entries[args.count].obj; + + if (atomic_read(&q->signaled) == -1) { + bool all = ntsync_lock_obj(dev, obj); + try_wake_any_obj(obj); + ntsync_unlock_obj(dev, obj, all); + } + } + /* sleep */ ret = ntsync_schedule(q, &args); @@ -1094,6 +1134,18 @@ static int ntsync_wait_all(struct ntsync_device *dev, void __user *argp) mutex_unlock(&dev->wait_all_lock); + if (args.alert) { + struct ntsync_q_entry *entry = &q->entries[args.count]; + struct ntsync_obj *obj = entry->obj; + bool all; + + all = ntsync_lock_obj(dev, obj); + list_del(&entry->node); + ntsync_unlock_obj(dev, obj, all); + + put_obj(obj); + } + signaled = atomic_read(&q->signaled); if (signaled != -1) { struct ntsync_wait_args __user *user_args = argp; diff --git a/include/uapi/linux/ntsync.h b/include/uapi/linux/ntsync.h index 74abeba832f7..4a8095a3fc34 100644 --- a/include/uapi/linux/ntsync.h +++ b/include/uapi/linux/ntsync.h @@ -37,7 +37,8 @@ struct ntsync_wait_args { __u32 index; __u32 flags; __u32 owner; - __u32 pad[2]; + __u32 alert; + __u32 pad; }; #define NTSYNC_MAX_WAIT_COUNT 64 From patchwork Mon Dec 9 18:58:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849512 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36D9E171E7C; Mon, 9 Dec 2024 19:02:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770964; cv=none; b=phPf1p8dG3E1F1T6DRBZHtgRDnBkwLdMUibDsgIHbr+ez3emGbY1G111/zVcyVNmoB33bVojPwjejPkl5rhoF7j1p6OYe9dYXzBRc601EEs0aR096ObPvmU+PBziXXvcIuklYOS5erR9ER0h+qTJnp7yJa+2k244N9uTYlVwrWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770964; c=relaxed/simple; bh=bCPu1ycb6CaEqcRe9eBfUowEMdbfE+OisPigVavxhC8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nVMVCr96zDhKyqHf8oXIP0NOaHTOfqI90i4NIG+W9vMi8GCQmifRSFYppdPb+HQh3DPTgKO/FdooCHVK2f+Mga5orDK6lcxIuC829KTy1YPqt3suUZcGCQ/hQCLv7Lty5tfhj4gJt0rggaQ+gJBp5YQZNBnJ2rYv89FdUzirVww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=l8BhUBw2; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="l8BhUBw2" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=x1ZwlxPQqB3lIRG8mseHmBWNLATzIEV5th7ltmFSSvM=; b=l8BhUBw295VHpPc80K3UUw4nHy 5U+2+Yh+Cqff9cZyl9AqdrvJ+f6xggchVFYOTih6rbpSzAX/qWMfaLrPCVuz860mepIm9ijwUDkjS e6m5Gj9jz7siSY4rKyc5YuPPSje1ZIfvpysFwWdrj2Vkqrg8YN2z/kuZf6rTwc83b4k1oUldetDpk kdgUhMEWu2nZEZK99B8E0zRA/vYouL3u4rsBbwqflnGh2/4WEeKVJ1Cde98u12PJNpfhhhV+/UlTp DsKCGLIjH+OLDbwbHeZZ69t3lDVn5LDmHr7hPEVcrHnjwFPls5jdgJf5SRfde1wi1NWb+2Pho9KVz z7fPd4Ug==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyb-001Gd5-1f; Mon, 09 Dec 2024 12:59:25 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 14/28] selftests: ntsync: Add some tests for semaphore state. Date: Mon, 9 Dec 2024 12:58:50 -0600 Message-ID: <20241209185904.507350-15-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Wine has tests for its synchronization primitives, but these are more accessible to kernel developers, and also allow us to test some edge cases that Wine does not care about. This patch adds tests for semaphore-specific ioctls NTSYNC_IOC_SEM_POST and NTSYNC_IOC_SEM_READ, and waiting on semaphores. Signed-off-by: Elizabeth Figura --- tools/testing/selftests/Makefile | 1 + .../selftests/drivers/ntsync/.gitignore | 1 + .../testing/selftests/drivers/ntsync/Makefile | 7 + tools/testing/selftests/drivers/ntsync/config | 1 + .../testing/selftests/drivers/ntsync/ntsync.c | 149 ++++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 tools/testing/selftests/drivers/ntsync/.gitignore create mode 100644 tools/testing/selftests/drivers/ntsync/Makefile create mode 100644 tools/testing/selftests/drivers/ntsync/config create mode 100644 tools/testing/selftests/drivers/ntsync/ntsync.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 2401e973c359..a8c9648e5adc 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -18,6 +18,7 @@ TARGETS += devices/error_logs TARGETS += devices/probe TARGETS += dmabuf-heaps TARGETS += drivers/dma-buf +TARGETS += drivers/ntsync TARGETS += drivers/s390x/uvdevice TARGETS += drivers/net TARGETS += drivers/net/bonding diff --git a/tools/testing/selftests/drivers/ntsync/.gitignore b/tools/testing/selftests/drivers/ntsync/.gitignore new file mode 100644 index 000000000000..848573a3d3ea --- /dev/null +++ b/tools/testing/selftests/drivers/ntsync/.gitignore @@ -0,0 +1 @@ +ntsync diff --git a/tools/testing/selftests/drivers/ntsync/Makefile b/tools/testing/selftests/drivers/ntsync/Makefile new file mode 100644 index 000000000000..dbf2b055c0b2 --- /dev/null +++ b/tools/testing/selftests/drivers/ntsync/Makefile @@ -0,0 +1,7 @@ +# SPDX-LICENSE-IDENTIFIER: GPL-2.0-only +TEST_GEN_PROGS := ntsync + +CFLAGS += $(KHDR_INCLUDES) +LDLIBS += -lpthread + +include ../../lib.mk diff --git a/tools/testing/selftests/drivers/ntsync/config b/tools/testing/selftests/drivers/ntsync/config new file mode 100644 index 000000000000..60539c826d06 --- /dev/null +++ b/tools/testing/selftests/drivers/ntsync/config @@ -0,0 +1 @@ +CONFIG_WINESYNC=y diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c new file mode 100644 index 000000000000..1e145c6dfded --- /dev/null +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Various unit tests for the "ntsync" synchronization primitive driver. + * + * Copyright (C) 2021-2022 Elizabeth Figura + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include "../../kselftest_harness.h" + +static int read_sem_state(int sem, __u32 *count, __u32 *max) +{ + struct ntsync_sem_args args; + int ret; + + memset(&args, 0xcc, sizeof(args)); + ret = ioctl(sem, NTSYNC_IOC_SEM_READ, &args); + *count = args.count; + *max = args.max; + return ret; +} + +#define check_sem_state(sem, count, max) \ + ({ \ + __u32 __count, __max; \ + int ret = read_sem_state((sem), &__count, &__max); \ + EXPECT_EQ(0, ret); \ + EXPECT_EQ((count), __count); \ + EXPECT_EQ((max), __max); \ + }) + +static int post_sem(int sem, __u32 *count) +{ + return ioctl(sem, NTSYNC_IOC_SEM_POST, count); +} + +static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) +{ + struct ntsync_wait_args args = {0}; + struct timespec timeout; + int ret; + + clock_gettime(CLOCK_MONOTONIC, &timeout); + + args.timeout = timeout.tv_sec * 1000000000 + timeout.tv_nsec; + args.count = count; + args.objs = (uintptr_t)objs; + args.owner = owner; + args.index = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &args); + *index = args.index; + return ret; +} + +TEST(semaphore_state) +{ + struct ntsync_sem_args sem_args; + struct timespec timeout; + __u32 count, index; + int fd, ret, sem; + + clock_gettime(CLOCK_MONOTONIC, &timeout); + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 3; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + sem_args.count = 2; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + sem = sem_args.sem; + check_sem_state(sem, 2, 2); + + count = 0; + ret = post_sem(sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, count); + check_sem_state(sem, 2, 2); + + count = 1; + ret = post_sem(sem, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOVERFLOW, errno); + check_sem_state(sem, 2, 2); + + ret = wait_any(fd, 1, &sem, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem, 1, 2); + + ret = wait_any(fd, 1, &sem, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem, 0, 2); + + ret = wait_any(fd, 1, &sem, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + count = 3; + ret = post_sem(sem, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOVERFLOW, errno); + check_sem_state(sem, 0, 2); + + count = 2; + ret = post_sem(sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + check_sem_state(sem, 2, 2); + + ret = wait_any(fd, 1, &sem, 123, &index); + EXPECT_EQ(0, ret); + ret = wait_any(fd, 1, &sem, 123, &index); + EXPECT_EQ(0, ret); + + count = 1; + ret = post_sem(sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + check_sem_state(sem, 1, 2); + + count = ~0u; + ret = post_sem(sem, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOVERFLOW, errno); + check_sem_state(sem, 1, 2); + + close(sem); + + close(fd); +} + +TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849510 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D13019ABC6; Mon, 9 Dec 2024 19:02:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770975; cv=none; b=SzSBvh55RFt/Fhj7iW+R97EbSDj1T9q9NGT+nrCmbY9mkXoG56TMiZmCpq/IQAYlWGGMKEEhj2mSCmS5E+/oWdnayJT3LU/et8RjBN3Zozb+e3Jkq/vit6N46VCaRoursRYAqfXLy5AAxZdOrNbfgsoMFthAFZFB/an/D85eN0o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770975; c=relaxed/simple; bh=QPnXynynXjG10ullDNsO7VmGGYw/z1Un2ZNUe4EXu98=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WpbY3ZI+KkfERLa264M01CQHS4P4ZA7/urvhjbmSlO89WPNEcv6D3bBBcwBN78tBkPpRP+y+3CYtrh+RAg1YKI67aI82dyWXGzTaGdQs4oPjZkohgScUuOWIvbpSpghluVF/1JlVcvhwBJNICIuW0VSIB5XET2VrHMAB4QRjS3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=nDzW5UBF; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="nDzW5UBF" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=T9Qsn+owaaej5zrPQzEap5fL6Byc4tHr9W1jenKmGTI=; b=nDzW5UBFZOg+pkVoObYSSaxdXq vXykA/2xTjyrV1uTczrBRFrtIdfdP5AYwEDqjM7JXqtkplOo9/1cYsGhAkhSfuIYBMrvvAfBqxqDz K+RZrnDEu3txeduPT/Fc4YaRAjMvrcFMurafXcAXmnJrYEVamIBY9okx105g0ybeASPAammJFw8Sa JCWfRET45BaACqsJmFd3uBfZesarfukMM68lBOP0LP4JqT4bmRQ4MMvmkYF4WxARTEHq80tf2CPWM E1fcEZuPkIw/HXYvfracFbXeoma6TwRQN8qvr4WYHDUTR7i5f4Eb8kTqXqytrvKAyTHSno1P0YYdg Or9fy6Gg==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyb-001Gd5-3C; Mon, 09 Dec 2024 12:59:26 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 15/28] selftests: ntsync: Add some tests for mutex state. Date: Mon, 9 Dec 2024 12:58:51 -0600 Message-ID: <20241209185904.507350-16-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test mutex-specific ioctls NTSYNC_IOC_MUTEX_UNLOCK and NTSYNC_IOC_MUTEX_READ, and waiting on mutexes. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 196 ++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 1e145c6dfded..7cd0f40594fd 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -40,6 +40,39 @@ static int post_sem(int sem, __u32 *count) return ioctl(sem, NTSYNC_IOC_SEM_POST, count); } +static int read_mutex_state(int mutex, __u32 *count, __u32 *owner) +{ + struct ntsync_mutex_args args; + int ret; + + memset(&args, 0xcc, sizeof(args)); + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &args); + *count = args.count; + *owner = args.owner; + return ret; +} + +#define check_mutex_state(mutex, count, owner) \ + ({ \ + __u32 __count, __owner; \ + int ret = read_mutex_state((mutex), &__count, &__owner); \ + EXPECT_EQ(0, ret); \ + EXPECT_EQ((count), __count); \ + EXPECT_EQ((owner), __owner); \ + }) + +static int unlock_mutex(int mutex, __u32 owner, __u32 *count) +{ + struct ntsync_mutex_args args; + int ret; + + args.owner = owner; + args.count = 0xdeadbeef; + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_UNLOCK, &args); + *count = args.count; + return ret; +} + static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) { struct ntsync_wait_args args = {0}; @@ -146,4 +179,167 @@ TEST(semaphore_state) close(fd); } +TEST(mutex_state) +{ + struct ntsync_mutex_args mutex_args; + __u32 owner, count, index; + struct timespec timeout; + int fd, ret, mutex; + + clock_gettime(CLOCK_MONOTONIC, &timeout); + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + mutex_args.owner = 123; + mutex_args.count = 0; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + mutex_args.owner = 0; + mutex_args.count = 2; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + mutex_args.owner = 123; + mutex_args.count = 2; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + mutex = mutex_args.mutex; + check_mutex_state(mutex, 2, 123); + + ret = unlock_mutex(mutex, 0, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + ret = unlock_mutex(mutex, 456, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EPERM, errno); + check_mutex_state(mutex, 2, 123); + + ret = unlock_mutex(mutex, 123, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, count); + check_mutex_state(mutex, 1, 123); + + ret = unlock_mutex(mutex, 123, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, count); + check_mutex_state(mutex, 0, 0); + + ret = unlock_mutex(mutex, 123, &count); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EPERM, errno); + + ret = wait_any(fd, 1, &mutex, 456, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_mutex_state(mutex, 1, 456); + + ret = wait_any(fd, 1, &mutex, 456, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_mutex_state(mutex, 2, 456); + + ret = unlock_mutex(mutex, 456, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, count); + check_mutex_state(mutex, 1, 456); + + ret = wait_any(fd, 1, &mutex, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + owner = 0; + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + owner = 123; + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EPERM, errno); + check_mutex_state(mutex, 1, 456); + + owner = 456; + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(0, ret); + + memset(&mutex_args, 0xcc, sizeof(mutex_args)); + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(0, mutex_args.count); + EXPECT_EQ(0, mutex_args.owner); + + memset(&mutex_args, 0xcc, sizeof(mutex_args)); + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(0, mutex_args.count); + EXPECT_EQ(0, mutex_args.owner); + + ret = wait_any(fd, 1, &mutex, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(0, index); + check_mutex_state(mutex, 1, 123); + + owner = 123; + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(0, ret); + + memset(&mutex_args, 0xcc, sizeof(mutex_args)); + ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(0, mutex_args.count); + EXPECT_EQ(0, mutex_args.owner); + + ret = wait_any(fd, 1, &mutex, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(0, index); + check_mutex_state(mutex, 1, 123); + + close(mutex); + + mutex_args.owner = 0; + mutex_args.count = 0; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + mutex = mutex_args.mutex; + check_mutex_state(mutex, 0, 0); + + ret = wait_any(fd, 1, &mutex, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_mutex_state(mutex, 1, 123); + + close(mutex); + + mutex_args.owner = 123; + mutex_args.count = ~0u; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + mutex = mutex_args.mutex; + check_mutex_state(mutex, ~0u, 123); + + ret = wait_any(fd, 1, &mutex, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + close(mutex); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849504 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E95AB1AAE08; Mon, 9 Dec 2024 19:03:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771014; cv=none; b=eBow8sdEh/iVruOvaUWG8ZZy2etIp5IGzzs3kJ3cWfDDomfmAd8U/PQWtdvHrCvPx9c+5ZuKH7akp9+9GIXIcRshpdAjn0uKM3qY3BXVPJV6QHE1SlzlQgkexF1XVcwKxggwRyCjUwXQ/2KmnrYQC5KBtXj8lK/dLcnIFn5/Ebs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733771014; c=relaxed/simple; bh=rJWsvs4U0G6yXgAaGWcQ9pNuvEMrOusrUUu0b1tVjMU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=utBlWinQDlMdT5GyMXwYX7LdQmuWxdtde3oSTrhDRDkhKm/a4W6LnlsyO2mt/2Rptr4TYW30aEskKRln51if7TLSV3+Fqa1ImBbmcvNE0RHVCy75JYm8UXbsSg0tsxgR3JSAJj0saApZYynYo8ugCim6E/DGEWSmGkK1amDLnUA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=B9vwEuMU; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="B9vwEuMU" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=TBV3K6DkdEwWEB8hQ4zHRU1jHPbyqEKzqoNldAknSUo=; b=B9vwEuMUxxGznjfGTin+lFv739 5W3jBSfwKidqfwLONNFZ+X5Jl+PGIur5G8LKjLPKx+BJ/A5k70PkR2nCphXjCr6QhQvPH3hAi90qs VIjq48BWIYFN2FDchKRY2HNHM/+3nkANcWRKiV5fdWMfSbIAirj8opoewx0eRurgI41JmJ1KQY5oo 2ibcmOI9it6BhU/m2vx5MOCaZLIsUXvoDPjsnhklxMZSFMR+aBiGSoggYllLqVm49curtuNh0ZULb HAHRMZW6ebs2vq5goSWhI4fSRu7KfsyBrh3HRYgaHwHkmF9NIWAqFZOmtzShXTiTqh9NFOxzdiiEk lwWfVTCg==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyc-001Gd5-2x; Mon, 09 Dec 2024 12:59:27 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 16/28] selftests: ntsync: Add some tests for NTSYNC_IOC_WAIT_ANY. Date: Mon, 9 Dec 2024 12:58:52 -0600 Message-ID: <20241209185904.507350-17-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test basic synchronous functionality of NTSYNC_IOC_WAIT_ANY, when objects are considered signaled or not signaled, and how they are affected by a successful wait. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 7cd0f40594fd..40ad8cbd3138 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -342,4 +342,123 @@ TEST(mutex_state) close(fd); } +TEST(test_wait_any) +{ + int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret; + struct ntsync_mutex_args mutex_args = {0}; + struct ntsync_sem_args sem_args = {0}; + __u32 owner, index, count, i; + struct timespec timeout; + + clock_gettime(CLOCK_MONOTONIC, &timeout); + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 2; + sem_args.max = 3; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + + mutex_args.owner = 0; + mutex_args.count = 0; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + + objs[0] = sem_args.sem; + objs[1] = mutex_args.mutex; + + ret = wait_any(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 1, 3); + check_mutex_state(mutex_args.mutex, 0, 0); + + ret = wait_any(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 0, 0); + + ret = wait_any(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, index); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 1, 123); + + count = 1; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + + ret = wait_any(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 1, 123); + + ret = wait_any(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, index); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 2, 123); + + ret = wait_any(fd, 2, objs, 456, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + owner = 123; + ret = ioctl(mutex_args.mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(0, ret); + + ret = wait_any(fd, 2, objs, 456, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + EXPECT_EQ(1, index); + + ret = wait_any(fd, 2, objs, 456, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, index); + + /* test waiting on the same object twice */ + count = 2; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + + objs[0] = objs[1] = sem_args.sem; + ret = wait_any(fd, 2, objs, 456, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 1, 3); + + ret = wait_any(fd, 0, NULL, 456, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + for (i = 0; i < NTSYNC_MAX_WAIT_COUNT + 1; ++i) + objs[i] = sem_args.sem; + + ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT + 1, objs, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + ret = wait_any(fd, -1, objs, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + close(sem_args.sem); + close(mutex_args.mutex); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849518 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CE1919924A; Mon, 9 Dec 2024 18:59:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770776; cv=none; b=XLHR+pqKaj5ljSrbdhOyckdQDoTAmV1KhQWDQu7dVO4REqRA3KNXDjc4GYqql+CqbiR0yW4kUTLGt6Af3jetzkrqc3jevdWODt+JzVw9FHk1fFODqd9zsoWrWf6B0WHPUbxyWmlniNCGn21d1edQcARsz2voiTQOSFWUyMJvmpI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770776; c=relaxed/simple; bh=JvVmg1UN/TaLoMpuByeMdl8BxvJCfzEncRZ/E8RvE98=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=of5tjisw8r8dVl9gPgBdFML+WrAApJ2d5977YmaXR8Kws2ePgbAfrU+TVUZFqaQUXIwWQt0Y2uP54+Yr027IrPGuNfwGzkH5BMjkEIXUL9DhyPVoAv5SkefRhZeY8YFoXhJ7KtuBHjK9mb2YUNMDJZoV6LjcBFOKNTUhVGJP9Yo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=rA7/pcdf; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="rA7/pcdf" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=lYFNZhuVigdg2tLeh5rrT9NNlUPQrUYIEI4aFbYYiYM=; b=rA7/pcdf7JqQnRIh8dUJHkjn/P Bw6feVBUSrl7BwEL+d0iQwrLI0aI/aipgMX9tKpRjiiU2fAGs+uUBoVjUTNacfRx83l2w3TtT/THe niS9MaqX1E7OnIZrseT3jlutDzr+GTUDWI+vSZZXJ5+vN8RNMxLNtYxeqN0JXbTyda0quNr1W8D0z m+XhiCLhVSGhMPzN8YsTCDojuOCThiI9knix98jxdI29kQBf1Ju/jF4CfXyUGywdvPzWGgUUNCDGi VEeB+mnKB0/NKIeLI4vdkhs+Dkb+kRtZy+pYMJfOaN7e3hMPR+EcS4S/ITTN9Mic40haWInDwcKoM avd6TTSA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyd-001Gd5-28; Mon, 09 Dec 2024 12:59:27 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 17/28] selftests: ntsync: Add some tests for NTSYNC_IOC_WAIT_ALL. Date: Mon, 9 Dec 2024 12:58:53 -0600 Message-ID: <20241209185904.507350-18-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test basic synchronous functionality of NTSYNC_IOC_WAIT_ALL, and when objects are considered simultaneously signaled. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 99 ++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 40ad8cbd3138..c0f372167557 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -73,7 +73,8 @@ static int unlock_mutex(int mutex, __u32 owner, __u32 *count) return ret; } -static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) +static int wait_objs(int fd, unsigned long request, __u32 count, + const int *objs, __u32 owner, __u32 *index) { struct ntsync_wait_args args = {0}; struct timespec timeout; @@ -86,11 +87,21 @@ static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *in args.objs = (uintptr_t)objs; args.owner = owner; args.index = 0xdeadbeef; - ret = ioctl(fd, NTSYNC_IOC_WAIT_ANY, &args); + ret = ioctl(fd, request, &args); *index = args.index; return ret; } +static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) +{ + return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, index); +} + +static int wait_all(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) +{ + return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, index); +} + TEST(semaphore_state) { struct ntsync_sem_args sem_args; @@ -461,4 +472,88 @@ TEST(test_wait_any) close(fd); } +TEST(test_wait_all) +{ + struct ntsync_mutex_args mutex_args = {0}; + struct ntsync_sem_args sem_args = {0}; + __u32 owner, index, count; + int objs[2], fd, ret; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 2; + sem_args.max = 3; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + + mutex_args.owner = 0; + mutex_args.count = 0; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + + objs[0] = sem_args.sem; + objs[1] = mutex_args.mutex; + + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 1, 3); + check_mutex_state(mutex_args.mutex, 1, 123); + + ret = wait_all(fd, 2, objs, 456, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + check_sem_state(sem_args.sem, 1, 3); + check_mutex_state(mutex_args.mutex, 1, 123); + + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 2, 123); + + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + check_sem_state(sem_args.sem, 0, 3); + check_mutex_state(mutex_args.mutex, 2, 123); + + count = 3; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 2, 3); + check_mutex_state(mutex_args.mutex, 3, 123); + + owner = 123; + ret = ioctl(mutex_args.mutex, NTSYNC_IOC_MUTEX_KILL, &owner); + EXPECT_EQ(0, ret); + + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EOWNERDEAD, errno); + check_sem_state(sem_args.sem, 1, 3); + check_mutex_state(mutex_args.mutex, 1, 123); + + /* test waiting on the same object twice */ + objs[0] = objs[1] = sem_args.sem; + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno); + + close(sem_args.sem); + close(mutex_args.mutex); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848525 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB10314E2CC; Mon, 9 Dec 2024 18:59:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770776; cv=none; b=Tn5OqR9dYXMnektpu6g9sU//R1RT/2mEpQLMSVQIEbg5WbF2tmA/xhEnneN7Gl2ESNpu562TJfJfY8lH9EbyJxJrRCLLQIrVxv8GnZGdRVGIi6nDH4BUdfMo88Qyo2QQgrXVZR6tZthr9N18VYqZWhDpE7Xhf2L2cPbm92DW+EU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770776; c=relaxed/simple; bh=CAgcnAWVndXCc5CdhXm4Yv0C2toEM5VQmYN5+fMdcjo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VQVVN1j16rF65fnzxMIOrXJtHyA6UQ96+U8xJMntpKrN6GT8EhVFVyJ8VOkrdbMIhpHX5NMF7GRTLxmmlmM0S/ULXXj9Lsc85oHj3qjjpbgJK7KiBEMSnoTLjcj/3CdPSzIlCHY0QBYrD+Vs2ebuGQwL3f0Bx05WjQQiNSeMV7c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=NntiBX5l; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="NntiBX5l" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=zwZaONPTRv1TAeaJhWHoQ0+5xaoskz2R0vBPXkeiQgY=; b=NntiBX5lgSFwK/t9vKf9Xfmn2i AlhZ+bg49mbeOqB5/GSlv43olfzgrulic2EJswn+ExbboGgs7z9DnNvd0ARUoIwrgkPP7ZZydUY9N 5ZwYyWTnQJHmpWIYbZD2jhn6lclTeAi2ahe+t5euotUfrYTymiDz/Kv+aPOBSx7eD+0YdAJj5bNzs NFrdfHDzo4h8oOmn5jzgKrhF8eWmCAsZZHKrDroebGV4vB5898YMLJh/eTmkTMGdggXOYY9H0m38+ 6xkSUxTvyjuUe2CXOMPBZXfffyApu4j4ZnAEhHesfuZWoI6Ykg5mJJFq9cGGxcEl4IhFlIsOeIOyS UifLSzDw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiye-001Gd5-0N; Mon, 09 Dec 2024 12:59:28 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 18/28] selftests: ntsync: Add some tests for wakeup signaling with WINESYNC_IOC_WAIT_ANY. Date: Mon, 9 Dec 2024 12:58:54 -0600 Message-ID: <20241209185904.507350-19-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test contended "wait-for-any" waits, to make sure that scheduling and wakeup logic works correctly. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index c0f372167557..993f5db23768 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -556,4 +556,154 @@ TEST(test_wait_all) close(fd); } +struct wake_args { + int fd; + int obj; +}; + +struct wait_args { + int fd; + unsigned long request; + struct ntsync_wait_args *args; + int ret; + int err; +}; + +static void *wait_thread(void *arg) +{ + struct wait_args *args = arg; + + args->ret = ioctl(args->fd, args->request, args->args); + args->err = errno; + return NULL; +} + +static __u64 get_abs_timeout(unsigned int ms) +{ + struct timespec timeout; + clock_gettime(CLOCK_MONOTONIC, &timeout); + return (timeout.tv_sec * 1000000000) + timeout.tv_nsec + (ms * 1000000); +} + +static int wait_for_thread(pthread_t thread, unsigned int ms) +{ + struct timespec timeout; + + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_nsec += ms * 1000000; + timeout.tv_sec += (timeout.tv_nsec / 1000000000); + timeout.tv_nsec %= 1000000000; + return pthread_timedjoin_np(thread, NULL, &timeout); +} + +TEST(wake_any) +{ + struct ntsync_mutex_args mutex_args = {0}; + struct ntsync_wait_args wait_args = {0}; + struct ntsync_sem_args sem_args = {0}; + struct wait_args thread_args; + int objs[2], fd, ret; + __u32 count, index; + pthread_t thread; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 0; + sem_args.max = 3; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + + mutex_args.owner = 123; + mutex_args.count = 1; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + + objs[0] = sem_args.sem; + objs[1] = mutex_args.mutex; + + /* test waking the semaphore */ + + wait_args.timeout = get_abs_timeout(1000); + wait_args.objs = (uintptr_t)objs; + wait_args.count = 2; + wait_args.owner = 456; + wait_args.index = 0xdeadbeef; + thread_args.fd = fd; + thread_args.args = &wait_args; + thread_args.request = NTSYNC_IOC_WAIT_ANY; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + count = 1; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + check_sem_state(sem_args.sem, 0, 3); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(0, wait_args.index); + + /* test waking the mutex */ + + /* first grab it again for owner 123 */ + ret = wait_any(fd, 1, &mutex_args.mutex, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + wait_args.timeout = get_abs_timeout(1000); + wait_args.owner = 456; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = unlock_mutex(mutex_args.mutex, 123, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, count); + + ret = pthread_tryjoin_np(thread, NULL); + EXPECT_EQ(EBUSY, ret); + + ret = unlock_mutex(mutex_args.mutex, 123, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, mutex_args.count); + check_mutex_state(mutex_args.mutex, 1, 456); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(1, wait_args.index); + + /* delete an object while it's being waited on */ + + wait_args.timeout = get_abs_timeout(200); + wait_args.owner = 123; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + close(sem_args.sem); + close(mutex_args.mutex); + + ret = wait_for_thread(thread, 200); + EXPECT_EQ(0, ret); + EXPECT_EQ(-1, thread_args.ret); + EXPECT_EQ(ETIMEDOUT, thread_args.err); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849517 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A67CF199EAD; Mon, 9 Dec 2024 18:59:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770778; cv=none; b=Jyd8Uyu/cTo1fKKTZiMb0E2LSDEh4xZNSCNn0vidjSPUn3oM4ifhcbY7cxQHNECZoFysv+gpCK3aOleAfLIZ0pKwj+lwMIpBlBOC7qpuJljqKJjKxXtCiaRjhqaJgs/igWomv6qFBnU6U5vRx4hpA1BfCFzap6YO1WW8D3VL15o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770778; c=relaxed/simple; bh=UvuUUiKl0TXB4gj3KcmBPnL2z48m1/i2HNcvwWZlHU0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WaeZMjawAcljITre1I617GjaqczPyyw1OTOrO5t/ajyEl4Jcvi7eVQKkh65jTQ2oJ1qZU2liB2lDCEhTAOVVrKmD9sH/Kj52DfkRDcgiygC8y5Zkp8bGsv0lvCxSMRCT+OIpbFQWPuXckDgwQxf/XZlwSlRbxwjZTPTtM4oItjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=SExVDlED; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="SExVDlED" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=M/LBZlwH5ARcKJyd/bNhiFQzDMVjAnUNfHR23x8Gew4=; b=SExVDlEDv875MyQ/z/+3uiktO2 oEdKUN5qGUvsN1IwQoUKnXcmztxr+4DQyiyaSFSd0kcvoAqnuiNHkx4WugU5lwyNkl2/nVC60nUb8 pxH8z5S1Wisf5fXCm7sjqVC+piS9jmOG/JpnkftNfmfWwl0Q2/6Jv7xMVhV0aPoVuPLCG3zJ2HV07 33LjCz145mfdf0AOSHK5ShXd7JJMsArDijXIsqOiNWkc/FHB3utTvXRC9vEShh5/SCutvLVkdU3/M OMf2Oyj2iav2JjfCirBUdQq9KghirLMerqPfubo/mq78H+7bqu9HVWk2M4yTmXz50f2kwzN30SyUF K+xYvSzQ==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyi-001Gd5-2p; Mon, 09 Dec 2024 12:59:33 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 19/28] selftests: ntsync: Add some tests for wakeup signaling with WINESYNC_IOC_WAIT_ALL. Date: Mon, 9 Dec 2024 12:58:55 -0600 Message-ID: <20241209185904.507350-20-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test contended "wait-for-all" waits, to make sure that scheduling and wakeup logic works correctly, and that the wait only exits once objects are all simultaneously signaled. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 993f5db23768..b77fb0b2c4b1 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -706,4 +706,102 @@ TEST(wake_any) close(fd); } +TEST(wake_all) +{ + struct ntsync_mutex_args mutex_args = {0}; + struct ntsync_wait_args wait_args = {0}; + struct ntsync_sem_args sem_args = {0}; + struct wait_args thread_args; + int objs[2], fd, ret; + __u32 count, index; + pthread_t thread; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 0; + sem_args.max = 3; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + + mutex_args.owner = 123; + mutex_args.count = 1; + mutex_args.mutex = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, mutex_args.mutex); + + objs[0] = sem_args.sem; + objs[1] = mutex_args.mutex; + + wait_args.timeout = get_abs_timeout(1000); + wait_args.objs = (uintptr_t)objs; + wait_args.count = 2; + wait_args.owner = 456; + thread_args.fd = fd; + thread_args.args = &wait_args; + thread_args.request = NTSYNC_IOC_WAIT_ALL; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + count = 1; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + + ret = pthread_tryjoin_np(thread, NULL); + EXPECT_EQ(EBUSY, ret); + + check_sem_state(sem_args.sem, 1, 3); + + ret = wait_any(fd, 1, &sem_args.sem, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = unlock_mutex(mutex_args.mutex, 123, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, count); + + ret = pthread_tryjoin_np(thread, NULL); + EXPECT_EQ(EBUSY, ret); + + check_mutex_state(mutex_args.mutex, 0, 0); + + count = 2; + ret = post_sem(sem_args.sem, &count); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, count); + check_sem_state(sem_args.sem, 1, 3); + check_mutex_state(mutex_args.mutex, 1, 456); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + + /* delete an object while it's being waited on */ + + wait_args.timeout = get_abs_timeout(200); + wait_args.owner = 123; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + close(sem_args.sem); + close(mutex_args.mutex); + + ret = wait_for_thread(thread, 200); + EXPECT_EQ(0, ret); + EXPECT_EQ(-1, thread_args.ret); + EXPECT_EQ(ETIMEDOUT, thread_args.err); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:58:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848524 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2492C199E88; Mon, 9 Dec 2024 18:59:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770778; cv=none; b=ZFR5p7/PiwEekO4keq+lTUC2cbaM/9+NqMNcNx/7kGZcaA1BJ3X/WP4pIOfNIYOqSw5rx6HNRjgeepWsEOe3IUFTw1tqO/uWUbkjK5jeFzhrATzQb/vu5BLLz/eyQ7dWIcv9FGsMX1Ds2h9SrawfFN2wDT2X/98O+TiZusRMqK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770778; c=relaxed/simple; bh=gUeggPXQJGkMh6eRAwgiCm0iDKCVGgZZ6WmAgLMYBT0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kan3NjvkiqAzX4nLHJVq/7zwUeSP21cuHEceTXysetn2rJDj6mgHBG3Ghze8jIfXLggcHz7BgiSR4BW4R7e9CpINMk+JhbDW0UbjixYHKsIPzskcWyRFf8xmn55nOxrEfTfM1AOfw/ShsN9PSr/IbXUDAuKCwIgfbdeJgg7VSuU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=IWLyhQ5n; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="IWLyhQ5n" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=BUq+yFXfQFOO6nGetAGw328oHc106G/AysMITfp64g4=; b=IWLyhQ5n/+buKpKtbPXTWqJs87 yXSyHwTVL8asCcAUabzsLUm/xXh2neKbANbMjGClu42pIbTzke4ShG2ihg5qvmaLBdy5GjdFlhis9 3yRF3qbMBefp/LirQaQoHGXIkpEMBf8vb2SnZyC1iSHuocx9kTczw0dJDDZnH8ctKD0Q/H2IBIsIp VvURa04O0QlnPCeECyPZ1Du8LaBNefowMuAgm49qD8mpO/a+IZhabcW3vWP2D8hLpVpMZCk0OV+GA 885jP2TST9XsPiHeSt8Ie8Q7WkUjIuugx6fVNgFHDW5lGvqV9gxVP2PUXd5ZBo/VVdOouXiVTkGTO BU0PjlcA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyj-001Gd5-37; Mon, 09 Dec 2024 12:59:34 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 20/28] selftests: ntsync: Add some tests for manual-reset event state. Date: Mon, 9 Dec 2024 12:58:56 -0600 Message-ID: <20241209185904.507350-21-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test event-specific ioctls NTSYNC_IOC_EVENT_SET, NTSYNC_IOC_EVENT_RESET, NTSYNC_IOC_EVENT_PULSE, NTSYNC_IOC_EVENT_READ for manual-reset events, and waiting on manual-reset events. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index b77fb0b2c4b1..b6481c2b85cc 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -73,6 +73,27 @@ static int unlock_mutex(int mutex, __u32 owner, __u32 *count) return ret; } +static int read_event_state(int event, __u32 *signaled, __u32 *manual) +{ + struct ntsync_event_args args; + int ret; + + memset(&args, 0xcc, sizeof(args)); + ret = ioctl(event, NTSYNC_IOC_EVENT_READ, &args); + *signaled = args.signaled; + *manual = args.manual; + return ret; +} + +#define check_event_state(event, signaled, manual) \ + ({ \ + __u32 __signaled, __manual; \ + int ret = read_event_state((event), &__signaled, &__manual); \ + EXPECT_EQ(0, ret); \ + EXPECT_EQ((signaled), __signaled); \ + EXPECT_EQ((manual), __manual); \ + }) + static int wait_objs(int fd, unsigned long request, __u32 count, const int *objs, __u32 owner, __u32 *index) { @@ -353,6 +374,74 @@ TEST(mutex_state) close(fd); } +TEST(manual_event_state) +{ + struct ntsync_event_args event_args; + __u32 index, signaled; + int fd, event, ret; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + event_args.manual = 1; + event_args.signaled = 0; + event_args.event = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, event_args.event); + event = event_args.event; + check_event_state(event, 0, 1); + + signaled = 0xdeadbeef; + ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event, 1, 1); + + ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + check_event_state(event, 1, 1); + + ret = wait_any(fd, 1, &event, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_event_state(event, 1, 1); + + signaled = 0xdeadbeef; + ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + check_event_state(event, 0, 1); + + ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event, 0, 1); + + ret = wait_any(fd, 1, &event, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + + ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + check_event_state(event, 0, 1); + + ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event, 0, 1); + + close(event); + + close(fd); +} + TEST(test_wait_any) { int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret; From patchwork Mon Dec 9 18:58:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848523 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 06DEF199FDC; Mon, 9 Dec 2024 18:59:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770779; cv=none; b=m8x2IzjfVbEZyVq68GncyfrojIv6RcFiDl/dI9pIKYIaHcpAD/seaa0azjmdR/lOh/ARm7B0pWgtmoKk+NBwMo++WNIos+4iJAwqSVEzMTKXjk0LLQjwcq/eGuZos5Ih/ySY0fS1MpkT8s2RzgPW2wpfKDuJov8F76ae7DPye7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770779; c=relaxed/simple; bh=4Ab/sQIbAd81VaBoQcLVwxOsdxge96BedL56C5osvQg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AgQ1VdTsgZVzCZM0e3UirS1ZcAs/F9mkoYi6Xomq88rFcLwlrFpWhNkIhO/p3bU6cXPMR3axHUZnX6396B+IebdpEWQEdpLtrPdGL4+PDy/HTSJRMIuGwm+1MSAA4mNlxi0x1vqrJR4yMrqClAxRGPCg+mp3Ie3laseBnbyKOQA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=QweM9zmT; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="QweM9zmT" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Eeq3Ehv4lJUwOdLSmPyFK5uFI6EH6FzbCtzv+EtsojA=; b=QweM9zmTwz6LxC5w2j11j62DY4 OtmStgufVHHiBncnxgkivzKNyLml8b0ImnaFp02Ol34827E7T79IzgeC0kUgi9GxymtjO9n2kEhGx BL8YYMobu5Ta+0P56Ytegz7W8Faf2dSIRW2+1lFvnNiFYwYOjoyJTsWsbZBlyISKjxUsTj8l+QUF5 eGehAGVBsRF/dAwaJd2WSPjVlXnDV4M/P+IZzDt1B+EFdEez8EcAFXOTkOVPmSnnczXn+ZXrVt0cc +NnFLPwkCLEjn4boGXG94lf4BUCVf4W2LV/DDek8XwKrao2eQFql3GTaqmm01RhNtg232yX+n/+A4 5NCDjjMw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyk-001Gd5-16; Mon, 09 Dec 2024 12:59:34 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 21/28] selftests: ntsync: Add some tests for auto-reset event state. Date: Mon, 9 Dec 2024 12:58:57 -0600 Message-ID: <20241209185904.507350-22-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test event-specific ioctls NTSYNC_IOC_EVENT_SET, NTSYNC_IOC_EVENT_RESET, NTSYNC_IOC_EVENT_PULSE, NTSYNC_IOC_EVENT_READ for auto-reset events, and waiting on auto-reset events. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index b6481c2b85cc..12ccb4ec28e4 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -442,6 +442,65 @@ TEST(manual_event_state) close(fd); } +TEST(auto_event_state) +{ + struct ntsync_event_args event_args; + __u32 index, signaled; + int fd, event, ret; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + event_args.manual = 0; + event_args.signaled = 1; + event_args.event = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, event_args.event); + event = event_args.event; + + check_event_state(event, 1, 0); + + signaled = 0xdeadbeef; + ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + check_event_state(event, 1, 0); + + ret = wait_any(fd, 1, &event, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_event_state(event, 0, 0); + + signaled = 0xdeadbeef; + ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event, 0, 0); + + ret = wait_any(fd, 1, &event, 123, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + + ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + check_event_state(event, 0, 0); + + ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event, 0, 0); + + close(event); + + close(fd); +} + TEST(test_wait_any) { int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret; From patchwork Mon Dec 9 18:58:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849516 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA32019AA5D; Mon, 9 Dec 2024 18:59:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770779; cv=none; b=cx7GjvJm01COQQhFKqRjFrNkc8J7kBW5AhFvDeimsf5kjb3OfautOps0za1Cm6lMtTh1ug7rXG2L74j86C4zd5FDLZKGrtfLZ0lpMOZls0wT5Jg30reTYAvYIV6aS0B/zQ5vW0bNmx11a0fT/lvxNIc7qwdZq04qwmdQZkzbc9o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770779; c=relaxed/simple; bh=DjnEbJDoB9Dul+eXHq8clKxcbVu75NwycVVhQWnf0ig=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EPElPRj0F8L+jA6PAnHFFp9vjIqodVkxtiMj5yM+3SnahnBr6c/75R6XvSnKuHGCOBIX7W+8Q2jskN8zkh+K+0Ub5RIdDb9hJdzjsYd1UQMOYrEBBsqFyEFV6gJ+WURQjnftq95zwtELh2dyUSMR62GNRjsaln++6V4yCeofeD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=RHJxmLBb; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="RHJxmLBb" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=X2FClKwDD6Y5NBJzrFcfOYwIT9ygvxJfJzIcvxri0Xc=; b=RHJxmLBbEv0UfgKHPNnS0TDckw BNjKqD83SPLehXu69xkLvUQJlpCujZ0rT2yqLkKSg4qNSZjtYUCugS6zo0uOWWrUYcSiA63iesJej ki8+qaqiYsH6mFSiJCBZjsRKHUv8vU1IQmzQw1WzrIpV5OF9udEetP5e6Bg/I5bplu3+pdQqYt+Eb myNQq9i2hTxn1ASU/NzJwFHpiup+auL4VBufMJy3WgB8KIe+5QXanjdYa8xgcYq9JsFQcEmmLZfqY vpytIHJVsiSl7rKX7nDbhxpjJSmBKj0b/x/Q3zRxf/isJa/2BnaPstFmGQB8JDK7YzFlYwzwqVcnV 8HVhY+6g==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyl-001Gd5-2u; Mon, 09 Dec 2024 12:59:36 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 22/28] selftests: ntsync: Add some tests for wakeup signaling with events. Date: Mon, 9 Dec 2024 12:58:58 -0600 Message-ID: <20241209185904.507350-23-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Expand the contended wait tests, which previously only covered events and semaphores, to cover events as well. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 151 +++++++++++++++++- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 12ccb4ec28e4..5d17eff6a370 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -622,6 +622,7 @@ TEST(test_wait_any) TEST(test_wait_all) { + struct ntsync_event_args event_args = {0}; struct ntsync_mutex_args mutex_args = {0}; struct ntsync_sem_args sem_args = {0}; __u32 owner, index, count; @@ -644,6 +645,11 @@ TEST(test_wait_all) EXPECT_EQ(0, ret); EXPECT_NE(0xdeadbeef, mutex_args.mutex); + event_args.manual = true; + event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + objs[0] = sem_args.sem; objs[1] = mutex_args.mutex; @@ -692,6 +698,14 @@ TEST(test_wait_all) check_sem_state(sem_args.sem, 1, 3); check_mutex_state(mutex_args.mutex, 1, 123); + objs[0] = sem_args.sem; + objs[1] = event_args.event; + ret = wait_all(fd, 2, objs, 123, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + check_sem_state(sem_args.sem, 0, 3); + check_event_state(event_args.event, 1, 1); + /* test waiting on the same object twice */ objs[0] = objs[1] = sem_args.sem; ret = wait_all(fd, 2, objs, 123, &index); @@ -700,6 +714,7 @@ TEST(test_wait_all) close(sem_args.sem); close(mutex_args.mutex); + close(event_args.event); close(fd); } @@ -746,12 +761,13 @@ static int wait_for_thread(pthread_t thread, unsigned int ms) TEST(wake_any) { + struct ntsync_event_args event_args = {0}; struct ntsync_mutex_args mutex_args = {0}; struct ntsync_wait_args wait_args = {0}; struct ntsync_sem_args sem_args = {0}; struct wait_args thread_args; + __u32 count, index, signaled; int objs[2], fd, ret; - __u32 count, index; pthread_t thread; fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); @@ -833,10 +849,101 @@ TEST(wake_any) EXPECT_EQ(0, thread_args.ret); EXPECT_EQ(1, wait_args.index); + /* test waking events */ + + event_args.manual = false; + event_args.signaled = false; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + objs[1] = event_args.event; + wait_args.timeout = get_abs_timeout(1000); + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event_args.event, 0, 0); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(1, wait_args.index); + + wait_args.timeout = get_abs_timeout(1000); + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event_args.event, 0, 0); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(1, wait_args.index); + + close(event_args.event); + + event_args.manual = true; + event_args.signaled = false; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + objs[1] = event_args.event; + wait_args.timeout = get_abs_timeout(1000); + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event_args.event, 1, 1); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(1, wait_args.index); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + + wait_args.timeout = get_abs_timeout(1000); + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_PULSE, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_event_state(event_args.event, 0, 1); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(1, wait_args.index); + + close(event_args.event); + /* delete an object while it's being waited on */ wait_args.timeout = get_abs_timeout(200); wait_args.owner = 123; + objs[1] = mutex_args.mutex; ret = pthread_create(&thread, NULL, wait_thread, &thread_args); EXPECT_EQ(0, ret); @@ -856,12 +963,14 @@ TEST(wake_any) TEST(wake_all) { + struct ntsync_event_args manual_event_args = {0}; + struct ntsync_event_args auto_event_args = {0}; struct ntsync_mutex_args mutex_args = {0}; struct ntsync_wait_args wait_args = {0}; struct ntsync_sem_args sem_args = {0}; struct wait_args thread_args; - int objs[2], fd, ret; - __u32 count, index; + __u32 count, index, signaled; + int objs[4], fd, ret; pthread_t thread; fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); @@ -881,12 +990,24 @@ TEST(wake_all) EXPECT_EQ(0, ret); EXPECT_NE(0xdeadbeef, mutex_args.mutex); + manual_event_args.manual = true; + manual_event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &manual_event_args); + EXPECT_EQ(0, ret); + + auto_event_args.manual = false; + auto_event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &auto_event_args); + EXPECT_EQ(0, ret); + objs[0] = sem_args.sem; objs[1] = mutex_args.mutex; + objs[2] = manual_event_args.event; + objs[3] = auto_event_args.event; wait_args.timeout = get_abs_timeout(1000); wait_args.objs = (uintptr_t)objs; - wait_args.count = 2; + wait_args.count = 4; wait_args.owner = 456; thread_args.fd = fd; thread_args.args = &wait_args; @@ -920,12 +1041,32 @@ TEST(wake_all) check_mutex_state(mutex_args.mutex, 0, 0); + ret = ioctl(manual_event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + count = 2; ret = post_sem(sem_args.sem, &count); EXPECT_EQ(0, ret); EXPECT_EQ(0, count); + check_sem_state(sem_args.sem, 2, 3); + + ret = ioctl(auto_event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, signaled); + + ret = ioctl(manual_event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + + ret = ioctl(auto_event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, signaled); + check_sem_state(sem_args.sem, 1, 3); check_mutex_state(mutex_args.mutex, 1, 456); + check_event_state(manual_event_args.event, 1, 1); + check_event_state(auto_event_args.event, 0, 0); ret = wait_for_thread(thread, 100); EXPECT_EQ(0, ret); @@ -943,6 +1084,8 @@ TEST(wake_all) close(sem_args.sem); close(mutex_args.mutex); + close(manual_event_args.event); + close(auto_event_args.event); ret = wait_for_thread(thread, 200); EXPECT_EQ(0, ret); From patchwork Mon Dec 9 18:58:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849515 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AF8C19AD5C; Mon, 9 Dec 2024 18:59:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770780; cv=none; b=MG0yGbFRot+lL3f/Il0FAebf+RAMnVbOZLCH91M97kxJjwvAoKoQ2HGEciUzMR5mlmHnwI4c3NE2rSn0yHXI63iQFqTMRwSKsZY7MwcAezXUXXQbZJBRN+3OcUvmWsycReaMfgV2Pnql2C/6/BBZzfpd2ba6FTSdE5BnfKSDaKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770780; c=relaxed/simple; bh=reWkrE9+tNSvts+xEwfERx10CymuFOMyKdMi5FNpBiI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=crNdVFiSNXxfSpX9AHqmqB71wJ1k9vMObsXHQQUSyGRJvhn9h845IVB8vGduzOUtT/6H0rCKu3pXvYvah5oQvAx84pm43dzP6tnS5U+6NgzwAWsi6akkyPodrAKEaopEEuBuXyXKQqYZg6OY3PGejqyCUFP9x1Lq3WEbwREdjac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=Y+eA0Z+5; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="Y+eA0Z+5" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=/I9wdylc6MAvbvqkJ3X2n+g3DiuXUQW068q5UyJeaFc=; b=Y+eA0Z+5sO+j1SX9b+ABlkpv9b pATwPBOquN7PQVRNH0Nhq9mNF3Pp6oEOslHAcc3YtoipTE0IOK+jXX5xOQtS6oxkAayRPTX97M+Cm Yyxr27lYgwhbdurTiK2J8Zat6pcMPk7SBEhFenlx98WZDnVnIueZicn5mzUTPoPif0o5NPR6Hm+Zn lAFKU0PymtcE8XoTJFf0G6qIfrTvOnSIPPKljSHoE4H067mLwU9BZmMQskkDH9eEjZu1OExn1iwZS QMCSrg9AWuUTDxs4sFqMoy5zOvEfmWlwyUEwO23hkMgKeyLtQuncYbzkjNMvnfrZ9u4FicSh/1MUh m2Fl4kLA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiym-001Gd5-0i; Mon, 09 Dec 2024 12:59:36 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 23/28] selftests: ntsync: Add tests for alertable waits. Date: Mon, 9 Dec 2024 12:58:59 -0600 Message-ID: <20241209185904.507350-24-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test the "alert" functionality of NTSYNC_IOC_WAIT_ALL and NTSYNC_IOC_WAIT_ANY, when a wait is woken with an alert and when it is woken by an object. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 179 +++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 5d17eff6a370..5465a16d38b3 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -95,7 +95,7 @@ static int read_event_state(int event, __u32 *signaled, __u32 *manual) }) static int wait_objs(int fd, unsigned long request, __u32 count, - const int *objs, __u32 owner, __u32 *index) + const int *objs, __u32 owner, int alert, __u32 *index) { struct ntsync_wait_args args = {0}; struct timespec timeout; @@ -108,6 +108,7 @@ static int wait_objs(int fd, unsigned long request, __u32 count, args.objs = (uintptr_t)objs; args.owner = owner; args.index = 0xdeadbeef; + args.alert = alert; ret = ioctl(fd, request, &args); *index = args.index; return ret; @@ -115,12 +116,26 @@ static int wait_objs(int fd, unsigned long request, __u32 count, static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) { - return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, index); + return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, 0, index); } static int wait_all(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index) { - return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, index); + return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, 0, index); +} + +static int wait_any_alert(int fd, __u32 count, const int *objs, + __u32 owner, int alert, __u32 *index) +{ + return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, + count, objs, owner, alert, index); +} + +static int wait_all_alert(int fd, __u32 count, const int *objs, + __u32 owner, int alert, __u32 *index) +{ + return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, + count, objs, owner, alert, index); } TEST(semaphore_state) @@ -1095,4 +1110,162 @@ TEST(wake_all) close(fd); } +TEST(alert_any) +{ + struct ntsync_event_args event_args = {0}; + struct ntsync_sem_args sem_args = {0}; + __u32 index, count, signaled; + int objs[2], fd, ret; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 0; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + objs[0] = sem_args.sem; + + sem_args.count = 1; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + objs[1] = sem_args.sem; + + event_args.manual = true; + event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + ret = wait_any_alert(fd, 0, NULL, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + + ret = wait_any_alert(fd, 0, NULL, 123, event_args.event, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + + ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(1, index); + + ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, index); + + close(event_args.event); + + /* test with an auto-reset event */ + + event_args.manual = false; + event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + count = 1; + ret = post_sem(objs[0], &count); + EXPECT_EQ(0, ret); + + ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, index); + + ret = wait_any_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + close(event_args.event); + + close(objs[0]); + close(objs[1]); + + close(fd); +} + +TEST(alert_all) +{ + struct ntsync_event_args event_args = {0}; + struct ntsync_sem_args sem_args = {0}; + __u32 index, count, signaled; + int objs[2], fd, ret; + + fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, fd); + + sem_args.count = 2; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + objs[0] = sem_args.sem; + + sem_args.count = 1; + sem_args.max = 2; + sem_args.sem = 0xdeadbeef; + ret = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args); + EXPECT_EQ(0, ret); + EXPECT_NE(0xdeadbeef, sem_args.sem); + objs[1] = sem_args.sem; + + event_args.manual = true; + event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, index); + + close(event_args.event); + + /* test with an auto-reset event */ + + event_args.manual = false; + event_args.signaled = true; + ret = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + + count = 2; + ret = post_sem(objs[1], &count); + EXPECT_EQ(0, ret); + + ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, index); + + ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(0, ret); + EXPECT_EQ(2, index); + + ret = wait_all_alert(fd, 2, objs, 123, event_args.event, &index); + EXPECT_EQ(-1, ret); + EXPECT_EQ(ETIMEDOUT, errno); + + close(event_args.event); + + close(objs[0]); + close(objs[1]); + + close(fd); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:59:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848521 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94A6419F130; Mon, 9 Dec 2024 18:59:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770783; cv=none; b=IkP+Wubgqdq/AaECqZsK9FsS3x3XFpnFmmcl0gYFDdcPep3kOm2KH6tXqjynz/eM44Sl5RL13woXh+vXbKZz67gXZKuND0OycOfH17PWGW543+Vy2Ys0QbNGVoxICKZUVhLUxZDv6SFV2454S8cDN/k1p7sCWW2mS9tzBKKewtU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770783; c=relaxed/simple; bh=oZlH871wgcJLL9ukiEsDxPWhFE+tDhB1jJ+zJrhg1B8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f9zuc2MUCRzog83YutBARC3ZyDibf8ylwByboyxlZJNiMgSWQc5IrdS9KxCAvfBlAml6wRkvk9k9a3Hdk+FS5BgdxhGehqnqXRi2cpt3oT4DIILCaI9ibc/AA7bLIXyrnvePcpsAFgYGAYekZeYpAcYA8pr1h6hq2IPWfeo0tZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=ka/nM3bC; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="ka/nM3bC" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=3XGXZLANAg39CSRLjWPFEQoZ9yJ6vyFbmQa56UpXQ+U=; b=ka/nM3bC6lTe9DEhcTPX1MwSTv /+PrtAiS592D/8NuAajNd5wQNRDwBGxjBg3citxU1FSor4HZSgY3J9ro+Smhz9EhpESqvBs89PVDt YXVaL51Ab9sutIYOhH80pyRiiGdVyDnJ8Pr2H4443ZPNtYyN8C/VBgSWjaiHWL4Za5nmLAGXdICYN r9AKL1NPIHRCXuXNHiCvcWQGfVbClLarjYHGlnWLGSZMkZ27GufhKnqgsHJCPSRg8lfS5q7VdsUC/ pyvmdTwMCOjVBl/7YPbYPh3vn9gqQbF8vfddD3keqrU/vEMFlsDfX/7ttDS/GLxJwpqOYpSCXdfqR nzzr7B2g==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiym-001Gd5-2e; Mon, 09 Dec 2024 12:59:37 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 24/28] selftests: ntsync: Add some tests for wakeup signaling via alerts. Date: Mon, 9 Dec 2024 12:59:00 -0600 Message-ID: <20241209185904.507350-25-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Expand the alert tests to cover alerting a thread mid-wait, to test that the relevant scheduling logic works correctly. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 5465a16d38b3..968874d7e325 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -1113,9 +1113,12 @@ TEST(wake_all) TEST(alert_any) { struct ntsync_event_args event_args = {0}; + struct ntsync_wait_args wait_args = {0}; struct ntsync_sem_args sem_args = {0}; __u32 index, count, signaled; + struct wait_args thread_args; int objs[2], fd, ret; + pthread_t thread; fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); ASSERT_LE(0, fd); @@ -1163,6 +1166,34 @@ TEST(alert_any) EXPECT_EQ(0, ret); EXPECT_EQ(2, index); + /* test wakeup via alert */ + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + + wait_args.timeout = get_abs_timeout(1000); + wait_args.objs = (uintptr_t)objs; + wait_args.count = 2; + wait_args.owner = 123; + wait_args.index = 0xdeadbeef; + wait_args.alert = event_args.event; + thread_args.fd = fd; + thread_args.args = &wait_args; + thread_args.request = NTSYNC_IOC_WAIT_ANY; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(2, wait_args.index); + close(event_args.event); /* test with an auto-reset event */ @@ -1199,9 +1230,12 @@ TEST(alert_any) TEST(alert_all) { struct ntsync_event_args event_args = {0}; + struct ntsync_wait_args wait_args = {0}; struct ntsync_sem_args sem_args = {0}; + struct wait_args thread_args; __u32 index, count, signaled; int objs[2], fd, ret; + pthread_t thread; fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); ASSERT_LE(0, fd); @@ -1235,6 +1269,34 @@ TEST(alert_all) EXPECT_EQ(0, ret); EXPECT_EQ(2, index); + /* test wakeup via alert */ + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_RESET, &signaled); + EXPECT_EQ(0, ret); + + wait_args.timeout = get_abs_timeout(1000); + wait_args.objs = (uintptr_t)objs; + wait_args.count = 2; + wait_args.owner = 123; + wait_args.index = 0xdeadbeef; + wait_args.alert = event_args.event; + thread_args.fd = fd; + thread_args.args = &wait_args; + thread_args.request = NTSYNC_IOC_WAIT_ALL; + ret = pthread_create(&thread, NULL, wait_thread, &thread_args); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(ETIMEDOUT, ret); + + ret = ioctl(event_args.event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + + ret = wait_for_thread(thread, 100); + EXPECT_EQ(0, ret); + EXPECT_EQ(0, thread_args.ret); + EXPECT_EQ(2, wait_args.index); + close(event_args.event); /* test with an auto-reset event */ From patchwork Mon Dec 9 18:59:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848522 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C05C019F419; Mon, 9 Dec 2024 18:59:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770782; cv=none; b=QzVtdatWwG3Cod594gfDBGlpLDIxIsYNIYZsBvWIX/F6sFbUoRhTxuoA1Cjr12WiPGZJ6sUhvXntfTbkAeQS/kG0OujwWQLoplb9hUkDMQzS57BD5g5/4eHpvN32dCIfik8/Qitf1HdbX/dtCeXNuM41cSKYHGiuw+KbY+6Z1mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770782; c=relaxed/simple; bh=ZIh44mQVASfA0ovsmUwbP4RzKpAfEg1Og4aqH4VQKxg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QjCiDzPQPtdehpBA4oXG5s4LtOOIGGY+Zg6hjzURiRzu1lN5kfN3gS1+F6BR60uMyq/Ou+Bd1LUbiSwjTIE455nzlrEoRb+Qy/hlwg6PIxnXPlVijnBZ/iryDPX/26WHZIG5u/EnO8sI4B9v5IcZJO7ywcebUujbLM3ev1o2IZU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=Vs7E3403; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="Vs7E3403" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=QnT7u9WQnQV6Z7kAgJwKz2tLPbeiW30uAJvzsjmk9Ak=; b=Vs7E3403XmYBR1/9Z3Ns8V7GxP za+cn7LLkJsk92vC5Af+U3ouysSRJKI5cTtDuXFDSmbLK/31tKX9jKMRayMT+14sk/BjdVF/35cWU GiD2wy/YSQBCv5jDiY6kXD7wlovzd1+jBDacH7SnVKXlFhJo4FFxOXUg6BilXnyirBq1PISBfciNa FKMlZShyltQjVNJmeTUfM+d5wMlLlaNXvb7tBeVkdg1U/ZRgf7j2+LZG+Q3n60d36PWcoNm4U8A2/ hKBofYe3G9EBy7U5z4PfF5YwzInrw8MhtrNzftCfEbiiamaPFkbl+h2dI+X1/Icz+aI5OPy1Ko2ym xUOUKcEA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyn-001Gd5-1N; Mon, 09 Dec 2024 12:59:37 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 25/28] selftests: ntsync: Add a stress test for contended waits. Date: Mon, 9 Dec 2024 12:59:01 -0600 Message-ID: <20241209185904.507350-26-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Test a more realistic usage pattern, and one with heavy contention, in order to actually exercise ntsync's internal synchronization. This test has several threads in a tight loop acquiring a mutex, modifying some shared data, and then releasing the mutex. At the end we check if the data is consistent. Signed-off-by: Elizabeth Figura --- .../testing/selftests/drivers/ntsync/ntsync.c | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tools/testing/selftests/drivers/ntsync/ntsync.c b/tools/testing/selftests/drivers/ntsync/ntsync.c index 968874d7e325..5fa2c9a0768c 100644 --- a/tools/testing/selftests/drivers/ntsync/ntsync.c +++ b/tools/testing/selftests/drivers/ntsync/ntsync.c @@ -1330,4 +1330,78 @@ TEST(alert_all) close(fd); } +#define STRESS_LOOPS 10000 +#define STRESS_THREADS 4 + +static unsigned int stress_counter; +static int stress_device, stress_start_event, stress_mutex; + +static void *stress_thread(void *arg) +{ + struct ntsync_wait_args wait_args = {0}; + __u32 index, count, i; + int ret; + + wait_args.timeout = UINT64_MAX; + wait_args.count = 1; + wait_args.objs = (uintptr_t)&stress_start_event; + wait_args.owner = gettid(); + wait_args.index = 0xdeadbeef; + + ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args); + + wait_args.objs = (uintptr_t)&stress_mutex; + + for (i = 0; i < STRESS_LOOPS; ++i) { + ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args); + + ++stress_counter; + + unlock_mutex(stress_mutex, wait_args.owner, &count); + } + + return NULL; +} + +TEST(stress_wait) +{ + struct ntsync_event_args event_args; + struct ntsync_mutex_args mutex_args; + pthread_t threads[STRESS_THREADS]; + __u32 signaled, i; + int ret; + + stress_device = open("/dev/ntsync", O_CLOEXEC | O_RDONLY); + ASSERT_LE(0, stress_device); + + mutex_args.owner = 0; + mutex_args.count = 0; + ret = ioctl(stress_device, NTSYNC_IOC_CREATE_MUTEX, &mutex_args); + EXPECT_EQ(0, ret); + stress_mutex = mutex_args.mutex; + + event_args.manual = 1; + event_args.signaled = 0; + ret = ioctl(stress_device, NTSYNC_IOC_CREATE_EVENT, &event_args); + EXPECT_EQ(0, ret); + stress_start_event = event_args.event; + + for (i = 0; i < STRESS_THREADS; ++i) + pthread_create(&threads[i], NULL, stress_thread, NULL); + + ret = ioctl(stress_start_event, NTSYNC_IOC_EVENT_SET, &signaled); + EXPECT_EQ(0, ret); + + for (i = 0; i < STRESS_THREADS; ++i) { + ret = pthread_join(threads[i], NULL); + EXPECT_EQ(0, ret); + } + + EXPECT_EQ(STRESS_LOOPS * STRESS_THREADS, stress_counter); + + close(stress_start_event); + close(stress_mutex); + close(stress_device); +} + TEST_HARNESS_MAIN From patchwork Mon Dec 9 18:59:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849514 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A3E019F487; Mon, 9 Dec 2024 18:59:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770783; cv=none; b=BvTEFaBHZWeamccJxdPSx/zEP1b2WD6Ak0x5INfG1xuoYY8aCPm7wzcy4iHY1VLoGPu25migR70YO2EQs9PztDUEGY5rwmy/fsaQsRGwUb8csz3fU45N3Zz/AHqui9HYW+/o6qoDGpltOvM66uGi59u4GqxEJiLHkGBQinj8vWg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770783; c=relaxed/simple; bh=OJvM6op5wYx37WguuHJVy5B8DCwQrTuTTPhePbmCAcE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kTOC3EP3yGed/HxaN87ACdcyS/DCo0Fui7OOLl1OD4HA1XBWzkMJAhEZHwfEYqAmemt4nZuu2N0JafolPicOqITZrqUJDpqfMZVy/Xp0ECKurC/aU0HZAq2ykfPJXDbZVlx71MP6kiabSCALwdkmeuNFSVsCE0k0xShhRyPRHGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=c1T75YrA; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="c1T75YrA" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=0P2C43dx5tRTctB9mu2F7UXtDC2Bs0A7lV36tqxIGe4=; b=c1T75YrA/L1v8+syaiQ4OKQh54 oJbSeRMf1dguNcP6sqUy4+L4InsJpRrz4aUSEs4lVzRl7RZU1LR6nwFw+BNbd2aQYedfYg+DFUZc4 +BWDJf7+QeL2y2B4kWPHFBHKS729r213XWt/PQpB98UtpNBRnI+9NAP0y5VaBfrxvxaSb1/B5ryP6 ofCP+sp1e4Lqh+FMfuXiefhzCGEo1l3LHtGrN2+LNiF//ahOFNQsLxvR9HcFoDVI6ffuv3Qf3QHl7 reAdViCAZ/lFp7zP9nhmEOM2276KCN4tNfCcWBLH32yzeg7OZaWSaKLDH2teWTQBHOQbBDRUFKcOf /7YLc/ew==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyn-001Gd5-39; Mon, 09 Dec 2024 12:59:38 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 26/28] maintainers: Add an entry for ntsync. Date: Mon, 9 Dec 2024 12:59:02 -0600 Message-ID: <20241209185904.507350-27-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add myself as maintainer, supported by CodeWeavers. Signed-off-by: Elizabeth Figura --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1e930c7a58b1..8c3dd9077fc2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16708,6 +16708,15 @@ T: git https://github.com/Paragon-Software-Group/linux-ntfs3.git F: Documentation/filesystems/ntfs3.rst F: fs/ntfs3/ +NTSYNC SYNCHRONIZATION PRIMITIVE DRIVER +M: Elizabeth Figura +L: wine-devel@winehq.org +S: Supported +F: Documentation/userspace-api/ntsync.rst +F: drivers/misc/ntsync.c +F: include/uapi/linux/ntsync.h +F: tools/testing/selftests/drivers/ntsync/ + NUBUS SUBSYSTEM M: Finn Thain L: linux-m68k@lists.linux-m68k.org From patchwork Mon Dec 9 18:59:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 848520 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0416218CC15; Mon, 9 Dec 2024 18:59:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770785; cv=none; b=W8IjRaN9o+LGIEuviKlDNVLlti4XuJz52RY7tiDbPCEqNkRujpNbWazSH+d1UHJbLcHEB+GjfWNrwGJDmS6HIHL+F016FtnDp5Bhremhg2CC1WWjNqG/1JQEWnfnIKXHjDdpfq/ymBy+hnHWuTuQDzE1AiK2Ysm9ftCBFaxBhCc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770785; c=relaxed/simple; bh=r/s0mQS3sRYnKYpur3grbeHDa3BcWRtvlxinrMdufdo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lZfTEbHEXaQaSZUVyN2CWEj9/UcDZYxFNUgTOzyptYbJQmqxCZHYuYyf2jb6+JCON/xHt1KXDn9YTCDfqpWtlum/aIhsd+SUb8aDd2K4ur8tu0+hzuftPfnXHaPS5j4+w56kmjIjlMJGUo0fNgVFSn03E26laHFtjluouN2TKY4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=ITPLW/0Z; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="ITPLW/0Z" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=QDBtH3RxbOGQTsKfnISarRDVB17q/+z4U7sYEqabjAk=; b=ITPLW/0ZrNG9YEKGyTA/2UqwAc sGPYeHAmsBVsfcVB6LM/6K5AFlIJffPBmPNj0VcA9fp+b605/12zsgJpFL1/gpNWCalHE3mdGRwKM ol45/0BaAKmheGbCXY4V09pyJ1U7zoH9r/CiowOp7LVR7V+EptuXCHcmPlyvOTJYopekLoakACz+h JuyWZxFjB7uT3NpFkJMnF44ojxEItGc4ny4R+fbvIRSBU7TslQGhz6F4XbHnTEbSg0bfztJhxuwsf lBi71XL6SNpHFOaWAu7wAzqOhUDQO5wwknYHaE0k/hEELZC+Q+6wWJxzTXdxqY+rdkr3WS24/b/bM Ij2qEecw==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyo-001Gd5-2S; Mon, 09 Dec 2024 12:59:39 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 27/28] docs: ntsync: Add documentation for the ntsync uAPI. Date: Mon, 9 Dec 2024 12:59:03 -0600 Message-ID: <20241209185904.507350-28-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add an overall explanation of the driver architecture, and complete and precise specification for its intended behaviour. Signed-off-by: Elizabeth Figura --- Documentation/userspace-api/index.rst | 1 + Documentation/userspace-api/ntsync.rst | 398 +++++++++++++++++++++++++ 2 files changed, 399 insertions(+) create mode 100644 Documentation/userspace-api/ntsync.rst diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst index 274cc7546efc..9c1b15cd89ab 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst @@ -63,6 +63,7 @@ Everything else vduse futex2 perf_ring_buffer + ntsync .. only:: subproject and html diff --git a/Documentation/userspace-api/ntsync.rst b/Documentation/userspace-api/ntsync.rst new file mode 100644 index 000000000000..767844637a7d --- /dev/null +++ b/Documentation/userspace-api/ntsync.rst @@ -0,0 +1,398 @@ +=================================== +NT synchronization primitive driver +=================================== + +This page documents the user-space API for the ntsync driver. + +ntsync is a support driver for emulation of NT synchronization +primitives by user-space NT emulators. It exists because implementation +in user-space, using existing tools, cannot match Windows performance +while offering accurate semantics. It is implemented entirely in +software, and does not drive any hardware device. + +This interface is meant as a compatibility tool only, and should not +be used for general synchronization. Instead use generic, versatile +interfaces such as futex(2) and poll(2). + +Synchronization primitives +========================== + +The ntsync driver exposes three types of synchronization primitives: +semaphores, mutexes, and events. + +A semaphore holds a single volatile 32-bit counter, and a static 32-bit +integer denoting the maximum value. It is considered signaled (that is, +can be acquired without contention, or will wake up a waiting thread) +when the counter is nonzero. The counter is decremented by one when a +wait is satisfied. Both the initial and maximum count are established +when the semaphore is created. + +A mutex holds a volatile 32-bit recursion count, and a volatile 32-bit +identifier denoting its owner. A mutex is considered signaled when its +owner is zero (indicating that it is not owned). The recursion count is +incremented when a wait is satisfied, and ownership is set to the given +identifier. + +A mutex also holds an internal flag denoting whether its previous owner +has died; such a mutex is said to be abandoned. Owner death is not +tracked automatically based on thread death, but rather must be +communicated using ``NTSYNC_IOC_MUTEX_KILL``. An abandoned mutex is +inherently considered unowned. + +Except for the "unowned" semantics of zero, the actual value of the +owner identifier is not interpreted by the ntsync driver at all. The +intended use is to store a thread identifier; however, the ntsync +driver does not actually validate that a calling thread provides +consistent or unique identifiers. + +An event is similar to a semaphore with a maximum count of one. It holds +a volatile boolean state denoting whether it is signaled or not. There +are two types of events, auto-reset and manual-reset. An auto-reset +event is designaled when a wait is satisfied; a manual-reset event is +not. The event type is specified when the event is created. + +Unless specified otherwise, all operations on an object are atomic and +totally ordered with respect to other operations on the same object. + +Objects are represented by files. When all file descriptors to an +object are closed, that object is deleted. + +Char device +=========== + +The ntsync driver creates a single char device /dev/ntsync. Each file +description opened on the device represents a unique instance intended +to back an individual NT virtual machine. Objects created by one ntsync +instance may only be used with other objects created by the same +instance. + +ioctl reference +=============== + +All operations on the device are done through ioctls. There are four +structures used in ioctl calls:: + + struct ntsync_sem_args { + __u32 sem; + __u32 count; + __u32 max; + }; + + struct ntsync_mutex_args { + __u32 mutex; + __u32 owner; + __u32 count; + }; + + struct ntsync_event_args { + __u32 event; + __u32 signaled; + __u32 manual; + }; + + struct ntsync_wait_args { + __u64 timeout; + __u64 objs; + __u32 count; + __u32 owner; + __u32 index; + __u32 alert; + __u32 flags; + __u32 pad; + }; + +Depending on the ioctl, members of the structure may be used as input, +output, or not at all. All ioctls return 0 on success. + +The ioctls on the device file are as follows: + +.. c:macro:: NTSYNC_IOC_CREATE_SEM + + Create a semaphore object. Takes a pointer to struct + :c:type:`ntsync_sem_args`, which is used as follows: + + .. list-table:: + + * - ``sem`` + - On output, contains a file descriptor to the created semaphore. + * - ``count`` + - Initial count of the semaphore. + * - ``max`` + - Maximum count of the semaphore. + + Fails with ``EINVAL`` if ``count`` is greater than ``max``. + +.. c:macro:: NTSYNC_IOC_CREATE_MUTEX + + Create a mutex object. Takes a pointer to struct + :c:type:`ntsync_mutex_args`, which is used as follows: + + .. list-table:: + + * - ``mutex`` + - On output, contains a file descriptor to the created mutex. + * - ``count`` + - Initial recursion count of the mutex. + * - ``owner`` + - Initial owner of the mutex. + + If ``owner`` is nonzero and ``count`` is zero, or if ``owner`` is + zero and ``count`` is nonzero, the function fails with ``EINVAL``. + +.. c:macro:: NTSYNC_IOC_CREATE_EVENT + + Create an event object. Takes a pointer to struct + :c:type:`ntsync_event_args`, which is used as follows: + + .. list-table:: + + * - ``event`` + - On output, contains a file descriptor to the created event. + * - ``signaled`` + - If nonzero, the event is initially signaled, otherwise + nonsignaled. + * - ``manual`` + - If nonzero, the event is a manual-reset event, otherwise + auto-reset. + +The ioctls on the individual objects are as follows: + +.. c:macro:: NTSYNC_IOC_SEM_POST + + Post to a semaphore object. Takes a pointer to a 32-bit integer, + which on input holds the count to be added to the semaphore, and on + output contains its previous count. + + If adding to the semaphore's current count would raise the latter + past the semaphore's maximum count, the ioctl fails with + ``EOVERFLOW`` and the semaphore is not affected. If raising the + semaphore's count causes it to become signaled, eligible threads + waiting on this semaphore will be woken and the semaphore's count + decremented appropriately. + +.. c:macro:: NTSYNC_IOC_MUTEX_UNLOCK + + Release a mutex object. Takes a pointer to struct + :c:type:`ntsync_mutex_args`, which is used as follows: + + .. list-table:: + + * - ``mutex`` + - Ignored. + * - ``owner`` + - Specifies the owner trying to release this mutex. + * - ``count`` + - On output, contains the previous recursion count. + + If ``owner`` is zero, the ioctl fails with ``EINVAL``. If ``owner`` + is not the current owner of the mutex, the ioctl fails with + ``EPERM``. + + The mutex's count will be decremented by one. If decrementing the + mutex's count causes it to become zero, the mutex is marked as + unowned and signaled, and eligible threads waiting on it will be + woken as appropriate. + +.. c:macro:: NTSYNC_IOC_SET_EVENT + + Signal an event object. Takes a pointer to a 32-bit integer, which on + output contains the previous state of the event. + + Eligible threads will be woken, and auto-reset events will be + designaled appropriately. + +.. c:macro:: NTSYNC_IOC_RESET_EVENT + + Designal an event object. Takes a pointer to a 32-bit integer, which + on output contains the previous state of the event. + +.. c:macro:: NTSYNC_IOC_PULSE_EVENT + + Wake threads waiting on an event object while leaving it in an + unsignaled state. Takes a pointer to a 32-bit integer, which on + output contains the previous state of the event. + + A pulse operation can be thought of as a set followed by a reset, + performed as a single atomic operation. If two threads are waiting on + an auto-reset event which is pulsed, only one will be woken. If two + threads are waiting a manual-reset event which is pulsed, both will + be woken. However, in both cases, the event will be unsignaled + afterwards, and a simultaneous read operation will always report the + event as unsignaled. + +.. c:macro:: NTSYNC_IOC_READ_SEM + + Read the current state of a semaphore object. Takes a pointer to + struct :c:type:`ntsync_sem_args`, which is used as follows: + + .. list-table:: + + * - ``sem`` + - Ignored. + * - ``count`` + - On output, contains the current count of the semaphore. + * - ``max`` + - On output, contains the maximum count of the semaphore. + +.. c:macro:: NTSYNC_IOC_READ_MUTEX + + Read the current state of a mutex object. Takes a pointer to struct + :c:type:`ntsync_mutex_args`, which is used as follows: + + .. list-table:: + + * - ``mutex`` + - Ignored. + * - ``owner`` + - On output, contains the current owner of the mutex, or zero + if the mutex is not currently owned. + * - ``count`` + - On output, contains the current recursion count of the mutex. + + If the mutex is marked as abandoned, the function fails with + ``EOWNERDEAD``. In this case, ``count`` and ``owner`` are set to + zero. + +.. c:macro:: NTSYNC_IOC_READ_EVENT + + Read the current state of an event object. Takes a pointer to struct + :c:type:`ntsync_event_args`, which is used as follows: + + .. list-table:: + + * - ``event`` + - Ignored. + * - ``signaled`` + - On output, contains the current state of the event. + * - ``manual`` + - On output, contains 1 if the event is a manual-reset event, + and 0 otherwise. + +.. c:macro:: NTSYNC_IOC_KILL_OWNER + + Mark a mutex as unowned and abandoned if it is owned by the given + owner. Takes an input-only pointer to a 32-bit integer denoting the + owner. If the owner is zero, the ioctl fails with ``EINVAL``. If the + owner does not own the mutex, the function fails with ``EPERM``. + + Eligible threads waiting on the mutex will be woken as appropriate + (and such waits will fail with ``EOWNERDEAD``, as described below). + +.. c:macro:: NTSYNC_IOC_WAIT_ANY + + Poll on any of a list of objects, atomically acquiring at most one. + Takes a pointer to struct :c:type:`ntsync_wait_args`, which is + used as follows: + + .. list-table:: + + * - ``timeout`` + - Absolute timeout in nanoseconds. If ``NTSYNC_WAIT_REALTIME`` + is set, the timeout is measured against the REALTIME clock; + otherwise it is measured against the MONOTONIC clock. If the + timeout is equal to or earlier than the current time, the + function returns immediately without sleeping. If ``timeout`` + is U64_MAX, the function will sleep until an object is + signaled, and will not fail with ``ETIMEDOUT``. + * - ``objs`` + - Pointer to an array of ``count`` file descriptors + (specified as an integer so that the structure has the same + size regardless of architecture). If any object is + invalid, the function fails with ``EINVAL``. + * - ``count`` + - Number of objects specified in the ``objs`` array. + If greater than ``NTSYNC_MAX_WAIT_COUNT``, the function fails + with ``EINVAL``. + * - ``owner`` + - Mutex owner identifier. If any object in ``objs`` is a mutex, + the ioctl will attempt to acquire that mutex on behalf of + ``owner``. If ``owner`` is zero, the ioctl fails with + ``EINVAL``. + * - ``index`` + - On success, contains the index (into ``objs``) of the object + which was signaled. If ``alert`` was signaled instead, + this contains ``count``. + * - ``alert`` + - Optional event object file descriptor. If nonzero, this + specifies an "alert" event object which, if signaled, will + terminate the wait. If nonzero, the identifier must point to a + valid event. + * - ``flags`` + - Zero or more flags. Currently the only flag is + ``NTSYNC_WAIT_REALTIME``, which causes the timeout to be + measured against the REALTIME clock instead of MONOTONIC. + * - ``pad`` + - Unused, must be set to zero. + + This function attempts to acquire one of the given objects. If unable + to do so, it sleeps until an object becomes signaled, subsequently + acquiring it, or the timeout expires. In the latter case the ioctl + fails with ``ETIMEDOUT``. The function only acquires one object, even + if multiple objects are signaled. + + A semaphore is considered to be signaled if its count is nonzero, and + is acquired by decrementing its count by one. A mutex is considered + to be signaled if it is unowned or if its owner matches the ``owner`` + argument, and is acquired by incrementing its recursion count by one + and setting its owner to the ``owner`` argument. An auto-reset event + is acquired by designaling it; a manual-reset event is not affected + by acquisition. + + Acquisition is atomic and totally ordered with respect to other + operations on the same object. If two wait operations (with different + ``owner`` identifiers) are queued on the same mutex, only one is + signaled. If two wait operations are queued on the same semaphore, + and a value of one is posted to it, only one is signaled. + + If an abandoned mutex is acquired, the ioctl fails with + ``EOWNERDEAD``. Although this is a failure return, the function may + otherwise be considered successful. The mutex is marked as owned by + the given owner (with a recursion count of 1) and as no longer + abandoned, and ``index`` is still set to the index of the mutex. + + The ``alert`` argument is an "extra" event which can terminate the + wait, independently of all other objects. + + It is valid to pass the same object more than once, including by + passing the same event in the ``objs`` array and in ``alert``. If a + wakeup occurs due to that object being signaled, ``index`` is set to + the lowest index corresponding to that object. + + The function may fail with ``EINTR`` if a signal is received. + +.. c:macro:: NTSYNC_IOC_WAIT_ALL + + Poll on a list of objects, atomically acquiring all of them. Takes a + pointer to struct :c:type:`ntsync_wait_args`, which is used + identically to ``NTSYNC_IOC_WAIT_ANY``, except that ``index`` is + always filled with zero on success if not woken via alert. + + This function attempts to simultaneously acquire all of the given + objects. If unable to do so, it sleeps until all objects become + simultaneously signaled, subsequently acquiring them, or the timeout + expires. In the latter case the ioctl fails with ``ETIMEDOUT`` and no + objects are modified. + + Objects may become signaled and subsequently designaled (through + acquisition by other threads) while this thread is sleeping. Only + once all objects are simultaneously signaled does the ioctl acquire + them and return. The entire acquisition is atomic and totally ordered + with respect to other operations on any of the given objects. + + If an abandoned mutex is acquired, the ioctl fails with + ``EOWNERDEAD``. Similarly to ``NTSYNC_IOC_WAIT_ANY``, all objects are + nevertheless marked as acquired. Note that if multiple mutex objects + are specified, there is no way to know which were marked as + abandoned. + + As with "any" waits, the ``alert`` argument is an "extra" event which + can terminate the wait. Critically, however, an "all" wait will + succeed if all members in ``objs`` are signaled, *or* if ``alert`` is + signaled. In the latter case ``index`` will be set to ``count``. As + with "any" waits, if both conditions are filled, the former takes + priority, and objects in ``objs`` will be acquired. + + Unlike ``NTSYNC_IOC_WAIT_ANY``, it is not valid to pass the same + object more than once, nor is it valid to pass the same object in + ``objs`` and in ``alert``. If this is attempted, the function fails + with ``EINVAL``. From patchwork Mon Dec 9 18:59:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elizabeth Figura X-Patchwork-Id: 849513 Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21B1A1A08C1; Mon, 9 Dec 2024 18:59:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=4.36.192.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770784; cv=none; b=CP+IrOoWB8xfMx4SQVy5zjxt/+m5UvHEAqpNCxHK+/jk/CxDq6yRTlQoUUVryGGo38HB4HPqkNFn5g3Hi0AXAAgeNJPlrcK4HvxyKaHL16OCzle7PRwErmGGiNzQKSCapuUzbOMTF996FqKWRxJNgigOL+Mq0xKhaxZ01pMOPzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733770784; c=relaxed/simple; bh=U2jvLVxDBW1wqTl+8HqpuZ+B2aEhALkVpMFRfXjOGKY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o9VPy2NXa0RL1vQ6qZ91L4bsX4+zQJ9O7GUNuA3ZttTMMA7utNCnkiMPgpOKtssKockQCeXP1b+8EsheVOLEAvwaNCw4oM4QF60AlLGXncSQoHrOEVHkTv5FZSliPRcE8D2qDUoKAS/1YYIFSqUFfd8M/BL9RVY5P4zm1fBlocw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com; spf=pass smtp.mailfrom=codeweavers.com; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b=Gqqvsk/U; arc=none smtp.client-ip=4.36.192.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeweavers.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeweavers.com header.i=@codeweavers.com header.b="Gqqvsk/U" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=H78XD7mVtyigbR9tP1mufDrwr59LEZXCMX3E9nnMZnc=; b=Gqqvsk/UhZ00lHsnAOtQAReH+/ cdELKg9lCSQ/xQLM+11OtLlPicrJ+kQPkYd1ixPbDuCFKAX47SvtY6VJp4LG+/aY13L2KJrmV57F5 UmrohjllNAhdnYOD+0b5jChqSydukbds5sKupWwhlkMp9sTl6paA7XjWZ5ZAQ4JNVqod6KcpJ5kWH Xq49jhpQ4pRamn/5lvoeX7O90VLVQmb+cCyzcxmKus+O0TlvAmb8cQeCdVR7mrZYkjU9jNfiFDTAz LyXOFu9qKxQ+bJHU1u3D9Z2w9yGc1+BX7G3cQtTOIWEOd8ZkPkcgR9mcsnEVLf+ic8yZEyXrht66K PNtfKKUA==; Received: from cw137ip160.mn.codeweavers.com ([10.69.137.160] helo=camazotz.mn.codeweavers.com) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tKiyp-001Gd5-2o; Mon, 09 Dec 2024 12:59:39 -0600 From: Elizabeth Figura To: Arnd Bergmann , Greg Kroah-Hartman , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, wine-devel@winehq.org, =?utf-8?q?Andr=C3=A9_Almeida?= , Wolfram Sang , Arkadiusz Hiler , Peter Zijlstra , Andy Lutomirski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Randy Dunlap , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng , Elizabeth Figura Subject: [PATCH v6 28/28] ntsync: No longer depend on BROKEN. Date: Mon, 9 Dec 2024 12:59:04 -0600 Message-ID: <20241209185904.507350-29-zfigura@codeweavers.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241209185904.507350-1-zfigura@codeweavers.com> References: <20241209185904.507350-1-zfigura@codeweavers.com> Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 f5b335dc025cfee90957efa90dc72fada0d5abb4 ("misc: ntsync: mark driver as "broken" to prevent from building") was committed to avoid the driver being used while only part of its functionality was released. Since the rest of the functionality has now been committed, revert this. Signed-off-by: Elizabeth Figura --- drivers/misc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 09cbe3f0ab1e..fb772bfe27c3 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -517,7 +517,6 @@ config OPEN_DICE config NTSYNC tristate "NT synchronization primitive emulation" - depends on BROKEN help This module provides kernel support for emulation of Windows NT synchronization primitives. It is not a hardware driver.