Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-6]: src Pullup via patch (requested by he in ticket #1530)
details: https://anonhg.NetBSD.org/src/rev/9a4d568f6bfa
branches: netbsd-1-6
changeset: 530955:9a4d568f6bfa
user: jmc <jmc%NetBSD.org@localhost>
date: Wed Oct 22 06:06:50 2003 +0000
description:
Pullup via patch (requested by he in ticket #1530)
Introduce a new INVOKING status for callouts, and use it to close
a race condition in the TCP code. Fixes PR#20390.
diffstat:
share/man/man9/callout.9 | 42 +++++++++++++++++++++++++++++++++++++++++-
sys/kern/kern_clock.c | 5 +++--
sys/sys/callout.h | 5 ++++-
3 files changed, 48 insertions(+), 4 deletions(-)
diffs (115 lines):
diff -r d4e050c9c84d -r 9a4d568f6bfa share/man/man9/callout.9
--- a/share/man/man9/callout.9 Wed Oct 22 06:06:23 2003 +0000
+++ b/share/man/man9/callout.9 Wed Oct 22 06:06:50 2003 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: callout.9,v 1.6 2002/02/13 08:18:38 ross Exp $
+.\" $NetBSD: callout.9,v 1.6.2.1 2003/10/22 06:06:50 jmc Exp $
.\"
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -59,6 +59,10 @@
.Fn "callout_expired" "struct callout *c"
.Ft void
.Fn "callout_deactivate" "struct callout *c"
+.Ft int
+.Fn "callout_invoking" "struct callout *c"
+.Ft void
+.Fn "callout_ack" "struct callout *c"
.Sh DESCRIPTION
The
.Nm callout
@@ -179,6 +183,42 @@
if the callout function has already been executed, i.e. the callout
is no longer
.Em PENDING .
+.Pp
+The
+.Fn callout_invoking
+function checks whether the callout function in the callout
+handle
+.Em c
+is about to be executed, at which time the
+.Em INVOKING
+status is set.
+Since the priority is lowered prior to invocation of the callout
+function, other pending higher-priority code may run before the
+callout function is actually invoked.
+This may create a race condition if this higher-priority code
+deallocates storage containing one or more callout structures whose
+callout functions are about to run.
+In such cases one technique to prevent references to deallocated
+storage would be to test whether any callout functions are in the
+.Em INVOKING
+state using
+.Fn callout_invoking ,
+and if so, to mark the data structure and defer storage
+deallocation until the callout function is allowed to run.
+For this handshake protocol to work, the callout function will
+have to use the
+.Fn callout_ack
+function to clear this flag.
+.Pp
+The
+.Fn callout_ack
+function clears the
+.Em INVOKING
+state in the callout handle
+.Em c .
+This is used in situations where it is necessary to protect against
+the race condition described under
+.Fn callout_invoking .
.Sh SEE ALSO
.Xr hz 9
.Sh HISTORY
diff -r d4e050c9c84d -r 9a4d568f6bfa sys/kern/kern_clock.c
--- a/sys/kern/kern_clock.c Wed Oct 22 06:06:23 2003 +0000
+++ b/sys/kern/kern_clock.c Wed Oct 22 06:06:50 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_clock.c,v 1.79 2002/03/17 11:10:43 simonb Exp $ */
+/* $NetBSD: kern_clock.c,v 1.79.6.1 2003/10/22 06:06:50 jmc Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.79 2002/03/17 11:10:43 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_clock.c,v 1.79.6.1 2003/10/22 06:06:50 jmc Exp $");
#include "opt_callout.h"
#include "opt_ntp.h"
@@ -987,6 +987,7 @@
arg = c->c_arg;
c->c_func = NULL;
c->c_flags &= ~CALLOUT_PENDING;
+ c->c_flags |= CALLOUT_INVOKING;
CALLWHEEL_UNLOCK(s);
(*func)(arg);
CALLWHEEL_LOCK(s);
diff -r d4e050c9c84d -r 9a4d568f6bfa sys/sys/callout.h
--- a/sys/sys/callout.h Wed Oct 22 06:06:23 2003 +0000
+++ b/sys/sys/callout.h Wed Oct 22 06:06:50 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: callout.h,v 1.16 2001/09/11 04:32:19 thorpej Exp $ */
+/* $NetBSD: callout.h,v 1.16.12.1 2003/10/22 06:06:50 jmc Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -96,6 +96,7 @@
#define CALLOUT_ACTIVE 0x0001 /* callout is active */
#define CALLOUT_PENDING 0x0002 /* callout time has not yet arrived */
+#define CALLOUT_INVOKING 0x0004 /* callout func about to be called */
#define CALLOUT_INITIALIZER { { NULL, NULL }, 0, NULL, NULL, 0 }
@@ -122,6 +123,8 @@
#define callout_expired(c) (callout_pending((c)) == 0)
#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE)
+#define callout_invoking(c) ((c)->c_flags & CALLOUT_INVOKING)
+#define callout_ack(c) ((c)->c_flags &= ~CALLOUT_INVOKING)
#endif /* _KERNEL */
#endif /* !_SYS_CALLOUT_H_ */
Home |
Main Index |
Thread Index |
Old Index