[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-arch
Subject:    Re: callout_stop() return value
From:       Hans Petter Selasky <hps () selasky ! org>
Date:       2018-05-03 7:24:06
Message-ID: 1d28ee66-ee17-4515-b855-f33db9e8bbda () selasky ! org
[Download RAW message or body]

On 05/02/18 17:20, Mark Johnston wrote:
> Hi,
> 
> We have a few pieces of code that follow a pattern: a thread allocates a
> resource and schedules a callout. The callout handler releases the
> resource and never reschedules itself. In the common case, a thread
> will cancel the callout before it executes. To know whether it must
> release the resource associated with the callout, this thread must know
> whether the pending callout was cancelled.
> 
> Before r302350, our code happened to work; it could use the return value
> of callout_stop() to correctly determine whether to release the
> resource. Now, however, it cannot: the return value does not contain
> sufficient information. In particular, if the return value is 0, we do
> not know whether a future invocation of the callout was cancelled.
> 
> The resource's lifetime is effectively tied to the scheduling of the
> callout, so I think it's preferable to address this by extending the
> callout API rather than by adding some extra state to the structure
> containing the callout. Does anyone have any opinions on adding a new
> flag to _callout_stop_safe(), somewhat akin to CS_EXECUTING? When this
> flag is specified, _callout_stop_safe() will return 1 if a future
> invocation was cancelled, even if the callout was running at the time of
> the call.
> 
> The patch below implements this suggestion, but I haven't yet tested
> it and was wondering if anyone had opinions on how to handle this
> scenario. If I end up going ahead with this approach, I'll be sure to
> update the callout man page with a description of CS_EXECUTING and the
> new flag. Thanks in advance.
> 

Hi,

You cannot add nor change the current callout_xxx() return values!

There is a lot of code in the kernel (TCP stack for example) which 
simply compares this value with < > != and ==   !  Be warned !

To force all callers to re-evaluate the return value, I suggest to 
return the callout state as a bitmap structure. See:

https://svnweb.freebsd.org/base/projects/hps_head

> 55 	/* return value for all callout_xxx() functions */
> 56 	typedef union callout_ret {
> 57 	        struct {
> 58 	                unsigned cancelled : 1;
> 59 	                unsigned draining : 1;
> 60 	                unsigned reserved : 30;
> 61 	        } bit;
> 62 	        unsigned value;
> 63 	} callout_ret_t;

The clang compiler treats this structure as an integer.

Example:

>  if (callout_async_drain(t_callout, tcp_timer_discard).bit.draining) {

--HPS
_______________________________________________
freebsd-arch@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org"
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic