Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Mar 2005 00:24:58 +0100
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        Luigi Rizzo <rizzo@icir.org>
Cc:        net@FreeBSD.org
Subject:   Re: Giant-free polling [PATCH]
Message-ID:  <20050303232458.GO9291@darkness.comp.waw.pl>
In-Reply-To: <20050301162949.A64187@xorpc.icir.org>
References:  <E1D1nPr-000IE5-00._pppp-mail-ru@f37.mail.ru> <20050217161031.A46700@xorpc.icir.org> <200503011642.48813.jhb@FreeBSD.org> <20050301162949.A64187@xorpc.icir.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--QKFUq+IbM9AW97yF
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Mar 01, 2005 at 04:29:49PM -0800, Luigi Rizzo wrote:
+> [cc-ing net@freebsd.org to get more opinions]
+>=20
+> On Tue, Mar 01, 2005 at 04:42:48PM -0500, John Baldwin wrote:
+> > On Thursday 17 February 2005 07:10 pm, Luigi Rizzo wrote:
+> > > i am no expert about the locking but i see places where
+> > > you grab polling_lock followed by ifnet_lock, and others where
+> > > you use the opposite order. This seems prone to deadlock...
+> >=20
+> > Yes, it basically seems that the polling_lock should be removed and ju=
st the=20
+> > ifnet_lock used because the the ifnet_lock is already always held when=
 the=20
+> > polling_lock is locked.

Yeah, but we cannot grap ifnet_lock in polling code, because this is
internal mutex, not visible from outside.
I was thinking about moving ifnet_lock into ifnet structure...

+> this said, if the lock requests are blocking, you basically end
+> up with the polling loops always contending for the locks, with only one
+> doing actual work and the other one always busy-waiting.
+>=20
+> Assuming the primitive exists, I think the correct way to implement
+> SMP polling is to use non-blocking locks, something like this
+> (in pseudocode)
+>=20
+>     poll_loop() {
+> 	have_polling_lock =3D try_get_lock(polling_lock)
+> 	foreach(ifp in polled_interfaces) {
+> 	    if (have_polling_lock)
+> 		have_ifp_lock =3D get_lock(ifp) // returns true
+> 	    else
+> 		have_ifp_lock =3D try_get_lock(ifp)
+> 	    if (have_ifp_lock) {
+> 		ifp->poll();
+> 		release_lock(ifp)
+> 	    }
+> 	}
+> 	if (have_polling_lock)
+> 	    release_lock(polling_lock);
+>     }
+>=20
+> so additional polling processes after the first one will not
+> block on busy interfaces and move forward instead.
+> This should remove a bit of contention, and let separate processes actua=
lly
+> work on different interfaces.

I think we should just implement per-interface idlepoll threads, so we can
run polling code on many CPUs for many interfaces.

--=20
Pawel Jakub Dawidek                       http://www.wheel.pl
pjd@FreeBSD.org                           http://www.FreeBSD.org
FreeBSD committer                         Am I Evil? Yes, I Am!

--QKFUq+IbM9AW97yF
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iD8DBQFCJ5zKForvXbEpPzQRAi2lAKC2NdMRuUkUm/0YQuu8bJo6fEM/HwCg0OZy
axqDwvGKiDlorK9INal9ask=
=wq7q
-----END PGP SIGNATURE-----

--QKFUq+IbM9AW97yF--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050303232458.GO9291>