[PATCH 2/8] dovetail/tick: implement proxy tick device installing and uninstalling

Philippe Gerum rpm at xenomai.org
Sat Jan 16 12:42:01 CET 2021


hongzha1 via Xenomai <xenomai at xenomai.org> writes:

> Signed-off-by: hongzha1 <hongzhan.chen at intel.com>
>
> diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
> index 02cd86690..6a196496c 100644
> --- a/kernel/cobalt/dovetail/tick.c
> +++ b/kernel/cobalt/dovetail/tick.c
> @@ -6,11 +6,92 @@
>   */
>  
>  #include <linux/tick.h>
> +#include <linux/clockchips.h>
>  #include <cobalt/kernel/intr.h>
>  #include <pipeline/tick.h>
> +#include <cobalt/kernel/sched.h>
> +#include <cobalt/kernel/timer.h>
>  
>  extern struct xnintr nktimer;
>  
> +static DEFINE_PER_CPU(struct clock_proxy_device *, proxy_device);
> +
> +static int proxy_set_next_ktime(ktime_t expires,
> +				struct clock_event_device *proxy_dev)
> +{
> +	struct xnsched *sched;
> +	ktime_t delta;
> +	unsigned long flags;
> +	int ret;
> +
> +	/*
> +	 * When Negative delta have been observed, we set delta zero.
> +	 * Or else exntimer_start() will return -ETIMEDOUT and do not
> +	 * trigger shot
> +	 */
> +	delta = ktime_sub(expires, ktime_get_mono_fast_ns());
> +	if (delta < 0)
> +		delta = 0;
> +
> +	flags = hard_local_irq_save(); /* Prevent CPU migration. */
> +	sched = xnsched_current();
> +	ret = xntimer_start(&sched->htimer, delta, XN_INFINITE, XN_RELATIVE);
> +	hard_local_irq_restore(flags);
> +
> +	return ret ? -ETIME : 0;
> +}
> +
> +
> +void xn_core_tick(struct clock_event_device *dummy) /* hard irqs off */
> +{
> +	xnintr_core_clock_handler();
> +}
> +
> +static int proxy_set_oneshot_stopped(struct clock_event_device *proxy_dev)
> +{
> +	struct clock_event_device *real_dev;
> +	struct clock_proxy_device *dev;
> +	struct xnsched *sched;
> +	spl_t s;
> +
> +	dev = container_of(proxy_dev, struct clock_proxy_device, proxy_device);
> +
> +	/*
> +	 * In-band wants to disable the clock hardware on entering a
> +	 * tickless state, so we have to stop our in-band tick
> +	 * emulation. Propagate the request for shutting down the
> +	 * hardware to the real device only if we have no outstanding
> +	 * OOB timers. CAUTION: the in-band timer is counted when
> +	 * assessing the RQ_IDLE condition, so we need to stop it
> +	 * prior to testing the latter.
> +	 */
> +	xnlock_get_irqsave(&nklock, s);
> +	sched = xnsched_current();
> +	xntimer_stop(&sched->htimer);
> +	//sched->lflags |= XNTSTOP;
> +
> +	if (sched->lflags & XNIDLE) {
> +		real_dev = dev->real_device;
> +		real_dev->set_state_oneshot_stopped(real_dev);
> +	}
> +
> +	xnlock_put_irqrestore(&nklock, s);
> +
> +	return 0;
> +}
> +
> +static void setup_proxy(struct clock_proxy_device *dev)
> +{
> +	struct clock_event_device *proxy_dev = &dev->proxy_device;
> +
> +	dev->handle_oob_event = xn_core_tick;
> +	proxy_dev->features |= CLOCK_EVT_FEAT_KTIME;
> +	proxy_dev->set_next_ktime = proxy_set_next_ktime;
> +	if (proxy_dev->set_state_oneshot_stopped)
> +		proxy_dev->set_state_oneshot_stopped = proxy_set_oneshot_stopped;
> +	__this_cpu_write(proxy_device, dev);
> +}
> +
>  int pipeline_install_tick_proxy(void)
>  {
>  	int ret;
> @@ -20,7 +101,7 @@ int pipeline_install_tick_proxy(void)
>  		return ret;
>  
>  	/* Install the proxy tick device */
> -	TODO();	ret = 0;
> +	ret = tick_install_proxy(setup_proxy, &xnsched_realtime_cpus);
>  	if (ret)
>  		goto fail_proxy;
>  
> @@ -35,7 +116,7 @@ fail_proxy:
>  void pipeline_uninstall_tick_proxy(void)
>  {
>  	/* Uninstall the proxy tick device. */
> -	TODO();
> +	tick_uninstall_proxy(&xnsched_realtime_cpus);
>  
>  	pipeline_free_timer_ipi();


Merged, fixing up the short log for consistency with other patches, as:

cobalt/tick: dovetail: install/uninstall proxy tick device

-- 
Philippe.



More information about the Xenomai mailing list