From patchwork Tue May 7 05:55:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656275 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F8ED6BFA9 for ; Tue, 7 May 2024 05:56:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061376; cv=none; b=HtAV2RBE8mccFCDGrmgkeKJ9WPnN1OBoZMAMfdNVUVsT42LHFElsmtWdGZwF5wMl45kITr4wRhiCL+0OEVLf47ke6bmhMgDocFdXyHcPCvuzf4k5CkChDvdQlDlvltMVwFuGkhUDHdURM3ns5w1ULJO5QCVNaIjE0D2wGCNZcJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061376; c=relaxed/simple; bh=900zX55GN3ZLaa7mKoA3DBpRpwEN/NauKWYO4JFkpdI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EAETbh/OUdLtacse8vLnSRW7DltIZ9qL3hGuw0JxD/DImfPddXQHwaxcG4kd2OkYhyRfnKAKcZELUva030/nmOaKqNKTvwi9oIWNvk6zXUGY9cOC4DLcRuUcF8RZl4yDiXitnzOGMlfGr+NNpM+hlPjilVggr/FwGe4FcFjEBlc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FE1Y8VZT; arc=none smtp.client-ip=209.85.161.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FE1Y8VZT" Received: by mail-oo1-f43.google.com with SMTP id 006d021491bc7-5b205a3b3dcso896892eaf.1 for ; Mon, 06 May 2024 22:56:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061373; x=1715666173; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HprPl2jxGxgn2322TEJ1A5FUP6xMck5u8525adKN288=; b=FE1Y8VZTuhCDpAHBtqKD0tN3t0w8wI0/1Xlplrirn3OJmHG2GvZ/gv0wO+54q59nwG Cbpk1W0tOgcvogWmYtm1Q3xtE7cuzT2sTV9B/vL7eOMpJpSC1jurgCBGzablFTxgGbhE 1jWM7cO5kaYqE1yDxx572f0a8YtWKFJH6inEapBECM2qSTGvavXo7WNYkGlhfBGQCVfX zM+CqYrYtlUhS055XSH9OxQ3wB+yGqpX/4vzWPNyWQ6jEUgN14SYy0A5CzUiByC5QQh8 KNYHagu7yOb+htu1uwsBy5KTGLcIj40b3r9sUlexQi24Al5SisK4Hd2icsGvFF6LDLYm hYUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061373; x=1715666173; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HprPl2jxGxgn2322TEJ1A5FUP6xMck5u8525adKN288=; b=eVHgPbUfWMXFmG8xJy1i26Qtn4ANdbWwMtlkoeoK2Lf4ut5t0K1uAb308cl9JPTm9v J+tZLnRMRzexKTUTPuskZVkjEOc6FEpdyDGgxYOxi5awpUWMLdjmkwbQ2Tj7vwhOyFac Qp2JN4oRYzCw51sPH6JCFUKd7fQ9dTYc5R0WiUtYPvqe2ZgN5mOG6Ywdy2uxFIZjo2dI OF4l1hTYCNaRTGpRoTgOSao3nSB71+kUcvOEEKA3N9UOBTxu0080YBdTGhO6jX5sFIRK O8fPp4mKozrWLflXV153BknbQn84yYPB4hA4+ACdrQ9naJ6CFg/I+tCvyYKF2QkB0p64 Fbcg== X-Gm-Message-State: AOJu0YyBIH2Sei5YkGeMhiQBvLlVHC6iYkXMEamgS5lYl3J3YXa9pJEC 9xfeyXgkViiKtgR4SHMTtESsvghN6Qaqx1DdKSxsOREGFr2V/S++o1ysvQ== X-Google-Smtp-Source: AGHT+IG6/3CNGyBoyf5UB2/2gaE/S/gaEWr6qiip64j7NDLtJVSqdqeYHmaKp/+RJYuICeVXyGC+7A== X-Received: by 2002:a4a:4b01:0:b0:5ac:9ec3:8c76 with SMTP id q1-20020a4a4b01000000b005ac9ec38c76mr11519595ooa.7.1715061373527; Mon, 06 May 2024 22:56:13 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:13 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 1/6] bpf: pass bpf_struct_ops_link to callbacks in bpf_struct_ops. Date: Mon, 6 May 2024 22:55:55 -0700 Message-Id: <20240507055600.2382627-2-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Pass an additional pointer of bpf_struct_ops_link to callback function reg, unreg, and update provided by subsystems defined in bpf_struct_ops. A bpf_struct_ops_map can be registered for multiple links. Passing a pointer of bpf_struct_ops_link helps subsystems to distinguish them. This pointer will be used in the later patches to let the subsystem initiate a detachment on a link that was registered to it previously. Signed-off-by: Kui-Feng Lee --- include/linux/bpf.h | 6 +++--- kernel/bpf/bpf_struct_ops.c | 10 +++++----- net/bpf/bpf_dummy_struct_ops.c | 4 ++-- net/ipv4/bpf_tcp_ca.c | 6 +++--- .../selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c | 4 ++-- tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 90094400cc63..b600767ebe02 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1730,9 +1730,9 @@ struct bpf_struct_ops { int (*init_member)(const struct btf_type *t, const struct btf_member *member, void *kdata, const void *udata); - int (*reg)(void *kdata); - void (*unreg)(void *kdata); - int (*update)(void *kdata, void *old_kdata); + int (*reg)(void *kdata, struct bpf_link *link); + void (*unreg)(void *kdata, struct bpf_link *link); + int (*update)(void *kdata, void *old_kdata, struct bpf_link *link); int (*validate)(void *kdata); void *cfi_stubs; struct module *owner; diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index 86c7884abaf8..390f8c155135 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -757,7 +757,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, goto unlock; } - err = st_ops->reg(kdata); + err = st_ops->reg(kdata, NULL); if (likely(!err)) { /* This refcnt increment on the map here after * 'st_ops->reg()' is secure since the state of the @@ -805,7 +805,7 @@ static long bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key) BPF_STRUCT_OPS_STATE_TOBEFREE); switch (prev_state) { case BPF_STRUCT_OPS_STATE_INUSE: - st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data); + st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, NULL); bpf_map_put(map); return 0; case BPF_STRUCT_OPS_STATE_TOBEFREE: @@ -1060,7 +1060,7 @@ static void bpf_struct_ops_map_link_dealloc(struct bpf_link *link) /* st_link->map can be NULL if * bpf_struct_ops_link_create() fails to register. */ - st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data); + st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, st_link); bpf_map_put(&st_map->map); } kfree(st_link); @@ -1125,7 +1125,7 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map goto err_out; } - err = st_map->st_ops_desc->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data); + err = st_map->st_ops_desc->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data, link); if (err) goto err_out; @@ -1176,7 +1176,7 @@ int bpf_struct_ops_link_create(union bpf_attr *attr) if (err) goto err_out; - err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data); + err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data, &link->link); if (err) { bpf_link_cleanup(&link_primer); link = NULL; diff --git a/net/bpf/bpf_dummy_struct_ops.c b/net/bpf/bpf_dummy_struct_ops.c index 891cdf61c65a..3ea52b05adfb 100644 --- a/net/bpf/bpf_dummy_struct_ops.c +++ b/net/bpf/bpf_dummy_struct_ops.c @@ -272,12 +272,12 @@ static int bpf_dummy_init_member(const struct btf_type *t, return -EOPNOTSUPP; } -static int bpf_dummy_reg(void *kdata) +static int bpf_dummy_reg(void *kdata, struct bpf_link *link) { return -EOPNOTSUPP; } -static void bpf_dummy_unreg(void *kdata) +static void bpf_dummy_unreg(void *kdata, struct bpf_link *link) { } diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c index 7f518ea5f4ac..dd97f7ebcd29 100644 --- a/net/ipv4/bpf_tcp_ca.c +++ b/net/ipv4/bpf_tcp_ca.c @@ -257,17 +257,17 @@ static int bpf_tcp_ca_check_member(const struct btf_type *t, return 0; } -static int bpf_tcp_ca_reg(void *kdata) +static int bpf_tcp_ca_reg(void *kdata, struct bpf_link *link) { return tcp_register_congestion_control(kdata); } -static void bpf_tcp_ca_unreg(void *kdata) +static void bpf_tcp_ca_unreg(void *kdata, struct bpf_link *link) { tcp_unregister_congestion_control(kdata); } -static int bpf_tcp_ca_update(void *kdata, void *old_kdata) +static int bpf_tcp_ca_update(void *kdata, void *old_kdata, struct bpf_link *link) { return tcp_update_congestion_control(kdata, old_kdata); } diff --git a/tools/testing/selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c b/tools/testing/selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c index b1dd889d5d7d..948eb3962732 100644 --- a/tools/testing/selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c +++ b/tools/testing/selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c @@ -22,12 +22,12 @@ static int dummy_init_member(const struct btf_type *t, return 0; } -static int dummy_reg(void *kdata) +static int dummy_reg(void *kdata, struct bpf_link *link) { return 0; } -static void dummy_unreg(void *kdata) +static void dummy_unreg(void *kdata, struct bpf_link *link) { } diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c index eb2b78552ca2..e24a18bfee14 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c @@ -565,7 +565,7 @@ static const struct bpf_verifier_ops bpf_testmod_verifier_ops = { .is_valid_access = bpf_testmod_ops_is_valid_access, }; -static int bpf_dummy_reg(void *kdata) +static int bpf_dummy_reg(void *kdata, struct bpf_link *link) { struct bpf_testmod_ops *ops = kdata; @@ -580,7 +580,7 @@ static int bpf_dummy_reg(void *kdata) return 0; } -static void bpf_dummy_unreg(void *kdata) +static void bpf_dummy_unreg(void *kdata, struct bpf_link *link) { } @@ -616,7 +616,7 @@ struct bpf_struct_ops bpf_bpf_testmod_ops = { .owner = THIS_MODULE, }; -static int bpf_dummy_reg2(void *kdata) +static int bpf_dummy_reg2(void *kdata, struct bpf_link *link) { struct bpf_testmod_ops2 *ops = kdata; From patchwork Tue May 7 05:55:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656276 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-oo1-f47.google.com (mail-oo1-f47.google.com [209.85.161.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A97B16CDC2 for ; Tue, 7 May 2024 05:56:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061377; cv=none; b=dN8F2ydwl3ELZAq5hP4qMAUdgD5uUL+IbZOqZDMksrsK4pgTOfCXCLJ93pEdjh6kqV2k8LPJbOEkXfjvclJAIFeRgIiVNUdceERhRF5qM8iJs8XsHXhnb5Sejj+YofQoruhZ6BRYNcIk9nKz7NT93sBytaL/ae4PU6I130Ln+MY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061377; c=relaxed/simple; bh=uPWmX1ZDl3Scvkwd+Qvm9qmW/Y8tT2udwqye4SlcwTk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=n6dO0YjumdNs/RMOqBiLz3iDzgCOZHorE7gvnrR6DTdEkur4RuajegOCsjb8lu/pckxGuu+Qh9GMPeiwoUy0lx4e6IuD4KvWZGIJYagM860MyHfqmiAm+OzaiNzNVQmoWM52VQyLdruvjKqI/IWgNz/YvNq/u/4Cs1d1fzySp4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fsOp4G1y; arc=none smtp.client-ip=209.85.161.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fsOp4G1y" Received: by mail-oo1-f47.google.com with SMTP id 006d021491bc7-5ad2da2196aso1927273eaf.2 for ; Mon, 06 May 2024 22:56:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061374; x=1715666174; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qxv0UXm5oo+YZjnDWncrtkmdeIpbDTLDENA9DNvs+KE=; b=fsOp4G1ylKanap1EXQm//hd/mK+79drHveT9XLf4rIONNcf3ggqCp/Co9KFDxcwsdF TkeYJnBlo4k/kXw8ykQ+tScK/NZ2HZGVHedc5Ve/f2vM5si5xr6f7PoHX6CvCw81qgyC Y0DNuQmVuC6RtLRZbCyLgqidt5imZ5hm6NJQM8NuIFQRG5mVt+MTHkn+Tf+FDmn1ws2v xH7gQ/HzU+x1xcCgnightkwQ0GtTDawfcsaZ4KrD5KbzUGG/LZ1S8usv6fq5iQT3GXt6 xCSyqutcC0vq5qtvXvcQQ854iT2jLwpXAQspNsLP3ySRsQcWWxtYT71dE6iyj09BoIMD teoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061374; x=1715666174; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qxv0UXm5oo+YZjnDWncrtkmdeIpbDTLDENA9DNvs+KE=; b=LPP34+LBCPbn6falmRx3OLwzEquU2sFnZ+ZYPUlbgnOSuQZuFeuUwH5ANLbupleyBv MQ57n1hPElXKdSzL+VU4amFsUXnEBZyAhB6XXODPlTZE+DvoHE2DfWeZfwgqnxZRG5s9 5IfWtVeKbskeFXun8cki9wXuGFR/VSOQZs/v65QtaEksrFoFG2DgwPKXbziDeYS828yh UE0vNUe8Ip0TZenwtyDP2yqttIMyhMr7gVApxF1a/N2rtr3eKPBRmhOqk3mLQcKoRYC8 hKdKFLm2ehiwPWfh0tkpJ3lSfgv0ot+6CZricK4/KjKI8UdNwdk23ENvukS36seil3z9 Njzw== X-Gm-Message-State: AOJu0YxteBi+nH7u7z2xqZktqdF/40gYxm7nZOm4f1ZwGRiCgz11Np1I 5/pyxn4GYhXJoVYPABzJqQ1Gj7wZq8ujYSILBBBmKLnXuAAjZSpJTMENQQ== X-Google-Smtp-Source: AGHT+IH0Mw25n2gpbZRZwUFApn8LnWMvDAQKOface0kRX4XseZ3Qj+PbcepQ9N7Et0YJjMJ/DPgIXw== X-Received: by 2002:a4a:8c22:0:b0:5b2:2f55:e26 with SMTP id u31-20020a4a8c22000000b005b22f550e26mr1799700ooj.8.1715061374534; Mon, 06 May 2024 22:56:14 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:14 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 2/6] bpf: enable detaching links of struct_ops objects. Date: Mon, 6 May 2024 22:55:56 -0700 Message-Id: <20240507055600.2382627-3-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Implement the detach callback in bpf_link_ops for struct_ops. The subsystems that struct_ops objects are registered to can use this callback to detach the links being passed to them. Signed-off-by: Kui-Feng Lee --- kernel/bpf/bpf_struct_ops.c | 50 ++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index 390f8c155135..bd2602982e4d 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -1057,9 +1057,6 @@ static void bpf_struct_ops_map_link_dealloc(struct bpf_link *link) st_map = (struct bpf_struct_ops_map *) rcu_dereference_protected(st_link->map, true); if (st_map) { - /* st_link->map can be NULL if - * bpf_struct_ops_link_create() fails to register. - */ st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, st_link); bpf_map_put(&st_map->map); } @@ -1075,7 +1072,8 @@ static void bpf_struct_ops_map_link_show_fdinfo(const struct bpf_link *link, st_link = container_of(link, struct bpf_struct_ops_link, link); rcu_read_lock(); map = rcu_dereference(st_link->map); - seq_printf(seq, "map_id:\t%d\n", map->id); + if (map) + seq_printf(seq, "map_id:\t%d\n", map->id); rcu_read_unlock(); } @@ -1088,7 +1086,8 @@ static int bpf_struct_ops_map_link_fill_link_info(const struct bpf_link *link, st_link = container_of(link, struct bpf_struct_ops_link, link); rcu_read_lock(); map = rcu_dereference(st_link->map); - info->struct_ops.map_id = map->id; + if (map) + info->struct_ops.map_id = map->id; rcu_read_unlock(); return 0; } @@ -1113,6 +1112,10 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map mutex_lock(&update_mutex); old_map = rcu_dereference_protected(st_link->map, lockdep_is_held(&update_mutex)); + if (!old_map) { + err = -EINVAL; + goto err_out; + } if (expected_old_map && old_map != expected_old_map) { err = -EPERM; goto err_out; @@ -1139,8 +1142,37 @@ static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map return err; } +static int bpf_struct_ops_map_link_detach(struct bpf_link *link) +{ + struct bpf_struct_ops_link *st_link = container_of(link, struct bpf_struct_ops_link, link); + struct bpf_struct_ops_map *st_map; + struct bpf_map *map; + + mutex_lock(&update_mutex); + + map = rcu_dereference_protected(st_link->map, true); + if (!map) { + mutex_unlock(&update_mutex); + return -EINVAL; + } + st_map = container_of(map, struct bpf_struct_ops_map, map); + + st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, link); + + rcu_assign_pointer(st_link->map, NULL); + /* Pair with bpf_map_get() in bpf_struct_ops_link_create() or + * bpf_map_inc() in bpf_struct_ops_map_link_update(). + */ + bpf_map_put(&st_map->map); + + mutex_unlock(&update_mutex); + + return 0; +} + static const struct bpf_link_ops bpf_struct_ops_map_lops = { .dealloc = bpf_struct_ops_map_link_dealloc, + .detach = bpf_struct_ops_map_link_detach, .show_fdinfo = bpf_struct_ops_map_link_show_fdinfo, .fill_link_info = bpf_struct_ops_map_link_fill_link_info, .update_map = bpf_struct_ops_map_link_update, @@ -1176,13 +1208,19 @@ int bpf_struct_ops_link_create(union bpf_attr *attr) if (err) goto err_out; + /* Init link->map before calling reg() in case being detached + * immediately. + */ + RCU_INIT_POINTER(link->map, map); + err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data, &link->link); if (err) { + rcu_assign_pointer(link->map, NULL); bpf_link_cleanup(&link_primer); + /* The link has been free by bpf_link_cleanup() */ link = NULL; goto err_out; } - RCU_INIT_POINTER(link->map, map); return bpf_link_settle(&link_primer); From patchwork Tue May 7 05:55:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656277 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-oo1-f53.google.com (mail-oo1-f53.google.com [209.85.161.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C57DC6D1C8 for ; Tue, 7 May 2024 05:56:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061378; cv=none; b=DRXcJWUhd1/TkdouKzR6r+GYg/Oq/yRRJxUcVUrxBSC8mCjuxxaBv0JbX3Zdp4UQxgvSYRGJIKonicBak3kYB2uwOjM8kkkZZInaBGeeQNO8PHBeXsXjJvZUQPunbtcOO8Kp3IMLAskq0fQvLCyBpOYSredEsvLkAJ3s9WJs1uY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061378; c=relaxed/simple; bh=7+0B2PM4IXI7ORkqPIrseOZz5px6mK8KTyStKbg7jn8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=O7KwdrRg6s/G3c849B6LTcGojhIhWF/zfkRUmXIP688R4kJb+4XFWT3uiyfiI/egdGEZjEWxjEj3tMZ19g622D8k/It2eZfIsV6fU6ttuBYJIPwJVn+/uyMTSNOE51BxyWIrelZexlgq5O3V+v3cM1nem8Wwh1pd7XapeSiinNU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Io2V6ymJ; arc=none smtp.client-ip=209.85.161.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Io2V6ymJ" Received: by mail-oo1-f53.google.com with SMTP id 006d021491bc7-5ad2da2196bso1389539eaf.3 for ; Mon, 06 May 2024 22:56:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061375; x=1715666175; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/IgIxfryk/0GhM9FXe4Mf5a5mfor2fDNMojWu1TYABQ=; b=Io2V6ymJh2mbe9KePvRMUGtsV2ul8tDLKfga7YDaM3Sv10YzHgKwLl7LnbA3SL0PDq 5GZr8l5Lw4fUEP6TD1XvGZRQvZTdsJUXT91dSQPW0smWemya6gmFGMeCBU0I+QEFse43 9e+hAMdmpQDgMvkB1cbvLgVMgyGhi25s4fDvp5SqsNK4G04LQ5kKzBzJFrEJKzumaVhN pTFMbYJuMRwToRE/tSG/nJzUuaSZwyhmSpYje89LqVlfx0Mg5lvTPrK7CVJozv0EsUd0 sbXhEvop5Jf+CLlC3roiu0T2EO9hczQzu76MsMSJ4pU4IKVgSAN6uCDjsfbAHj0MlD/V NtwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061375; x=1715666175; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/IgIxfryk/0GhM9FXe4Mf5a5mfor2fDNMojWu1TYABQ=; b=ZmUdVukgAwDpZmTL7x8Yhex2Bi0b5OeRgepx0ZD6sBx/X/indhx4E6jFKtpFgx8bP5 JSUdBKMFEIfNF/3UGFOh2isBRka4laJx3WyaKOHE/qwXdVIatdzfhQjfueRawuvCSjoL HIy7Q1d/4lrI0smrZn5Ck2vxUiUo/VUGgsaLnSqskXGKQold52IL72iSJ44iEYalWdEN E/VJQUbdQfAjieWR5ScVEWpAavPyqeYCG2EgOFm65b/uf+AP82ENfMT2UWFRKK0ZG70U HgW3nbiZIQgZFY7FMzRaUYq+o9z7tn1d+R8ytIPpzbyu8e8ygGbE+30BVApmn9TOE1yU JMDw== X-Gm-Message-State: AOJu0Yz9Pe1/dXqfzSxRxEVlV6UF7sT2HsZNFoGqnkQ0yZQlTJ8DDHuj VYxZzvoUAKQKJ+qm9SOBLM+H2Q2lUWlMrpp/ccOdX9wMKSO+uS6QSCuBCw== X-Google-Smtp-Source: AGHT+IGuxdTVttejKjbV8ad9uELWof6n8gC9eWEmsicxPpPQag98gaXVWMp5WQfwm20TxMW/rknF1w== X-Received: by 2002:a4a:3117:0:b0:5b2:1e8:a66d with SMTP id k23-20020a4a3117000000b005b201e8a66dmr7222653ooa.8.1715061375539; Mon, 06 May 2024 22:56:15 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:15 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 3/6] bpf: support epoll from bpf struct_ops links. Date: Mon, 6 May 2024 22:55:57 -0700 Message-Id: <20240507055600.2382627-4-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add epoll support to bpf struct_ops links to trigger EPOLLHUP event upon detachment. Signed-off-by: Kui-Feng Lee --- include/linux/bpf.h | 1 + kernel/bpf/bpf_struct_ops.c | 17 +++++++++++++++++ kernel/bpf/syscall.c | 11 +++++++++++ 3 files changed, 29 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index b600767ebe02..5f7496ef8b7c 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1612,6 +1612,7 @@ struct bpf_link_ops { struct bpf_link_info *info); int (*update_map)(struct bpf_link *link, struct bpf_map *new_map, struct bpf_map *old_map); + __poll_t (*poll)(struct file *file, struct poll_table_struct *pts); }; struct bpf_tramp_link { diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index bd2602982e4d..f37844b1a94c 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -12,6 +12,7 @@ #include #include #include +#include struct bpf_struct_ops_value { struct bpf_struct_ops_common_value common; @@ -56,6 +57,7 @@ struct bpf_struct_ops_map { struct bpf_struct_ops_link { struct bpf_link link; struct bpf_map __rcu *map; + wait_queue_head_t wait_hup; }; static DEFINE_MUTEX(update_mutex); @@ -1167,15 +1169,28 @@ static int bpf_struct_ops_map_link_detach(struct bpf_link *link) mutex_unlock(&update_mutex); + wake_up_interruptible_poll(&st_link->wait_hup, EPOLLHUP); + return 0; } +static __poll_t bpf_struct_ops_map_link_poll(struct file *file, + struct poll_table_struct *pts) +{ + struct bpf_struct_ops_link *st_link = file->private_data; + + poll_wait(file, &st_link->wait_hup, pts); + + return (st_link->map) ? 0 : EPOLLHUP; +} + static const struct bpf_link_ops bpf_struct_ops_map_lops = { .dealloc = bpf_struct_ops_map_link_dealloc, .detach = bpf_struct_ops_map_link_detach, .show_fdinfo = bpf_struct_ops_map_link_show_fdinfo, .fill_link_info = bpf_struct_ops_map_link_fill_link_info, .update_map = bpf_struct_ops_map_link_update, + .poll = bpf_struct_ops_map_link_poll, }; int bpf_struct_ops_link_create(union bpf_attr *attr) @@ -1213,6 +1228,8 @@ int bpf_struct_ops_link_create(union bpf_attr *attr) */ RCU_INIT_POINTER(link->map, map); + init_waitqueue_head(&link->wait_hup); + err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data, &link->link); if (err) { rcu_assign_pointer(link->map, NULL); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 13ad74ecf2cd..ad4f81ed27f0 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -3150,6 +3150,16 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp) } #endif +static __poll_t bpf_link_poll(struct file *file, struct poll_table_struct *pts) +{ + struct bpf_link *link = file->private_data; + + if (link->ops->poll) + return link->ops->poll(file, pts); + + return 0; +} + static const struct file_operations bpf_link_fops = { #ifdef CONFIG_PROC_FS .show_fdinfo = bpf_link_show_fdinfo, @@ -3157,6 +3167,7 @@ static const struct file_operations bpf_link_fops = { .release = bpf_link_release, .read = bpf_dummy_read, .write = bpf_dummy_write, + .poll = bpf_link_poll, }; static int bpf_link_alloc_id(struct bpf_link *link) From patchwork Tue May 7 05:55:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656278 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0EAF76CDC2 for ; Tue, 7 May 2024 05:56:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061379; cv=none; b=TRbM1QgbBtriVngRO/GWDjJp8uLzpTMJepDKlWOxiSuys93x946aDaal0vZx3O1T3zfPE/NPNq2XmRUhwGJJ25mpYtz3EmKZJYAA5lWBJR2NAmYPYFXuJM85QS0gh7d1vKEuivmltxu2T5VgQ5YXuaIpS9IzTuwiS82/d5weS1Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061379; c=relaxed/simple; bh=i2I8DLeyGNfUX4yYt4rgQ8tn4yJjH6icPbJ/Y5yGxyE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZJokI0q8f1kartWAUqL1mfF7dtvxixl47A3KFRyKg8qihE+NYO7A7nDLJQQ4qjEKNX9Uc4wK1PWbLmIuu5TjlAyp16fLX+51Vr2GlR/IAfWE9Nb4MKeGMLhxGqCc8Xi+Uk1cMOy5BOkgTn5OGoJdVJPNaI2WK56LgEiVwfgpV64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=U0A30WY9; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U0A30WY9" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-6eb86b69e65so1709780a34.3 for ; Mon, 06 May 2024 22:56:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061376; x=1715666176; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MGAa9uCzEmcTsMh8N8SEx76nhZ7H6AlOyI9aIHDOpoA=; b=U0A30WY9JroI6z36QBLbbllM76cAkKWeQeU6T8WWQ+E0xU3vYM5/zNh3cMdwFA9h2l J1+3DhAmt/vjISuPUDJPweoVrxiu+1Zh0O9/cCNjnokUp8YPTJyQjW9x/cM5yj+v2Ro6 WpfBGfm+OgVpU9uCijuAz9UoWpMzCp3GXhZ11J5CWGHXpZ+N/GtClVEJDBHhSBy1SHpz 3rVDVkyoXYo62CL7OlawJIJTG70P2XMHfC3/U9zZsj9imYEEflDvT0XSSjRALyKz3Pm6 XMJx8o1VLPXf2ETwkc6SlXGDEgwfGoDUxerf09noWHi/n3Or7/eDuZ+UwzDAJFs7nHxn Rpkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061376; x=1715666176; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MGAa9uCzEmcTsMh8N8SEx76nhZ7H6AlOyI9aIHDOpoA=; b=ZtUzcNGlP+C/1LGc8b9RULF8PZxBkSBmCDtK1vi28DKQYKKYCr5kItuCnF7oJYFFHW LxZ9RiJj0sPvqx6NtuuNm6ugZZqGZBw/KNnHJ2h2SD3jVLj5hTRPZHNsziu6cwVX4BII qN/+P/+ppWeaB/+M+DGHUpNHwsoWNY6iaJDtdn4v2/3RLt1OIM2GcqLPp855K9satVqq ZV9QgwHoMT4pA42YNznStCtA8kO+D2JBnd0FhtSU0Z3/AIUJjHNJTJ4ZVSLC6L8ZlLMu PdBD4YeTZIHvT20wItx0ahq13WfaSt11JxfKZMsd7SeJRAkogej8Cn72Uh3540XD5Cwu dZNQ== X-Gm-Message-State: AOJu0YzhAwJjf6Af17LgxrkFg84ICcGlEyp/yK/q1J2FXsh+r+Pet4iU iM966qGJoRI+Q+no9WVrGlBYSE3t1843fixoNTSxarYYNO2yu8E81NjUAg== X-Google-Smtp-Source: AGHT+IHJTTO5N6IdiuyKzqjwxz/c6dyoREvwbB9KqAiBVYMbLY+Vq+urEbY4w5QEUhAjQl9N/DvqVA== X-Received: by 2002:a9d:6494:0:b0:6ee:ead5:25c with SMTP id g20-20020a9d6494000000b006eeead5025cmr14400712otl.1.1715061376592; Mon, 06 May 2024 22:56:16 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:16 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 4/6] selftests/bpf: test struct_ops with epoll Date: Mon, 6 May 2024 22:55:58 -0700 Message-Id: <20240507055600.2382627-5-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Verify whether a user space program is informed through epoll with EPOLLHUP when a struct_ops object is detached. Signed-off-by: Kui-Feng Lee --- .../selftests/bpf/bpf_testmod/bpf_testmod.c | 13 +++++ .../bpf/bpf_testmod/bpf_testmod_kfunc.h | 1 + .../bpf/prog_tests/test_struct_ops_module.c | 57 +++++++++++++++++++ .../selftests/bpf/progs/struct_ops_detach.c | 31 ++++++++++ 4 files changed, 102 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/struct_ops_detach.c diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c index e24a18bfee14..c89a6414c69f 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "bpf_testmod.h" #include "bpf_testmod_kfunc.h" @@ -498,6 +499,9 @@ __bpf_kfunc void bpf_kfunc_call_test_sleepable(void) { } +static DEFINE_MUTEX(detach_mutex); +static struct bpf_link *link_to_detach; + BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids) BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc) BTF_ID_FLAGS(func, bpf_kfunc_call_test1) @@ -577,11 +581,20 @@ static int bpf_dummy_reg(void *kdata, struct bpf_link *link) if (ops->test_2) ops->test_2(4, ops->data); + mutex_lock(&detach_mutex); + if (!link_to_detach) + link_to_detach = link; + mutex_unlock(&detach_mutex); + return 0; } static void bpf_dummy_unreg(void *kdata, struct bpf_link *link) { + mutex_lock(&detach_mutex); + if (link == link_to_detach) + link_to_detach = NULL; + mutex_unlock(&detach_mutex); } static int bpf_testmod_test_1(void) diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h index ce5cd763561c..9f9b60880fd3 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod_kfunc.h @@ -105,6 +105,7 @@ void bpf_kfunc_call_test_fail1(struct prog_test_fail1 *p); void bpf_kfunc_call_test_fail2(struct prog_test_fail2 *p); void bpf_kfunc_call_test_fail3(struct prog_test_fail3 *p); void bpf_kfunc_call_test_mem_len_fail1(void *mem, int len); +int bpf_dummy_do_link_detach(void) __ksym; void bpf_kfunc_common_test(void) __ksym; #endif /* _BPF_TESTMOD_KFUNC_H */ diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c index bd39586abd5a..f39455b81664 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c @@ -2,8 +2,12 @@ /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ #include #include +#include + +#include #include "struct_ops_module.skel.h" +#include "struct_ops_detach.skel.h" static void check_map_info(struct bpf_map_info *info) { @@ -174,6 +178,57 @@ static void test_struct_ops_incompatible(void) struct_ops_module__destroy(skel); } +/* Detach a link from a user space program */ +static void test_detach_link(void) +{ + struct epoll_event ev, events[2]; + struct struct_ops_detach *skel; + struct bpf_link *link = NULL; + int fd, epollfd = -1, nfds; + int err; + + skel = struct_ops_detach__open_and_load(); + if (!ASSERT_OK_PTR(skel, "struct_ops_detach__open_and_load")) + return; + + link = bpf_map__attach_struct_ops(skel->maps.testmod_do_detach); + if (!ASSERT_OK_PTR(link, "attach_struct_ops")) + goto cleanup; + + fd = bpf_link__fd(link); + if (!ASSERT_GE(fd, 0, "link_fd")) + goto cleanup; + + epollfd = epoll_create1(0); + if (!ASSERT_GE(epollfd, 0, "epoll_create1")) + goto cleanup; + + ev.events = EPOLLHUP; + ev.data.fd = fd; + err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); + if (!ASSERT_OK(err, "epoll_ctl")) + goto cleanup; + + err = bpf_link__detach(link); + if (!ASSERT_OK(err, "detach_link")) + goto cleanup; + + /* Wait for EPOLLHUP */ + nfds = epoll_wait(epollfd, events, 2, 500); + if (!ASSERT_EQ(nfds, 1, "epoll_wait")) + goto cleanup; + + if (!ASSERT_EQ(events[0].data.fd, fd, "epoll_wait_fd")) + goto cleanup; + if (!ASSERT_TRUE(events[0].events & EPOLLHUP, "events[0].events")) + goto cleanup; + +cleanup: + close(epollfd); + bpf_link__destroy(link); + struct_ops_detach__destroy(skel); +} + void serial_test_struct_ops_module(void) { if (test__start_subtest("test_struct_ops_load")) @@ -182,5 +237,7 @@ void serial_test_struct_ops_module(void) test_struct_ops_not_zeroed(); if (test__start_subtest("test_struct_ops_incompatible")) test_struct_ops_incompatible(); + if (test__start_subtest("test_detach_link")) + test_detach_link(); } diff --git a/tools/testing/selftests/bpf/progs/struct_ops_detach.c b/tools/testing/selftests/bpf/progs/struct_ops_detach.c new file mode 100644 index 000000000000..aeb355b3bea3 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/struct_ops_detach.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ +#include +#include +#include +#include "../bpf_testmod/bpf_testmod.h" +#include "../bpf_testmod/bpf_testmod_kfunc.h" + +char _license[] SEC("license") = "GPL"; + +int test_1_result = 0; +int test_2_result = 0; + +SEC("struct_ops/test_1") +int BPF_PROG(test_1) +{ + test_1_result = 0xdeadbeef; + return 0; +} + +SEC("struct_ops/test_2") +void BPF_PROG(test_2, int a, int b) +{ + test_2_result = a + b; +} + +SEC(".struct_ops.link") +struct bpf_testmod_ops testmod_do_detach = { + .test_1 = (void *)test_1, + .test_2 = (void *)test_2, +}; From patchwork Tue May 7 05:55:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656279 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-ot1-f53.google.com (mail-ot1-f53.google.com [209.85.210.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC65E6BFC7 for ; Tue, 7 May 2024 05:56:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061380; cv=none; b=OpFZJjz6tIqZQpkpqVqBiJlslBiNedLeIMrFp6yLqZW69cczLmB5PByy47GGcsABXe3y2xowPVZcw3eEBvzw2fGaxaAoJfDhY0qER8LJ34MoqawMBtukI6SUbOARQQcAXjsOIZbKvNcE8yeeVnE1ovomHG8ir0Cm3tMqH+8bblo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061380; c=relaxed/simple; bh=q9Swa1+K8h4SGfXzsShvJjtTA7qzi1225dIDLnWciog=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=mNbpSC1j+6VErIl0Wjxvgw8Hkb4vjF7jpaKXUmxo6KGmsbWy5GsfPX8eubF0hONoyTvWkN+99LywXPYFsKwadjD1SqiGeeEHrhVJvcA0sMYi6F2zzn182keF1JOfgnP41isDrJGJDOJDrsBxuNGbnft2TQ3Mt8ihu3RwAD1MVuI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cTfp6x/8; arc=none smtp.client-ip=209.85.210.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cTfp6x/8" Received: by mail-ot1-f53.google.com with SMTP id 46e09a7af769-6f08ce51e02so373172a34.3 for ; Mon, 06 May 2024 22:56:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061377; x=1715666177; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jAykHutB81ybakCfShPFVvAxaH5qZF5mTZ4X1NwUf+0=; b=cTfp6x/8S+VnXypG7Hb/r0F8+XzP50vREt9SMvpOuj6p+gNmy5EObA7MyKKweIzpl9 pfWy8acO9+CztGIaFL/JSDB/alR+8x7QrlJJQFZgcxBIuAFIAStjeTLuuH1r2qZC906u 83qrvnekh0jcfYwKs+vtP8IDDQn5GlPH94k/HA2fM0hOTRSpfvMGEmaz5smljJxKGwyj 2eb+7Q6oeOokgunC3aNgSJBgvGrQSzWvHyj2aLqiY/MZA6TQWchCuvN1oZddkamtMZCp gNn5JDL9b/GIFx2Os0LZbM04ciowbPrrLe+5bn6EpiYFtmYFbdGC803BjTwXd5wIUd2Y 5Tow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061377; x=1715666177; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jAykHutB81ybakCfShPFVvAxaH5qZF5mTZ4X1NwUf+0=; b=F+86McOi7XoGl6BpiWvyN1kafTtJAYyTkSztg/0gKrCuJ149WPWw7uh1FltDahQmbK iUdKkG5M3fMFA/4t3dS++oZEBLpCcGku5WZKPwhj2qQRDaraHc8f03T39RWs2FUmhTrM UdYKItfYgMBX6ZJmKF+FnUeQ0sX6jW93p7bvvcOX8ApytHDBOUf7k2K3j0y9UC3pD1Yo qk2jMHRd6HsTx7kMRI9WRO6Ky0uhsnsJeV4WRMf3qQbxul/0LIwR5Cco5nLLolW84S0N Ech0FgARE2msFviAgFLkqcXKBK9P9jCoBVv/BSG0uYr4GSGzLrRwb/tSjctkLCR8Bef5 mGng== X-Gm-Message-State: AOJu0Yyq/3yAUT2qFqL+cDigDWDqbPKw9tqqt/Iq3ZXxhhRzf4jaW9qQ sYN0lPCLVBPPEjtoQCwOeipfg7YztvohGGztXm7eFzG87lN1VxWLHt0Idw== X-Google-Smtp-Source: AGHT+IGNyy5Mk9qW0ZZ6sQyIpNcRPAD47hsGtGhd18ipc7vtbw8C8Z3ls32Kv7JcmlrID8fJLwOazw== X-Received: by 2002:a9d:6554:0:b0:6f0:4bfc:4c49 with SMTP id q20-20020a9d6554000000b006f04bfc4c49mr5705634otl.15.1715061377652; Mon, 06 May 2024 22:56:17 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:17 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 5/6] selftests/bpf: detach a struct_ops link from the subsystem managing it. Date: Mon, 6 May 2024 22:55:59 -0700 Message-Id: <20240507055600.2382627-6-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Not only a user space program can detach a struct_ops link, the subsystem managing a link can also detach the link. This patch add a kfunc to simulate detaching a link by the subsystem managing it. Signed-off-by: Kui-Feng Lee --- .../selftests/bpf/bpf_testmod/bpf_testmod.c | 21 ++++++ .../bpf/prog_tests/test_struct_ops_module.c | 65 +++++++++++++++++++ .../selftests/bpf/progs/struct_ops_detach.c | 6 ++ 3 files changed, 92 insertions(+) diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c index c89a6414c69f..0bf1acc1767a 100644 --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c @@ -502,6 +502,26 @@ __bpf_kfunc void bpf_kfunc_call_test_sleepable(void) static DEFINE_MUTEX(detach_mutex); static struct bpf_link *link_to_detach; +__bpf_kfunc int bpf_dummy_do_link_detach(void) +{ + struct bpf_link *link; + int ret = -ENOENT; + + mutex_lock(&detach_mutex); + link = link_to_detach; + /* Make sure the link is still valid by increasing its refcnt */ + if (link && !atomic64_inc_not_zero(&link->refcnt)) + link = NULL; + mutex_unlock(&detach_mutex); + + if (link) { + ret = link->ops->detach(link); + bpf_link_put(link); + } + + return ret; +} + BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids) BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc) BTF_ID_FLAGS(func, bpf_kfunc_call_test1) @@ -529,6 +549,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE) BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg) BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset) BTF_ID_FLAGS(func, bpf_kfunc_call_test_sleepable, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_dummy_do_link_detach) BTF_KFUNCS_END(bpf_testmod_check_kfunc_ids) static int bpf_testmod_ops_init(struct btf *btf) diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c index f39455b81664..9f6657b53a93 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c @@ -229,6 +229,69 @@ static void test_detach_link(void) struct_ops_detach__destroy(skel); } +/* Detach a link from the subsystem that the link was registered to */ +static void test_subsystem_detach(void) +{ + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4)); + struct epoll_event ev, events[2]; + struct struct_ops_detach *skel; + struct bpf_link *link = NULL; + int fd, epollfd = -1, nfds; + int prog_fd; + int err; + + skel = struct_ops_detach__open_and_load(); + if (!ASSERT_OK_PTR(skel, "struct_ops_detach_open_and_load")) + return; + + link = bpf_map__attach_struct_ops(skel->maps.testmod_do_detach); + if (!ASSERT_OK_PTR(link, "attach_struct_ops")) + goto cleanup; + + fd = bpf_link__fd(link); + if (!ASSERT_GE(fd, 0, "link_fd")) + goto cleanup; + + prog_fd = bpf_program__fd(skel->progs.start_detach); + if (!ASSERT_GE(prog_fd, 0, "start_detach_fd")) + goto cleanup; + + /* Do detachment from the registered subsystem */ + err = bpf_prog_test_run_opts(prog_fd, &topts); + if (!ASSERT_OK(err, "start_detach_run")) + goto cleanup; + + if (!ASSERT_EQ(topts.retval, 0, "start_detach_run retval")) + goto cleanup; + + epollfd = epoll_create1(0); + if (!ASSERT_GE(epollfd, 0, "epoll_create1")) + goto cleanup; + + ev.events = EPOLLHUP; + ev.data.fd = fd; + err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); + if (!ASSERT_OK(err, "epoll_ctl")) + goto cleanup; + + /* Wait for EPOLLHUP */ + nfds = epoll_wait(epollfd, events, 2, 5000); + if (!ASSERT_EQ(nfds, 1, "epoll_wait")) + goto cleanup; + + if (!ASSERT_EQ(events[0].data.fd, fd, "epoll_wait_fd")) + goto cleanup; + if (!ASSERT_TRUE(events[0].events & EPOLLHUP, "events[0].events")) + goto cleanup; + +cleanup: + close(epollfd); + bpf_link__destroy(link); + struct_ops_detach__destroy(skel); +} + void serial_test_struct_ops_module(void) { if (test__start_subtest("test_struct_ops_load")) @@ -239,5 +302,7 @@ void serial_test_struct_ops_module(void) test_struct_ops_incompatible(); if (test__start_subtest("test_detach_link")) test_detach_link(); + if (test__start_subtest("test_subsystem_detach")) + test_subsystem_detach(); } diff --git a/tools/testing/selftests/bpf/progs/struct_ops_detach.c b/tools/testing/selftests/bpf/progs/struct_ops_detach.c index aeb355b3bea3..139f9a5c5601 100644 --- a/tools/testing/selftests/bpf/progs/struct_ops_detach.c +++ b/tools/testing/selftests/bpf/progs/struct_ops_detach.c @@ -29,3 +29,9 @@ struct bpf_testmod_ops testmod_do_detach = { .test_1 = (void *)test_1, .test_2 = (void *)test_2, }; + +SEC("tc") +int start_detach(void *skb) +{ + return bpf_dummy_do_link_detach(); +} From patchwork Tue May 7 05:56:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13656280 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-oo1-f41.google.com (mail-oo1-f41.google.com [209.85.161.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05CD46EB64 for ; Tue, 7 May 2024 05:56:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061381; cv=none; b=D1jrHJNvthy1WBUc0JuYT1WpUdZLrC3NYNRDVF4rJtqtr+LoS5N8r+KZPRln9XgmIpvrKvir0GJq/mCVk8x5nT+fuL58N7TaTS90VUvlY+MLAumvIEtj+MM6fnHaVY4onMTZZOY/Qcsia42Bzx+Q9a1p8k9ahND14g09GT6jEnE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715061381; c=relaxed/simple; bh=WfXwWy1Qzg/be4xT68IA/an8B7CbXHK2t5RTqaBtWOU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kCb5PO2PPFnJ6vjyY4AZ8VquSffPWj6eO/1hyoXdxcPVWb+Ae00/sARMkuMRZYjbnC/E5SdVpRrHfxZCj9kmNPQbSBtNUczoksQglXvnNQPhG6s4M+bTJGzOslkLJovPGmNLO67pIjE7WlL3FGa/9xAcZ7DSLaeF5TbkK34u2Gg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Zk43ki1F; arc=none smtp.client-ip=209.85.161.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Zk43ki1F" Received: by mail-oo1-f41.google.com with SMTP id 006d021491bc7-5ac90ad396dso1658652eaf.3 for ; Mon, 06 May 2024 22:56:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1715061379; x=1715666179; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QkS70W5e30KvFUPoJEEVO+XU2mME9AFDkQqS2+2/LKE=; b=Zk43ki1FjMeL76XsvkM09pRC13U8ILpvRkhQLY06ICZle6CmCNYCuMVKdbRb5yzUBF Qpcv2CF69aXtxevK78rSFEB8JGKZsdaAtNVdTrF/yfdoa0MUKEd+V9Tb8g6qRG9wj8G7 nDyfE1DvlFqi0P4lhPQv+yHk23LKG8LF1bJZ1wpXl0QuXWE/5+kPZVNH/ul44VkdeEbk S5YbzPIsZ4eqrSJiNDhEocWKy6VRzXvKhFmBgvzNJSRKom9fq5T8q63gEL7X1IE72FqD IrxF72ckylDntbXx+II7YMYT5mVp5o+znYUCGwbAjNuOlfK+E9VlduppBBFmJm692PfT xvYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715061379; x=1715666179; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QkS70W5e30KvFUPoJEEVO+XU2mME9AFDkQqS2+2/LKE=; b=u/D6+GQx5q0YLIyN9OhaRlFMo4imw5bzjJQDPQIAyoQ/mQ5762HP8JLrll5fB/EQrb iy5cLlveKkX+ELvgCE9IeQzZovQ5BlfJOvyQGlIh+xTdPb4VLbVB2ZXVBIEizbJsr+O8 Wxj9yIeSSGmFrFKeyLnRpgHQaF5jOQPXDx0t2vZu/crdMgIv+4BhwQkYIhQ+GAQzKrSO 5FWri1mSbtxLVIhW+YAb4fwYVR+tSrOL1tjYTg78mGmJJTHNHB3WGDIx/ethlbuySDP8 uqd6a77xpUmTbRZk/+XXa2ukLb9x50bE57ZiZO/simKPD8Sc8czU3+SC4HGhV0fNEoE3 iIhg== X-Gm-Message-State: AOJu0YyZe8Ku2nlBqBYZZTi7YLtKNP34GDkfYh320luzWWRDtyb6KvIc gZ2G8FIuXT9cT9F0sH8UW2780XLxUkBNALDHkU0V9Utfp74QoKY6BAp/CA== X-Google-Smtp-Source: AGHT+IF4Zug0XeLJYtkRRmm3QyJBNe2+YD2526xEKLbSXeFQqJrx/W+iQ/pq+OVPTT19JRFKiP1dpg== X-Received: by 2002:a4a:944:0:b0:5aa:17bf:8e3d with SMTP id 65-20020a4a0944000000b005aa17bf8e3dmr12023463ooa.9.1715061378676; Mon, 06 May 2024 22:56:18 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:2e7d:922e:d30d:e503]) by smtp.gmail.com with ESMTPSA id eo8-20020a0568200f0800b005a586b0906esm2317011oob.26.2024.05.06.22.56.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 May 2024 22:56:18 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, song@kernel.org, kernel-team@meta.com, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [PATCH bpf-next v2 6/6] selftests/bpf: make sure bpf_testmod handling racing link destroying well. Date: Mon, 6 May 2024 22:56:00 -0700 Message-Id: <20240507055600.2382627-7-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240507055600.2382627-1-thinker.li@gmail.com> References: <20240507055600.2382627-1-thinker.li@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Subsystems that manage struct_ops objects may attempt to detach a link when the link has been released or is about to be released. The test in this patch demonstrate to developers the correct way to handle this situation using a locking mechanism and atomic64_inc_not_zero(). A subsystem must ensure that a link is valid when detaching the link. In order to achieve that, the subsystem may need to obtain a lock to safeguard a table that holds the pointer to the link being detached. However, the subsystem cannot invoke link->ops->detach() while holding the lock because other tasks may be in the process of unregistering, which could lead to a deadlock. This is why atomic64_inc_not_zero() is used to maintain the link's validity. (Refer to bpf_dummy_do_link_detach() in the previous patch for more details.) This test make sure the pattern mentioned above work correctly. Signed-off-by: Kui-Feng Lee --- .../bpf/prog_tests/test_struct_ops_module.c | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c index 9f6657b53a93..1e37037cfd8a 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c @@ -292,6 +292,48 @@ static void test_subsystem_detach(void) struct_ops_detach__destroy(skel); } +/* A subsystem detachs a link while the link is going to be free. */ +static void test_subsystem_detach_free(void) +{ + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4)); + struct struct_ops_detach *skel; + struct bpf_link *link = NULL; + int prog_fd; + int err; + + skel = struct_ops_detach__open_and_load(); + if (!ASSERT_OK_PTR(skel, "struct_ops_detach_open_and_load")) + return; + + link = bpf_map__attach_struct_ops(skel->maps.testmod_do_detach); + if (!ASSERT_OK_PTR(link, "attach_struct_ops")) + goto cleanup; + + bpf_link__destroy(link); + + prog_fd = bpf_program__fd(skel->progs.start_detach); + if (!ASSERT_GE(prog_fd, 0, "start_detach_fd")) + goto cleanup; + + /* Do detachment from the registered subsystem */ + err = bpf_prog_test_run_opts(prog_fd, &topts); + if (!ASSERT_OK(err, "start_detach_run")) + goto cleanup; + + /* The link may have zero refcount value and may have been + * unregistered, so the detachment from the subsystem should fail. + */ + ASSERT_EQ(topts.retval, (u32)-ENOENT, "start_detach_run retval"); + + /* Sync RCU to make sure the link is freed without any crash */ + ASSERT_OK(kern_sync_rcu(), "sync rcu"); + +cleanup: + struct_ops_detach__destroy(skel); +} + void serial_test_struct_ops_module(void) { if (test__start_subtest("test_struct_ops_load")) @@ -304,5 +346,7 @@ void serial_test_struct_ops_module(void) test_detach_link(); if (test__start_subtest("test_subsystem_detach")) test_subsystem_detach(); + if (test__start_subtest("test_subsystem_detach_free")) + test_subsystem_detach_free(); }