From nobody Thu Mar 16 15:04:29 2023 X-Original-To: freebsd-arch@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PcrCH1gkpz3yD11 for ; Thu, 16 Mar 2023 15:04:43 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PcrCG70fwz3N8Z for ; Thu, 16 Mar 2023 15:04:42 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-ed1-x533.google.com with SMTP id o12so8835105edb.9 for ; Thu, 16 Mar 2023 08:04:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdimp-com.20210112.gappssmtp.com; s=20210112; t=1678979081; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=OpKgiFfO7qzsq9xtsoDfn6NRpTD3xSoCtg5TxsTIG/c=; b=fKsoAVjZNhjz1VrmrmjXUYBlBvsVScnAc5p8LirKolTTXnDoini+nlSYtMvtWK666m cm9d1cXoL7NOo4xhG80TJ/HbVC9SXVdTCJEaeuN77ddcvHCl39I5k6AzsLziAD7YLiC5 kdDVg2ZUr/jHIlOUs/Vck8hpkDWuAINdISZBtItBxHA0KDpxcliG+MYzTWPorZ8ozRRo UMmup2G2lzmh1YtvprnBRQzgbY0KiKE1Xr6tLHk6fyA1gpa5Ss5uvlWND9U3EbKNw435 94cPLnlrMBaxDlmWXXK4Ps6y/dwlKJTNJOEdmE4/TtUhriIh+HYVFjvC1wfT0qIjLmOj p7Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678979081; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=OpKgiFfO7qzsq9xtsoDfn6NRpTD3xSoCtg5TxsTIG/c=; b=UtP+2lw4i1Ukf1xBJejMXrIEVMJOAx+UfdlTagPWF+BklYLAxNFYUmqGod33bSdZ0W sDtbXpoITWGqwoxmbN/jwXDQVsdy5dsh8qKCJIs++r90dIpfb3fX3cJRSl8/TrXBZE1V eUHnxMvOKVD9+uooLeYrqqoLjLuq+U3aqNYLRrAMlTgsfaUekrJzSGk9sjQ6l9/fLI1i VsT7bNiumWrV2axVh9osY+WYz+Y82n7AvOSNMtc0QYcKHCatvX7H7MfJRePwTAYBfwKZ ed/QAzlZdqreHSOWVIka9T6HW9PFaoK9oN5zl7RRHrrFfkJ3DsZOEvbH7IpFKaSOVFRZ w56g== X-Gm-Message-State: AO0yUKVUBAxOZfK98ztxkgvXBvumw3VX8wwhpYl0goj2KbtiaC6btmAs sHmjJJYzopQtc9YAql8uGc+lCAJLYdaizgpvC7NoQQ== X-Google-Smtp-Source: AK7set93pvrY4668mM3nQSupw+LnwYMVDgtZbf3+FV16mJ3j2cNrsDNreWLIghsp2Z0ZKuR25CyqJHRi3GfIJca9444= X-Received: by 2002:a17:906:d041:b0:8b1:3298:c587 with SMTP id bo1-20020a170906d04100b008b13298c587mr5421959ejb.2.1678979081207; Thu, 16 Mar 2023 08:04:41 -0700 (PDT) List-Id: Discussion related to FreeBSD architecture List-Archive: https://lists.freebsd.org/archives/freebsd-arch List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-arch@freebsd.org MIME-Version: 1.0 References: <20230316100611.4892008c@gonegalt.net> In-Reply-To: <20230316100611.4892008c@gonegalt.net> From: Warner Losh Date: Thu, 16 Mar 2023 09:04:29 -0600 Message-ID: Subject: Re: Blocks runtime in the kernel To: Justin Hibbits Cc: "freebsd-arch@freebsd.org" Content-Type: multipart/alternative; boundary="000000000000b8964a05f705c77a" X-Rspamd-Queue-Id: 4PcrCG70fwz3N8Z X-Spamd-Bar: ---- X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US] X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-ThisMailContainsUnwantedMimeParts: N --000000000000b8964a05f705c77a Content-Type: text/plain; charset="UTF-8" On Thu, Mar 16, 2023, 8:06 AM Justin Hibbits wrote: > Most probably know I've been working on the IfAPI conversion of all > network drivers in order to hide the contents of `struct ifnet`. I'm > pretty much done with the development, and it's all in review. > However, there's one bit that I've thought is very clunky since I added > it, the if_foreach() iterator function, which iterates over all > interfaces in the current VNET, and calls a callback to operate on each > interface. I've noticed that oftentimes I end up with a 2 line > callback, which just calls if_foreach_addr_type(), so I end up with > just trivial callback functions, which seems like a waste. > > All that backstory to say, would it be beneficial to anyone else to > add a (very basic) blocks runtime to the kernel for doing things like > this? The rough change to the IfAPI becomes: > > int if_foreach_b(int (^)(if_t)); > > __block int foo = 0; > > if_foreach_b(^(if_t ifp) { > if (if_getlinkstate(ifp) == LINK_STATE_UP) > foo++; > }); > > The same could be done for other *_foreach KPIs as well, if this proves > out. I think I could have something working in the next several days. > > The only technical snag I see with this would be other compilers. I'm > not sure if GCC still supports blocks, it did at one point. > > What do you think? > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78352 Suggests that there were issues upstreaming the apple code. So there's that. The gcc12 port I have can't cope with the sample blocks code I found on Wikipedia: /* blocks-test.c */ #include #include /* Type of block taking nothing returning an int */ typedef int (^IntBlock)(); IntBlock MakeCounter(int start, int increment) { __block int i = start; return Block_copy( ^(void) { int ret = i; i += increment; return ret; }); } int main(void) { IntBlock mycounter = MakeCounter(5, 2); printf("First call: %d\n", mycounter()); printf("Second call: %d\n", mycounter()); printf("Third call: %d\n", mycounter()); /* because it was copied, it must also be released */ Block_release(mycounter); return 0; } Our current clang is OK: % clang -fblocks a.c -o a -lBlocksRuntime % But there's no current users of __block in the kernel. There's no kernel-specific Block.h file, there's no references to BlockRuntime anywhere in the kernel tree and the code in contrib/llvm-project/compiler-rt/lib/BlocksRuntime is completely userland specific. There is no kernel support that I could see, since we don't have a libkern/OSAtomic.h. I'm happy to be corrected on this though: I've never tried to use blocks in the kernel and this is grep level confidence. Clang also doesn't enable blocks unless you pass it -fblock, so you'd need to change a fair portion of the kernel build system to enable that. So I'm thinking regardless of whether or not the project should do this, you'll have a fair amount of choppy waves ahead of you before you could get to the point of starting the ifnet work. Warner --000000000000b8964a05f705c77a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Thu, Mar 16, 2023, 8:06 AM Justin = Hibbits <jhibb= its@freebsd.org> wrote:
Most= probably know I've been working on the IfAPI conversion of all
network drivers in order to hide the contents of `struct ifnet`.=C2=A0 I= 9;m
pretty much done with the development, and it's all in review.
However, there's one bit that I've thought is very clunky since I a= dded
it, the if_foreach() iterator function, which iterates over all
interfaces in the current VNET, and calls a callback to operate on each
interface.=C2=A0 I've noticed that oftentimes I end up with a 2 line callback, which just calls if_foreach_addr_type(), so I end up with
just trivial callback functions, which seems like a waste.

