Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Sep 2015 21:52:07 +0300
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        Hans Petter Selasky <hselasky@FreeBSD.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r287780 - in head: share/man/man9 sys/kern sys/sys
Message-ID:  <20150918185207.GF1023@FreeBSD.org>
In-Reply-To: <201509141052.t8EAqRWf008293@repo.freebsd.org>
References:  <201509141052.t8EAqRWf008293@repo.freebsd.org>

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

  on behalf of core, I ask you to revert this change due to lack
of review and due to previous issues in this area.

On Mon, Sep 14, 2015 at 10:52:27AM +0000, Hans Petter Selasky wrote:
H> Author: hselasky
H> Date: Mon Sep 14 10:52:26 2015
H> New Revision: 287780
H> URL: https://svnweb.freebsd.org/changeset/base/287780
H> 
H> Log:
H>   Implement callout_drain_async(), inspired by the projects/hps_head
H>   branch.
H>   
H>   This function is used to drain a callout via a callback instead of
H>   blocking the caller until the drain is complete. Refer to the
H>   callout_drain_async() manual page for a detailed description.
H>   
H>   Limitation: If a lock is used with the callout, the callout can only
H>   be drained asynchronously one time unless the callout_init_mtx()
H>   function is called again. This limitation is not present in
H>   projects/hps_head and will require more invasive changes to the
H>   timeout code, which was not in the scope of this patch.
H>   
H>   Differential Revision:	https://reviews.freebsd.org/D3521
H>   Reviewed by:		wblock
H>   MFC after:		1 month
H> 
H> Modified:
H>   head/share/man/man9/Makefile
H>   head/share/man/man9/timeout.9
H>   head/sys/kern/kern_timeout.c
H>   head/sys/sys/_callout.h
H>   head/sys/sys/callout.h
H> 
H> Modified: head/share/man/man9/Makefile
H> ==============================================================================
H> --- head/share/man/man9/Makefile	Mon Sep 14 10:28:47 2015	(r287779)
H> +++ head/share/man/man9/Makefile	Mon Sep 14 10:52:26 2015	(r287780)
H> @@ -1641,6 +1641,7 @@ MLINKS+=timeout.9 callout.9 \
H>  	timeout.9 callout_active.9 \
H>  	timeout.9 callout_deactivate.9 \
H>  	timeout.9 callout_drain.9 \
H> +	timeout.9 callout_drain_async.9 \
H>  	timeout.9 callout_handle_init.9 \
H>  	timeout.9 callout_init.9 \
H>  	timeout.9 callout_init_mtx.9 \
H> 
H> Modified: head/share/man/man9/timeout.9
H> ==============================================================================
H> --- head/share/man/man9/timeout.9	Mon Sep 14 10:28:47 2015	(r287779)
H> +++ head/share/man/man9/timeout.9	Mon Sep 14 10:52:26 2015	(r287780)
H> @@ -36,6 +36,7 @@
H>  .Nm callout_active ,
H>  .Nm callout_deactivate ,
H>  .Nm callout_drain ,
H> +.Nm callout_drain_async ,
H>  .Nm callout_handle_init ,
H>  .Nm callout_init ,
H>  .Nm callout_init_mtx ,
H> @@ -70,6 +71,8 @@ typedef void timeout_t (void *);
H>  .Fn callout_deactivate "struct callout *c"
H>  .Ft int
H>  .Fn callout_drain "struct callout *c"
H> +.Ft int
H> +.Fn callout_drain_async "struct callout *c" "callout_func_t *fn" "void *arg"
H>  .Ft void
H>  .Fn callout_handle_init "struct callout_handle *handle"
H>  .Bd -literal
H> @@ -264,6 +267,24 @@ fully stopped before
H>  .Fn callout_drain
H>  returns.
H>  .Pp
H> +The function
H> +.Fn callout_drain_async
H> +is non-blocking and works the same as the
H> +.Fn callout_stop
H> +function.
H> +When this function returns non-zero, do not call it again until the callback function given by
H> +.Fa fn
H> +has been called with argument
H> +.Fa arg .
H> +Only one of
H> +.Fn callout_drain
H> +or
H> +.Fn callout_drain_async
H> +should be called at a time to drain a callout.
H> +If this function returns zero, it is safe to free the callout structure pointed to by the
H> +.Fa c
H> +argument immediately.
H> +.Pp
H>  The
H>  .Fn callout_reset
H>  and
H> 
H> Modified: head/sys/kern/kern_timeout.c
H> ==============================================================================
H> --- head/sys/kern/kern_timeout.c	Mon Sep 14 10:28:47 2015	(r287779)
H> +++ head/sys/kern/kern_timeout.c	Mon Sep 14 10:52:26 2015	(r287780)
H> @@ -1145,6 +1145,45 @@ callout_schedule(struct callout *c, int 
H>  }
H>  
H>  int
H> +callout_drain_async(struct callout *c, callout_func_t *func, void *arg)
H> +{
H> +	struct callout_cpu *cc;
H> +	struct lock_class *class;
H> +	int retval;
H> +	int direct;
H> +
H> +	/* stop callout */
H> +	callout_stop(c);
H> +
H> +	/* check if callback is being called */
H> +	cc = callout_lock(c);
H> +	if (c->c_iflags & CALLOUT_DIRECT) {
H> +		direct = 1;
H> +	} else {
H> +		direct = 0;
H> +	}
H> +	retval = (cc_exec_curr(cc, direct) == c);
H> +
H> +	/* drop locks, if any */
H> +	if (retval && c->c_lock != NULL &&
H> +	    c->c_lock != &Giant.lock_object) {
H> +		/* ensure we are properly locked */
H> +		class = LOCK_CLASS(c->c_lock);
H> +		class->lc_assert(c->c_lock, LA_XLOCKED);
H> +		/* the final callback should not be called locked */
H> +		c->c_lock = NULL;
H> +		c->c_iflags |= CALLOUT_RETURNUNLOCKED;
H> +	}
H> +	CC_UNLOCK(cc);
H> +
H> +	/* check if we should queue final callback */
H> +	if (retval)
H> +		callout_reset(c, 1, func, arg);
H> +
H> +	return (retval);
H> +}
H> +
H> +int
H>  _callout_stop_safe(struct callout *c, int safe)
H>  {
H>  	struct callout_cpu *cc, *old_cc;
H> 
H> Modified: head/sys/sys/_callout.h
H> ==============================================================================
H> --- head/sys/sys/_callout.h	Mon Sep 14 10:28:47 2015	(r287779)
H> +++ head/sys/sys/_callout.h	Mon Sep 14 10:52:26 2015	(r287780)
H> @@ -46,6 +46,8 @@ LIST_HEAD(callout_list, callout);
H>  SLIST_HEAD(callout_slist, callout);
H>  TAILQ_HEAD(callout_tailq, callout);
H>  
H> +typedef void callout_func_t(void *);
H> +
H>  struct callout {
H>  	union {
H>  		LIST_ENTRY(callout) le;
H> 
H> Modified: head/sys/sys/callout.h
H> ==============================================================================
H> --- head/sys/sys/callout.h	Mon Sep 14 10:28:47 2015	(r287779)
H> +++ head/sys/sys/callout.h	Mon Sep 14 10:52:26 2015	(r287780)
H> @@ -82,6 +82,7 @@ struct callout_handle {
H>  #define	callout_active(c)	((c)->c_flags & CALLOUT_ACTIVE)
H>  #define	callout_deactivate(c)	((c)->c_flags &= ~CALLOUT_ACTIVE)
H>  #define	callout_drain(c)	_callout_stop_safe(c, 1)
H> +int	callout_drain_async(struct callout *, callout_func_t *, void *);
H>  void	callout_init(struct callout *, int);
H>  void	_callout_init_lock(struct callout *, struct lock_object *, int);
H>  #define	callout_init_mtx(c, mtx, flags)					\
H> _______________________________________________
H> svn-src-all@freebsd.org mailing list
H> https://lists.freebsd.org/mailman/listinfo/svn-src-all
H> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"

-- 
Totus tuus, Glebius.



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