From nobody Thu Mar 16 14:06:11 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 4Pcpvp2Dt1z3y9Dl for ; Thu, 16 Mar 2023 14:06:14 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [IPv6:2610:1c1:1:606c::24b:4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Pcpvp08g1z3HTY for ; Thu, 16 Mar 2023 14:06:14 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678975574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=JIKF1n1HvTdvUS6JMPkVdquBzemFhmFxzxKUQLPvIa4=; b=scAloWCZ73ucJ7shXnYNgMhAuZNAl3dJf7+n/eLTtYu7R5st4ymSJH2RIDzbiFOHz3b9l9 VjrGNBB3soAT/4pwskomDQt0VIjiZthGUS5xez6Z9XetsM7D+DHpHQoTqBCZeCrtCS6KqV tC70FL3KJny34ml8g+TWPQXlaxzPZz/rr0A2YM4V+yh3L4mDd62547/ktKAsAKegEAPANi TPTOBjqdoVuqy5YQGFJfD5DPO30aINJAkqpFq7l3W0Gw7ryLd4VGjLPgYscYSwJVekSatC DuoCVz6g6TfbHrKY3d2lwDuIASd4buvzayBgw4w5VbMdfSD0SDsQ+FVMD60rtA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678975574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=JIKF1n1HvTdvUS6JMPkVdquBzemFhmFxzxKUQLPvIa4=; b=HPG+a/fJsZEN2DwBgV4z4KxmpWoMFUMIdnInIBPWS1DRMX/WKOvPlgVMvYi0FFnNL2v4o1 hpvGu6NxK/ruFPdFS+6hMbRuyQ2T4LWdauDuWfNvAGxI1vPe8l/aJ1ihB6KiFi6fpOMcAV 41ijiY7hOw5z0x3033eYJBNboGPSXQ1zrR9U37y0R51RxOPzjar91ZjLe5FVJ18Ahh/ZSd 9h6yDNGmapG0Nh84qCE1CGVr4Mwn5PE15v/WbFoaNKRxw43VRd3WbP1tsdYjLTfOnd9K5k joYh2YsAkJRDtFbQ3TiMQEjaPmqnGnd8N8dKKkCHIkER7Tz/2K44RRwOkbKiuA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1678975574; a=rsa-sha256; cv=none; b=OAxkaelMj7niYZPfv5oIIAYVyFspRD/mtbvAWD/buK1TZf+hfr8MoVd09Sj54dLGfFswob ub/dJGiWAQ4fLEjpBbWFQ585WsdxJVr9ALrP5YkLfz5g2Di2RtKSgIw6UiJj+k13sNf01j gPtKuVV87jYNYfz1VTBHQ54zAk+CSV+tDK+jAwSDdZ9A+A/kwtWDDi/fJCssigbjI4XAQX tPSrD08nl1M5n+TN7oCMBe2GXo9a27Iw/kTC1vv9SA7X0p881zAr6Dkfr7bhUpG3dCo/zp LO/p9ZpYQqGfDKtxYcUJ/glc5rORDAm4CUrMQKtvzIVqSeAZIjEl9QJY4TcU5Q== Received: from gonegalt.net (ip-163-182-7-56.dynamic.fuse.net [163.182.7.56]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: jhibbits) by smtp.freebsd.org (Postfix) with ESMTPSA id 4Pcpvn5WgVzXWY for ; Thu, 16 Mar 2023 14:06:13 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Date: Thu, 16 Mar 2023 10:06:11 -0400 From: Justin Hibbits To: freebsd-arch@freebsd.org Subject: Blocks runtime in the kernel Message-ID: <20230316100611.4892008c@gonegalt.net> X-Mailer: Claws Mail 4.1.1 (GTK 3.24.34; powerpc64le-unknown-linux-gnu) 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 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-ThisMailContainsUnwantedMimeParts: N 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? - Justin 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-- From nobody Thu Mar 16 15:22:22 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 4Pcrbh0mM2z3yFH3 for ; Thu, 16 Mar 2023 15:22:24 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Pcrbh0KSDz3Q7Y; Thu, 16 Mar 2023 15:22:24 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678980144; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PjrJ+vfw1I6+FlqrVqleqRrh/kum8zo09HBZyUdTPSY=; b=Np5Q1t5mErIHAIvy3U/XXjktxG0CzY4akcCawu5XHvdBTxVjvH3Xpic86HdK657+cYI8ul 9MriLBpmaqVi6xBbG0HZz7u7irnriuBd8vx9rgLcNCE0mxSQd76u2NUtGns1gWUKa6BA8p mPApecssgx/ekbwEJe2MLsei44ZERn8qXK3/ObHlfOQ3ZxuXrDoKvJktc/TZv6ExVZlbi3 surQhbvdjiGAFWMsbQsGEZllp9PAGY4t6TVc3qs1FCLHXI9OXZCXbHAiYRV/aFyNfyuAxR bPUqvHFin3Sj+qSQ8lTDUDmBUbkUB1SYxsZVOIulm5y9MDTrdWDGDG3AXGKjuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1678980144; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PjrJ+vfw1I6+FlqrVqleqRrh/kum8zo09HBZyUdTPSY=; b=Ek0SloHGUOhev0ANXmVv0nTUlxuG9PIeQK1tMSRZNMQgiNARgvkSqrHkfwP1yQ1UMP+Yke c6gAgqGMQTzAC87Qt9fNGS9oFkudWaKFlOocZumvy2WitSt3mHnlJ/kpazb94aKwPYrrIQ 2nUg/mG2JBb4gyVsDjjNUwBiZnuRjp8UT2v/Ui/UIX4uZVd4guSaV0Nd5+d91ZLC5QMQao swk3f6K2sW33bB+F0Y2qojQrXvonLyNeZYCawxEc6DbRH7FT0my9vwx26pngqjMKiC8OuM GEIl80sm9zf2AWFDksXBz88OBzy0Yhq0ztUcQ++3jhsOfkdPMNsQiXsWPuUH5g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1678980144; a=rsa-sha256; cv=none; b=jfVjc3ZQ2q0tZBFDVcQ4PrCpcPzGSiMGspxHAu1B2i23dDoJS1iVjGi+1ovI/9u/Uw9fJX uQGGKbx89rSI0DMgxpWuGCSLGCdhlmf8OhnnrI3v9Bbpvzc9DOJhpzRIVKlAut2fxX88Jx OeMlFRZzyVx8FOzvGZFWquvk8pTXIpuftTF/uDIhBJF5TwepcUNDwrefuh4WmqyWZzk7Tb cEp3Dnbfg5FSsyJ+UuRR14oLQ+PsUeIfW7Xzezb2VpYFmInQ/SKKfMRRUQ0D/Pfjq9zV8w T5ogxpApQvUr/Fn5fQLgeiJZkSB9x8PX4AVlxQnHVwGM/8nXv8D0HFyBSug9aA== Received: from gonegalt.net (ip-163-182-7-56.dynamic.fuse.net [163.182.7.56]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: jhibbits) by smtp.freebsd.org (Postfix) with ESMTPSA id 4Pcrbg5YyyzZVC; Thu, 16 Mar 2023 15:22:23 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Date: Thu, 16 Mar 2023 11:22:22 -0400 From: Justin Hibbits To: Warner Losh Cc: "freebsd-arch@freebsd.org" Subject: Re: Blocks runtime in the kernel Message-ID: <20230316112222.31b1620e@gonegalt.net> In-Reply-To: References: <20230316100611.4892008c@gonegalt.net> X-Mailer: Claws Mail 4.1.1 (GTK 3.24.34; powerpc64le-unknown-linux-gnu) 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 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-ThisMailContainsUnwantedMimeParts: N On Thu, 16 Mar 2023 09:04:29 -0600 Warner Losh wrote: > 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 Hi Warner, I did a very very simple test to see what is required link-wise for blocks in kernel. This was done by changing https://reviews.freebsd.org/D38962 to use a block instead of a callback for the "bootpc_init_count_if_cb". I didn't include Block.h or anything, and simply added "-fblocks" to kern.mk. The result is it compiles fine, then fails to link (expected) with the following missing symbols: _Block_object_dispose _Block_object_assign _NSConcreteStackBlock Reading through contrib/llvm-project/compiler-rt/lib/BlocksRuntime/runtime.c these missing symbols look straightforward to implement for the basic case. I'm not thinking of working within the Clang runtime.c, I'm thinking of reimplementing the needed functions for this constrained use case (no need for GC, etc). This testing was only marginally more than you did, so I'm probably missing some things as well for more complex use cases. I'm guessing from GCC's issues that this is a nonstarter anyway? - Justin From nobody Thu Mar 16 15:41:17 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 4Pcs1l0WM2z3yG4k for ; Thu, 16 Mar 2023 15:41:31 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) (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 4Pcs1k5Nxkz3h9K for ; Thu, 16 Mar 2023 15:41:30 +0000 (UTC) (envelope-from wlosh@bsdimp.com) Authentication-Results: mx1.freebsd.org; none Received: by mail-ed1-x52d.google.com with SMTP id z21so9385188edb.4 for ; Thu, 16 Mar 2023 08:41:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bsdimp-com.20210112.gappssmtp.com; s=20210112; t=1678981288; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=ag9s0H4L4jiypNwuPJ+ljtrk7nDPRCHtg2TBm9QNSyM=; b=cWyqPI9MQUxGbrXGbfm37fXXyC7esgSPhtMMYryWIY7Aq1fTp+ZsFgcenhHjQm2vFB jDqHavu8i73+lGY6R8bMJhcpmt7SUOqA7SFwVtUPTmNqAzbI7+iAnoPXkLNjkL9hQGhc iTRlBL7g1NG8HLzKuxij2Sg4kOdyfVOVkzfzco03tbBDOi81omDGUyroET4TcNLTEM9I ynuJk36XQQQC1Cp/1T+MxGBAD2nqb8VUCK/FbCdWPbbpVbarOYLH14xcMCMaLLdcNd5Z lwNy1Gg8Z/ge4S6/zpriHygQ6gefHsoQ7OoiejzcWHG4fNpV6ziVZXDjB5jJIpnRXdbQ 7ucg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678981288; 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=ag9s0H4L4jiypNwuPJ+ljtrk7nDPRCHtg2TBm9QNSyM=; b=I147LhUxhPw7DAkSp8bQWxDIiYdnaO5833oZl4QR5WTa5AAieAk+P91dJsPwqT/d8B H63gFQ/XUFhB6m+gYztgHzPgppwsz5RRujav0T3L3rV45yMi3OOPhrRkAZiAk93I+I5q ecBCqynxcuvBGVFClPjOoFRmdxhBjUIyqKD088B/v+yCm5zq0WyBLv7M57/RFzUKrKgs 3NGSfvEa0wfOXYU+zVR4nlC9RAUijjr714EtGOnrksyN28qUwNNOwoO2FPMfLiTFY1qx hCWe5215Hbt83JRm9lQRB95/TTKbbyQ4EcZyhiCkQafXNELW5tKotYOSIRIb+5Y9YAcX evLg== X-Gm-Message-State: AO0yUKXjzecinGWTGEtX5MwSlGWTTXkYqDKUUDoSFJSz8N1PNjCEtFJE RxDcjsogXArKBWlo+CrWcSMYCS/2ACTeM2hs+G/xhFBiFo79G9Bw X-Google-Smtp-Source: AK7set+C3Ms41gxGXg2uEFCO1smROqU8VgcoqXbu40Q0s+3emSk5FxM1keOzKjz+yI7FUfbIRM9Bbe0/8HOLoidZkqw= X-Received: by 2002:a17:906:16d6:b0:930:310:abcf with SMTP id t22-20020a17090616d600b009300310abcfmr1992039ejd.2.1678981288462; Thu, 16 Mar 2023 08:41:28 -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> <20230316112222.31b1620e@gonegalt.net> In-Reply-To: <20230316112222.31b1620e@gonegalt.net> From: Warner Losh Date: Thu, 16 Mar 2023 09:41:17 -0600 Message-ID: Subject: Re: Blocks runtime in the kernel To: Justin Hibbits Cc: "freebsd-arch@freebsd.org" Content-Type: multipart/alternative; boundary="000000000000489b0605f7064b0f" X-Rspamd-Queue-Id: 4Pcs1k5Nxkz3h9K 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 --000000000000489b0605f7064b0f Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Mar 16, 2023 at 9:22=E2=80=AFAM Justin Hibbits wrote: > On Thu, 16 Mar 2023 09:04:29 -0600 > Warner Losh wrote: > > > 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 =3D 0; > > > > > > if_foreach_b(^(if_t ifp) { > > > if (if_getlinkstate(ifp) =3D=3D 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=3D78352 > > > > 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 =3D start; > > > > return Block_copy( ^(void) { > > int ret =3D i; > > i +=3D increment; > > return ret; > > }); > > > > } > > > > int main(void) { > > IntBlock mycounter =3D 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 > > Hi Warner, > > I did a very very simple test to see what is required link-wise for > blocks in kernel. This was done by changing > https://reviews.freebsd.org/D38962 to use a block instead of a callback > for the "bootpc_init_count_if_cb". I didn't include Block.h or > anything, and simply added "-fblocks" to kern.mk. The result is it > compiles fine, then fails to link (expected) with the following missing > symbols: > As a basic test, that's fine. But I'm not sure we want to globally add -fblocks to the kernel. I don't know if that changes anything else. People will want to know if there's global performance or size impact from doing this and whether or not the compiler inserts other code because blocks are possible. _Block_object_dispose > _Block_object_assign > _NSConcreteStackBlock > > Reading through > contrib/llvm-project/compiler-rt/lib/BlocksRuntime/runtime.c these > missing symbols look straightforward to implement for the basic case. > I'm not thinking of working within the Clang runtime.c, I'm thinking of > reimplementing the needed functions for this constrained use case (no > need for GC, etc). > > This testing was only marginally more than you did, so I'm probably > missing some things as well for more complex use cases. > I was worried about two things when I looked at the code: reference countin= g (which I think is kinda required, even though objc uses it for GC) and memory allocation / handling. The former is well understood, and we can adapt things (though knowing which subset is required here might be tricky, there's a lo= t of flags). The latter, though, would limit the use of these APIs to situations where you can call malloc/free M_WAIT, or you'd need to deal with malloc failures better than runtime.c does. So while the number of routines is small, I think they are the tip of the iceburg and may be more work than you're suggesting. > I'm guessing from GCC's issues that this is a nonstarter anyway? > In the past we've said that it's OK to use clang specific code to get bette= r performance, but that depending on it entirely would require a careful discussion. gcc is produces code that's easier to debug than clang (though gcc12 build is currently still broken), and that's not nothing and has been useful for me in the past. jhb can likely speak to other benefits for gcc12 since he did the last round of updates. So given the difficulties on multiple fronts, I'm not sure it's a great idea. But maybe I'm wrong about how difficult things will be and maybe it would work out in the end. But selecting the network stack to use what will be an unproven, or at least immature technology is ambitious. We've had a mixed bag with that stuff (see epoch and smr for examples). I'm trying hard not to say a flat out "no," because I know that sometimes things that look hard like this pay off. But no gcc support does make it really hard to say yes. I've had my say, and I'll let others say from here. Warner --000000000000489b0605f7064b0f Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Thu, Mar 16, 2023 at 9:22=E2=80=AF= AM Justin Hibbits <jhibbits@free= bsd.org> wrote:
On Thu, 16 Mar 2023 09:04:29 -0600
Warner Losh <imp@bsd= imp.com> wrote:

> On Thu, Mar 16, 2023, 8:06 AM Justin Hibbits <jhibbits@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`.<= br> > > I'm pretty much done with the development, and it's all i= n 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 opera= te
> > on each interface.=C2=A0 I've noticed that oftentimes I end u= p 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<= br> > > 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 =C2=A0if (if_getlinkstate(ifp) =3D=3D LINK_STATE_UP)
> >=C2=A0 =C2=A0 =C2=A0foo++;
> > });
> >
> > The same could be done for other *_foreach KPIs as well, if this<= br> > > proves out.=C2=A0 I think I could have something working in the n= ext
> > 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 poin= t.
> >
> > What do you think?
> >=C2=A0
>
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi= ?id=3D78352
>
> Suggests that there were issues upstreaming the apple code. So
> 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>
> /* Type of block taking nothing returning an int */
> typedef int (^IntBlock)();
>
> IntBlock MakeCounter(int start, int increment) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0__block int i =3D start;
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return Block_copy( ^(void) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int ret = =3D i;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0i +=3D in= crement;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return re= t;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0});
>
> }
>
> int main(void) {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IntBlock mycounter =3D MakeCounter(5,= 2);
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("First call: %d\n", = mycounter());
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("Second call: %d\n",= mycounter());
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("Third call: %d\n", = mycounter());
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* because it was copied, it must als= o be released */
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Block_release(mycounter);
>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 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 yo= u'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

Hi Warner,

I did a very very simple test to see what is required link-wise for
blocks in kernel.=C2=A0 This was done by changing
https://reviews.freebsd.org/D38962 to use a block instead of a= callback
for the "bootpc_init_count_if_cb".=C2=A0 I didn't include Blo= ck.h or
anything, and simply added "-fblocks" to kern.mk.=C2=A0 The result is it=
compiles fine, then fails to link (expected) with the following missing
symbols:

As a basic test, that's fi= ne. But I'm not sure we want to globally add -fblocks
to the = kernel. I don't know if that changes anything else. People will want
to know if there's global performance or size impact from doing= this and
whether or not the compiler inserts other code because = blocks are possible.

_Block_object_dispose
_Block_object_assign
_NSConcreteStackBlock

Reading through
contrib/llvm-project/compiler-rt/lib/BlocksRuntime/runtime.c these
missing symbols look straightforward to implement for the basic case.
I'm not thinking of working within the Clang runtime.c, I'm thinkin= g of
reimplementing the needed functions for this constrained use case (no
need for GC, etc).

This testing was only marginally more than you did, so I'm probably
missing some things as well for more complex use cases.

I was worried about two things when I looked at the code: = reference counting
(which I think is kinda required, even though = objc uses it for GC) and memory
allocation / handling. The former= is well understood, and we can adapt things
(though knowing whic= h subset is required here might be tricky, there's a lot
of f= lags). The latter, though, would limit the use of these APIs to situations<= /div>
where you can call malloc/free M_WAIT, or you'd need to deal = with malloc
failures better than runtime.c does.

So while the number of routines is small, I think they are the tip= of the iceburg
and may be more work than you're suggesting.<= /div>
=C2=A0
I'm guessing from GCC's issues that this is a nonstarter anyway?

In the past we've said that it's = OK to use clang specific code to get better
performance, but that= depending on it entirely would require a careful
discussion. gcc= is produces code that's easier to debug than clang (though
g= cc12 build is currently still broken), and that's not nothing and has b= een
useful for me in the past. jhb can likely speak to other bene= fits for gcc12
since he did the last round of updates.
=
So given the difficulties on multiple fronts, I'm not su= re it's a great idea.
But maybe I'm wrong about how diffi= cult things will be and maybe it would
work out in the end. But s= electing the network stack to use what will be
an unproven, or at= least immature technology is ambitious. We've had a
mixed ba= g with that stuff (see epoch and smr for examples).=C2=A0

I'm trying hard not to say a flat out "no," because I= know that sometimes
things that look hard like this pay off. But= no gcc support does make it
really hard to say yes. I've had= my say, and I'll let others say from
here.

Warner
--000000000000489b0605f7064b0f--