All that backstory to say, would it be beneficial to anyone else to
add a (very basic) blocks runtime to the kernel for doing things like
this?=C2=A0 The rough change to the IfAPI becomes:

int if_foreach_b(int (^)(if_t));

__block int foo =3D 0;

if_foreach_b(^(if_t ifp) {
=C2=A0 if (if_getlinkstate(ifp) =3D=3D LINK_STATE_UP)
=C2=A0 =C2=A0 foo++;
});

The same could be done for other *_foreach KPIs as well, if this proves
out.=C2=A0 I think I could have something working in the next several days.=

The only technical snag I see with this would be other compilers.=C2=A0 I&#= 39;m
not sure if GCC still supports blocks, it did at one point.

What do you think?

=


Suggests that there were issues upstreaming the apple code. So<= /div>
there's that.=C2=A0 The gcc12 port I have can't cope with= the sample blocks
code I found on Wikipedia:
/* blocks= -test.c */
#include <stdio.h>
#include <Block.h>
/* Ty= pe of block taking nothing returning an int */
typedef int (^IntBlock)()= ;

IntBlock MakeCounter(int start, int increment) {
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 __block int i =3D start;

=C2=A0 =C2=A0 =C2=A0 =C2=A0 r= eturn Block_copy( ^(void) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 int ret =3D i;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 i +=3D increment;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 return ret;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 });

}
int main(void) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 IntBlock mycounter = =3D MakeCounter(5, 2);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("First ca= ll: %d\n", mycounter());
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("S= econd call: %d\n", mycounter());
=C2=A0 =C2=A0 =C2=A0 =C2=A0 printf= ("Third call: %d\n", mycounter());

=C2=A0 =C2=A0 =C2=A0 = =C2=A0 /* because it was copied, it must also be released */
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 Block_release(mycounter);

=C2=A0 =C2=A0 =C2=A0 =C2= =A0 return 0;
}

Our current clang is OK:
% clang -fblocks a.c -o a -lBlocksRuntime
%=C2=A0

But there's no current users of __block in the ke= rnel. There's no kernel-specific Block.h file,
there's no= references to BlockRuntime anywhere in the kernel tree and the code in
contrib/llvm-project/compiler-rt/lib/BlocksRuntime is completely use= rland specific. There
is no kernel support that I could see, = since we don't have a libkern/OSAtomic.h. I'm happy
to be= corrected on this though: I've never tried to use blocks in the kernel= and this is grep
level confidence.

Clan= g also doesn't enable blocks unless you pass it -fblock, so you'd n= eed to change a fair
portion of the kernel build system to enable= that.

So I'm thinking regardless of whether o= r not the project should do this, you'll have a fair amount
o= f choppy waves ahead of you before you could get to the point of starting t= he ifnet work.

Warner
--000000000000b8964a05f705c77a--