Unverified Commit f861c739 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!1727 add support for timer_shutdown() api

Merge Pull Request from: @ci-robot 
 
PR sync from: Yu Liao <liaoyu15@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/N7DVTGONEIVDI2GITMMBE6T4J2YVA4WH/ 
timer_shutdown_sync() function is useful for final teardown of an
infrastructure where the timer is subject to a circular dependency
problem.

A common pattern for this is a timer and a workqueue where the timer can
schedule work and work can arm the timer. On shutdown the workqueue must
be destroyed and the timer must be prevented from rearming. Unless the
code has conditionals like 'if (mything->in_shutdown)' to prevent that
there is no way to get this correct with timer_delete_sync().

timer_shutdown_sync() is solving the problem. The correct ordering of
calls in this case is:

 timer_shutdown_sync(&mything->timer);
 workqueue_destroy(&mything->workqueue);

After this 'mything' can be safely freed.

Steven Rostedt (Google) (3):
  ARM: spear: Do not use timer namespace for timer_shutdown() function
  clocksource/drivers/arm_arch_timer: Do not use timer namespace for
    timer_shutdown() function
  clocksource/drivers/sp804: Do not use timer namespace for
    timer_shutdown() function

Thomas Gleixner (10):
  timers: Get rid of del_singleshot_timer_sync()
  timers: Replace BUG_ON()s
  timers: Update kernel-doc for various functions
  timers: Use del_timer_sync() even on UP
  timers: Rename del_timer_sync() to timer_delete_sync()
  timers: Rename del_timer() to timer_delete()
  timers: Silently ignore timers with a NULL function
  timers: Add shutdown mechanism to the internal functions
  timers: Provide timer_shutdown[_sync]()

Yu Liao (2):
  sw64: Do not use timer namespace for timer_shutdown() function
  timers: Keep del_timer[_sync]() exported


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/I7R8WG 
 
Link:https://gitee.com/openeuler/kernel/pulls/1727

 

Reviewed-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 4199dd39 ec2d781a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ static void __init spear_clocksource_init(void)
		200, 16, clocksource_mmio_readw_up);
}

static inline void timer_shutdown(struct clock_event_device *evt)
static inline void spear_timer_shutdown(struct clock_event_device *evt)
{
	u16 val = readw(gpt_base + CR(CLKEVT));

@@ -104,7 +104,7 @@ static inline void timer_shutdown(struct clock_event_device *evt)

static int spear_shutdown(struct clock_event_device *evt)
{
	timer_shutdown(evt);
	spear_timer_shutdown(evt);

	return 0;
}
@@ -114,7 +114,7 @@ static int spear_set_oneshot(struct clock_event_device *evt)
	u16 val;

	/* stop the timer */
	timer_shutdown(evt);
	spear_timer_shutdown(evt);

	val = readw(gpt_base + CR(CLKEVT));
	val |= CTRL_ONE_SHOT;
@@ -129,7 +129,7 @@ static int spear_set_periodic(struct clock_event_device *evt)
	u16 val;

	/* stop the timer */
	timer_shutdown(evt);
	spear_timer_shutdown(evt);

	period = clk_get_rate(gpt_clk) / HZ;
	period >>= CTRL_PRESCALER16;
+4 −4
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@

static int timer_next_event(unsigned long delta,
		struct clock_event_device *evt);
static int timer_shutdown(struct clock_event_device *evt);
static int sw64_timer_shutdown(struct clock_event_device *evt);
static int timer_set_oneshot(struct clock_event_device *evt);

/*
@@ -23,7 +23,7 @@ static struct clock_event_device timer_clockevent = {
	.features		= CLOCK_EVT_FEAT_ONESHOT,
	.shift			= 20,
	.mult			= 0,
	.set_state_shutdown	= timer_shutdown,
	.set_state_shutdown	= sw64_timer_shutdown,
	.set_state_oneshot	= timer_set_oneshot,
	.set_next_event		= timer_next_event,
	.rating			= 300,
@@ -71,7 +71,7 @@ static int timer_next_event(unsigned long delta,
	return 0;
}

static int timer_shutdown(struct clock_event_device *evt)
static int sw64_timer_shutdown(struct clock_event_device *evt)
{
	wrtimer(0);
	return 0;
@@ -134,7 +134,7 @@ void sw64_timer_interrupt(void)
	if (!evt->event_handler) {
		pr_warn("Spurious local timer interrupt on cpu %d\n",
				smp_processor_id());
		timer_shutdown(evt);
		sw64_timer_shutdown(evt);
		return;
	}

+2 −2
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
out:
	if (!priv->response_length) {
		*off = 0;
		del_singleshot_timer_sync(&priv->user_read_timer);
		del_timer_sync(&priv->user_read_timer);
		flush_work(&priv->timeout_work);
	}
	mutex_unlock(&priv->buffer_mutex);
@@ -263,7 +263,7 @@ __poll_t tpm_common_poll(struct file *file, poll_table *wait)
void tpm_common_release(struct file *file, struct file_priv *priv)
{
	flush_work(&priv->async_work);
	del_singleshot_timer_sync(&priv->user_read_timer);
	del_timer_sync(&priv->user_read_timer);
	flush_work(&priv->timeout_work);
	file->private_data = NULL;
	priv->response_length = 0;
+6 −6
Original line number Diff line number Diff line
@@ -679,7 +679,7 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id)
	return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
}

static __always_inline int timer_shutdown(const int access,
static __always_inline int arch_timer_shutdown(const int access,
					       struct clock_event_device *clk)
{
	unsigned long ctrl;
@@ -693,22 +693,22 @@ static __always_inline int timer_shutdown(const int access,

static int arch_timer_shutdown_virt(struct clock_event_device *clk)
{
	return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
	return arch_timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
}

static int arch_timer_shutdown_phys(struct clock_event_device *clk)
{
	return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
	return arch_timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
}

static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk)
{
	return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
	return arch_timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
}

static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk)
{
	return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
	return arch_timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
}

static __always_inline void set_next_event(const int access, unsigned long evt,
+3 −3
Original line number Diff line number Diff line
@@ -170,14 +170,14 @@ static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static inline void timer_shutdown(struct clock_event_device *evt)
static inline void evt_timer_shutdown(struct clock_event_device *evt)
{
	writel(0, common_clkevt->ctrl);
}

static int sp804_shutdown(struct clock_event_device *evt)
{
	timer_shutdown(evt);
	evt_timer_shutdown(evt);
	return 0;
}

@@ -186,7 +186,7 @@ static int sp804_set_periodic(struct clock_event_device *evt)
	unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE |
			     TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;

	timer_shutdown(evt);
	evt_timer_shutdown(evt);
	writel(common_clkevt->reload, common_clkevt->load);
	writel(ctrl, common_clkevt->ctrl);
	return 0;
Loading