From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp1.cs.Stanford.EDU (smtp1.cs.stanford.edu [171.64.64.25]) (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 D7B9E20A5F1 for ; Mon, 9 Jun 2025 15:41:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=171.64.64.25 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749483689; cv=none; b=vCDcbGQ85ZTPMiWTNvdMAcSaHP+WdqBUd2P3IdqHYFFgQJUabEoA14nMzJa9FD2HtaUCGAtMIF1OlTlg+KjBrx9uZhAbj5kfxFiALmtQFdukdur0x6a7uCP5IUu+MMhKxMfuyqtXiKp6cYvfvEqGeje7oYRv7xKsuzzn/+JkLI8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749483689; c=relaxed/simple; bh=Rq67B/u346M6NF/JhnvmZ/hCnsHFai4mSaONDfOOs4o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OpB+sFyc71qDZD3i6jBU9KefdmkcEssBwDOv9o0grgyJoZ5fgoH+G75z/1XMabT/JJ4gf7Ja55iXy/yjk9ocPH15aC4SjnS2DJiM0y4z4CKa3f1jXfaDBT8EbjHlnyaOrhNjq6a2VFBb1c2ZVJ3P6xttyvZ4whhGjUyfUhz0IUc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cs.stanford.edu; spf=pass smtp.mailfrom=cs.stanford.edu; dkim=pass (2048-bit key) header.d=cs.stanford.edu header.i=@cs.stanford.edu header.b=iKMV2PZT; arc=none smtp.client-ip=171.64.64.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cs.stanford.edu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cs.stanford.edu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cs.stanford.edu header.i=@cs.stanford.edu header.b="iKMV2PZT" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=cs.stanford.edu; s=cs2308; 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=RurG7nIWhQVsSDQJEOXFOo/35itnfaQtWfds4UUSsd8=; t=1749483687; x=1750347687; b=iKMV2PZT8KQCYOASBME7G2db8JyGazW4yTwNApqyWTFUMOlTg2xP53Lza17fOTzCMA48KUVdVWB /fN+7zJk5FYVLlcyfbr4YEh5wN8Qvbmj266nsgdBiqlD8jV2T8fJmRw8WfnkfUeX71ATDjdVmCa4a TonUnH/aNAv6BVhiASq0J4Exfa0M8UVRI1YiQlLFqmDNfIpAfP8fa4CCKvYeHoV9AYsTtnu8QyRrM yE7s/uhyN+23Oq462NMNgJfo833OsF/UM93U/BauMlSa7maa9MkoRXd4IQ4fcEaG+QbRDAf2KNbJP WZBC1XZwYIg5OlIlo0aqAWGgSO8pqtTC92gA==; Received: from 70-228-78-207.lightspeed.sntcca.sbcglobal.net ([70.228.78.207]:55275 helo=localhost.localdomain) by smtp1.cs.Stanford.EDU with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uOeco-0003cu-F3; Mon, 09 Jun 2025 08:41:27 -0700 From: John Ousterhout To: netdev@vger.kernel.org Cc: pabeni@redhat.com, edumazet@google.com, horms@kernel.org, kuba@kernel.org, John Ousterhout Subject: [PATCH net-next v9 07/15] net: homa: create homa_interest.h and homa_interest. Date: Mon, 9 Jun 2025 08:40:40 -0700 Message-ID: <20250609154051.1319-8-ouster@cs.stanford.edu> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20250609154051.1319-1-ouster@cs.stanford.edu> References: <20250609154051.1319-1-ouster@cs.stanford.edu> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -1.0 X-Scan-Signature: cf179b4f16c459bea543772a169d0769 These files implement the homa_interest struct, which is used to wait for incoming messages. Signed-off-by: John Ousterhout --- Changes for v9: * Remove unused field homa_interest->core --- net/homa/homa_interest.c | 120 +++++++++++++++++++++++++++++++++++++++ net/homa/homa_interest.h | 96 +++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 net/homa/homa_interest.c create mode 100644 net/homa/homa_interest.h diff --git a/net/homa/homa_interest.c b/net/homa/homa_interest.c new file mode 100644 index 000000000000..cef042acc84f --- /dev/null +++ b/net/homa/homa_interest.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: BSD-2-Clause + +/* This file contains functions for managing homa_interest structs. */ + +#include "homa_impl.h" +#include "homa_interest.h" +#include "homa_rpc.h" +#include "homa_sock.h" + +/** + * homa_interest_init_shared() - Initialize an interest and queue it up on a socket. + * @interest: Interest to initialize + * @hsk: Socket on which the interests should be queued. Must be locked + * by caller. + */ +void homa_interest_init_shared(struct homa_interest *interest, + struct homa_sock *hsk) + __must_hold(&hsk->lock) +{ + interest->rpc = NULL; + atomic_set(&interest->ready, 0); + interest->blocked = 0; + init_waitqueue_head(&interest->wait_queue); + interest->hsk = hsk; + list_add(&interest->links, &hsk->interests); +} + +/** + * homa_interest_init_private() - Initialize an interest that will wait + * on a particular (private) RPC, and link it to that RPC. + * @interest: Interest to initialize. + * @rpc: RPC to associate with the interest. Must be private, and + * caller must have locked it. + * + * Return: 0 for success, otherwise a negative errno. + */ +int homa_interest_init_private(struct homa_interest *interest, + struct homa_rpc *rpc) + __must_hold(&rpc->bucket->lock) +{ + if (rpc->private_interest) + return -EINVAL; + + interest->rpc = rpc; + atomic_set(&interest->ready, 0); + interest->blocked = 0; + init_waitqueue_head(&interest->wait_queue); + interest->hsk = rpc->hsk; + rpc->private_interest = interest; + return 0; +} + +/** + * homa_interest_wait() - Wait for an interest to have an actionable RPC, + * or for an error to occur. + * @interest: Interest to wait for; must previously have been initialized + * and linked to a socket or RPC. On return, the interest + * will have been unlinked if its ready flag is set; otherwise + * it may still be linked. + * @nonblocking: Nonzero means return without blocking if the interest + * doesn't become ready immediately. + * + * Return: 0 for success (there is an actionable RPC in the interest), or + * a negative errno. + */ +int homa_interest_wait(struct homa_interest *interest, int nonblocking) +{ + struct homa_sock *hsk = interest->hsk; + int result = 0; + int iteration; + int wait_err; + + interest->blocked = 0; + + /* This loop iterates in order to poll and/or reap dead RPCS. */ + for (iteration = 0; ; iteration++) { + if (iteration != 0) + /* Give NAPI/SoftIRQ tasks a chance to run. */ + schedule(); + + if (atomic_read_acquire(&interest->ready) != 0) + goto done; + + /* See if we can cleanup dead RPCs while waiting. */ + if (homa_rpc_reap(hsk, false) != 0) + continue; + + if (nonblocking) { + result = -EAGAIN; + goto done; + } + + break; + } + + interest->blocked = 1; + wait_err = wait_event_interruptible_exclusive(interest->wait_queue, + atomic_read_acquire(&interest->ready) != 0); + if (wait_err == -ERESTARTSYS) + result = -EINTR; + +done: + return result; +} + +/** + * homa_interest_notify_private() - If a thread is waiting on the private + * interest for an RPC, wake it up. + * @rpc: RPC that may (potentially) have a private interest. Must be + * locked by the caller. + */ +void homa_interest_notify_private(struct homa_rpc *rpc) + __must_hold(&rpc->bucket->lock) +{ + if (rpc->private_interest) { + atomic_set_release(&rpc->private_interest->ready, 1); + wake_up(&rpc->private_interest->wait_queue); + } +} + diff --git a/net/homa/homa_interest.h b/net/homa/homa_interest.h new file mode 100644 index 000000000000..1c93f30983d0 --- /dev/null +++ b/net/homa/homa_interest.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* This file defines struct homa_interest and related functions. */ + +#ifndef _HOMA_INTEREST_H +#define _HOMA_INTEREST_H + +#include "homa_rpc.h" +#include "homa_sock.h" + +/** + * struct homa_interest - Holds info that allows applications to wait for + * incoming RPC messages. An interest can be either private, in which case + * the application is waiting for a single specific RPC response and the + * interest is referenced by an rpc->private_interest, or shared, in which + * case the application is waiting for any incoming message that isn't + * private and the interest is present on hsk->interests. + */ +struct homa_interest { + /** + * @rpc: If ready is set, then this holds an RPC that needs + * attention, or NULL if this is a shared interest and hsk has + * been shutdown. If ready is not set, this will be NULL if the + * interest is shared; if it's private, it holds the RPC the + * interest is associated with. If non-NULL, a reference has been + * taken on the RPC. + */ + struct homa_rpc *rpc; + + /** + * @ready: Nonzero means the interest is ready for attention: either + * there is an RPC that needs attention or @hsk has been shutdown. + */ + atomic_t ready; + + /** + * @blocked: Zero means a handoff was received without the thread + * needing to block; nonzero means the thread blocked. + */ + int blocked; + + /** + * @wait_queue: Used to block the thread while waiting (will never + * have more than one queued thread). + */ + struct wait_queue_head wait_queue; + + /** @hsk: Socket that the interest is associated with. */ + struct homa_sock *hsk; + + /** + * @links: If the interest is shared, used to link this object into + * @hsk->interests. + */ + struct list_head links; +}; + +/** + * homa_interest_unlink_shared() - Remove an interest from the list for a + * socket. Note: this can race with homa_rpc_handoff, so on return it's + * possible that the interest is ready. + * @interest: Interest to remove. Must have been initialized with + * homa_interest_init_shared. + */ +static inline void homa_interest_unlink_shared(struct homa_interest *interest) +{ + if (!list_empty(&interest->links)) { + homa_sock_lock(interest->hsk); + list_del_init(&interest->links); + homa_sock_unlock(interest->hsk); + } +} + +/** + * homa_interest_unlink_private() - Detach a private interest from its + * RPC. Note: this can race with homa_rpc_handoff, so on return it's + * possible that the interest is ready. + * @interest: Interest to remove. Must have been initialized with + * homa_interest_init_private. Its RPC must be locked by + * the caller. + */ +static inline void homa_interest_unlink_private(struct homa_interest *interest) + __must_hold(&interest->rpc->bucket->lock) +{ + if (interest == interest->rpc->private_interest) + interest->rpc->private_interest = NULL; +} + +void homa_interest_init_shared(struct homa_interest *interest, + struct homa_sock *hsk); +int homa_interest_init_private(struct homa_interest *interest, + struct homa_rpc *rpc); +void homa_interest_notify_private(struct homa_rpc *rpc); +int homa_interest_wait(struct homa_interest *interest, int nonblocking); + +#endif /* _HOMA_INTEREST_H */ -- 2.43.0