mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
0577fee283
There is no explicit way to know when a switch started via bL_switch_request() is complete. This can lead to unpredictable behaviour when the switcher is controlled by a subsystem which makes dynamic decisions (such as cpufreq). The CPU PM notifier is not really suitable for signalling completion, because the CPU could get suspended and resumed for other, independent reasons while a switch request is in flight. Adding a whole new notifier for this seems excessive, and may tempt people to put heavyweight code on this path. This patch implements a new bL_switch_request_cb() function that allows for a per-request lightweight callback, private between the switcher and the caller of bL_switch_request_cb(). Overlapping switches on a single CPU are considered incorrect if they are requested via bL_switch_request_cb() with a callback (they will lead to an unpredictable final state without explicit external synchronisation to force the requests into a particular order). Queuing requests robustly would be overkill because only one subsystem should be attempting to control the switcher at any time. Overlapping requests of this kind will be failed with -EBUSY to indicate that the second request won't take effect and the completer will never be called for it. bL_switch_request() is retained as a wrapper round the new function, with the old, fire-and-forget semantics. In this case the last request will always win. The request may still be denied if a previous request with a completer is still pending. Signed-off-by: Dave Martin <dave.martin@linaro.org> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
73 lines
2.1 KiB
C
73 lines
2.1 KiB
C
/*
|
|
* arch/arm/include/asm/bL_switcher.h
|
|
*
|
|
* Created by: Nicolas Pitre, April 2012
|
|
* Copyright: (C) 2012-2013 Linaro Limited
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#ifndef ASM_BL_SWITCHER_H
|
|
#define ASM_BL_SWITCHER_H
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/types.h>
|
|
|
|
typedef void (*bL_switch_completion_handler)(void *cookie);
|
|
|
|
int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id,
|
|
bL_switch_completion_handler completer,
|
|
void *completer_cookie);
|
|
static inline int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id)
|
|
{
|
|
return bL_switch_request_cb(cpu, new_cluster_id, NULL, NULL);
|
|
}
|
|
|
|
/*
|
|
* Register here to be notified about runtime enabling/disabling of
|
|
* the switcher.
|
|
*
|
|
* The notifier chain is called with the switcher activation lock held:
|
|
* the switcher will not be enabled or disabled during callbacks.
|
|
* Callbacks must not call bL_switcher_{get,put}_enabled().
|
|
*/
|
|
#define BL_NOTIFY_PRE_ENABLE 0
|
|
#define BL_NOTIFY_POST_ENABLE 1
|
|
#define BL_NOTIFY_PRE_DISABLE 2
|
|
#define BL_NOTIFY_POST_DISABLE 3
|
|
|
|
#ifdef CONFIG_BL_SWITCHER
|
|
|
|
int bL_switcher_register_notifier(struct notifier_block *nb);
|
|
int bL_switcher_unregister_notifier(struct notifier_block *nb);
|
|
|
|
/*
|
|
* Use these functions to temporarily prevent enabling/disabling of
|
|
* the switcher.
|
|
* bL_switcher_get_enabled() returns true if the switcher is currently
|
|
* enabled. Each call to bL_switcher_get_enabled() must be followed
|
|
* by a call to bL_switcher_put_enabled(). These functions are not
|
|
* recursive.
|
|
*/
|
|
bool bL_switcher_get_enabled(void);
|
|
void bL_switcher_put_enabled(void);
|
|
|
|
#else
|
|
static inline int bL_switcher_register_notifier(struct notifier_block *nb)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline bool bL_switcher_get_enabled(void) { return false; }
|
|
static inline void bL_switcher_put_enabled(void) { }
|
|
#endif /* CONFIG_BL_SWITCHER */
|
|
|
|
#endif
|