On Tue, 5 Jul 2016 18:47:18 +0000 (UTC) Gleb Smirnoff <gleb...@freebsd.org> wrote:
> Author: glebius > Date: Tue Jul 5 18:47:17 2016 > New Revision: 302350 > URL: https://svnweb.freebsd.org/changeset/base/302350 > > Log: > The paradigm of a callout is that it has three consequent states: > not scheduled -> scheduled -> running -> not scheduled. The API and > the manual page assume that, some comments in the code assume that, > and looks like some contributors to the code also did. The problem is > that this paradigm isn't true. A callout can be scheduled and running > at the same time, which makes API description ambigouous. In such > case callout_stop() family of functions/macros should return 1 and 0 > at the same time, since it successfully unscheduled future callout > but the current one is running. Before this change we returned 1 in > such a case, with an exception that if running callout was migrating > we returned 0, unless CS_MIGRBLOCK was specified. > > With this change, we now return 0 in case if future callout was > unscheduled, but another one is still in action, indicating to API > users that resources are not yet safe to be freed. > > However, the sleepqueue code relies on getting 1 return code in > that case, and there already was CS_MIGRBLOCK flag, that covered one > of the edge cases. In the new return path we will also use this flag, > to keep sleepqueue safe. > Since the flag CS_MIGRBLOCK doesn't block migration and now isn't > limited to migration edge case, rename it to CS_EXECUTING. > > This change fixes panics on a high loaded TCP server. > > Reviewed by: jch, hselasky, rrs, kib > Approved by: re (gjb) > Differential Revision: https://reviews.freebsd.org/D7042 > Hi, this change also breaks ARP reliably in my nfsroot setup for multiple MIPS board. The cause is following: before this change, the sequence of calls: callout_init(&la->lle_timer, 1); ret = callout_stop(&ls->lle_timer); would result in ret == -1 after the change, same sequence causes callout_stop to return 1. This does not bode well for lle entries that were allocated, but for which callout_reset was never called, because we have several constructs in the source tree that do something like if (callout_stop(&lle->lle_timer) > 0) LLE_REMREF(lle); This results in panics as described in: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=210884 -- Alexander Kabaev
pgpCIQAIpPC7t.pgp
Description: Цифровая подпись OpenPGP