[PATCH 1/2] perf scripts python: export-to-postgresql.py: Fix DROP VIEW power_events_view
PostgreSQL can error if power_events_view is not dropped before its dependent tables e.g. Exception: Query failed: ERROR: cannot drop table mwait because other objects depend on it DETAIL: view power_events_view depends on table mwait Signed-off-by: Adrian Hunter Fixes: aba44287a224 ("perf scripts python: export-to-postgresql.py: Export Intel PT power and ptwrite events") --- tools/perf/scripts/python/export-to-postgresql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 4447f0d7c754..92713d93e956 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py @@ -898,11 +898,11 @@ def trace_end(): if is_table_empty("ptwrite"): drop("ptwrite") if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): + do_query(query, 'DROP VIEW power_events_view'); drop("mwait") drop("pwre") drop("exstop") drop("pwrx") - do_query(query, 'DROP VIEW power_events_view'); if is_table_empty("cbr"): drop("cbr") -- 2.17.1
[PATCH 2/2] perf scripts python: export-to-sqlite.py: Fix DROP VIEW power_events_view
Drop power_events_view before its dependent tables. SQLite does not seem to mind but the fix was needed for PostgreSQL (export-to-postgresql.py script), so do the same fix for the SQLite. It is more logical and keeps the 2 scripts following the same approach. Signed-off-by: Adrian Hunter Fixes: 5130c6e55531 ("perf scripts python: export-to-sqlite.py: Export Intel PT power and ptwrite events") --- tools/perf/scripts/python/export-to-sqlite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py index 3222a83f4184..021326c46285 100644 --- a/tools/perf/scripts/python/export-to-sqlite.py +++ b/tools/perf/scripts/python/export-to-sqlite.py @@ -608,11 +608,11 @@ def trace_end(): if is_table_empty("ptwrite"): drop("ptwrite") if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): + do_query(query, 'DROP VIEW power_events_view'); drop("mwait") drop("pwre") drop("exstop") drop("pwrx") - do_query(query, 'DROP VIEW power_events_view'); if is_table_empty("cbr"): drop("cbr") -- 2.17.1
[PATCH 0/2] perf scripts python: export-to-postgresql/sqlite.py: Fix DROP VIEW power_events_view
Hi Here is a small fix to the export-to-postgresql.py script. The export-to-sqlite.py script had the same issue but SQLite did not seem to mind. However I made the fix anyway for good measure. Adrian Hunter (2): perf scripts python: export-to-postgresql.py: Fix DROP VIEW power_events_view perf scripts python: export-to-sqlite.py: Fix DROP VIEW power_events_view tools/perf/scripts/python/export-to-postgresql.py | 2 +- tools/perf/scripts/python/export-to-sqlite.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) Regards Adrian
[PATCH v2] gpiolib: fix incorrect IRQ requesting of an active-low lineevent
When a pin is active-low, logical trigger edge should be inverted to match the same interrupt opportunity. For example, a button pushed triggers falling edge in ACTIVE_HIGH case; in ACTIVE_LOW case, the button pushed triggers rising edge. For user space the IRQ requesting doesn't need to do any modification except to configuring GPIOHANDLE_REQUEST_ACTIVE_LOW. For example, we want to catch the event when the button is pushed. The button on the original board drives level to be low when it is pushed, and drives level to be high when it is released. In user space we can do: req.handleflags = GPIOHANDLE_REQUEST_INPUT; req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; while (1) { read(fd, , sizeof(dat)); if (dat.id == GPIOEVENT_EVENT_FALLING_EDGE) printf("button pushed\n"); } Run the same logic on another board which the polarity of the button is inverted; it drives level to be high when pushed, and level to be low when released. For this inversion we add flag GPIOHANDLE_REQUEST_ACTIVE_LOW: req.handleflags = GPIOHANDLE_REQUEST_INPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW; req.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; At the result, there are no any events caught when the button is pushed. By the way, button releasing will emit a "falling" event. The timing of "falling" catching is not expected. Cc: sta...@vger.kernel.org Signed-off-by: Michael Wu --- Changes from v1: - Correct undeclared 'IRQ_TRIGGER_RISING' - Add an example to descibe the issue --- drivers/gpio/gpiolib.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e013d417a936..9c9597f929d7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -956,9 +956,11 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) } if (eflags & GPIOEVENT_REQUEST_RISING_EDGE) - irqflags |= IRQF_TRIGGER_RISING; + irqflags |= test_bit(FLAG_ACTIVE_LOW, >flags) ? + IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; if (eflags & GPIOEVENT_REQUEST_FALLING_EDGE) - irqflags |= IRQF_TRIGGER_FALLING; + irqflags |= test_bit(FLAG_ACTIVE_LOW, >flags) ? + IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; irqflags |= IRQF_ONESHOT; INIT_KFIFO(le->events); -- 2.17.1
Re: [PATCH] net: hisilicon: Add an tx_desc to adapt HI13X1_GMAC
From: Jiangfeng Xiao Date: Fri, 5 Jul 2019 14:10:03 +0800 > HI13X1 changed the offsets and bitmaps for tx_desc > registers in the same peripheral device on different > models of the hip04_eth. > > Signed-off-by: Jiangfeng Xiao Applied.
Re: [PATCH net-next] hinic: add fw version query
From: Xue Chaojing Date: Fri, 5 Jul 2019 02:40:28 + > This patch adds firmware version query in ethtool -i. > > Signed-off-by: Xue Chaojing Applied, thank you.
[PATCH 2/2] e1000e: disable force K1-off feature
Forwardport from http://mails.dpdk.org/archives/dev/2016-November/050658.html MAC-PHY desync may occur causing misdetection of link up event. Disabling K1-off feature can work around the problem. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204057 Signed-off-by: Kai-Heng Feng --- drivers/net/ethernet/intel/e1000e/hw.h | 1 + drivers/net/ethernet/intel/e1000e/ich8lan.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index eff75bd8a8f0..e3c71fd093ee 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -662,6 +662,7 @@ struct e1000_dev_spec_ich8lan { bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; bool nvm_k1_enabled; + bool disable_k1_off; bool eee_disable; u16 eee_lp_ability; enum e1000_ulp_state ulp_state; diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 56f88a4e538c..c1e0e03dc5cb 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1538,6 +1538,9 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; } + if (hw->dev_spec.ich8lan.disable_k1_off == true) + fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; + ew32(FEXTNVM6, fextnvm6); } -- 2.17.1
[PATCH 1/2] e1000e: add workaround for possible stalled packet
Forwardport from http://mails.dpdk.org/archives/dev/2016-November/050657.html This works around a possible stalled packet issue, which may occur due to clock recovery from the PCH being too slow, when the LAN is transitioning from K1 at 1G link speed. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204057 Signed-off-by: Kai-Heng Feng --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 10 ++ drivers/net/ethernet/intel/e1000e/ich8lan.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 395b05701480..56f88a4e538c 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1429,6 +1429,16 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) else phy_reg |= 0xFA; e1e_wphy_locked(hw, I217_PLL_CLOCK_GATE_REG, phy_reg); + + if (speed == SPEED_1000) { + hw->phy.ops.read_reg_locked(hw, HV_PM_CTRL, + _reg); + + phy_reg |= HV_PM_CTRL_K1_CLK_REQ; + + hw->phy.ops.write_reg_locked(hw, HV_PM_CTRL, + phy_reg); + } } hw->phy.ops.release(hw); diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index eb09c755fa17..1502895eb45d 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -210,7 +210,7 @@ /* PHY Power Management Control */ #define HV_PM_CTRL PHY_REG(770, 17) -#define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100 +#define HV_PM_CTRL_K1_CLK_REQ 0x200 #define HV_PM_CTRL_K1_ENABLE 0x4000 #define I217_PLL_CLOCK_GATE_REGPHY_REG(772, 28) -- 2.17.1
[RFC 2/2] sched/fair: Optimize the idle CPU search
Optimize idle CPUs search by marking already found non idle CPUs during idle core search. This reduces iteration count when searching for idle CPUs, resulting in the lower iteration count. Signed-off-by: Parth Shah --- kernel/sched/core.c | 3 +++ kernel/sched/fair.c | 13 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d5a6bdc956c8..196e4eaca66e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5951,6 +5951,7 @@ static struct kmem_cache *task_group_cache __read_mostly; DECLARE_PER_CPU(cpumask_var_t, load_balance_mask); DECLARE_PER_CPU(cpumask_var_t, iterator_mask); +DECLARE_PER_CPU(cpumask_var_t, select_idle_mask); void __init sched_init(void) { @@ -5991,6 +5992,8 @@ void __init sched_init(void) cpumask_size(), GFP_KERNEL, cpu_to_node(i)); per_cpu(iterator_mask, i) = (cpumask_var_t)kzalloc_node( cpumask_size(), GFP_KERNEL, cpu_to_node(i)); + per_cpu(select_idle_mask, i) = (cpumask_var_t)kzalloc_node( + cpumask_size(), GFP_KERNEL, cpu_to_node(i)); } #endif /* CONFIG_CPUMASK_OFFSTACK */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 20affe03379d..2b70b94b3e66 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5295,6 +5295,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) /* Working cpumask for: load_balance, load_balance_newidle. */ DEFINE_PER_CPU(cpumask_var_t, load_balance_mask); DEFINE_PER_CPU(cpumask_var_t, iterator_mask); +DEFINE_PER_CPU(cpumask_var_t, select_idle_mask); #ifdef CONFIG_NO_HZ_COMMON /* @@ -6084,6 +6085,7 @@ void __update_idle_core(struct rq *rq) static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int target) { struct cpumask *cpus = this_cpu_cpumask_var_ptr(iterator_mask); + struct cpumask *idle_cpus = this_cpu_cpumask_var_ptr(select_idle_mask); int core, cpu; if (!static_branch_likely(_smt_present)) @@ -6099,8 +6101,10 @@ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int for_each_cpu(cpu, cpu_smt_mask(core)) { __cpumask_clear_cpu(cpu, cpus); - if (!available_idle_cpu(cpu)) + if (!available_idle_cpu(cpu)) { idle = false; + __cpumask_clear_cpu(cpu, idle_cpus); + } } if (idle) @@ -6161,6 +6165,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t u64 time, cost; s64 delta; int cpu, nr = INT_MAX; + struct cpumask *idle_cpus = this_cpu_cpumask_var_ptr(select_idle_mask); this_sd = rcu_dereference(*this_cpu_ptr(_llc)); if (!this_sd) @@ -6186,11 +6191,9 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t time = local_clock(); - for_each_cpu_wrap(cpu, sched_domain_span(sd), target) { + for_each_cpu_wrap(cpu, idle_cpus, target) { if (!--nr) return -1; - if (!cpumask_test_cpu(cpu, >cpus_allowed)) - continue; if (available_idle_cpu(cpu)) break; } @@ -6210,6 +6213,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) { struct sched_domain *sd; int i, recent_used_cpu; + struct cpumask *idle_cpus = this_cpu_cpumask_var_ptr(select_idle_mask); if (available_idle_cpu(target)) return target; @@ -6239,6 +6243,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) if (!sd) return target; + cpumask_and(idle_cpus, sched_domain_span(sd), >cpus_allowed); i = select_idle_core(p, sd, target); if ((unsigned)i < nr_cpumask_bits) return i; -- 2.17.1
[RFC 0/2] Optimize the idle CPU search
When searching for an idle_sibling, scheduler first iterates to search for an idle core and then for an idle CPU. By maintaining the idle CPU mask while iterating through idle cores, we can mark non-idle CPUs for which idle CPU search would not have to iterate through again. This is especially true in a moderately load system Optimize idle CPUs search by marking already found non idle CPUs during idle core search. This reduces iteration count when searching for idle CPUs, resulting in lower iteration count. The results show that the time for `select_idle_cpu` decreases and there is no regression on time search for `select_idle_core` and almost no regression on schbench as well. With proper tuning schbench shows benefit as well when idle_core search fails most times. When doing this, rename locally used cpumask 'select_idle_mask' to something else to use this existing mask for such optimization. Patch set based on tip/core/core Results === IBM POWER9 system: 2-socket, 44 cores, 176 CPUs Function latency (with tb tick): (lower is better) +--+--++-++ | select_idle_ | Baseline | stddev |Patch| stddev | +--+--++-++ | core | 2080 | 1307 | 1975(+5.3%) | 1286 | | cpu | 834 |393 |91(+89%) | 64 | | sibling | 0.96 | 0.003 | 0.89(+7%) | 0.02 | +--+--++-++ Schbench: - schbench -m 44 -t 1 (lower is better) +--+--++++ | %ile | Baseline | stddev | Patch| stddev | +--+--++++ | 50 | 9.9 | 2 | 10(-1.01) |1.4 | | 95 | 465 |3.9 | 465(0%)| 2 | | 99 | 561 | 24 | 483(-1.0%) | 14 | | 99.5 | 631 | 29 | 635(-0.6%) | 32 | | 99.9 | 801 | 41 | 763(+4.7%) |125 | +--+--++++ - 44 threads spread across cores to make select_idle_core return -1 most times - schbench -m 44 -t 1 +---+--++---++ | %ile | Baseline | stddev | patch | stddev | +---+--++---++ |50 | 10 | 9 | 12(-20%) | 1 | |95 | 468 | 3 | 31(+93%) | 1 | |99 | 577 | 16 | 477(+17%) | 38 | | 99.95 | 647 | 26 | 482(+25%) | 2 | | 99.99 | 835 | 61 | 492(+41%) | 2 | +---+--++---++ Hackbench: - 44 threads spread across cores to make select_idle_core return -1 most times - perf bench sched messaging -g 1 -l 10 (lower is better) +--++--++ | Baseline | stddev |patch | stddev | +--++--++ | 16.107 | 0.62 | 16.02(+0.5%) | 0.32 | +--++--++ Series: - Patch 01: Rename select_idle_mask to reuse the name in next patch - Patch 02: Optimize the wakeup fast path Parth Shah (2): sched/fair: Rename select_idle_mask to iterator_mask sched/fair: Optimize idle CPU search kernel/sched/core.c | 3 +++ kernel/sched/fair.c | 15 ++- 2 files changed, 13 insertions(+), 5 deletions(-) -- 2.17.1
[RFC 1/2] sched/fair: Rename select_idle_mask to iterator_mask
Per cpu variable 'select_idle_mask' serves the only purpose of an iterator inside select_idle_core method. Also there is an opportunity to optimize the search for an idle CPU for which this mask is required in the subsequent patch. Hence renaming this per_cpu variable to iterator mask which can be used locally for CPU iteration. Subsequent patch uses the select_idle_mask to keep track of the idle CPUs which can be shared across function calls. Signed-off-by: Parth Shah --- kernel/sched/core.c | 4 ++-- kernel/sched/fair.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4778c48a7fda..d5a6bdc956c8 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5950,7 +5950,7 @@ static struct kmem_cache *task_group_cache __read_mostly; #endif DECLARE_PER_CPU(cpumask_var_t, load_balance_mask); -DECLARE_PER_CPU(cpumask_var_t, select_idle_mask); +DECLARE_PER_CPU(cpumask_var_t, iterator_mask); void __init sched_init(void) { @@ -5989,7 +5989,7 @@ void __init sched_init(void) for_each_possible_cpu(i) { per_cpu(load_balance_mask, i) = (cpumask_var_t)kzalloc_node( cpumask_size(), GFP_KERNEL, cpu_to_node(i)); - per_cpu(select_idle_mask, i) = (cpumask_var_t)kzalloc_node( + per_cpu(iterator_mask, i) = (cpumask_var_t)kzalloc_node( cpumask_size(), GFP_KERNEL, cpu_to_node(i)); } #endif /* CONFIG_CPUMASK_OFFSTACK */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index fdab7eb6f351..20affe03379d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5294,7 +5294,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) /* Working cpumask for: load_balance, load_balance_newidle. */ DEFINE_PER_CPU(cpumask_var_t, load_balance_mask); -DEFINE_PER_CPU(cpumask_var_t, select_idle_mask); +DEFINE_PER_CPU(cpumask_var_t, iterator_mask); #ifdef CONFIG_NO_HZ_COMMON /* @@ -6083,7 +6083,7 @@ void __update_idle_core(struct rq *rq) */ static int select_idle_core(struct task_struct *p, struct sched_domain *sd, int target) { - struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask); + struct cpumask *cpus = this_cpu_cpumask_var_ptr(iterator_mask); int core, cpu; if (!static_branch_likely(_smt_present)) -- 2.17.1
RE: linux-next: build failure after merge of the slave-dma tree
On 2019/7/8 12:17 Vinod Koul wrote: > On 08-07-19, 11:06, zhangfei wrote: > > Hi, Robin > > > > On 2019/7/8 上午9:22, Robin Gong wrote: > > > Hi Stephen, > > > That's caused by 'of_irq_count' NOT export to global symbol, and > > > I'm curious why it has been here for so long since Zhangfei found it > > > in 2015. > > I remembered Rob suggested us not using of_irq_count and use > > platform_get_irq etc. > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml > > .org%2Flkml%2F2015%2F11%2F18%2F466data=02%7C01%7Cyibin.go > ng%40nxp > > .com%7Cb6d84a6976d7457dc34408d7035baaf5%7C686ea1d3bc2b4c6fa92 > cd99c5c30 > > > 1635%7C0%7C0%7C636981564557143537sdata=jEgFnB3YNkVtsigfbN6 > XGJojlb > > JAyOi8kiGd5JHJEcM%3Dreserved=0 > > The explanation looks sane to me, so it makes sense to revert the commit for > now. Reverted now Ok, I will send v6 with the fix.
RE: linux-next: build failure after merge of the slave-dma tree
On 2019/7/8 11:06 AM, zhangfei wrote: > Hi, Robin > > On 2019/7/8 上午9:22, Robin Gong wrote: > > Hi Stephen, > > That's caused by 'of_irq_count' NOT export to global symbol, and I'm > > curious why it has been here for so long since Zhangfei found it in > > 2015. > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc > > > hwork.kernel.org%2Fpatch%2F7404681%2Fdata=02%7C01%7Cyibin.gon > g%40 > > > nxp.com%7C5917e41babe84d562d4708d703514ed8%7C686ea1d3bc2b4c6fa > 92cd99c5 > > > c301635%7C0%7C0%7C636981520060417930sdata=QwPjifxeCEJmlrk0 > 2Ne71Bb > > hSgsZNLLgx7PnO81MHmA%3Dreserved=0 > > Hi Rob, > > Is there something I miss so that Zhangfei's patch not accepted finally? > > > > > > I remembered Rob suggested us not using of_irq_count and use > platform_get_irq etc. > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.org > %2Flkml%2F2015%2F11%2F18%2F466data=02%7C01%7Cyibin.gong%4 > 0nxp.com%7C5917e41babe84d562d4708d703514ed8%7C686ea1d3bc2b4c6f > a92cd99c5c301635%7C0%7C0%7C636981520060417930sdata=g2mNB > 33%2Ba09JIpXot6j0w%2FV30grSVCt1GxZJCHyEgiM%3Dreserved=0 > > So we remove of_irq_count > commit 8c77dca011125b795bfa1c86f85a80132feee578 > Author: John Garry > Date: Thu Nov 19 20:23:59 2015 +0800 > > hisi_sas: Remove dependency on of_irq_count > > Thanks Thank Fei for your kind information:)
Re: [RFC 1/2] arm64/mm: Change THP helpers to comply with generic MM semantics
On 07/03/2019 11:22 PM, Catalin Marinas wrote: > On Tue, Jul 02, 2019 at 09:07:28AM +0530, Anshuman Khandual wrote: >> On 06/28/2019 03:50 PM, Catalin Marinas wrote: >>> On Thu, Jun 27, 2019 at 06:18:15PM +0530, Anshuman Khandual wrote: pmd_present() and pmd_trans_huge() are expected to behave in the following manner during various phases of a given PMD. It is derived from a previous detailed discussion on this topic [1] and present THP documentation [2]. pmd_present(pmd): - Returns true if pmd refers to system RAM with a valid pmd_page(pmd) - Returns false if pmd does not refer to system RAM - Invalid pmd_page(pmd) pmd_trans_huge(pmd): - Returns true if pmd refers to system RAM and is a trans huge mapping > [...] >>> Before we actually start fixing this, I would strongly suggest that you >>> add a boot selftest (see lib/Kconfig.debug for other similar cases) >>> which checks the consistency of the page table macros w.r.t. the >>> expected mm semantics. Once the mm maintainers agreed with the >>> semantics, it will really help architecture maintainers in implementing >>> them correctly. >> >> Sure and it will help all architectures to be in sync wrt semantics. >> >>> You wouldn't need actual page tables, just things like assertions on >>> pmd_trans_huge(pmd_mkhuge(pmd)) == true. You could go further and have >>> checks on pmdp_invalidate(_vma, dummy_addr, _pmd) with the >>> dummy_* variables on the stack. >> >> Hmm. I guess macros which operate directly on a page table entry will be >> okay but the ones which check on specific states for VMA or MM might be >> bit tricky. Try to emulate VMA/MM states while on stack ?. But sure, will >> explore adding such a test. > > You can pretend that the page table is on the stack. See the _pmd > variable in do_huge_pmd_wp_page_fallback() and > __split_huge_zero_page_pmd(). Similarly, the vma and even the mm can be > faked on the stack (see the arm64 tlb_flush()). Sure will explore them and other similar examples. I am already working on a module which will test various architecture page table accessors semantics as expected from generic MM. This should help us making sure that all architectures are on same page. > The problem: PMD is first invalidated with pmdp_invalidate() before it's splitting. This invalidation clears PMD_SECT_VALID as below. PMD Split -> pmdp_invalidate() -> pmd_mknotpresent -> Clears PMD_SECT_VALID Once PMD_SECT_VALID gets cleared, it results in pmd_present() return false on the PMD entry. >>> >>> I think that's an inconsistency in the expected semantics here. Do you >>> mean that pmd_present(pmd_mknotpresent(pmd)) should be true? If not, do > [...] >> pmd_present() and pmd_mknotpresent() are not exact inverse. > > I find this very confusing (not your fault, just the semantics expected > by the core code). I can see that x86 is using _PAGE_PSE to make > pmd_present(pmd_mknotpresent()) == true. However, for pud that's not the > case (because it's not used for transhuge). > > I'd rather have this renamed to pmd_mknotvalid(). Right, it makes sense to do the renaming even without considering this proposal. > >> In absence of a positive section mapping bit on arm64, PTE_SPECIAL is being >> set >> temporarily to remember that it was a mapped PMD which got invalidated >> recently >> but which still points to memory. Hence pmd_present() must evaluate true. > > I wonder if we can encode this safely for arm64 in the bottom two bits > of a pmd : > > 0b00 - not valid, not present > 0b10 - not valid, present, huge > 0b01 - valid, present, huge > 0b11 - valid, table (not huge) > > Do we ever call pmdp_invalidate() on a table entry? I don't think we do. > > So a pte_mknotvalid would set bit 1 and I think swp_entry_to_pmd() would > have to clear it so that pmd_present() actually returns false for a swp > pmd entry. All these makes it riskier for collision with other core MM paths as compared to using a an isolated SW bit like PTE_SPECIAL exclusively for this purpose. This is in line with using PTE_PROTNONE. PTE_SPECIAL seems to be well away from core PMD path. Is there any particular concern about using PTE_SPECIAL ? Nonetheless I will evaluate above proposal of using (0b10) to represent invalid but present huge PMD entry during splitting. > >>> we need to implement our own pmdp_invalidate() or change the generic one >>> to set a "special" bit instead of just a pmd_mknotpresent? >> >> Though arm64 can subscribe __HAVE_ARCH_PMDP_INVALIDATE and implement it's own >> pmdp_invalidate() in order to not call pmd_mknotpresent() and instead operate >> on the invalid and special bits directly. But its not going to alter relevant >> semantics here. AFAICS it might be bit better as it saves pmd_mknotpresent() >> from putting in that special bit in there which it is not supposed do. >> >> IFAICS there is no compelling reason for generic
[RFC PATCH linux-next] mfd: bd70528: bit0_offsets[] can be static
Fixes: 21b7c58fc194 ("mfd: bd70528: Support ROHM bd70528 PMIC core") Signed-off-by: kbuild test robot --- rohm-bd70528.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/rohm-bd70528.c b/drivers/mfd/rohm-bd70528.c index 55599d5..43c859f 100644 --- a/drivers/mfd/rohm-bd70528.c +++ b/drivers/mfd/rohm-bd70528.c @@ -106,14 +106,14 @@ static struct regmap_config bd70528_regmap = { */ /* bit [0] - Shutdown register */ -unsigned int bit0_offsets[] = {0}; /* Shutdown register */ -unsigned int bit1_offsets[] = {1}; /* Power failure register */ -unsigned int bit2_offsets[] = {2}; /* VR FAULT register */ -unsigned int bit3_offsets[] = {3}; /* PMU register interrupts */ -unsigned int bit4_offsets[] = {4, 5}; /* Charger 1 and Charger 2 registers */ -unsigned int bit5_offsets[] = {6}; /* RTC register */ -unsigned int bit6_offsets[] = {7}; /* GPIO register */ -unsigned int bit7_offsets[] = {8}; /* Invalid operation register */ +static unsigned int bit0_offsets[] = {0}; /* Shutdown register */ +static unsigned int bit1_offsets[] = {1}; /* Power failure register */ +static unsigned int bit2_offsets[] = {2}; /* VR FAULT register */ +static unsigned int bit3_offsets[] = {3}; /* PMU register interrupts */ +static unsigned int bit4_offsets[] = {4, 5}; /* Charger 1 and Charger 2 registers */ +static unsigned int bit5_offsets[] = {6}; /* RTC register */ +static unsigned int bit6_offsets[] = {7}; /* GPIO register */ +static unsigned int bit7_offsets[] = {8}; /* Invalid operation register */ static struct regmap_irq_sub_irq_map bd70528_sub_irq_offsets[] = { REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
[linux-next:master 9908/12641] drivers/mfd/rohm-bd70528.c:109:14: sparse: sparse: symbol 'bit0_offsets' was not declared. Should it be static?
tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/next/linux-next.git master head: 22c45ec32b4a9fa8c48ef4f5bf9b189b307aae12 commit: 21b7c58fc1943f3aa8c18a994ab9bed4ae5aa72d [9908/12641] mfd: bd70528: Support ROHM bd70528 PMIC core reproduce: # apt-get install sparse # sparse version: v0.6.1-rc1-7-g2b96cd8-dirty git checkout 21b7c58fc1943f3aa8c18a994ab9bed4ae5aa72d make ARCH=x86_64 allmodconfig make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' If you fix the issue, kindly add following tag Reported-by: kbuild test robot sparse warnings: (new ones prefixed by >>) >> drivers/mfd/rohm-bd70528.c:109:14: sparse: sparse: symbol 'bit0_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:110:14: sparse: sparse: symbol 'bit1_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:111:14: sparse: sparse: symbol 'bit2_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:112:14: sparse: sparse: symbol 'bit3_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:113:14: sparse: sparse: symbol 'bit4_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:114:14: sparse: sparse: symbol 'bit5_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:115:14: sparse: sparse: symbol 'bit6_offsets' was >> not declared. Should it be static? >> drivers/mfd/rohm-bd70528.c:116:14: sparse: sparse: symbol 'bit7_offsets' was >> not declared. Should it be static? Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Re: linux-next: build failure after merge of the slave-dma tree
On 08-07-19, 11:06, zhangfei wrote: > Hi, Robin > > On 2019/7/8 上午9:22, Robin Gong wrote: > > Hi Stephen, > > That's caused by 'of_irq_count' NOT export to global symbol, and I'm > > curious why it has been > > here for so long since Zhangfei found it in 2015. > > https://patchwork.kernel.org/patch/7404681/ > > Hi Rob, > > Is there something I miss so that Zhangfei's patch not accepted finally? > > > > > > I remembered Rob suggested us not using of_irq_count and use > platform_get_irq etc. > https://lkml.org/lkml/2015/11/18/466 The explanation looks sane to me, so it makes sense to revert the commit for now. Reverted now -- >8 -- >From 5c274ca4cfb22a455e880f61536b1894fa29fd17 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 8 Jul 2019 09:42:55 +0530 Subject: [PATCH] dmaengine: Revert "dmaengine: fsl-edma: add i.mx7ulp edma2 version support" This reverts commit 7144afd025b2 ("dmaengine: fsl-edma: add i.mx7ulp edma2 version support") as this fails to build with module option due to usage of of_irq_count() which is not an exported symbol as kernel drivers are *not* expected to use it (rightly so). Signed-off-by: Vinod Koul --- drivers/dma/fsl-edma-common.c | 18 +- drivers/dma/fsl-edma-common.h | 4 --- drivers/dma/fsl-edma.c| 66 --- 3 files changed, 1 insertion(+), 87 deletions(-) diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index 6d6d8a4e8e38..44d92c34dec3 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -90,19 +90,6 @@ static void mux_configure8(struct fsl_edma_chan *fsl_chan, void __iomem *addr, iowrite8(val8, addr + off); } -void mux_configure32(struct fsl_edma_chan *fsl_chan, void __iomem *addr, -u32 off, u32 slot, bool enable) -{ - u32 val; - - if (enable) - val = EDMAMUX_CHCFG_ENBL << 24 | slot; - else - val = EDMAMUX_CHCFG_DIS; - - iowrite32(val, addr + off * 4); -} - void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, unsigned int slot, bool enable) { @@ -116,10 +103,7 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux]; slot = EDMAMUX_CHCFG_SOURCE(slot); - if (fsl_chan->edma->drvdata->version == v3) - mux_configure32(fsl_chan, muxaddr, ch_off, slot, enable); - else - mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); + mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); } EXPORT_SYMBOL_GPL(fsl_edma_chan_mux); diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index 5eaa2902ed39..4e175560292c 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -125,7 +125,6 @@ struct fsl_edma_chan { dma_addr_t dma_dev_addr; u32 dma_dev_size; enum dma_data_direction dma_dir; - charchan_name[16]; }; struct fsl_edma_desc { @@ -140,13 +139,11 @@ struct fsl_edma_desc { enum edma_version { v1, /* 32ch, Vybrid, mpc57x, etc */ v2, /* 64ch Coldfire */ - v3, /* 32ch, i.mx7ulp */ }; struct fsl_edma_drvdata { enum edma_version version; u32 dmamuxs; - boolhas_dmaclk; int (*setup_irq)(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma); }; @@ -156,7 +153,6 @@ struct fsl_edma_engine { void __iomem*membase; void __iomem*muxbase[DMAMUX_NR]; struct clk *muxclk[DMAMUX_NR]; - struct clk *dmaclk; struct mutexfsl_edma_mutex; const struct fsl_edma_drvdata *drvdata; u32 n_chans; diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 50fe196b0c73..e616425acd5f 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -166,50 +166,6 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma return 0; } -static int -fsl_edma2_irq_init(struct platform_device *pdev, - struct fsl_edma_engine *fsl_edma) -{ -- ~Vinod
Re: linux-next: build failure after merge of the slave-dma tree
On 08-07-19, 02:01, Robin Gong wrote: > On 06-07-19, 22:43, Vinod Koul wrote: > > > That's caused by 'of_irq_count' NOT export to global symbol, and I'm > > > curious why it has been here for so long since Zhangfei found it in > > > 2015. > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc > > > > > hwork.kernel.org%2Fpatch%2F7404681%2Fdata=02%7C01%7Cyibin.gon > > g%40 > > > > > nxp.com%7C6172242dfadd4f71c09a08d70220bf6f%7C686ea1d3bc2b4c6fa92 > > cd99c5 > > > > > c301635%7C0%7C0%7C636980211986259586sdata=L8v%2B1o5zfgIAS > > go4qr3pu > > > cQ%2Byox1irANsvRv5ZNLlLM%3Dreserved=0 > > > > Yes this does not seem to be applied, perhaps Rob can explain why. But this > > was > > not exported how did you test it? > I had no such issue because I built in fsl-edma instead of Stephen's config > with building module. But you support it as a module, right? I am inclined to revert the patch now! -- ~Vinod
Re: [PATCH v4 1/2] sched/isolation: Prefer housekeeping cpu in local node
Kindly ping for these two patches, :) On Fri, 28 Jun 2019 at 16:51, Wanpeng Li wrote: > > From: Wanpeng Li > > In real product setup, there will be houseeking cpus in each nodes, it > is prefer to do housekeeping from local node, fallback to global online > cpumask if failed to find houseeking cpu from local node. > > Reviewed-by: Frederic Weisbecker > Reviewed-by: Srikar Dronamraju > Cc: Ingo Molnar > Cc: Peter Zijlstra > Cc: Frederic Weisbecker > Cc: Thomas Gleixner > Cc: Srikar Dronamraju > Signed-off-by: Wanpeng Li > --- > v3 -> v4: > * have a static function for sched_numa_find_closest > * cleanup sched_numa_find_closest comments > v2 -> v3: > * add sched_numa_find_closest comments > v1 -> v2: > * introduce sched_numa_find_closest > > kernel/sched/isolation.c | 12 ++-- > kernel/sched/sched.h | 8 +--- > kernel/sched/topology.c | 20 > 3 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c > index 7b9e1e0..191f751 100644 > --- a/kernel/sched/isolation.c > +++ b/kernel/sched/isolation.c > @@ -16,9 +16,17 @@ static unsigned int housekeeping_flags; > > int housekeeping_any_cpu(enum hk_flags flags) > { > - if (static_branch_unlikely(_overridden)) > - if (housekeeping_flags & flags) > + int cpu; > + > + if (static_branch_unlikely(_overridden)) { > + if (housekeeping_flags & flags) { > + cpu = sched_numa_find_closest(housekeeping_mask, > smp_processor_id()); > + if (cpu < nr_cpu_ids) > + return cpu; > + > return cpumask_any_and(housekeeping_mask, > cpu_online_mask); > + } > + } > return smp_processor_id(); > } > EXPORT_SYMBOL_GPL(housekeeping_any_cpu); > diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index 802b1f3..ec65d90 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -1261,16 +1261,18 @@ enum numa_topology_type { > extern enum numa_topology_type sched_numa_topology_type; > extern int sched_max_numa_distance; > extern bool find_numa_distance(int distance); > -#endif > - > -#ifdef CONFIG_NUMA > extern void sched_init_numa(void); > extern void sched_domains_numa_masks_set(unsigned int cpu); > extern void sched_domains_numa_masks_clear(unsigned int cpu); > +extern int sched_numa_find_closest(const struct cpumask *cpus, int cpu); > #else > static inline void sched_init_numa(void) { } > static inline void sched_domains_numa_masks_set(unsigned int cpu) { } > static inline void sched_domains_numa_masks_clear(unsigned int cpu) { } > +static inline int sched_numa_find_closest(const struct cpumask *cpus, int > cpu) > +{ > + return nr_cpu_ids; > +} > #endif > > #ifdef CONFIG_NUMA_BALANCING > diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c > index f751ce0..4eea2c9 100644 > --- a/kernel/sched/topology.c > +++ b/kernel/sched/topology.c > @@ -1724,6 +1724,26 @@ void sched_domains_numa_masks_clear(unsigned int cpu) > } > } > > +/* > + * sched_numa_find_closest() - given the NUMA topology, find the cpu > + * closest to @cpu from @cpumask. > + * cpumask: cpumask to find a cpu from > + * cpu: cpu to be close to > + * > + * returns: cpu, or nr_cpu_ids when nothing found. > + */ > +int sched_numa_find_closest(const struct cpumask *cpus, int cpu) > +{ > + int i, j = cpu_to_node(cpu); > + > + for (i = 0; i < sched_domains_numa_levels; i++) { > + cpu = cpumask_any_and(cpus, sched_domains_numa_masks[i][j]); > + if (cpu < nr_cpu_ids) > + return cpu; > + } > + return nr_cpu_ids; > +} > + > #endif /* CONFIG_NUMA */ > > static int __sdt_alloc(const struct cpumask *cpu_map) > -- > 2.7.4 >
[PATCH 3/6] irqchip/irq-pruss-intc: Add support for shared and invalid interrupts
The PRUSS INTC has a fixed number of output interrupt lines that are connected to a number of processors or other PRUSS instances or other devices (like DMA) on the SoC. The output interrupt lines 2 through 9 are usually connected to the main ARM host processor and are referred to as host interrupts 0 through 7 from ARM/MPU perspective. All of these 8 host interrupts are not always exclusively connected to the ARM GIC. Some SoCs have some interrupt lines not connected to the ARM GIC at all, while a few others have the interrupt lines connected to multiple processors in which they need to be partitioned as per SoC integration needs. For example, AM437x and 66AK2G SoCs have 2 PRUSS instances each and have the host interrupt 5 connected to the other PRUSS, while AM335x has host interrupt 0 shared between MPU and TSC_ADC and host interrupts 6 & 7 shared between MPU and a DMA controller. Add support to the PRUSS INTC driver to allow both these shared and invalid interrupts by not returning a failure if any of these interrupts are skipped from the corresponding INTC DT node. Signed-off-by: Suman Anna --- drivers/irqchip/irq-pruss-intc.c | 44 +++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index d62186ad1be4..142d01b434e0 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -68,6 +68,8 @@ * @domain: irq domain for this interrupt controller * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled + * @shared_intr: bit-map denoting if the MPU host interrupt is shared + * @invalid_intr: bit-map denoting if host interrupt is connected to MPU */ struct pruss_intc { unsigned int irqs[MAX_NUM_HOST_IRQS]; @@ -76,6 +78,8 @@ struct pruss_intc { struct irq_domain *domain; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; + u16 shared_intr; + u16 invalid_intr; }; static inline u32 pruss_intc_read_reg(struct pruss_intc *intc, unsigned int reg) @@ -243,7 +247,8 @@ static int pruss_intc_probe(struct platform_device *pdev) struct pruss_intc *intc; struct resource *res; struct irq_chip *irqchip; - int i, irq; + int i, irq, count; + u8 temp_intr[MAX_NUM_HOST_IRQS] = { 0 }; intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL); if (!intc) @@ -260,6 +265,39 @@ static int pruss_intc_probe(struct platform_device *pdev) dev_dbg(dev, "intc memory: pa %pa size 0x%zx va %pK\n", >start, (size_t)resource_size(res), intc->base); + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-reserved", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + if (count < 0 && count != -EINVAL) + return count; + count = (count == -EINVAL ? 0 : count); + for (i = 0; i < count; i++) { + if (temp_intr[i] < MAX_NUM_HOST_IRQS) { + intc->invalid_intr |= BIT(temp_intr[i]); + } else { + dev_warn(dev, "ignoring invalid reserved irq %d\n", +temp_intr[i]); + } + temp_intr[i] = 0; + } + + count = of_property_read_variable_u8_array(dev->of_node, + "ti,irqs-shared", + temp_intr, 0, + MAX_NUM_HOST_IRQS); + if (count < 0 && count != -EINVAL) + return count; + count = (count == -EINVAL ? 0 : count); + for (i = 0; i < count; i++) { + if (temp_intr[i] < MAX_NUM_HOST_IRQS) { + intc->shared_intr |= BIT(temp_intr[i]); + } else { + dev_warn(dev, "ignoring invalid reserved irq %d\n", +temp_intr[i]); + } + } + mutex_init(>lock); pruss_intc_init(intc); @@ -286,6 +324,10 @@ static int pruss_intc_probe(struct platform_device *pdev) for (i = 0; i < MAX_NUM_HOST_IRQS; i++) { irq = platform_get_irq_byname(pdev, irq_names[i]); if (irq < 0) { + if (intc->shared_intr & BIT(i) || + intc->invalid_intr & BIT(i)) + continue; + dev_err(dev->parent, "platform_get_irq_byname failed for %s : %d\n", irq_names[i], irq); goto fail_irq; -- 2.22.0
[PATCH 1/6] dt-bindings: irqchip: Add PRUSS interrupt controller bindings
The Programmable Real-Time Unit Subsystem (PRUSS) contains an interrupt controller (INTC) that can handle various system input events and post interrupts back to the device-level initiators. The INTC can support upto 64 input events on most SoCs with individual control configuration and hardware prioritization. These events are mapped onto 10 interrupt lines through two levels of many-to-one mapping support. Different interrupt lines are routed to the individual PRU cores or to the host CPU or to other PRUSS instances. The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP, commonly called ICSSG. The ICSSG interrupt controller on K3 SoCs provide a higher number of host interrupts (20 vs 10) and can handle an increased number of input events (160 vs 64) from various SoC interrupt sources. Add the bindings document for these interrupt controllers on all the applicable SoCs. It covers the OMAP architecture SoCs - AM33xx, AM437x and AM57xx; the Keystone 2 architecture based 66AK2G SoC; the Davinci architecture based OMAPL138 SoCs, and the K3 architecture based AM65x and J721E SoCs. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros --- Prior version: https://patchwork.kernel.org/patch/10795771/ .../interrupt-controller/ti,pruss-intc.txt| 92 +++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt new file mode 100644 index ..020073c07a92 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt @@ -0,0 +1,92 @@ +PRU ICSS INTC on TI SoCs + + +Each PRUSS has a single interrupt controller instance that is common to both +the PRU cores. Most interrupt controllers can route 64 input events which are +then mapped to 10 possible output interrupts through two levels of mapping. +The input events can be triggered by either the PRUs and/or various other +PRUSS internal and external peripherals. The first 2 output interrupts are +fed exclusively to the internal PRU cores, with the remaining 8 (2 through 9) +connected to external interrupt controllers including the MPU and/or other +PRUSS instances, DSPs or devices. + +The K3 family of SoCs can handle 160 input events that can be mapped to 20 +different possible output interrupts. The additional output interrupts (10 +through 19) are connected to new sub-modules within the ICSSG instances. + +This interrupt-controller node should be defined as a child node of the +corresponding PRUSS node. The node should be named "interrupt-controller". +Please see the overall PRUSS bindings document for additional details +including a complete example, +Documentation/devicetree/bindings/soc/ti/ti,pruss.txt + +Required Properties: + +- compatible : should be one of the following, + "ti,pruss-intc" for OMAP-L13x/AM18x/DA850 SoCs, + AM335x family of SoCs, + AM437x family of SoCs, + AM57xx family of SoCs + 66AK2G family of SoCs + "ti,icssg-intc" for K3 AM65x & J721E family of SoCs +- reg : base address and size for the PRUSS INTC sub-module +- interrupts : all the interrupts generated towards the main host + processor in the SoC. The format depends on the + interrupt specifier for the particular SoC's ARM GIC + parent interrupt controller. A shared interrupt can + be skipped if the desired destination and usage is by + a different processor/device. +- interrupt-names : should use one of the following names for each valid + interrupt connected to ARM GIC, the name should match + the corresponding host interrupt number, + "host0", "host1", "host2", "host3", "host4", + "host5", "host6" or "host7" +- interrupt-controller : mark this node as an interrupt controller +- #interrupt-cells : should be 1. Client users shall use the PRU System + event number (the interrupt source that the client + is interested in) as the value of the interrupts + property in their node + +Optional Properties: + +The following properties are _required_ only for some SoCs. If none of the below +properties are defined, it implies that all the host interrupts 2 through 9 are +connected exclusively to the ARM GIC. +
[PATCH 4/6] irqchip/irq-pruss-intc: Add helper functions to configure internal mapping
The PRUSS INTC receives a number of system input interrupt source events and supports individual control configuration and hardware prioritization. These input events can be mapped to some output host interrupts through 2 levels of many-to-one mapping i.e. events to channel mapping and channels to host interrupts. This mapping information is provided through the PRU firmware that is loaded onto a PRU core/s or through the device tree node of the PRU application. The mapping is configured by the PRU remoteproc driver, and is setup before the PRU core is started and cleaned up after the PRU core is stopped. This event mapping configuration logic is optimized to program the Channel Map Registers (CMRx) and Host-Interrupt Map Registers (HMRx) only when a new program is being loaded/started and simply disables the same events and interrupt channels without zeroing out the corresponding map registers when stopping a PRU. Add two helper functions: pruss_intc_configure() & pruss_intc_unconfigure() that the PRU remoteproc driver can use to configure the PRUSS INTC. Signed-off-by: Suman Anna Signed-off-by: Andrew F. Davis Signed-off-by: Roger Quadros --- drivers/irqchip/irq-pruss-intc.c | 258 - include/linux/irqchip/irq-pruss-intc.h | 33 2 files changed, 289 insertions(+), 2 deletions(-) create mode 100644 include/linux/irqchip/irq-pruss-intc.h diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 142d01b434e0..8118c2a2ac43 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -24,8 +25,8 @@ /* minimum starting host interrupt number for MPU */ #define MIN_PRU_HOST_INT 2 -/* maximum number of system events */ -#define MAX_PRU_SYS_EVENTS 64 +/* maximum number of host interrupts */ +#define MAX_PRU_HOST_INT 10 /* PRU_ICSS_INTC registers */ #define PRU_INTC_REVID 0x @@ -57,15 +58,29 @@ #define PRU_INTC_HINLR(x) (0x1100 + (x) * 4) #define PRU_INTC_HIER 0x1500 +/* CMR register bit-field macros */ +#define CMR_EVT_MAP_MASK 0xf +#define CMR_EVT_MAP_BITS 8 +#define CMR_EVT_PER_REG4 + +/* HMR register bit-field macros */ +#define HMR_CH_MAP_MASK0xf +#define HMR_CH_MAP_BITS8 +#define HMR_CH_PER_REG 4 + /* HIPIR register bit-fields */ #define INTC_HIPIR_NONE_HINT 0x8000 +/* use -1 to mark unassigned events and channels */ +#define FREE -1 + /** * struct pruss_intc - PRUSS interrupt controller structure * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @irqchip: irq chip for this interrupt controller * @domain: irq domain for this interrupt controller + * @config_map: stored INTC configuration mapping data * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled * @shared_intr: bit-map denoting if the MPU host interrupt is shared @@ -76,6 +91,7 @@ struct pruss_intc { void __iomem *base; struct irq_chip *irqchip; struct irq_domain *domain; + struct pruss_intc_config config_map; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; u16 shared_intr; @@ -107,6 +123,238 @@ static int pruss_intc_check_write(struct pruss_intc *intc, unsigned int reg, return 0; } +static struct pruss_intc *to_pruss_intc(struct device *pru_dev) +{ + struct device_node *np; + struct platform_device *pdev; + struct device *pruss_dev = pru_dev->parent; + struct pruss_intc *intc = ERR_PTR(-ENODEV); + + np = of_get_child_by_name(pruss_dev->of_node, "interrupt-controller"); + if (!np) { + dev_err(pruss_dev, "pruss does not have an interrupt-controller node\n"); + return intc; + } + + pdev = of_find_device_by_node(np); + if (!pdev) { + dev_err(pruss_dev, "no associated platform device\n"); + goto out; + } + + intc = platform_get_drvdata(pdev); + if (!intc) { + dev_err(pruss_dev, "pruss intc device probe failed?\n"); + intc = ERR_PTR(-EINVAL); + } + +out: + of_node_put(np); + return intc; +} + +/** + * pruss_intc_configure() - configure the PRUSS INTC + * @dev: pru device pointer + * @intc_config: PRU core-specific INTC configuration + * + * Configures the PRUSS INTC with the provided configuration from + * a PRU core. Any existing event to channel mappings or channel to + * host interrupt mappings are checked to make sure there are no + * conflicting configuration between both the PRU cores. The function + * is intended to be used only by the PRU remoteproc driver. + * + * Returns 0 on success, or a suitable error code otherwise + */ +int
[PATCH 5/6] irqchip/irq-pruss-intc: Add API to trigger a PRU sysevent
From: "Andrew F. Davis" The PRUSS INTC can generate an interrupt to various processor subsystems on the SoC through a set of 64 possible PRU system events. These system events can be used by PRU client drivers or applications for event notifications/signalling between PRUs and MPU or other processors. A new API, pruss_intc_trigger() is provided to MPU-side PRU client drivers/applications to be able to trigger an event/interrupt using IRQ numbers provided by the PRUSS-INTC irqdomain chip. Signed-off-by: Andrew F. Davis Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- drivers/irqchip/irq-pruss-intc.c | 31 +++ include/linux/pruss_intc.h | 26 ++ 2 files changed, 57 insertions(+) create mode 100644 include/linux/pruss_intc.h diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index 8118c2a2ac43..a0ad50b95cd5 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -421,6 +421,37 @@ static void pruss_intc_irq_relres(struct irq_data *data) module_put(THIS_MODULE); } +/** + * pruss_intc_trigger() - trigger a PRU system event + * @irq: linux IRQ number associated with a PRU system event + * + * Trigger an interrupt by signalling a specific PRU system event. + * This can be used by PRUSS client users to raise/send an event to + * a PRU or any other core that is listening on the host interrupt + * mapped to that specific PRU system event. The @irq variable is the + * Linux IRQ number associated with a specific PRU system event that + * a client user/application uses. The interrupt mappings for this is + * provided by the PRUSS INTC irqchip instance. + * + * Returns 0 on success, or an error value upon failure. + */ +int pruss_intc_trigger(unsigned int irq) +{ + struct irq_desc *desc; + + if (irq <= 0) + return -EINVAL; + + desc = irq_to_desc(irq); + if (!desc) + return -EINVAL; + + pruss_intc_irq_retrigger(>irq_data); + + return 0; +} +EXPORT_SYMBOL_GPL(pruss_intc_trigger); + static int pruss_intc_irq_domain_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw) { diff --git a/include/linux/pruss_intc.h b/include/linux/pruss_intc.h new file mode 100644 index ..84aa7f7edf42 --- /dev/null +++ b/include/linux/pruss_intc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/** + * TI PRU-ICSS Subsystem user interfaces + * + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com + * Andrew F. Davis + * Suman Anna + */ + +#ifndef __LINUX_PRUSS_INTC_H +#define __LINUX_PRUSS_INTC_H + +#if IS_ENABLED(CONFIG_TI_PRUSS_INTC) + +int pruss_intc_trigger(unsigned int irq); + +#else + +static inline int pruss_intc_trigger(unsigned int irq) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_TI_PRUSS_INTC */ + +#endif /* __LINUX_PRUSS_INTC_H */ -- 2.22.0
[PATCH 2/6] irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts
From: "Andrew F. Davis" The Programmable Real-Time Unit Subsystem (PRUSS) contains a local interrupt controller (INTC) that can handle various system input events and post interrupts back to the device-level initiators. The INTC can support upto 64 input events with individual control configuration and hardware prioritization. These events are mapped onto 10 output interrupt lines through two levels of many-to-one mapping support. Different interrupt lines are routed to the individual PRU cores or to the host CPU, or to other devices on the SoC. Some of these events are sourced from peripherals or other sub-modules within that PRUSS, while a few others are sourced from SoC-level peripherals/devices. The PRUSS INTC platform driver manages this PRUSS interrupt controller and implements an irqchip driver to provide a Linux standard way for the PRU client users to enable/disable/ack/re-trigger a PRUSS system event. The system events to interrupt channels and host interrupts relies on the mapping configuration provided either through the PRU firmware blob or via the PRU application's device tree node. The mappings will be programmed during the boot/shutdown of a PRU core. The PRUSS INTC module is reference counted during the interrupt setup phase through the irqchip's irq_request_resources() and irq_release_resources() ops. This restricts the module from being removed as long as there are active interrupt users. The driver currently supports and can be built for OMAP architecture based AM335x, AM437x and AM57xx SoCs; Keystone2 architecture based 66AK2G SoCs and Davinci architecture based OMAP-L13x/AM18x/DA850 SoCs. All of these SoCs support 64 system events, 10 interrupt channels and 10 output interrupt lines per PRUSS INTC with a few SoC integration differences. NOTE: Each PRU-ICSS's INTC on AM57xx SoCs is preceded by a Crossbar that enables multiple external events to be routed to a specific number of input interrupt events. Any non-default external interrupt event directed towards PRUSS needs this crossbar to be setup properly. Signed-off-by: Andrew F. Davis Signed-off-by: Suman Anna Signed-off-by: Roger Quadros --- Prior version: https://patchwork.kernel.org/patch/10795761/ drivers/irqchip/Kconfig | 10 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-pruss-intc.c | 352 +++ 3 files changed, 363 insertions(+) create mode 100644 drivers/irqchip/irq-pruss-intc.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 659c5e0fb835..b0a9479d527c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -447,6 +447,16 @@ config TI_SCI_INTA_IRQCHIP If you wish to use interrupt aggregator irq resources managed by the TI System Controller, say Y here. Otherwise, say N. +config TI_PRUSS_INTC + tristate "TI PRU-ICSS Interrupt Controller" + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM437X || SOC_DRA7XX || ARCH_KEYSTONE + select IRQ_DOMAIN + help + This enables support for the PRU-ICSS Local Interrupt Controller + present within a PRU-ICSS subsystem present on various TI SoCs. + The PRUSS INTC enables various interrupts to be routed to multiple + different processors within the SoC. + endmenu config SIFIVE_PLIC diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 606a003a..717f1d49e549 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -100,3 +100,4 @@ obj-$(CONFIG_MADERA_IRQ)+= irq-madera.o obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o +obj-$(CONFIG_TI_PRUSS_INTC)+= irq-pruss-intc.o diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c new file mode 100644 index ..d62186ad1be4 --- /dev/null +++ b/drivers/irqchip/irq-pruss-intc.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PRU-ICSS INTC IRQChip driver for various TI SoCs + * + * Copyright (C) 2016-2019 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * Suman Anna + */ + +#include +#include +#include +#include +#include +#include + +/* + * Number of host interrupts reaching the main MPU sub-system. Note that this + * is not the same as the total number of host interrupts supported by the PRUSS + * INTC instance + */ +#define MAX_NUM_HOST_IRQS 8 + +/* minimum starting host interrupt number for MPU */ +#define MIN_PRU_HOST_INT 2 + +/* maximum number of system events */ +#define MAX_PRU_SYS_EVENTS 64 + +/* PRU_ICSS_INTC registers */ +#define PRU_INTC_REVID 0x +#define PRU_INTC_CR0x0004 +#define PRU_INTC_GER 0x0010 +#define PRU_INTC_GNLR 0x001c +#define PRU_INTC_SISR 0x0020 +#define PRU_INTC_SICR 0x0024 +#define PRU_INTC_EISR
[PATCH 0/6] Add TI PRUSS Local Interrupt Controller IRQChip driver
Hi All, The following series adds an IRQChip driver for the local interrupt controller present within a Programmable Real-Time Unit and Industrial Communication Subsystem (PRU-ICSS) present on a number of TI SoCs including OMAP architecture based AM335x, AM437x, AM57xx SoCs, Keystone 2 architecture based 66AK2G SoCs, Davinci architecture based OMAP-L138/DA850 SoCs and the latest K3 architecture based AM65x and J721E SoCs. This series splits out the INTC portions into a separate stand-alone series from the previous PRUSS support patch series [1] as requested by various maintainers. Patches are on top of latest master. The PRUSS local INTC is a unique interrupt controller designed to map a number of SoC-level device or internal PRUSS interrupt sources into a smaller set of output interrupt lines that are connected to various SoC-level processors like the host ARM, PRU cores themselves and optionally to some DSPs, other PRUSS, DMA controllers etc. The following are some of the features: - Capture of 64 (160 on K3) System Events/input interrupt sources - Multiplexing of these system events onto 10 (20 on K3) output interrupt channels in a many-to-one fashion - Multiplexing of the output interrupt channels onto 10 (20 on K3) host interrupts split between multiple processors. Typical integration connects the first 2 host interrupts to PRU cores, and the next 8 host interrupts to ARM cores. - Independent enable and disable of system events and their mapping onto a channel - Independent enable and disable of host events and the mapping to host events per interrupt channel. - Inherent hardward prioritization of events and channels (lower number indicates higher priority). - Additional input interrupt sources multiplexing using either a SoC-level CFG MMR or PRUSS CFG MMR (support will be added through PRU rproc client bindings). More details can be found in any of the supported SoC TRMs. Eg: Chapter 30.1.6 of AM5728 TRM [2] Changes from previous series include: - Update bindings to move away from SoC-specific compatibles - Use new DT properties to add support for shared and exclusive ARM GIC interrupt lines - Include support for Davinci OMAP-L138 and K3 AM65x & J721E SoCs - Split up the driver patch into granular incremental support patches regards Suman [1] https://patchwork.kernel.org/cover/10795721/ [2] http://www.ti.com/lit/pdf/spruhz6 Andrew F. Davis (2): irqchip/irq-pruss-intc: Add a PRUSS irqchip driver for PRUSS interrupts irqchip/irq-pruss-intc: Add API to trigger a PRU sysevent Suman Anna (4): dt-bindings: irqchip: Add PRUSS interrupt controller bindings irqchip/irq-pruss-intc: Add support for shared and invalid interrupts irqchip/irq-pruss-intc: Add helper functions to configure internal mapping irqchip/irq-pruss-intc: Add support for ICSSG INTC on K3 SoCs .../interrupt-controller/ti,pruss-intc.txt| 92 +++ drivers/irqchip/Kconfig | 10 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-pruss-intc.c | 749 ++ include/linux/irqchip/irq-pruss-intc.h| 33 + include/linux/pruss_intc.h| 26 + 6 files changed, 911 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.txt create mode 100644 drivers/irqchip/irq-pruss-intc.c create mode 100644 include/linux/irqchip/irq-pruss-intc.h create mode 100644 include/linux/pruss_intc.h -- 2.22.0
[PATCH 6/6] irqchip/irq-pruss-intc: Add support for ICSSG INTC on K3 SoCs
The K3 AM65x and J721E SoCs have the next generation of the PRU-ICSS IP, commonly called ICSSG. The PRUSS INTC present within the ICSSG supports more System Events (160 vs 64), more Interrupt Channels and Host Interrupts (20 vs 10) compared to the previous generation PRUSS INTC instances. The first 2 and the last 10 of these host interrupt lines are used by the PRU and other auxiliary cores and sub-modules within the ICSSG, with 8 host interrupts connected to MPU. The host interrupts 5, 6, 7 are also connected to the other ICSSG instances within the SoC and can be partitioned as per system integration through the board dts files. Enhance the PRUSS INTC driver to add support for this ICSSG INTC instance. This support is added using specific compatible and match data and updating the code to use this data instead of the current hard-coded macros. The INTC config structure is updated to use the higher events and channels on all SoCs, while limiting the actual processing to only the relevant number of events/channels/interrupts. Signed-off-by: Suman Anna --- drivers/irqchip/Kconfig| 2 +- drivers/irqchip/irq-pruss-intc.c | 172 + include/linux/irqchip/irq-pruss-intc.h | 4 +- 3 files changed, 124 insertions(+), 54 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index b0a9479d527c..9f36a6252302 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -449,7 +449,7 @@ config TI_SCI_INTA_IRQCHIP config TI_PRUSS_INTC tristate "TI PRU-ICSS Interrupt Controller" - depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM437X || SOC_DRA7XX || ARCH_KEYSTONE + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM437X || SOC_DRA7XX || ARCH_KEYSTONE || ARCH_K3 select IRQ_DOMAIN help This enables support for the PRU-ICSS Local Interrupt Controller diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c index a0ad50b95cd5..702b1c120b21 100644 --- a/drivers/irqchip/irq-pruss-intc.c +++ b/drivers/irqchip/irq-pruss-intc.c @@ -7,6 +7,7 @@ * Suman Anna */ +#include #include #include #include @@ -25,9 +26,6 @@ /* minimum starting host interrupt number for MPU */ #define MIN_PRU_HOST_INT 2 -/* maximum number of host interrupts */ -#define MAX_PRU_HOST_INT 10 - /* PRU_ICSS_INTC registers */ #define PRU_INTC_REVID 0x #define PRU_INTC_CR0x0004 @@ -40,21 +38,23 @@ #define PRU_INTC_HIEISR0x0034 #define PRU_INTC_HIDISR0x0038 #define PRU_INTC_GPIR 0x0080 +#define PRU_INTC_SRSR(x) (0x0200 + (x) * 4) #define PRU_INTC_SRSR0 0x0200 #define PRU_INTC_SRSR1 0x0204 +#define PRU_INTC_SECR(x) (0x0280 + (x) * 4) #define PRU_INTC_SECR0 0x0280 #define PRU_INTC_SECR1 0x0284 +#define PRU_INTC_ESR(x)(0x0300 + (x) * 4) #define PRU_INTC_ESR0 0x0300 #define PRU_INTC_ESR1 0x0304 +#define PRU_INTC_ECR(x)(0x0380 + (x) * 4) #define PRU_INTC_ECR0 0x0380 #define PRU_INTC_ECR1 0x0384 #define PRU_INTC_CMR(x)(0x0400 + (x) * 4) #define PRU_INTC_HMR(x)(0x0800 + (x) * 4) #define PRU_INTC_HIPIR(x) (0x0900 + (x) * 4) -#define PRU_INTC_SIPR0 0x0d00 -#define PRU_INTC_SIPR1 0x0d04 -#define PRU_INTC_SITR0 0x0d80 -#define PRU_INTC_SITR1 0x0d84 +#define PRU_INTC_SIPR(x) (0x0d00 + (x) * 4) +#define PRU_INTC_SITR(x) (0x0d80 + (x) * 4) #define PRU_INTC_HINLR(x) (0x1100 + (x) * 4) #define PRU_INTC_HIER 0x1500 @@ -74,12 +74,23 @@ /* use -1 to mark unassigned events and channels */ #define FREE -1 +/** + * struct pruss_intc_match_data - match data to handle SoC variations + * @num_system_events: number of input system events handled by the PRUSS INTC + * @num_host_intrs: number of host interrupts supported by the PRUSS INTC + */ +struct pruss_intc_match_data { + u8 num_system_events; + u8 num_host_intrs; +}; + /** * struct pruss_intc - PRUSS interrupt controller structure * @irqs: kernel irq numbers corresponding to PRUSS host interrupts * @base: base virtual address of INTC register space * @irqchip: irq chip for this interrupt controller * @domain: irq domain for this interrupt controller + * @data: cached PRUSS INTC IP configuration data * @config_map: stored INTC configuration mapping data * @lock: mutex to serialize access to INTC * @host_mask: indicate which HOST IRQs are enabled @@ -91,6 +102,7 @@ struct pruss_intc { void __iomem *base; struct irq_chip *irqchip; struct irq_domain *domain; + const struct pruss_intc_match_data *data; struct pruss_intc_config config_map; struct mutex lock; /* PRUSS INTC lock */ u32 host_mask; @@ -115,7 +127,7 @@ static int pruss_intc_check_write(struct pruss_intc
Re: Linux 5.2
Well, thanks a bunch Linus :) On 16:10 Sun 07 Jul , Linus Torvalds wrote: So I was somewhat pre-disposed towards making an rc8, simply because of my travels and being entirely off the internet for a few days last week, and with spotty internet for a few days before that [*]. But there really doesn't seem to be any reason for another rc, since it's been very quiet. Yes, I had a few pull requests since rc7, but they were all small, and I had many more that are for the upcoming merge window. Part of it may be due to the July 4th week, of course, but whatever - I'll take the quiet week as a good sign. So despite a fairly late core revert, I don't see any real reason for another week of rc, and so we have a v5.2 with the normal release timing. There's no particular area that stands out there - the changes are so small that the sppended shortlog really is the best description of last week. A few small random changes all over: drivers, architectures, filesystem, mm, ... So with this, the merge window for 5.2 is open. Linus [*] Courtesy of the Ocean Hunter III in Palau. Because of blurry fish-butt, I don't carry a camera under water any more, but I guess can point you to some of Dirk's highlights: https://hohndel.name/palau-2019 --- Alex Deucher (1): drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE Ard Biesheuvel (1): arm64: kaslr: keep modules inside module region when KASAN is enabled Arnd Bergmann (2): soc: ti: fix irq-ti-sci link error devres: allow const resource arguments Bartosz Golaszewski (3): ARM: davinci: da830-evm: add missing regulator constraints for OHCI ARM: davinci: omapl138-hawk: add missing regulator constraints for OHCI ARM: davinci: da830-evm: fix GPIO lookup for OHCI Boris Brezillon (1): drm/panfrost: Fix a double-free error Cedric Hombourger (1): MIPS: have "plain" make calls build dtbs for selected platforms Chris Wilson (1): drm/i915/ringbuffer: EMIT_INVALIDATE *before* switch context Christian Brauner (1): fork: return proper negative error code Chuck Lever (1): svcrdma: Ignore source port when computing DRC hash Colin Ian King (2): ALSA: usb-audio: fix sign unintended sign extension on left shifts ALSA: seq: fix incorrect order of dest_client/dest_ports arguments Dan Carpenter (1): dmaengine: jz4780: Fix an endian bug in IRQ handler Dennis Wassenberg (1): ALSA: hda/realtek - Change front mic location for Lenovo M710q Dmitry Korotin (1): MIPS: Add missing EHB in mtc0 -> mfc0 sequence. Dmitry Osipenko (1): i2c: tegra: Add Dmitry as a reviewer Eiichi Tsukata (1): tracing/snapshot: Resize spare buffer if size changed Eric Biggers (3): vfs: move_mount: reject moving kernel internal mounts crypto: user - prevent operating on larval algorithms fs/userfaultfd.c: disable irqs for fault_pending and event locks Evan Green (1): ALSA: hda: Fix widget_mutex incomplete protection Evan Quan (1): drm/amd/powerplay: use hardware fan control if no powerplay fan table Frieder Schrempf (1): mtd: spinand: Fix max_bad_eraseblocks_per_lun info in memorg Geert Uytterhoeven (1): fs: VALIDATE_FS_PARSER should default to n Gerd Hoffmann (1): drm/virtio: move drm_connector_update_edid_property() call Greg Kroah-Hartman (1): blk-mq: fix up placement of debugfs directory of queue files Hauke Mehrtens (1): MIPS: Fix bounds check virt_addr_valid Herbert Xu (1): lib/mpi: Fix karactx leak in mpi_powm Jan Kara (1): dax: Fix xarray entry association for mixed mappings Jann Horn (1): ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME Jiri Kosina (1): ftrace/x86: Anotate text_mutex split between ftrace_arch_code_modify_post_process() and ftrace_arch_code_modify_prepare() Joshua Scott (1): ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node Juergen Gross (1): mm/page_alloc.c: fix regression with deferred struct page init Kevin Darbyshire-Bryant (1): MIPS: fix build on non-linux hosts Linus Torvalds (2): Revert "mm: page cache: store only head pages in i_pages" Linux 5.2 Linus Walleij (1): gpio/spi: Fix spi-gpio regression on active high CS Liran Alon (2): KVM: nVMX: Allow restore nested-state to enable eVMCS when vCPU in SMM KVM: nVMX: Change KVM_STATE_NESTED_EVMCS to signal vmcs12 is copied from eVMCS Lucas Stach (1): drm/etnaviv: add missing failure path to destroy suballoc Lyude Paul (1): drm/amdgpu: Don't skip display settings in hwmgr_resume() Matias Karhumaa (1): Bluetooth: Fix faulty expression for minimum encryption key size check Maurizio Lombardi (1): scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported Miquel Raynal (2): Revert "mtd: rawnand: sunxi: Add A23/A33 DMA support" mtd: rawnand: sunxi: Add A23/A33 DMA support with extra MBUS configuration Nathan Chancellor (1):
Re: [PATCH] cpufreq: imx-cpufreq-dt: Add i.MX8MN support
On 08-07-19, 11:03, anson.hu...@nxp.com wrote: > From: Anson Huang > > i.MX8MN is a new SoC of i.MX8M series, it also uses speed > grading and market segment fuses for OPP definitions, add > support for this SoC. > > Signed-off-by: Anson Huang > --- > drivers/cpufreq/imx-cpufreq-dt.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/cpufreq/imx-cpufreq-dt.c > b/drivers/cpufreq/imx-cpufreq-dt.c > index b54fd26..4f85f31 100644 > --- a/drivers/cpufreq/imx-cpufreq-dt.c > +++ b/drivers/cpufreq/imx-cpufreq-dt.c > @@ -44,10 +44,11 @@ static int imx_cpufreq_dt_probe(struct platform_device > *pdev) >* According to datasheet minimum speed grading is not supported for >* consumer parts so clamp to 1 to avoid warning for "no OPPs" >* > - * Applies to 8mq and 8mm. > + * Applies to i.MX8M series SoCs. >*/ > if (mkt_segment == 0 && speed_grade == 0 && ( > of_machine_is_compatible("fsl,imx8mm") || > + of_machine_is_compatible("fsl,imx8mn") || > of_machine_is_compatible("fsl,imx8mq"))) > speed_grade = 1; Acked-by: Viresh Kumar @Rafael: Can you pick this one directly, no point sending another pull request for just one patch. Thanks. -- viresh
linux-next: manual merge of the gfs2 tree with the vfs tree
Hi all, Today's linux-next merge of the gfs2 tree got a conflict in: fs/gfs2/super.c between commit: 000c8e591016 ("gfs2: Convert gfs2 to fs_context") from the vfs tree and commit: 5b3a9f348bc5 ("gfs2: kthread and remount improvements") from the gfs2 tree. I fixed it up (I just used the vfs tree version since it removed some of the code modified by the latter) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell pgpj1DqPGVd1l.pgp Description: OpenPGP digital signature
Re: [GIT PULL] FSI changes for 5.3
On Thu, 4 Jul 2019 at 21:32, Stephen Rothwell wrote: > > Hi Joel, > > On Thu, 4 Jul 2019 06:03:18 + Joel Stanley wrote: > > Stephen, can you swap out ben's fsi tree in linux-next for this one: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/joel/fsi.git > > > > Branch is 'next'. > > There is no "next" branch in that tree, so for now I have used the > master branch. I have replaced Ben with you and Jeremy as contacts. Thanks. There is a next branch now, please take that instead. Cheers, Joel
Re: [PATCH] powerpc/hw_breakpoint: move instruction stepping out of hw_breakpoint_handler()
On 7/6/19 1:56 PM, Christophe Leroy wrote: > > > Le 03/07/2019 à 08:20, Ravi Bangoria a écrit : >> >> >> On 6/28/19 9:25 PM, Christophe Leroy wrote: >>> On 8xx, breakpoints stop after executing the instruction, so >>> stepping/emulation is not needed. Move it into a sub-function and >>> remove the #ifdefs. >>> >>> Signed-off-by: Christophe Leroy >>> --- >> >> Reviewed-by: Ravi Bangoria >> >> Just one neat below... > > Thanks for the review. > >> >> [...] >> >>> -#ifndef CONFIG_PPC_8xx >>> - /* Do not emulate user-space instructions, instead single-step them */ >>> - if (user_mode(regs)) { >>> - current->thread.last_hit_ubp = bp; >>> - regs->msr |= MSR_SE; >>> + if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, >>> info->address)) >> >> May be split this line. It's 86 chars long and checkpatch.pl is warning >> about this: > > Didn't you use arch/powerpc/tools/checkpatch.sh ? > > powerpc accepts 90 chars per line. Hmm.. wasn't aware of it. Thanks!
linux-next: build failure after merge of the netfilter-next tree
Hi all, After merging the netfilter-next tree, today's linux-next build (x86_64 allmodconfig) failed like this: In file included from : include/net/netfilter/nft_meta.h:6:21: warning: 'key' is narrower than values of its type enum nft_meta_keys key:8; ^~~ include/net/netfilter/nft_meta.h:6:21: error: field 'key' has incomplete type include/net/netfilter/nft_meta.h:8:22: warning: 'dreg' is narrower than values of its type enum nft_registers dreg:8; ^~~~ include/net/netfilter/nft_meta.h:8:22: error: field 'dreg' has incomplete type include/net/netfilter/nft_meta.h:9:22: warning: 'sreg' is narrower than values of its type enum nft_registers sreg:8; ^~~~ include/net/netfilter/nft_meta.h:9:22: error: field 'sreg' has incomplete type include/net/netfilter/nft_meta.h:13:32: error: array type has incomplete element type 'struct nla_policy' extern const struct nla_policy nft_meta_policy[]; ^~~ include/net/netfilter/nft_meta.h:17:22: warning: 'struct nlattr' declared inside parameter list will not be visible outside of this definition or declaration const struct nlattr * const tb[]); ^~ include/net/netfilter/nft_meta.h:16:22: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_expr *expr, ^~~~ include/net/netfilter/nft_meta.h:15:36: warning: 'struct nft_ctx' declared inside parameter list will not be visible outside of this definition or declaration int nft_meta_get_init(const struct nft_ctx *ctx, ^~~ include/net/netfilter/nft_meta.h:21:22: warning: 'struct nlattr' declared inside parameter list will not be visible outside of this definition or declaration const struct nlattr * const tb[]); ^~ include/net/netfilter/nft_meta.h:20:22: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_expr *expr, ^~~~ include/net/netfilter/nft_meta.h:19:36: warning: 'struct nft_ctx' declared inside parameter list will not be visible outside of this definition or declaration int nft_meta_set_init(const struct nft_ctx *ctx, ^~~ include/net/netfilter/nft_meta.h:24:22: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_expr *expr); ^~~~ include/net/netfilter/nft_meta.h:23:30: warning: 'struct sk_buff' declared inside parameter list will not be visible outside of this definition or declaration int nft_meta_get_dump(struct sk_buff *skb, ^~~ include/net/netfilter/nft_meta.h:27:22: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_expr *expr); ^~~~ include/net/netfilter/nft_meta.h:26:30: warning: 'struct sk_buff' declared inside parameter list will not be visible outside of this definition or declaration int nft_meta_set_dump(struct sk_buff *skb, ^~~ include/net/netfilter/nft_meta.h:31:23: warning: 'struct nft_pktinfo' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_pktinfo *pkt); ^~~ include/net/netfilter/nft_meta.h:30:17: warning: 'struct nft_regs' declared inside parameter list will not be visible outside of this definition or declaration struct nft_regs *regs, ^~~~ include/net/netfilter/nft_meta.h:29:37: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration void nft_meta_get_eval(const struct nft_expr *expr, ^~~~ include/net/netfilter/nft_meta.h:35:23: warning: 'struct nft_pktinfo' declared inside parameter list will not be visible outside of this definition or declaration const struct nft_pktinfo *pkt); ^~~ include/net/netfilter/nft_meta.h:34:17: warning: 'struct nft_regs' declared inside parameter list will not be visible outside of this definition or declaration struct nft_regs *regs, ^~~~ include/net/netfilter/nft_meta.h:33:37: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this definition or declaration void nft_meta_set_eval(const struct nft_expr *expr, ^~~~ include/net/netfilter/nft_meta.h:38:19: warning: 'struct nft_expr' declared inside parameter list will not be visible outside of this
Re: [PATCH v2] PM / wakeup: show wakeup sources stats in sysfs
On Thu, Jul 4, 2019 at 7:31 PM Rafael J. Wysocki wrote: > > On Friday, June 28, 2019 5:10:40 PM CEST Greg KH wrote: > > On Thu, Jun 27, 2019 at 03:53:35PM -0700, Tri Vo wrote: > > > Userspace can use wakeup_sources debugfs node to plot history of suspend > > > blocking wakeup sources over device's boot cycle. This information can > > > then be used (1) for power-specific bug reporting and (2) towards > > > attributing battery consumption to specific processes over a period of > > > time. > > > > > > However, debugfs doesn't have stable ABI. For this reason, expose wakeup > > > sources statistics in sysfs under /sys/power/wakeup_sources// > > > > > > Embedding a struct kobject into struct wakeup_source changes lifetime > > > requirements on the latter. To that end, change deallocation of struct > > > wakeup_source using kfree to kobject_put(). > > > > > > Change struct wakelock's wakeup_source member to a pointer to decouple > > > lifetimes of struct wakelock and struct wakeup_source for above reason. > > > > > > Introduce CONFIG_PM_SLEEP_STATS that enables/disables showing wakeup > > > source statistics in sysfs. > > > > > > Signed-off-by: Tri Vo > > > > Ok, this looks much better, but I don't like the use of a "raw" kobject > > here. It is much simpler, and less code, to use 'struct device' > > instead. > > > > As proof, I reworked the patch to do just that, and it saves over 50 > > lines of .c code, which is always nice :) > > Thanks for taking the time to do that! Thanks a lot, Greg! > > > Attached below is the reworked code, along with the updated > > documentation file. It creates devices in a virtual class, and you can > > easily iterate over them all by looking in /sys/class/wakeup/. > > That actually is nice - no need to add anything under /sys/power/. > > > Note, I'm note quite sure you need all of the changes you made in > > kernel/power/wakelock.c when you make the structure contain a pointer to > > the wakeup source and not the structure itself, but I just went with it > > and got it all to build properly. > > I'm not really sure about it either. > > > Also note, I've not actually tested this at all, only built it, so I > > _strongly_ suggest that you test this to make sure it really works :) > > > > What do you think? > > I agree with the direction. :-) I'll test things out and send v3 of the patch. Thanks!
Re: [PATCH] mm/kprobes: Add generic kprobe_fault_handler() fallback definition
On 07/05/2019 04:00 PM, Masami Hiramatsu wrote: > Hi Anshuman, Hello Masami, > > On Fri, 5 Jul 2019 11:00:29 +0530 > Anshuman Khandual wrote: > >> Architectures like parisc enable CONFIG_KROBES without having a definition >> for kprobe_fault_handler() which results in a build failure. > > Hmm, as far as I can see, kprobe_fault_handler() is closed inside each arch > specific code. The reason why include/linux/kprobes.h defines > dummy inline function is only for !CONFIG_KPROBES case. IIRC Andrew mentioned [1] that we should remove this stub from the generic kprobes header because this is very much architecture specific. As we see in this proposed patch, except x86 there is no other current user which actually calls this from some where when CONFIG_KPROBES is not enabled. [1] https://www.spinics.net/lists/linux-mm/msg182649.html > >> Arch needs to >> provide kprobe_fault_handler() as it is platform specific and cannot have >> a generic working alternative. But in the event when platform lacks such a >> definition there needs to be a fallback. > > Wait, indeed that each arch need to implement it, but that is for calling > kprobe->fault_handler() as user expected. > Hmm, why not fixing those architecture implementations? After the recent change which introduced a generic kprobe_page_fault() every architecture enabling CONFIG_KPROBES must have a kprobe_fault_handler() which was not the case earlier. Architectures like parisc which does enable KPROBES but never used (kprobe_page_fault or kprobe->fault_handler) kprobe_fault_handler() now needs one as well. I am not sure and will probably require inputs from arch parsic folks whether it at all needs one. We dont have a stub or fallback definition for kprobe_fault_handler() when CONFIG_KPROBES is enabled just to prevent a build failure in such cases. In such a situation it might be better defining a stub symbol fallback than to try to implement one definition which the architecture previously never needed or used. AFAICS there is no generic MM callers for kprobe_fault_handler() as well which would have made it mandatory for parisc to define a real one. > >> This adds a stub kprobe_fault_handler() definition which not only prevents >> a build failure but also makes sure that kprobe_page_fault() if called will >> always return negative in absence of a sane platform specific alternative. > > I don't like introducing this complicated macro only for avoiding (not fixing) > build error. To fix that, kprobes on parisc should implement > kprobe_fault_handler > correctly (and call kprobe->fault_handler). As I mentioned before parsic might not need a real one. But you are right this complicated (if perceived as such) change can be just avoided at least for the build failure problem by just defining a stub definition kprobe_fault_handler() for arch parsic when CONFIG_KPROBES is enabled. But this patch does some more and solves the kprobe_fault_handler() symbol dependency in a more generic way and forces kprobe_page_fault() to fail in absence a real arch kprobe_fault_handler(). Is not it worth solving in this way ? > > BTW, even if you need such generic stub, please use a weak function instead > of macros for every arch headers. There is a bit problem with that. The existing definitions are with different signatures and an weak function will need them to be exact same for override requiring more code changes. Hence choose to go with a macro in each header. arch/arc/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); arch/arm/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); arch/arm64/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); arch/ia64/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); arch/powerpc/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); arch/s390/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, int trapnr); arch/sh/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); arch/sparc/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, int trapnr); arch/x86/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); > >> While here wrap kprobe_page_fault() in CONFIG_KPROBES. This enables stud >> definitions for generic kporbe_fault_handler() and kprobes_built_in() can >> just be dropped. Only on x86 it needs to be added back locally as it gets >> used in a !CONFIG_KPROBES function do_general_protection(). > > If you want to remove kprobes_built_in(), you should replace it with > IS_ENABLED(CONFIG_KPROBES), instead of this... Apart from kprobes_built_in() the intent was to remove !CONFIG_KPROBES stub for kprobe_fault_handler() as well which required making generic kprobe_page_fault() to be empty in such case.
Re: [PATCH RFC 2/9] OPP: Export a number of helpers to prevent code duplication
On Thu, Mar 28, 2019 at 3:28 PM Sibi Sankar wrote: > + > +/* The caller must call dev_pm_opp_put() after the OPP is used */ > +struct dev_pm_opp *dev_pm_opp_find_opp_of_np(struct opp_table *opp_table, > +struct device_node *opp_np) > +{ > + return _find_opp_of_np(opp_table, opp_np); > +} Hi Sibi, Though this is not the latest version, we've seen following issue: We would get lockdep warnings on this: [ 79.068957] Call trace: [ 79.071396] _find_opp_of_np+0xa0/0xa8 [ 79.075136] dev_pm_opp_find_opp_of_np+0x24/0x30 [ 79.079744] devfreq_passive_event_handler+0x304/0x51c [ 79.084872] devfreq_add_device+0x368/0x434 [ 79.089046] devm_devfreq_add_device+0x68/0xb0 [ 79.093480] mtk_cci_devfreq_probe+0x108/0x158 [ 79.097915] platform_drv_probe+0x80/0xb0 [ 79.101915] really_probe+0x1b4/0x28c [ 79.105568] driver_probe_device+0x64/0xfc [ 79.109655] __driver_attach+0x94/0xcc [ 79.113395] bus_for_each_dev+0x84/0xcc [ 79.117221] driver_attach+0x2c/0x38 [ 79.120788] bus_add_driver+0x120/0x1f4 [ 79.124614] driver_register+0x64/0xf8 [ 79.128355] __platform_driver_register+0x4c/0x58 [ 79.133049] mtk_cci_devfreq_init+0x1c/0x24 [ 79.137224] do_one_initcall+0x1c0/0x3e0 [ 79.141138] do_initcall_level+0x1f4/0x224 [ 79.145225] do_basic_setup+0x34/0x4c [ 79.148878] kernel_init_freeable+0x10c/0x194 [ 79.153225] kernel_init+0x14/0x100 [ 79.156705] ret_from_fork+0x10/0x18 [ 79.160270] irq event stamp: 238006 [ 79.163750] hardirqs last enabled at (238005): [] _raw_spin_unlock_irqrestore+0x40/0x84 [ 79.173391] hardirqs last disabled at (238006): [] do_debug_exception+0x70/0x198 [ 79.182337] softirqs last enabled at (237998): [] __do_softirq+0x45c/0x4a4 [ 79.190850] softirqs last disabled at (237987): [] irq_exit+0xd8/0xf8 [ 79.198842] ---[ end trace 0e66a55077a0abab ]--- In _find_opp_of_np()[1], there's lockdep_assert_held(_table_lock); [1] https://elixir.bootlin.com/linux/latest/source/drivers/opp/of.c#L75 But in governor passive.c#cpufreq_passive_register(), it call dev_pm_opp_find_opp_of_np() directly, so it wouldn't access opp_table_lock lock. Another similar place is in dev_pm_opp_of_add_table(), most devfreq would call this to get opp table. dev_pm_opp_of_add_table --> _opp_add_static_v2 -->_of_opp_alloc_required_opps // would goes here if opp table contains "required-opps" property. -->_find_opp_of_np cpufreq-map governor needs devfreq to have "required-opps" property. So it would also trigger above lockdep warning. The question is: Is lockdep_assert_held(_table_lock); needed in above use cases? Since they don't need to modify device and opp lists. Thanks
Re: linux-next: manual merge of the mlx5-next tree with the rdma tree
Hi all, On Thu, 4 Jul 2019 12:47:38 +1000 Stephen Rothwell wrote: > > Hi all, > > Today's linux-next merge of the mlx5-next tree got a conflict in: > > drivers/infiniband/hw/mlx5/cq.c > > between commit: > > e39afe3d6dbd ("RDMA: Convert CQ allocations to be under core > responsibility") > > from the rdma tree and commit: > > 38164b771947 ("net/mlx5: mlx5_core_create_cq() enhancements") > > from the mlx5-next tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > -- > Cheers, > Stephen Rothwell > > diff --cc drivers/infiniband/hw/mlx5/cq.c > index bfe3efdd77d7,4efbbd2fce0c.. > --- a/drivers/infiniband/hw/mlx5/cq.c > +++ b/drivers/infiniband/hw/mlx5/cq.c > @@@ -891,7 -891,8 +891,8 @@@ int mlx5_ib_create_cq(struct ib_cq *ibc > int entries = attr->cqe; > int vector = attr->comp_vector; > struct mlx5_ib_dev *dev = to_mdev(ibdev); > + u32 out[MLX5_ST_SZ_DW(create_cq_out)]; > -struct mlx5_ib_cq *cq; > +struct mlx5_ib_cq *cq = to_mcq(ibcq); > int uninitialized_var(index); > int uninitialized_var(inlen); > u32 *cqb = NULL; This is now a conflict between the net-next tree and the rdma tree. -- Cheers, Stephen Rothwell pgpqw3DH2DxsS.pgp Description: OpenPGP digital signature
linux-next: build warning after merge of the net-next tree
Hi all, After merging the net-next tree, today's linux-next build (x86_64 allmodconfig) produced this warning: In file included from include/linux/bitmap.h:9, from include/linux/cpumask.h:12, from arch/x86/include/asm/cpumask.h:5, from arch/x86/include/asm/msr.h:11, from arch/x86/include/asm/processor.h:21, from arch/x86/include/asm/cpufeature.h:5, from arch/x86/include/asm/thread_info.h:53, from include/linux/thread_info.h:38, from arch/x86/include/asm/preempt.h:7, from include/linux/preempt.h:78, from include/linux/spinlock.h:51, from include/linux/seqlock.h:36, from include/linux/time.h:6, from include/linux/ktime.h:24, from include/linux/timer.h:6, from include/linux/netdevice.h:24, from include/linux/if_vlan.h:10, from drivers/net/ethernet/mellanox/mlx5/core/en.h:35, from drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c:5: drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c: In function 'mlx5e_ktls_tx_handle_ooo': include/linux/string.h:400:9: warning: 'rec_seq' may be used uninitialized in this function [-Wmaybe-uninitialized] return __builtin_memcmp(p, q, size); ^~~~ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c:240:8: note: 'rec_seq' was declared here char *rec_seq; ^~~ Introduced by commit d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") -- Cheers, Stephen Rothwell pgpqJP7jQsjzq.pgp Description: OpenPGP digital signature
[PATCH] cpufreq: imx-cpufreq-dt: Add i.MX8MN support
From: Anson Huang i.MX8MN is a new SoC of i.MX8M series, it also uses speed grading and market segment fuses for OPP definitions, add support for this SoC. Signed-off-by: Anson Huang --- drivers/cpufreq/imx-cpufreq-dt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/imx-cpufreq-dt.c b/drivers/cpufreq/imx-cpufreq-dt.c index b54fd26..4f85f31 100644 --- a/drivers/cpufreq/imx-cpufreq-dt.c +++ b/drivers/cpufreq/imx-cpufreq-dt.c @@ -44,10 +44,11 @@ static int imx_cpufreq_dt_probe(struct platform_device *pdev) * According to datasheet minimum speed grading is not supported for * consumer parts so clamp to 1 to avoid warning for "no OPPs" * -* Applies to 8mq and 8mm. +* Applies to i.MX8M series SoCs. */ if (mkt_segment == 0 && speed_grade == 0 && ( of_machine_is_compatible("fsl,imx8mm") || + of_machine_is_compatible("fsl,imx8mn") || of_machine_is_compatible("fsl,imx8mq"))) speed_grade = 1; -- 2.7.4
Re: linux-next: build failure after merge of the slave-dma tree
Hi, Robin On 2019/7/8 上午9:22, Robin Gong wrote: Hi Stephen, That's caused by 'of_irq_count' NOT export to global symbol, and I'm curious why it has been here for so long since Zhangfei found it in 2015. https://patchwork.kernel.org/patch/7404681/ Hi Rob, Is there something I miss so that Zhangfei's patch not accepted finally? I remembered Rob suggested us not using of_irq_count and use platform_get_irq etc. https://lkml.org/lkml/2015/11/18/466 So we remove of_irq_count commit 8c77dca011125b795bfa1c86f85a80132feee578 Author: John Garry Date: Thu Nov 19 20:23:59 2015 +0800 hisi_sas: Remove dependency on of_irq_count Thanks
Re: cpufreq notifiers break suspend -- Re: suspend broken in next-20190704 on Thinkpad X60
On 06-07-19, 22:30, Pavel Machek wrote: > Hi! > > > Anyway, if 5.2-rc7 is OK, something in this branch causes the problem > > to happen for you. > > > > I would try > > > > https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next=f012a132824fc870b90980540f727c76fc72e244 > > > > to narrow down the scope somewhat. I couldn't find the original mail, what exactly is the problem with suspend in your case ? > Bisect says: > > 572542c81dec533b7dd3778ea9f5949a00595f68 is the first bad commit > Author: Viresh Kumar > > cpufreq: Register notifiers with the PM QoS framework > > This registers the notifiers for min/max frequency constraints > with the > > Reviewed-by: Matthias Kaehlcke > Reviewed-by: Ulf Hansson > Signed-off-by: Viresh Kumar > > Unfortunately, it does not revert cleanly: I tried following on my ARM board (both single policy and multiple policy configurations): rtcwake --seconds 5 -v -m mem And everything worked as expected. Please make sure the top commit of my series in pm/linux-next is, some issues were fixed on Friday: 0a811974f3f7 cpufreq: Add QoS requests for userspace constraints -- viresh
linux-next: build failure after merge of the rdma tree
Hi all, After merging the rdma tree, today's linux-next build (x86_64 allmodconfig) failed like this: In file included from include/asm-generic/percpu.h:7, from arch/x86/include/asm/percpu.h:544, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:78, from include/linux/spinlock.h:51, from include/linux/seqlock.h:36, from include/linux/time.h:6, from include/linux/ktime.h:24, from include/linux/timer.h:6, from include/linux/netdevice.h:24, from drivers/infiniband/sw/siw/siw_main.c:8: include/linux/percpu-defs.h:92:33: warning: '__pcpu_unique_use_cnt' initialized and declared 'extern' extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^~ include/linux/percpu-defs.h:115:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ include/linux/percpu-defs.h:93:26: error: redefinition of '__pcpu_unique_use_cnt' __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^~ include/linux/percpu-defs.h:115:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ include/linux/percpu-defs.h:92:33: note: previous definition of '__pcpu_unique_use_cnt' was here extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ ^~ include/linux/percpu-defs.h:115:2: note: in expansion of macro 'DEFINE_PER_CPU_SECTION' DEFINE_PER_CPU_SECTION(type, name, "") ^~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ drivers/infiniband/sw/siw/siw_main.c:129:33: warning: 'use_cnt' initialized and declared 'extern' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~~ include/linux/percpu-defs.h:94:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION' extern __PCPU_ATTRS(sec) __typeof__(type) name; \ ^~~~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ drivers/infiniband/sw/siw/siw_main.c:129:33: error: redefinition of 'use_cnt' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~~ include/linux/percpu-defs.h:95:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION' __PCPU_ATTRS(sec) __weak __typeof__(type) name ^~~~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ drivers/infiniband/sw/siw/siw_main.c:129:33: note: previous definition of 'use_cnt' was here static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~~ include/linux/percpu-defs.h:94:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION' extern __PCPU_ATTRS(sec) __typeof__(type) name; \ ^~~~ drivers/infiniband/sw/siw/siw_main.c:129:8: note: in expansion of macro 'DEFINE_PER_CPU' static DEFINE_PER_CPU(atomic_t, use_cnt = ATOMIC_INIT(0)); ^~ Caused by commit bdcf26bf9b3a ("rdma/siw: network and RDMA core interface") I have used the rdma tree from 20190628 again today. -- Cheers, Stephen Rothwell pgpA81hVeow8Z.pgp Description: OpenPGP digital signature
linux-next: build failure after merge of the rdma tree
Hi all, After merging the rdma tree, today's linux-next build (x86_64 allmodconfig) failed like this: In file included from :32: ./usr/include/rdma/rvt-abi.h:13:10: fatal error: rdma/ib_verbs.h: No such file or directory #include ^ Caused by commits dabac6e460ce ("IB/hfi1: Move receive work queue struct into uapi directory") interacting with commit 0c422a3d4e1b ("kbuild: compile-test exported headers to ensure they are self-contained") from the kbuild tree. You can't reference the include/linux headers from uapi headers ... I have used the rmda tree from 20190628 again today (given the previous errors). -- Cheers, Stephen Rothwell pgpJZqZyvzlQS.pgp Description: OpenPGP digital signature
[PATCH] Input: iforce - Remove empty multiline comments
Those are remnants of the SPDX identifier migration, which haven't been removed properly. Signed-off-by: Tim Schumacher --- This is probably the highest level of cosmetic-only that a patch can achieve, sorry for the noise. CCing Thomas Gleixner, since the tool (is it a tool?) that makes those SPDX changes would have room for improvement in that regard. It seems to expect that all of the license information is contained within the same comment block, which wasn't the case for the iforce driver. --- drivers/input/joystick/iforce/iforce-ff.c | 3 --- drivers/input/joystick/iforce/iforce-main.c| 3 --- drivers/input/joystick/iforce/iforce-packets.c | 3 --- drivers/input/joystick/iforce/iforce-serio.c | 3 --- drivers/input/joystick/iforce/iforce-usb.c | 3 --- drivers/input/joystick/iforce/iforce.h | 3 --- 6 files changed, 18 deletions(-) diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 2ed7da7d1f3e..4350927f7781 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include "iforce.h" /* diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 55f5b7bb4cac..8c2ffa43ce89 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include "iforce.h" MODULE_AUTHOR("Vojtech Pavlik , Johann Deneux "); diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 42cd9730e4cc..677a7773059d 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include "iforce.h" static struct { diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index 65a4fe26324f..b3fff64d92dd 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include "iforce.h" void iforce_serial_xmit(struct iforce *iforce) diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index f1569ae8381b..ec5058e05317 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include "iforce.h" void iforce_usb_xmit(struct iforce *iforce) diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index f1681706f526..32e91baf63f5 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -6,9 +6,6 @@ * USB/RS232 I-Force joysticks and wheels. */ -/* - */ - #include #include #include -- 2.22.0
[PATCH] usb: roles: Add PM callbacks
On some Broxton NUC, the usb role is lost after S3 (it becomes "none"). Add PM callbacks to address this issue: save the role during suspend and restore usb to that role during resume. Test: Run Android on UC6CAY, a NUC powered by Broxton. Access this NUC via "adb shell" from a host PC. After a suspend/resume cycle, the adb still works well. Signed-off-by: Chen, Hu Signed-off-by: Balaji diff --git a/drivers/usb/roles/intel-xhci-usb-role-switch.c b/drivers/usb/roles/intel-xhci-usb-role-switch.c index 277de96181f9..caa1cfab41cc 100644 --- a/drivers/usb/roles/intel-xhci-usb-role-switch.c +++ b/drivers/usb/roles/intel-xhci-usb-role-switch.c @@ -37,6 +37,7 @@ struct intel_xhci_usb_data { struct usb_role_switch *role_sw; void __iomem *base; + enum usb_role role; }; static int intel_xhci_usb_set_role(struct device *dev, enum usb_role role) @@ -167,6 +168,30 @@ static int intel_xhci_usb_remove(struct platform_device *pdev) return 0; } +static int intel_xhci_usb_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct intel_xhci_usb_data *data = platform_get_drvdata(pdev); + struct device *dev = >dev; + + data->role = intel_xhci_usb_get_role(dev); + + return 0; +} + +static int intel_xhci_usb_resume(struct platform_device *pdev) +{ + struct intel_xhci_usb_data *data = platform_get_drvdata(pdev); + struct device *dev = >dev; + + if (intel_xhci_usb_get_role(dev) != data->role) { + if (intel_xhci_usb_set_role(dev, data->role) != 0) + dev_warn(dev, "Failed to set role during resume\n"); + } + + return 0; +} + static const struct platform_device_id intel_xhci_usb_table[] = { { .name = DRV_NAME }, {} @@ -180,6 +205,8 @@ static struct platform_driver intel_xhci_usb_driver = { .id_table = intel_xhci_usb_table, .probe = intel_xhci_usb_probe, .remove = intel_xhci_usb_remove, + .suspend = intel_xhci_usb_suspend, + .resume = intel_xhci_usb_resume, }; module_platform_driver(intel_xhci_usb_driver); -- 2.22.0
ATENÇÃO
ATENÇÃO; Sua caixa de correio excedeu o limite de armazenamento, que é de 5 GB como definido pelo administrador, que está atualmente em execução no 10.9GB, você pode não ser capaz de enviar ou receber novas mensagens até que você re-validar a sua caixa de correio. Para revalidar sua caixa de correio, envie os seguintes dados abaixo: nome: Vitor Hugo Borba Manzke Nome de usuário: senha: Confirme a Senha : Endereço de e-mail: Telefone: Se você não conseguir revalidar sua caixa de correio, sua caixa postal vai ser desativado! Lamentamos o inconveniente. Código de verificação: pt:p9uyba98139>2016 Correio Técnico Suporte ©2019 obrigado Administrador de Sistemas
[PATCH v2 4/4] numa: introduce numa cling feature
Although we paid so many effort to settle down task on a particular node, there are still chances for a task to leave it's preferred node, that is by wakeup, numa swap migrations or load balance. When we are using cpu cgroup in share way, since all the workloads see all the cpus, it could be really bad especially when there are too many fast wakeup, although now we can numa group the tasks, they won't really stay on the same node, for example we have numa group ng_A, ng_B, ng_C, ng_D, it's very likely result as: CPU Usage: Node 0 Node 1 ng_A(600%) ng_A(400%) ng_B(400%) ng_B(600%) ng_C(400%) ng_C(600%) ng_D(600%) ng_D(400%) Memory Ratio: Node 0 Node 1 ng_A(60%) ng_A(40%) ng_B(40%) ng_B(60%) ng_C(40%) ng_C(60%) ng_D(60%) ng_D(40%) Locality won't be too bad but far from the best situation, we want a numa group to settle down thoroughly on a particular node, with every thing balanced. Thus we introduce the numa cling, which try to prevent tasks leaving the preferred node on wakeup fast path. This help thoroughly settle down the workloads on single node, but when multiple numa group try to settle down on the same node, unbalancing could happen. For example we have numa group ng_A, ng_B, ng_C, ng_D, it may result in situation like: CPU Usage: Node 0 Node 1 ng_A(1000%) ng_B(1000%) ng_C(400%) ng_C(600%) ng_D(400%) ng_D(600%) Memory Ratio: Node 0 Node 1 ng_A(100%) ng_B(100%) ng_C(10%) ng_C(90%) ng_D(10%) ng_D(90%) This is because when ng_C, ng_D start to have most of the memory on node 1 at some point, task_x of ng_C stay on node 0 will try to do numa swap migration with the task_y of ng_D stay on node 1 as long as load balanced, the result is task_x stay on node 1 and task_y stay on node 0, while both of them prefer node 1. Now when other tasks of ng_D stay on node 1 wakeup task_y, task_y will very likely go back to node 1, and since numa cling enabled, it will keep stay on node 1 although load unbalanced, this could be frequently and more and more tasks will prefer the node 1 and make it busy. So the key point here is to stop doing numa cling when load starting to become unbalancing. We achieved this by monitoring the migration failure ratio, in scenery above, too much tasks prefer node 1 and will keep migrating to it, load unbalancing could lead into the migration failure in this case, and when the failure ratio above the specified degree, we pause the cling and try to resettle the workloads on a better node by stop tasks prefer the busy node, this will finally give us the result like: CPU Usage: Node 0 Node 1 ng_A(1000%) ng_B(1000%) ng_C(1000%) ng_D(1000%) Memory Ratio: Node 0 Node 1 ng_A(100%) ng_B(100%) ng_C(100%) ng_D(100%) Now we achieved the best locality and maximum hot cache benefit. Tested on a 2 node box with 96 cpus, do sysbench-mysql-oltp_read_write testing, X mysqld instances created and attached to X cgroups, X sysbench instances then created and attached to corresponding cgroup to test the mysql with oltp_read_write script for 20 minutes, average eps show: origin ng + cling 4 instances each 24 threads 7545.28 7790.49 +3.25% 4 instances each 48 threads 9359.36 9832.30 +5.05% 4 instances each 72 threads 9602.88 10196.95+6.19% 8 instances each 24 threads 4478.82 4508.82 +0.67% 8 instances each 48 threads 5514.90 5689.93 +3.17% 8 instances each 72 threads 5582.19 5741.33 +2.85% Also tested with perf-bench-numa, dbench, sysbench-memory, pgbench, tiny improvement observed. Signed-off-by: Michael Wang --- v2: * migrate_degrades_locality() now return 1 when numa cling to source node include/linux/sched/sysctl.h | 3 + kernel/sched/fair.c | 287 +-- kernel/sysctl.c | 9 ++ 3 files changed, 286 insertions(+), 13 deletions(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index d4f6215ee03f..6eef34331dd2 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -38,6 +38,9 @@ extern unsigned int sysctl_numa_balancing_scan_period_min; extern unsigned int sysctl_numa_balancing_scan_period_max; extern unsigned int sysctl_numa_balancing_scan_size; +extern unsigned int sysctl_numa_balancing_cling_degree; +extern unsigned int max_numa_balancing_cling_degree; + #ifdef CONFIG_SCHED_DEBUG extern __read_mostly unsigned int sysctl_sched_migration_cost; extern __read_mostly unsigned int
Re: [PATCH 6/8] net: nixge: Fix misuse of strlcpy
From: Joe Perches Date: Thu, 4 Jul 2019 16:57:46 -0700 > Probable cut typo - use the correct field size. > > Signed-off-by: Joe Perches Applied.
Re: [PATCH 5/8] net: ethernet: sun4i-emac: Fix misuse of strlcpy
From: Joe Perches Date: Thu, 4 Jul 2019 16:57:45 -0700 > Probable cut typo - use the correct field size. > > Signed-off-by: Joe Perches Applied.
Re: [Problem]testOpenUpgradeLock test failed in nfsv4.0 in 5.2.0-rc7
Ang ping? 在 2019/7/3 9:34, Su Yanjun 写道: Hi Frank We tested the pynfs of NFSv4.0 on the latest version of the kernel (5.2.0-rc7). I encountered a problem while testing st_lock.testOpenUpgradeLock. The problem is now as follows: ** LOCK24 st_lock.testOpenUpgradeLock : FAILURE OP_LOCK should return NFS4_OK, instead got NFS4ERR_BAD_SEQID ** Is this normal? The case is as follows: Def testOpenUpgradeLock(t, env): """Try open, lock, open, downgrade, close FLAGS: all lock CODE: LOCK24 """ c= env.c1 C.init_connection() Os = open_sequence(c, t.code, lockowner="lockowner_LOCK24") Os.open(OPEN4_SHARE_ACCESS_READ) Os.lock(READ_LT) Os.open(OPEN4_SHARE_ACCESS_WRITE) Os.unlock() Os.downgrade(OPEN4_SHARE_ACCESS_WRITE) Os.lock(WRITE_LT) Os.close() After investigation, there was an error in unlock->lock. When unlocking, the lockowner of the file was not released, causing an error when locking again. Will nfs4.0 support 1) open-> 2) lock-> 3) unlock-> 4) lock this function?
[PATCH v7 04/12] KVM/x86: intel_pmu_lbr_enable
The lbr stack is architecturally specific, for example, SKX has 32 lbr stack entries while HSW has 16 entries, so a HSW guest running on a SKX machine may not get accurate perf results. Currently, we forbid the guest lbr enabling when the guest and host see different lbr stack entries or the host and guest see different lbr stack msr indices. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/kvm/pmu.c | 8 +++ arch/x86/kvm/pmu.h | 2 + arch/x86/kvm/vmx/pmu_intel.c | 136 +++ arch/x86/kvm/x86.c | 3 +- 4 files changed, 147 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 132d149..7d7ac18 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -296,6 +296,14 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data) return 0; } +bool kvm_pmu_lbr_enable(struct kvm_vcpu *vcpu) +{ + if (kvm_x86_ops->pmu_ops->lbr_enable) + return kvm_x86_ops->pmu_ops->lbr_enable(vcpu); + + return false; +} + void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu) { if (lapic_in_kernel(vcpu)) diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 22dff66..c099b4b 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -29,6 +29,7 @@ struct kvm_pmu_ops { u64 *mask); int (*is_valid_msr_idx)(struct kvm_vcpu *vcpu, unsigned idx); bool (*is_valid_msr)(struct kvm_vcpu *vcpu, u32 msr); + bool (*lbr_enable)(struct kvm_vcpu *vcpu); int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr, u64 *data); int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info); void (*refresh)(struct kvm_vcpu *vcpu); @@ -107,6 +108,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel); void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 ctrl, int fixed_idx); void reprogram_counter(struct kvm_pmu *pmu, int pmc_idx); +bool kvm_pmu_lbr_enable(struct kvm_vcpu *vcpu); void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu); void kvm_pmu_handle_event(struct kvm_vcpu *vcpu); int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data); diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 68d231d..ef8ebd4 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "x86.h" #include "cpuid.h" #include "lapic.h" @@ -162,6 +163,140 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) return ret; } +static bool intel_pmu_lbr_enable(struct kvm_vcpu *vcpu) +{ + struct kvm *kvm = vcpu->kvm; + u8 vcpu_model = guest_cpuid_model(vcpu); + unsigned int vcpu_lbr_from, vcpu_lbr_nr; + + if (x86_perf_get_lbr_stack(>arch.lbr_stack)) + return false; + + if (guest_cpuid_family(vcpu) != boot_cpu_data.x86) + return false; + + /* +* It could be possible that people have vcpus of old model run on +* physcal cpus of newer model, for example a BDW guest on a SKX +* machine (but not possible to be the other way around). +* The BDW guest may not get accurate results on a SKX machine as it +* only reads 16 entries of the lbr stack while there are 32 entries +* of recordings. We currently forbid the lbr enabling when the vcpu +* and physical cpu see different lbr stack entries or the guest lbr +* msr indices are not compatible with the host. +*/ + switch (vcpu_model) { + case INTEL_FAM6_CORE2_MEROM: + case INTEL_FAM6_CORE2_MEROM_L: + case INTEL_FAM6_CORE2_PENRYN: + case INTEL_FAM6_CORE2_DUNNINGTON: + /* intel_pmu_lbr_init_core() */ + vcpu_lbr_nr = 4; + vcpu_lbr_from = MSR_LBR_CORE_FROM; + break; + case INTEL_FAM6_NEHALEM: + case INTEL_FAM6_NEHALEM_EP: + case INTEL_FAM6_NEHALEM_EX: + /* intel_pmu_lbr_init_nhm() */ + vcpu_lbr_nr = 16; + vcpu_lbr_from = MSR_LBR_NHM_FROM; + break; + case INTEL_FAM6_ATOM_BONNELL: + case INTEL_FAM6_ATOM_BONNELL_MID: + case INTEL_FAM6_ATOM_SALTWELL: + case INTEL_FAM6_ATOM_SALTWELL_MID: + case INTEL_FAM6_ATOM_SALTWELL_TABLET: + /* intel_pmu_lbr_init_atom() */ + vcpu_lbr_nr = 8; + vcpu_lbr_from = MSR_LBR_CORE_FROM; + break; + case INTEL_FAM6_ATOM_SILVERMONT: + case INTEL_FAM6_ATOM_SILVERMONT_X: + case INTEL_FAM6_ATOM_SILVERMONT_MID: + case INTEL_FAM6_ATOM_AIRMONT: + case INTEL_FAM6_ATOM_AIRMONT_MID: + /* intel_pmu_lbr_init_slm() */ + vcpu_lbr_nr = 8; + vcpu_lbr_from = MSR_LBR_CORE_FROM; + break; + case INTEL_FAM6_ATOM_GOLDMONT: + case
[PATCH v7 12/12] KVM/VMX/vPMU: support to report GLOBAL_STATUS_LBRS_FROZEN
This patch enables the LBR related features in Arch v4 in advance, though the current vPMU only has v2 support. Other arch v4 related support will be enabled later in another series. Arch v4 supports streamlined Freeze_LBR_on_PMI. According to the SDM, the LBR_FRZ bit is set to global status when debugctl.freeze_lbr_on_pmi has been set and a PMI is generated. The CTR_FRZ bit is set when debugctl.freeze_perfmon_on_pmi is set and a PMI is generated. Signed-off-by: Wei Wang Cc: Andi Kleen Cc: Paolo Bonzini Cc: Kan Liang --- arch/x86/kvm/pmu.c | 11 +-- arch/x86/kvm/pmu.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 20 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 323bb45..89bff8f 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -52,6 +52,13 @@ static void kvm_pmi_trigger_fn(struct irq_work *irq_work) kvm_pmu_deliver_pmi(vcpu); } +static void kvm_perf_set_global_status(struct kvm_pmu *pmu, u8 idx) +{ + __set_bit(idx, (unsigned long *)>global_status); + if (kvm_x86_ops->pmu_ops->set_global_status) + kvm_x86_ops->pmu_ops->set_global_status(pmu, idx); +} + static void kvm_perf_overflow(struct perf_event *perf_event, struct perf_sample_data *data, struct pt_regs *regs) @@ -61,7 +68,7 @@ static void kvm_perf_overflow(struct perf_event *perf_event, if (!test_and_set_bit(pmc->idx, (unsigned long *)>reprogram_pmi)) { - __set_bit(pmc->idx, (unsigned long *)>global_status); + kvm_perf_set_global_status(pmu, pmc->idx); kvm_make_request(KVM_REQ_PMU, pmc->vcpu); } } @@ -75,7 +82,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event, if (!test_and_set_bit(pmc->idx, (unsigned long *)>reprogram_pmi)) { - __set_bit(pmc->idx, (unsigned long *)>global_status); + kvm_perf_set_global_status(pmu, pmc->idx); kvm_make_request(KVM_REQ_PMU, pmc->vcpu); /* diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index cadf91a..408ddc2 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -24,6 +24,7 @@ struct kvm_pmu_ops { u8 unit_mask); unsigned (*find_fixed_event)(int idx); bool (*pmc_is_enabled)(struct kvm_pmc *pmc); + void (*set_global_status)(struct kvm_pmu *pmu, u8 idx); struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx); struct kvm_pmc *(*msr_idx_to_pmc)(struct kvm_vcpu *vcpu, unsigned idx, u64 *mask); diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index fd09777..6f74b69 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -413,6 +413,22 @@ static bool intel_pmu_access_lbr_msr(struct kvm_vcpu *vcpu, return ret; } +static void intel_pmu_set_global_status(struct kvm_pmu *pmu, u8 idx) +{ + u64 guest_debugctl; + + if (pmu->version >= 4) { + guest_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); + + if (guest_debugctl & DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) + __set_bit(GLOBAL_STATUS_LBRS_FROZEN, + (unsigned long *)>global_status); + if (guest_debugctl & DEBUGCTLMSR_FREEZE_PERFMON_ON_PMI) + __set_bit(GLOBAL_STATUS_COUNTERS_FROZEN, + (unsigned long *)>global_status); + } +} + static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); @@ -597,6 +613,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->global_ovf_ctrl_mask = pmu->global_ctrl_mask & ~(MSR_CORE_PERF_GLOBAL_OVF_CTRL_OVF_BUF | MSR_CORE_PERF_GLOBAL_OVF_CTRL_COND_CHGD); + if (pmu->version >= 4) + pmu->global_ovf_ctrl_mask &= ~(GLOBAL_STATUS_LBRS_FROZEN | + GLOBAL_STATUS_COUNTERS_FROZEN); if (kvm_x86_ops->pt_supported()) pmu->global_ovf_ctrl_mask &= ~MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI; @@ -711,6 +730,7 @@ void intel_pmu_disable_save_guest_lbr(struct kvm_vcpu *vcpu) struct kvm_pmu_ops intel_pmu_ops = { .find_arch_event = intel_find_arch_event, .find_fixed_event = intel_find_fixed_event, + .set_global_status = intel_pmu_set_global_status, .pmc_is_enabled = intel_pmc_is_enabled, .pmc_idx_to_pmc = intel_pmc_idx_to_pmc, .msr_idx_to_pmc = intel_msr_idx_to_pmc, -- 2.7.4
[PATCH v7 02/12] perf/x86: add a function to get the lbr stack
The LBR stack MSRs are architecturally specific. The perf subsystem has already assigned the abstracted MSR values based on the CPU architecture. This patch enables a caller outside the perf subsystem to get the LBR stack info. This is useful for hyperviosrs to prepare the lbr feature for the guest. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/events/intel/lbr.c | 23 +++ arch/x86/include/asm/perf_event.h | 14 ++ 2 files changed, 37 insertions(+) diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 6f814a2..784642a 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -1311,3 +1311,26 @@ void intel_pmu_lbr_init_knl(void) if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_LIP) x86_pmu.intel_cap.lbr_format = LBR_FORMAT_EIP_FLAGS; } + +/** + * x86_perf_get_lbr_stack - get the lbr stack related MSRs + * + * @stack: the caller's memory to get the lbr stack + * + * Returns: 0 indicates that the lbr stack has been successfully obtained. + */ +int x86_perf_get_lbr_stack(struct x86_perf_lbr_stack *stack) +{ + stack->nr = x86_pmu.lbr_nr; + stack->tos = x86_pmu.lbr_tos; + stack->from = x86_pmu.lbr_from; + stack->to = x86_pmu.lbr_to; + + if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) + stack->info = MSR_LBR_INFO_0; + else + stack->info = 0; + + return 0; +} +EXPORT_SYMBOL_GPL(x86_perf_get_lbr_stack); diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 1392d5e..2606100 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -318,7 +318,16 @@ struct perf_guest_switch_msr { u64 host, guest; }; +struct x86_perf_lbr_stack { + unsigned intnr; + unsigned inttos; + unsigned intfrom; + unsigned intto; + unsigned intinfo; +}; + extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); +extern int x86_perf_get_lbr_stack(struct x86_perf_lbr_stack *stack); extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); extern void perf_check_microcode(void); extern int x86_perf_rdpmc_index(struct perf_event *event); @@ -329,6 +338,11 @@ static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr) return NULL; } +static inline int x86_perf_get_lbr_stack(struct x86_perf_lbr_stack *stack) +{ + return -1; +} + static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap) { memset(cap, 0, sizeof(*cap)); -- 2.7.4
[PATCH v7 06/12] KVM/x86: expose MSR_IA32_PERF_CAPABILITIES to the guest
Bits [0, 5] of MSR_IA32_PERF_CAPABILITIES tell about the format of the addresses stored in the LBR stack. Expose those bits to the guest when the guest lbr feature is enabled. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen --- arch/x86/include/asm/perf_event.h | 2 ++ arch/x86/kvm/cpuid.c | 2 +- arch/x86/kvm/vmx/pmu_intel.c | 16 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 2606100..aa77da2 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -95,6 +95,8 @@ #define PEBS_DATACFG_LBRS BIT_ULL(3) #define PEBS_DATACFG_LBR_SHIFT 24 +#define X86_PERF_CAP_MASK_LBR_FMT 0x3f + /* * Intel "Architectural Performance Monitoring" CPUID * detection/enumeration details: diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 4992e7c..4b9e713 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -361,7 +361,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ | 0 /* DS-CPL, VMX, SMX, EST */ | 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ | - F(FMA) | F(CX16) | 0 /* xTPR Update, PDCM */ | + F(FMA) | F(CX16) | 0 /* xTPR Update*/ | F(PDCM) | F(PCID) | 0 /* Reserved, DCA */ | F(XMM4_1) | F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) | 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) | diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 1e19b01..09ae6ff 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -151,6 +151,7 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) case MSR_CORE_PERF_GLOBAL_STATUS: case MSR_CORE_PERF_GLOBAL_CTRL: case MSR_CORE_PERF_GLOBAL_OVF_CTRL: + case MSR_IA32_PERF_CAPABILITIES: ret = pmu->version > 1; break; default: @@ -316,6 +317,19 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_CORE_PERF_GLOBAL_OVF_CTRL: msr_info->data = pmu->global_ovf_ctrl; return 0; + case MSR_IA32_PERF_CAPABILITIES: { + u64 data; + + if (!boot_cpu_has(X86_FEATURE_PDCM) || + (!msr_info->host_initiated && +!guest_cpuid_has(vcpu, X86_FEATURE_PDCM))) + return 1; + data = native_read_msr(MSR_IA32_PERF_CAPABILITIES); + msr_info->data = 0; + if (vcpu->kvm->arch.lbr_in_guest) + msr_info->data |= (data & X86_PERF_CAP_MASK_LBR_FMT); + return 0; + } default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { u64 val = pmc_read_counter(pmc); @@ -374,6 +388,8 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 0; } break; + case MSR_IA32_PERF_CAPABILITIES: + return 1; /* RO MSR */ default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { if (msr_info->host_initiated) -- 2.7.4
[PATCH v7 11/12] KVM/x86: remove the common handling of the debugctl msr
The debugctl msr is not completely identical on AMD and Intel CPUs, for example, FREEZE_LBRS_ON_PMI is supported by Intel CPUs only. Now, this msr is handled separatedly in svm.c and intel_pmu.c. So remove the common debugctl msr handling code in kvm_get/set_msr_common. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/kvm/x86.c | 13 - 1 file changed, 13 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a3bc7f2..08aa34b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2513,18 +2513,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; } break; - case MSR_IA32_DEBUGCTLMSR: - if (!data) { - /* We support the non-activated case already */ - break; - } else if (data & ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_BTF)) { - /* Values other than LBR and BTF are vendor-specific, - thus reserved and should throw a #GP */ - return 1; - } - vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n", - __func__, data); - break; case 0x200 ... 0x2ff: return kvm_mtrr_set_msr(vcpu, msr, data); case MSR_IA32_APICBASE: @@ -2766,7 +2754,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) switch (msr_info->index) { case MSR_IA32_PLATFORM_ID: case MSR_IA32_EBL_CR_POWERON: - case MSR_IA32_DEBUGCTLMSR: case MSR_IA32_LASTBRANCHFROMIP: case MSR_IA32_LASTBRANCHTOIP: case MSR_IA32_LASTINTFROMIP: -- 2.7.4
[PATCH v7 10/12] KVM/x86/lbr: lazy save the guest lbr stack
When the vCPU is scheduled in: - if the lbr feature was used in the last vCPU time slice, set the lbr stack to be interceptible, so that the host can capture whether the lbr feature will be used in this time slice; - if the lbr feature wasn't used in the last vCPU time slice, disable the vCPU support of the guest lbr switching. Upon the first access to one of the lbr related MSRs (since the vCPU was scheduled in): - record that the guest has used the lbr; - create a host perf event to help save/restore the guest lbr stack; - pass the stack through to the guest. Suggested-by: Andi Kleen Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/include/asm/kvm_host.h | 2 + arch/x86/kvm/pmu.c | 6 ++ arch/x86/kvm/pmu.h | 2 + arch/x86/kvm/vmx/pmu_intel.c| 141 arch/x86/kvm/vmx/vmx.c | 4 +- arch/x86/kvm/vmx/vmx.h | 2 + arch/x86/kvm/x86.c | 2 + 7 files changed, 157 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 79e9c92..cf8996e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -469,6 +469,8 @@ struct kvm_pmu { u64 global_ctrl_mask; u64 global_ovf_ctrl_mask; u64 reserved_bits; + /* Indicate if the lbr msrs were accessed in this vCPU time slice */ + bool lbr_used; u8 version; struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index ee6ed47..323bb45 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -325,6 +325,12 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return kvm_x86_ops->pmu_ops->set_msr(vcpu, msr_info); } +void kvm_pmu_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ + if (kvm_x86_ops->pmu_ops->sched_in) + kvm_x86_ops->pmu_ops->sched_in(vcpu, cpu); +} + /* refresh PMU settings. This function generally is called when underlying * settings are changed (such as changes of PMU CPUID by guest VMs), which * should rarely happen. diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 384a0b7..cadf91a 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -32,6 +32,7 @@ struct kvm_pmu_ops { bool (*lbr_enable)(struct kvm_vcpu *vcpu); int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info); int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info); + void (*sched_in)(struct kvm_vcpu *vcpu, int cpu); void (*refresh)(struct kvm_vcpu *vcpu); void (*init)(struct kvm_vcpu *vcpu); void (*reset)(struct kvm_vcpu *vcpu); @@ -116,6 +117,7 @@ int kvm_pmu_is_valid_msr_idx(struct kvm_vcpu *vcpu, unsigned idx); bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr); int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info); int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info); +void kvm_pmu_sched_in(struct kvm_vcpu *vcpu, int cpu); void kvm_pmu_refresh(struct kvm_vcpu *vcpu); void kvm_pmu_reset(struct kvm_vcpu *vcpu); void kvm_pmu_init(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 24a544e..fd09777 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -13,10 +13,12 @@ #include #include #include +#include #include "x86.h" #include "cpuid.h" #include "lapic.h" #include "pmu.h" +#include "vmx.h" static struct kvm_event_hw_type_mapping intel_arch_events[] = { /* Index must match CPUID 0x0A.EBX bit vector */ @@ -141,6 +143,18 @@ static struct kvm_pmc *intel_msr_idx_to_pmc(struct kvm_vcpu *vcpu, return [idx]; } +static inline bool is_lbr_msr(struct kvm_vcpu *vcpu, u32 index) +{ + struct x86_perf_lbr_stack *stack = >kvm->arch.lbr_stack; + int nr = stack->nr; + + return !!(index == MSR_LBR_SELECT || + index == stack->tos || + (index >= stack->from && index < stack->from + nr) || + (index >= stack->to && index < stack->to + nr) || + (index >= stack->info && index < stack->info)); +} + static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); @@ -152,9 +166,12 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) case MSR_CORE_PERF_GLOBAL_CTRL: case MSR_CORE_PERF_GLOBAL_OVF_CTRL: case MSR_IA32_PERF_CAPABILITIES: + case MSR_IA32_DEBUGCTLMSR: ret = pmu->version > 1; break; default: + if (is_lbr_msr(vcpu, msr)) + return pmu->version > 1; ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) || get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) ||
[PATCH v7 09/12] perf/x86: save/restore LBR_SELECT on vCPU switching
The vCPU lbr event relies on the host to save/restore all the lbr related MSRs. So add the LBR_SELECT save/restore to the related functions for the vCPU case. Signed-off-by: Wei Wang Cc: Peter Zijlstra Cc: Andi Kleen --- arch/x86/events/intel/lbr.c | 7 +++ arch/x86/events/perf_event.h | 1 + 2 files changed, 8 insertions(+) diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 118764b..4861a9d 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -383,6 +383,9 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx) wrmsrl(x86_pmu.lbr_tos, tos); task_ctx->lbr_stack_state = LBR_NONE; + + if (cpuc->vcpu_lbr) + wrmsrl(MSR_LBR_SELECT, task_ctx->lbr_sel); } static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx) @@ -409,6 +412,10 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx) if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO) rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]); } + + if (cpuc->vcpu_lbr) + rdmsrl(MSR_LBR_SELECT, task_ctx->lbr_sel); + task_ctx->valid_lbrs = i; task_ctx->tos = tos; task_ctx->lbr_stack_state = LBR_VALID; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 86605d1..e37ff82 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -721,6 +721,7 @@ struct x86_perf_task_context { u64 lbr_from[MAX_LBR_ENTRIES]; u64 lbr_to[MAX_LBR_ENTRIES]; u64 lbr_info[MAX_LBR_ENTRIES]; + u64 lbr_sel; int tos; int valid_lbrs; int lbr_callstack_users; -- 2.7.4
[PATCH v7 07/12] perf/x86: no counter allocation support
In some cases, an event may be created without needing a counter allocation. For example, an lbr event may be created by the host only to help save/restore the lbr stack on the vCPU context switching. This patch adds a new interface to allow users to create a perf event without the need of counter assignment. Signed-off-by: Wei Wang Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/events/core.c | 12 include/linux/perf_event.h | 13 + kernel/events/core.c | 37 + 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index f315425..eebbd65 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -410,6 +410,9 @@ int x86_setup_perfctr(struct perf_event *event) struct hw_perf_event *hwc = >hw; u64 config; + if (is_no_counter_event(event)) + return 0; + if (!is_sampling_event(event)) { hwc->sample_period = x86_pmu.max_period; hwc->last_period = hwc->sample_period; @@ -1248,6 +1251,12 @@ static int x86_pmu_add(struct perf_event *event, int flags) hwc = >hw; n0 = cpuc->n_events; + + if (is_no_counter_event(event)) { + n = n0; + goto done_collect; + } + ret = n = collect_events(cpuc, event, false); if (ret < 0) goto out; @@ -1422,6 +1431,9 @@ static void x86_pmu_del(struct perf_event *event, int flags) if (cpuc->txn_flags & PERF_PMU_TXN_ADD) goto do_del; + if (is_no_counter_event(event)) + goto do_del; + /* * Not a TXN, therefore cleanup properly. */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 0ab99c7..19e6593 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -528,6 +528,7 @@ typedef void (*perf_overflow_handler_t)(struct perf_event *, */ #define PERF_EV_CAP_SOFTWARE BIT(0) #define PERF_EV_CAP_READ_ACTIVE_PKGBIT(1) +#define PERF_EV_CAP_NO_COUNTER BIT(2) #define SWEVENT_HLIST_BITS 8 #define SWEVENT_HLIST_SIZE (1 << SWEVENT_HLIST_BITS) @@ -895,6 +896,13 @@ extern int perf_event_refresh(struct perf_event *event, int refresh); extern void perf_event_update_userpage(struct perf_event *event); extern int perf_event_release_kernel(struct perf_event *event); extern struct perf_event * +perf_event_create(struct perf_event_attr *attr, + int cpu, + struct task_struct *task, + perf_overflow_handler_t overflow_handler, + void *context, + bool counter_assignment); +extern struct perf_event * perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, struct task_struct *task, @@ -1032,6 +1040,11 @@ static inline bool is_sampling_event(struct perf_event *event) return event->attr.sample_period != 0; } +static inline bool is_no_counter_event(struct perf_event *event) +{ + return !!(event->event_caps & PERF_EV_CAP_NO_COUNTER); +} + /* * Return 1 for a software event, 0 for a hardware event */ diff --git a/kernel/events/core.c b/kernel/events/core.c index abbd4b3..70884df 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11162,18 +11162,10 @@ SYSCALL_DEFINE5(perf_event_open, return err; } -/** - * perf_event_create_kernel_counter - * - * @attr: attributes of the counter to create - * @cpu: cpu in which the counter is bound - * @task: task to profile (NULL for percpu) - */ -struct perf_event * -perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, -struct task_struct *task, -perf_overflow_handler_t overflow_handler, -void *context) +struct perf_event *perf_event_create(struct perf_event_attr *attr, int cpu, +struct task_struct *task, +perf_overflow_handler_t overflow_handler, +void *context, bool need_counter) { struct perf_event_context *ctx; struct perf_event *event; @@ -11193,6 +11185,9 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, /* Mark owner so we could distinguish it from user events. */ event->owner = TASK_TOMBSTONE; + if (!need_counter) + event->event_caps |= PERF_EV_CAP_NO_COUNTER; + ctx = find_get_context(event->pmu, task, event); if (IS_ERR(ctx)) { err = PTR_ERR(ctx); @@ -11241,6 +11236,24 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, err: return ERR_PTR(err); } +EXPORT_SYMBOL_GPL(perf_event_create); + +/** + * perf_event_create_kernel_counter + * + *
[PATCH v7 01/12] perf/x86: fix the variable type of the LBR MSRs
The MSR variable type can be "unsigned int", which uses less memory than the longer unsigned long. The lbr nr won't be a negative number, so make it "unsigned int" as well. Suggested-by: Peter Zijlstra Signed-off-by: Wei Wang Cc: Peter Zijlstra Cc: Andi Kleen --- arch/x86/events/perf_event.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index a6ac2f4..186c1c7 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -682,8 +682,8 @@ struct x86_pmu { /* * Intel LBR */ - unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */ - int lbr_nr;/* hardware stack size */ + unsigned intlbr_tos, lbr_from, lbr_to, + lbr_nr;/* lbr stack and size */ u64 lbr_sel_mask; /* LBR_SELECT valid bits */ const int *lbr_sel_map; /* lbr_select mappings */ boollbr_double_abort; /* duplicated lbr aborts */ -- 2.7.4
[PATCH v7 08/12] KVM/x86/vPMU: Add APIs to support host save/restore the guest lbr stack
From: Like Xu This patch adds support to enable/disable the host side save/restore for the guest lbr stack on vCPU switching. To enable that, the host creates a perf event for the vCPU, and the event attributes are set to the user callstack mode lbr so that all the conditions are meet in the host perf subsystem to save the lbr stack on task switching. The host side lbr perf event are created only for the purpose of saving and restoring the lbr stack. There is no need to enable the lbr functionality for this perf event, because the feature is essentially used in the vCPU. So perf_event_create is invoked with need_counter=false to get no counter assigned for the perf event. The vcpu_lbr field is added to cpuc, to indicate if the lbr perf event is used by the vCPU only for context switching. When the perf subsystem handles this event (e.g. lbr enable or read lbr stack on PMI) and finds it's non-zero, it simply returns. Signed-off-by: Like Xu Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/events/intel/lbr.c | 13 +++-- arch/x86/events/perf_event.h| 1 + arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/pmu.h | 3 ++ arch/x86/kvm/vmx/pmu_intel.c| 61 + 5 files changed, 76 insertions(+), 3 deletions(-) diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 784642a..118764b 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -462,6 +462,9 @@ void intel_pmu_lbr_add(struct perf_event *event) if (!x86_pmu.lbr_nr) return; + if (event->attr.exclude_guest && is_no_counter_event(event)) + cpuc->vcpu_lbr = 1; + cpuc->br_sel = event->hw.branch_reg.reg; if (branch_user_callstack(cpuc->br_sel) && event->ctx->task_ctx_data) { @@ -509,6 +512,9 @@ void intel_pmu_lbr_del(struct perf_event *event) task_ctx->lbr_callstack_users--; } + if (event->attr.exclude_guest && is_no_counter_event(event)) + cpuc->vcpu_lbr = 0; + if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip > 0) cpuc->lbr_pebs_users--; cpuc->lbr_users--; @@ -521,7 +527,7 @@ void intel_pmu_lbr_enable_all(bool pmi) { struct cpu_hw_events *cpuc = this_cpu_ptr(_hw_events); - if (cpuc->lbr_users) + if (cpuc->lbr_users && !cpuc->vcpu_lbr) __intel_pmu_lbr_enable(pmi); } @@ -529,7 +535,7 @@ void intel_pmu_lbr_disable_all(void) { struct cpu_hw_events *cpuc = this_cpu_ptr(_hw_events); - if (cpuc->lbr_users) + if (cpuc->lbr_users && !cpuc->vcpu_lbr) __intel_pmu_lbr_disable(); } @@ -669,7 +675,8 @@ void intel_pmu_lbr_read(void) * This could be smarter and actually check the event, * but this simple approach seems to work for now. */ - if (!cpuc->lbr_users || cpuc->lbr_users == cpuc->lbr_pebs_users) + if (!cpuc->lbr_users || cpuc->vcpu_lbr || + cpuc->lbr_users == cpuc->lbr_pebs_users) return; if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32) diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 186c1c7..86605d1 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -238,6 +238,7 @@ struct cpu_hw_events { /* * Intel LBR bits */ + u8 vcpu_lbr; int lbr_users; int lbr_pebs_users; struct perf_branch_stacklbr_stack; diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 8d80925..79e9c92 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -474,6 +474,7 @@ struct kvm_pmu { struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; struct irq_work irq_work; u64 reprogram_pmi; + struct perf_event *vcpu_lbr_event; }; struct kvm_pmu_ops; diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 7926b65..384a0b7 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -123,6 +123,9 @@ void kvm_pmu_destroy(struct kvm_vcpu *vcpu); bool is_vmware_backdoor_pmc(u32 pmc_idx); +extern int intel_pmu_enable_save_guest_lbr(struct kvm_vcpu *vcpu); +extern void intel_pmu_disable_save_guest_lbr(struct kvm_vcpu *vcpu); + extern struct kvm_pmu_ops intel_pmu_ops; extern struct kvm_pmu_ops amd_pmu_ops; #endif /* __KVM_X86_PMU_H */ diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 09ae6ff..24a544e 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -507,6 +507,67 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu) pmu->global_ovf_ctrl = 0; } +int intel_pmu_enable_save_guest_lbr(struct kvm_vcpu *vcpu) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); +
[PATCH v7 03/12] KVM/x86: KVM_CAP_X86_GUEST_LBR
Introduce KVM_CAP_X86_GUEST_LBR to allow per-VM enabling of the guest lbr feature. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen Cc: Peter Zijlstra --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/x86.c | 14 ++ include/uapi/linux/kvm.h| 1 + 3 files changed, 17 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 26d1eb8..8d80925 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -871,6 +871,7 @@ struct kvm_arch { atomic_t vapics_in_nmi_mode; struct mutex apic_map_lock; struct kvm_apic_map *apic_map; + struct x86_perf_lbr_stack lbr_stack; bool apic_access_page_done; @@ -879,6 +880,7 @@ struct kvm_arch { bool mwait_in_guest; bool hlt_in_guest; bool pause_in_guest; + bool lbr_in_guest; unsigned long irq_sources_bitmap; s64 kvmclock_offset; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9857992..b35a118 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3086,6 +3086,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_GET_MSR_FEATURES: case KVM_CAP_MSR_PLATFORM_INFO: case KVM_CAP_EXCEPTION_PAYLOAD: + case KVM_CAP_X86_GUEST_LBR: r = 1; break; case KVM_CAP_SYNC_REGS: @@ -4622,6 +4623,19 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, kvm->arch.exception_payload_enabled = cap->args[0]; r = 0; break; + case KVM_CAP_X86_GUEST_LBR: + r = -EINVAL; + if (cap->args[0] && + x86_perf_get_lbr_stack(>arch.lbr_stack)) + break; + + if (copy_to_user((void __user *)cap->args[1], +>arch.lbr_stack, +sizeof(struct x86_perf_lbr_stack))) + break; + kvm->arch.lbr_in_guest = cap->args[0]; + r = 0; + break; default: r = -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 2fe12b4..5391cbc 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -993,6 +993,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_SVE 170 #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 +#define KVM_CAP_X86_GUEST_LBR 173 #ifdef KVM_CAP_IRQ_ROUTING -- 2.7.4
[PATCH v7 00/12] Guest LBR Enabling
Last Branch Recording (LBR) is a performance monitor unit (PMU) feature on Intel CPUs that captures branch related info. This patch series enables this feature to KVM guests. Here is a conclusion of the fundamental methods that we use: 1) the LBR feature is enabled per guest via QEMU setting of KVM_CAP_X86_GUEST_LBR; 2) the LBR stack is passed through to the guest for direct accesses after the guest's first access to any of the lbr related MSRs; 3) the host will help save/resotre the LBR stack when the vCPU is scheduled out/in. ChangeLog: pmu.c: - patch 4: remove guest_cpuid_is_intel, which can be avoided by directly checking pmu_ops->lbr_enable. pmu_intel.c: - patch 10: include MSR_LBR_SELECT into is_lbr_msr check, and pass this msr through to the guest, instead of trapping accesses. - patch 12: fix the condition check of setting LBRS_FROZEN and COUNTERS_FROZEN; update the global_ovf_ctrl_mask for LBRS_FROZEN and COUNTERS_FROZEN. previous: https://lkml.org/lkml/2019/6/6/133 Like Xu (1): KVM/x86/vPMU: Add APIs to support host save/restore the guest lbr stack Wei Wang (11): perf/x86: fix the variable type of the LBR MSRs perf/x86: add a function to get the lbr stack KVM/x86: KVM_CAP_X86_GUEST_LBR KVM/x86: intel_pmu_lbr_enable KVM/x86/vPMU: tweak kvm_pmu_get_msr KVM/x86: expose MSR_IA32_PERF_CAPABILITIES to the guest perf/x86: no counter allocation support perf/x86: save/restore LBR_SELECT on vCPU switching KVM/x86/lbr: lazy save the guest lbr stack KVM/x86: remove the common handling of the debugctl msr KVM/VMX/vPMU: support to report GLOBAL_STATUS_LBRS_FROZEN arch/x86/events/core.c| 12 ++ arch/x86/events/intel/lbr.c | 43 - arch/x86/events/perf_event.h | 6 +- arch/x86/include/asm/kvm_host.h | 5 + arch/x86/include/asm/perf_event.h | 16 ++ arch/x86/kvm/cpuid.c | 2 +- arch/x86/kvm/pmu.c| 29 ++- arch/x86/kvm/pmu.h| 12 +- arch/x86/kvm/pmu_amd.c| 7 +- arch/x86/kvm/vmx/pmu_intel.c | 393 +- arch/x86/kvm/vmx/vmx.c| 4 +- arch/x86/kvm/vmx/vmx.h| 2 + arch/x86/kvm/x86.c| 32 ++-- include/linux/perf_event.h| 13 ++ include/uapi/linux/kvm.h | 1 + kernel/events/core.c | 37 ++-- 16 files changed, 562 insertions(+), 52 deletions(-) -- 2.7.4
[PATCH v7 05/12] KVM/x86/vPMU: tweak kvm_pmu_get_msr
This patch changes kvm_pmu_get_msr to get the msr_data struct, because The host_initiated field from the struct could be used by get_msr. This also makes this API be consistent with kvm_pmu_set_msr. Signed-off-by: Wei Wang Cc: Paolo Bonzini Cc: Andi Kleen --- arch/x86/kvm/pmu.c | 4 ++-- arch/x86/kvm/pmu.h | 4 ++-- arch/x86/kvm/pmu_amd.c | 7 --- arch/x86/kvm/vmx/pmu_intel.c | 19 +++ arch/x86/kvm/x86.c | 4 ++-- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 7d7ac18..ee6ed47 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -315,9 +315,9 @@ bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) return kvm_x86_ops->pmu_ops->is_valid_msr(vcpu, msr); } -int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data) +int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { - return kvm_x86_ops->pmu_ops->get_msr(vcpu, msr, data); + return kvm_x86_ops->pmu_ops->get_msr(vcpu, msr_info); } int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index c099b4b..7926b65 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -30,7 +30,7 @@ struct kvm_pmu_ops { int (*is_valid_msr_idx)(struct kvm_vcpu *vcpu, unsigned idx); bool (*is_valid_msr)(struct kvm_vcpu *vcpu, u32 msr); bool (*lbr_enable)(struct kvm_vcpu *vcpu); - int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr, u64 *data); + int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info); int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info); void (*refresh)(struct kvm_vcpu *vcpu); void (*init)(struct kvm_vcpu *vcpu); @@ -114,7 +114,7 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu); int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data); int kvm_pmu_is_valid_msr_idx(struct kvm_vcpu *vcpu, unsigned idx); bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr); -int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data); +int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info); int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info); void kvm_pmu_refresh(struct kvm_vcpu *vcpu); void kvm_pmu_reset(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/pmu_amd.c b/arch/x86/kvm/pmu_amd.c index c838838..4a64a3f 100644 --- a/arch/x86/kvm/pmu_amd.c +++ b/arch/x86/kvm/pmu_amd.c @@ -208,21 +208,22 @@ static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) return ret; } -static int amd_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data) +static int amd_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); struct kvm_pmc *pmc; + u32 msr = msr_info->index; /* MSR_PERFCTRn */ pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_COUNTER); if (pmc) { - *data = pmc_read_counter(pmc); + msr_info->data = pmc_read_counter(pmc); return 0; } /* MSR_EVNTSELn */ pmc = get_gp_pmc_amd(pmu, msr, PMU_TYPE_EVNTSEL); if (pmc) { - *data = pmc->eventsel; + msr_info->data = pmc->eventsel; return 0; } diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index ef8ebd4..1e19b01 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -297,35 +297,38 @@ static bool intel_pmu_lbr_enable(struct kvm_vcpu *vcpu) return true; } -static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data) +static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); struct kvm_pmc *pmc; + u32 msr = msr_info->index; switch (msr) { case MSR_CORE_PERF_FIXED_CTR_CTRL: - *data = pmu->fixed_ctr_ctrl; + msr_info->data = pmu->fixed_ctr_ctrl; return 0; case MSR_CORE_PERF_GLOBAL_STATUS: - *data = pmu->global_status; + msr_info->data = pmu->global_status; return 0; case MSR_CORE_PERF_GLOBAL_CTRL: - *data = pmu->global_ctrl; + msr_info->data = pmu->global_ctrl; return 0; case MSR_CORE_PERF_GLOBAL_OVF_CTRL: - *data = pmu->global_ovf_ctrl; + msr_info->data = pmu->global_ovf_ctrl; return 0; default: if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { u64 val = pmc_read_counter(pmc); - *data = val & pmu->counter_bitmask[KVM_PMC_GP]; + msr_info->data = + val & pmu->counter_bitmask[KVM_PMC_GP]; return 0; } else
Re: [RFT][PATCH 2/2] regulator: lm363x: Fix n_voltages setting for lm36274
Axel Lin 於 2019年6月27日 週四 上午7:58寫道: > > > > With your current code where LM36274_LDO_VSEL_MAX and n_voltages is 0x34, > > > the maximum voltage will become 40 + 5 * 0x34 = 6.6V which > > > does not match the datasheet. > > > > Not sure how you get 6.6v the LDO max is 6.5v. > > > > After 0x32->0x7f maps to 6.5v > > > > 00 = 4 V > > 01 = 4.05 V > > : > > 00 = 5.5 V (Default) > > : > > 110010 = 6.5 V > > > > 110011 to 11 map to 6.5 V <- Should never see 6.6v from LDO > > > > Page 7 of the Datasheet says range is 4v->6.5v > Hi Dan, > > The device indeed can only support up to 6.5V, the point is you are using > linear equation to calculate the voltage of each selecter. > In your current code: > #define LM36274_LDO_VSEL_MAX 0x34 (and it's .n_voltages) > So it supports selector 0 ... 0x33. > For selector 0x33 in the linear equation is > 400 + 5 * 51 = 655 (i.e. 6.55V) > i.e. The device actually only support up to 6.5V but the driver > reports it support up to 6.55V > because regulator_list_voltage() will return 6.55V for selector 0x33. > (I have off-by-one in my previous reply because when .n_voltages is > 0x34, it supports up to 0x33) Similar comment as I mentioned in another path. Did you check regulator_list_voltage() output for the boundary case with and without this patch?
Re: [RFT][PATCH 1/2] regulator: lm363x: Fix off-by-one n_voltages for lm3632 ldo_vpos/ldo_vneg
Axel Lin 於 2019年6月26日 週三 下午11:12寫道: > > Dan Murphy 於 2019年6月26日 週三 下午11:07寫道: > > > > Hello > > > > On 6/26/19 8:26 AM, Axel Lin wrote: > > > According to the datasheet https://www.ti.com/lit/ds/symlink/lm3632a.pdf > > > Table 20. VPOS Bias Register Field Descriptions VPOS[5:0] > > > Sets the Positive Display Bias (LDO) Voltage (50 mV per step) > > > 00: 4 V > > > 01: 4.05 V > > > 10: 4.1 V > > > > > > 011101: 5.45 V > > > 00: 5.5 V (Default) > > > 01: 5.55 V > > > > > > 100111: 5.95 V > > > 101000: 6 V > > > Note: Codes 101001 to 11 map to 6 V > > > > > > The LM3632_LDO_VSEL_MAX should be 0b101000 (0x28), so the maximum voltage > > > can match the datasheet. > > > > > > Fixes: 3a8d1a73a037 ("regulator: add LM363X driver") > > > Signed-off-by: Axel Lin > > > --- > > > drivers/regulator/lm363x-regulator.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/drivers/regulator/lm363x-regulator.c > > > b/drivers/regulator/lm363x-regulator.c > > > index 5647e2f97ff8..e4a27d63bf90 100644 > > > --- a/drivers/regulator/lm363x-regulator.c > > > +++ b/drivers/regulator/lm363x-regulator.c > > > @@ -30,7 +30,7 @@ > > > > > > /* LM3632 */ > > > #define LM3632_BOOST_VSEL_MAX 0x26 > > > -#define LM3632_LDO_VSEL_MAX 0x29 > > > +#define LM3632_LDO_VSEL_MAX 0x28 > > > > Similar comment as I made on the LM36274 > > > > These are 0 based registers so it is 28 + 1 > The code shows: .n_voltages = LM3632_LDO_VSEL_MAX + 1 > so LM3632_LDO_VSEL_MAX needs to be 0x28. > > .name = "ldo_vpos", > .of_match = "vpos", > .id = LM3632_LDO_POS, > .ops= _regulator_voltage_table_ops, > .n_voltages = LM3632_LDO_VSEL_MAX + 1, Hi Dan, I'm wondering if you read my previous reply. You can try to call regulator_list_voltage() for selector 0x29 with current code, I believe it will return 6.05V which is wrong because the h/w only support up to 6V. And that is exactly the issue this patch try to fix. BTW, you seem mixes the meaning of latest valid selector (LM3632_LDO_VSEL_MAX) with n_voltage since you mentioned it's 0 based registers. >From the context all the LM3632_LDO_xxx_MAX are defined as latest valid selector because you can find the code: .n_voltages = LM3632_LDO_VSEL_MAX + 1. Regards, Axel
RE: linux-next: build failure after merge of the slave-dma tree
On 06-07-19, 22:43, Vinod Koul wrote: > > That's caused by 'of_irq_count' NOT export to global symbol, and I'm > > curious why it has been here for so long since Zhangfei found it in > > 2015. > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc > > > hwork.kernel.org%2Fpatch%2F7404681%2Fdata=02%7C01%7Cyibin.gon > g%40 > > > nxp.com%7C6172242dfadd4f71c09a08d70220bf6f%7C686ea1d3bc2b4c6fa92 > cd99c5 > > > c301635%7C0%7C0%7C636980211986259586sdata=L8v%2B1o5zfgIAS > go4qr3pu > > cQ%2Byox1irANsvRv5ZNLlLM%3Dreserved=0 > > Yes this does not seem to be applied, perhaps Rob can explain why. But this > was > not exported how did you test it? I had no such issue because I built in fsl-edma instead of Stephen's config with building module.
Re: linux-next: manual merge of the akpm-current tree with the pidfd tree
Hi all, On Wed, 15 May 2019 13:16:29 +1000 Stephen Rothwell wrote: > > Today's linux-next merge of the akpm-current tree got a conflict in: > > include/linux/pid.h > > between commit: > > 51f1b521a515 ("pidfd: add polling support") > > from the pidfd tree and commit: > > c02e28a1bb18 ("kernel/pid.c: convert struct pid:count to refcount_t") > > from the akpm-current tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > -- > Cheers, > Stephen Rothwell > > diff --cc include/linux/pid.h > index 1484db6ca8d1,0be5829ddd80.. > --- a/include/linux/pid.h > +++ b/include/linux/pid.h > @@@ -3,7 -3,7 +3,8 @@@ > #define _LINUX_PID_H > > #include > +#include > + #include > > enum pid_type > { I am still getting this conflict (the commits have changed). Just a reminder in case you think Linus may need to know. -- Cheers, Stephen Rothwell pgpbgwuwV9HaX.pgp Description: OpenPGP digital signature
linux-next: manual merge of the jc_docs tree with the vfs tree
Hi all, Today's linux-next merge of the jc_docs tree got a conflict in: Documentation/filesystems/vfs.txt between commit: 51eae7431ded ("vfs: Kill mount_single()") from the vfs tree and commit: af96c1e304f7 ("docs: filesystems: vfs: Convert vfs.txt to RST") from the jc_docs tree. I fixed it up (I removed the file and added the following merge fix patch) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. From: Stephen Rothwell Date: Mon, 8 Jul 2019 11:48:39 +1000 Subject: [PATCH] docs: filesystems: vfs: update for "vfs: Kill mount_single()" Signed-off-by: Stephen Rothwell --- Documentation/filesystems/vfs.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index 0f85ab21c2ca..a65ee69f02d1 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -195,8 +195,8 @@ and provides a fill_super() callback instead. The generic variants are: ``mount_nodev`` mount a filesystem that is not backed by a device -``mount_single`` - mount a filesystem which shares the instance between all mounts +``vfs_get_super`` + mount a filesystem with one of a number of superblock sharing options. A fill_super() callback implementation has the following arguments: -- 2.20.1 -- Cheers, Stephen Rothwell pgpDF3qmcZn70.pgp Description: OpenPGP digital signature
Re: [PATCH v8 net-next 0/5] net: ethernet: ti: cpsw: Add XDP support
From: David Miller Date: Sun, 07 Jul 2019 18:31:46 -0700 (PDT) > From: Ivan Khoronzhuk > Date: Fri, 5 Jul 2019 18:04:57 +0300 > >> This patchset adds XDP support for TI cpsw driver and base it on >> page_pool allocator. It was verified on af_xdp socket drop, >> af_xdp l2f, ebpf XDP_DROP, XDP_REDIRECT, XDP_PASS, XDP_TX. >> >> It was verified with following configs enabled: > ... > > I'm applying this to net-next, please deal with whatever follow-ups are > necessary. Nevermind, you really have to fix this: drivers/net/ethernet/ti/davinci_cpdma.c: In function ‘cpdma_chan_submit_si’: drivers/net/ethernet/ti/davinci_cpdma.c:1047:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] buffer = (u32)si->data; ^ drivers/net/ethernet/ti/davinci_cpdma.c: In function ‘cpdma_chan_idle_submit_mapped’: drivers/net/ethernet/ti/davinci_cpdma.c:1114:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] si.data = (void *)(u32)data; ^ drivers/net/ethernet/ti/davinci_cpdma.c: In function ‘cpdma_chan_submit_mapped’: drivers/net/ethernet/ti/davinci_cpdma.c:1164:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] si.data = (void *)(u32)data; ^
Re: [PATCH v8 net-next 0/5] net: ethernet: ti: cpsw: Add XDP support
From: Ivan Khoronzhuk Date: Fri, 5 Jul 2019 18:04:57 +0300 > This patchset adds XDP support for TI cpsw driver and base it on > page_pool allocator. It was verified on af_xdp socket drop, > af_xdp l2f, ebpf XDP_DROP, XDP_REDIRECT, XDP_PASS, XDP_TX. > > It was verified with following configs enabled: ... I'm applying this to net-next, please deal with whatever follow-ups are necessary. Thanks!
RE: linux-next: build failure after merge of the slave-dma tree
Hi Stephen, That's caused by 'of_irq_count' NOT export to global symbol, and I'm curious why it has been here for so long since Zhangfei found it in 2015. https://patchwork.kernel.org/patch/7404681/ Hi Rob, Is there something I miss so that Zhangfei's patch not accepted finally? On 04-07-19, 15:31 Stephen Rothwell wrote: > Hi all, > > After merging the slave-dma tree, today's linux-next build (x86_64 > allmodconfig) failed like this: > > ERROR: "of_irq_count" [drivers/dma/fsl-edma.ko] undefined! > > Caused by commit > > 7144afd025b2 ("dmaengine: fsl-edma: add i.mx7ulp edma2 version > support") > > I have reverted that commit for today. > > -- > Cheers, > Stephen Rothwell
Re: [PATCH v2] powerpc/mm: mark more tlb functions as __always_inline
On Tue, 2019-05-21 at 13:13:24 UTC, Masahiro Yamada wrote: > With CONFIG_OPTIMIZE_INLINING enabled, Laura Abbott reported error > with gcc 9.1.1: > > arch/powerpc/mm/book3s64/radix_tlb.c: In function '_tlbiel_pid': > arch/powerpc/mm/book3s64/radix_tlb.c:104:2: warning: asm operand 3 probably > doesn't match constraints > 104 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) > | ^~~ > arch/powerpc/mm/book3s64/radix_tlb.c:104:2: error: impossible constraint in > 'asm' > > Fixing _tlbiel_pid() is enough to address the warning above, but I > inlined more functions to fix all potential issues. > > To meet the "i" (immediate) constraint for the asm operands, functions > propagating "ric" must be always inlined. > > Fixes: 9012d011660e ("compiler: allow all arches to enable > CONFIG_OPTIMIZE_INLINING") > Reported-by: Laura Abbott > Signed-off-by: Masahiro Yamada > Reviewed-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/6d3ca7e73642ce17398f4cd5df1780da4a1ccdaf cheers
Re: [PATCH 1/4] powerpc/64: flush_inval_dcache_range() becomes flush_dcache_range()
On Tue, 2019-05-14 at 09:05:13 UTC, Christophe Leroy wrote: > On most arches having function flush_dcache_range(), including PPC32, > this function does a writeback and invalidation of the cache bloc. > > On PPC64, flush_dcache_range() only does a writeback while > flush_inval_dcache_range() does the invalidation in addition. > > In addition it looks like within arch/powerpc/, there are no PPC64 > platforms using flush_dcache_range() > > This patch drops the existing 64 bits version of flush_dcache_range() > and renames flush_inval_dcache_range() into flush_dcache_range(). > > Signed-off-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/1cfb725fb1899dc6fdc88f8b5354a65e8ad260c6 cheers
Re: [PATCH] selftests/powerpc: Add missing newline at end of file
On Mon, 2019-06-17 at 14:52:04 UTC, Geert Uytterhoeven wrote: > "git diff" says: > > \ No newline at end of file > > after modifying the file. > > Signed-off-by: Geert Uytterhoeven Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/7b570361f6f66c91443541b19121038c076e7d64 cheers
Re: [PATCH v3 3/5] powerpc: Use the correct style for SPDX License Identifier
On Tue, 2019-04-16 at 15:28:57 UTC, Nishad Kamdar wrote: > This patch corrects the SPDX License Identifier style > in the powerpc Hardware Architecture related files. > > Suggested-by: Joe Perches > Signed-off-by: Nishad Kamdar > Acked-by: Andrew Donnellan Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/2200bbec12c428d7b276fb450e5755cdfe435ae5 cheers
Re: [PATCH v3 01/10] powerpc/8xx: move CPM1 related files from sysdev/ to platforms/8xx
On Fri, 2019-06-14 at 06:41:38 UTC, Christophe Leroy wrote: > Only 8xx selects CPM1 and related CONFIG options are already > in platforms/8xx/Kconfig > > Move the related C files to platforms/8xx/. > > Signed-off-by: Christophe Leroy Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/4128a89ac80d3714babde5b2811ffd058b09c229 cheers
Re: [PATCH] powerpc/cell: set no_llseek in spufs_cntl_fops
On Sat, 2017-05-06 at 15:37:20 UTC, Geliang Tang wrote: > In spufs_cntl_fops, since we use nonseekable_open() to open, we > should use no_llseek() to seek, not generic_file_llseek(). > > Signed-off-by: Geliang Tang Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/658829dfe75c49e879e0c4c9cbcd3bd1e4fbdcf5 cheers
Re: [PATCH v3 1/3] powerpc/boot: don't force gzipped uImage
On Fri, 2019-06-14 at 10:16:23 UTC, Christophe Leroy wrote: > This patch modifies the generation of uImage by handing over > the selected compression type instead of forcing gzip > > Signed-off-by: Christophe Leroy Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/fbded57c962e7c42c932e1a46c8d801441726662 cheers
Re: [PATCH] powerpc/perf/24x7: use rb_entry
On Tue, 2016-12-20 at 14:02:17 UTC, Geliang Tang wrote: > To make the code clearer, use rb_entry() instead of container_of() to > deal with rbtree. > > Signed-off-by: Geliang Tang Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/c197922f0a8072d286dff8001f8ad0d4b95ec1dd cheers
Re: [PATCH] powerpc/configs: Remove useless UEVENT_HELPER_PATH
On Tue, 2019-06-04 at 08:00:33 UTC, Krzysztof Kozlowski wrote: > Remove the CONFIG_UEVENT_HELPER_PATH because: > 1. It is disabled since commit 1be01d4a5714 ("driver: base: Disable >CONFIG_UEVENT_HELPER by default") as its dependency (UEVENT_HELPER) was >made default to 'n', > 2. It is not recommended (help message: "This should not be used today >[...] creates a high system load") and was kept only for ancient >userland, > 3. Certain userland specifically requests it to be disabled (systemd >README: "Legacy hotplug slows down the system and confuses udev"). > > Signed-off-by: Krzysztof Kozlowski > Acked-by: Geert Uytterhoeven Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/14b2f7d908c374df57792410bc0100dd71be4e5c cheers
Re: [PATCH v3 1/3] powerpc: Move PPC_HA() PPC_HI() and PPC_LO() to ppc-opcode.h
On Fri, 2019-05-03 at 06:40:15 UTC, Christophe Leroy wrote: > PPC_HA() PPC_HI() and PPC_LO() macros are nice macros. Move them > from module64.c to ppc-opcode.h in order to use them in other places. > > Signed-off-by: Christophe Leroy Series applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/7f9c929a7ff203eae60b4225bb6824c3eb31796c cheers
Re: [PATCH 3/4] powerpc/32: define helpers to get L1 cache sizes.
On Tue, 2019-05-14 at 09:05:15 UTC, Christophe Leroy wrote: > This patch defines C helpers to retrieve the size of > cache blocks and uses them in the cacheflush functions. > > Signed-off-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/d98fc70fc139b72ae098d24fde42ad70c8ff2f81 cheers
Re: [PATCH] arch: powerpc: Kconfig: pedantic formatting
On Wed, 2019-07-03 at 16:04:13 UTC, "Enrico Weigelt, metux IT consult" wrote: > Formatting of Kconfig files doesn't look so pretty, so let the > Great White Handkerchief come around and clean it up. > > Also convert "---help---" as requested on lkml. > > Signed-off-by: Enrico Weigelt, metux IT consult Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/4f44e8aeaf1937d9148dfcc4c028cd8aff27902e cheers
Re: [PATCH 4/4] powerpc/64: reuse PPC32 static inline flush_dcache_range()
On Tue, 2019-05-14 at 09:05:16 UTC, Christophe Leroy wrote: > This patch drops the assembly PPC64 version of flush_dcache_range() > and re-uses the PPC32 static inline version. > > With GCC 8.1, the following code is generated: > > void flush_test(unsigned long start, unsigned long stop) > { > flush_dcache_range(start, stop); > } > > 0130 <.flush_test>: > 130: 3d 22 00 00 addis r9,r2,0 > 132: R_PPC64_TOC16_HA .data+0x8 > 134: 81 09 00 00 lwz r8,0(r9) > 136: R_PPC64_TOC16_LO .data+0x8 > 138: 3d 22 00 00 addis r9,r2,0 > 13a: R_PPC64_TOC16_HA .data+0xc > 13c: 80 e9 00 00 lwz r7,0(r9) > 13e: R_PPC64_TOC16_LO .data+0xc > 140: 7d 48 00 d0 neg r10,r8 > 144: 7d 43 18 38 and r3,r10,r3 > 148: 7c 00 04 ac hwsync > 14c: 4c 00 01 2c isync > 150: 39 28 ff ff addir9,r8,-1 > 154: 7c 89 22 14 add r4,r9,r4 > 158: 7c 83 20 50 subfr4,r3,r4 > 15c: 7c 89 3c 37 srd.r9,r4,r7 > 160: 41 82 00 1c beq 17c <.flush_test+0x4c> > 164: 7d 29 03 a6 mtctr r9 > 168: 60 00 00 00 nop > 16c: 60 00 00 00 nop > 170: 7c 00 18 ac dcbf0,r3 > 174: 7c 63 42 14 add r3,r3,r8 > 178: 42 00 ff f8 bdnz170 <.flush_test+0x40> > 17c: 7c 00 04 ac hwsync > 180: 4c 00 01 2c isync > 184: 4e 80 00 20 blr > 188: 60 00 00 00 nop > 18c: 60 00 00 00 nop > > Signed-off-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/22e9c88d486a0536d337d6e0973968be0a4cd4b2 cheers
Re: [PATCH v2] powerpc: slightly improve cache helpers
On Fri, 2019-05-10 at 09:24:48 UTC, Christophe Leroy wrote: > Cache instructions (dcbz, dcbi, dcbf and dcbst) take two registers > that are summed to obtain the target address. Using 'Z' constraint > and '%y0' argument gives GCC the opportunity to use both registers > instead of only one with the second being forced to 0. > > Suggested-by: Segher Boessenkool > Signed-off-by: Christophe Leroy Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/6c5875843b87c3adea2beade9d1b8b3d4523900a cheers
linux-next: manual merge of the vfs tree with the nfsd tree
Hi all, Today's linux-next merge of the vfs tree got a conflict in: fs/nfsd/nfsctl.c between commits: e8a79fb14f6b ("nfsd: add nfsd/clients directory") from the nfsd tree and commit: 96a374a35f82 ("vfs: Convert nfsctl to use the new mount API") from the vfs tree. I fixed it up (Maybe? see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc fs/nfsd/nfsctl.c index 4683ba5c69c7,bbff9c4ac49f.. --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@@ -1149,201 -1148,8 +1150,201 @@@ static ssize_t write_v4_end_grace(struc *populating the filesystem. */ +/* Basically copying rpc_get_inode. */ +static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) +{ + struct inode *inode = new_inode(sb); + if (!inode) + return NULL; + /* Following advice from simple_fill_super documentation: */ + inode->i_ino = iunique(sb, NFSD_MaxReserved); + inode->i_mode = mode; + inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); + switch (mode & S_IFMT) { + case S_IFDIR: + inode->i_fop = _dir_operations; + inode->i_op = _dir_inode_operations; + inc_nlink(inode); + default: + break; + } + return inode; +} + +static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +{ + struct inode *inode; + + inode = nfsd_get_inode(dir->i_sb, mode); + if (!inode) + return -ENOMEM; + d_add(dentry, inode); + inc_nlink(dir); + fsnotify_mkdir(dir, dentry); + return 0; +} + +static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name) +{ + struct inode *dir = parent->d_inode; + struct dentry *dentry; + int ret = -ENOMEM; + + inode_lock(dir); + dentry = d_alloc_name(parent, name); + if (!dentry) + goto out_err; + ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600); + if (ret) + goto out_err; + if (ncl) { + d_inode(dentry)->i_private = ncl; + kref_get(>cl_ref); + } +out: + inode_unlock(dir); + return dentry; +out_err: + dentry = ERR_PTR(ret); + goto out; +} + +static void clear_ncl(struct inode *inode) +{ + struct nfsdfs_client *ncl = inode->i_private; + + inode->i_private = NULL; + synchronize_rcu(); + kref_put(>cl_ref, ncl->cl_release); +} + + +struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode) +{ + struct nfsdfs_client *nc = inode->i_private; + + if (nc) + kref_get(>cl_ref); + return nc; +} + +struct nfsdfs_client *get_nfsdfs_client(struct inode *inode) +{ + struct nfsdfs_client *nc; + + rcu_read_lock(); + nc = __get_nfsdfs_client(inode); + rcu_read_unlock(); + return nc; +} +/* from __rpc_unlink */ +static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry) +{ + int ret; + + clear_ncl(d_inode(dentry)); + dget(dentry); + ret = simple_unlink(dir, dentry); + d_delete(dentry); + dput(dentry); + WARN_ON_ONCE(ret); +} + +static void nfsdfs_remove_files(struct dentry *root) +{ + struct dentry *dentry, *tmp; + + list_for_each_entry_safe(dentry, tmp, >d_subdirs, d_child) { + if (!simple_positive(dentry)) { + WARN_ON_ONCE(1); /* I think this can't happen? */ + continue; + } + nfsdfs_remove_file(d_inode(root), dentry); + } +} + +/* XXX: cut'n'paste from simple_fill_super; figure out if we could share + * code instead. */ +static int nfsdfs_create_files(struct dentry *root, + const struct tree_descr *files) +{ + struct inode *dir = d_inode(root); + struct inode *inode; + struct dentry *dentry; + int i; + + inode_lock(dir); + for (i = 0; files->name && files->name[0]; i++, files++) { + if (!files->name) + continue; + dentry = d_alloc_name(root, files->name); + if (!dentry) + goto out; + inode = nfsd_get_inode(d_inode(root)->i_sb, + S_IFREG | files->mode); + if (!inode) { + dput(dentry); + goto out; + } + inode->i_fop = files->ops; + inode->i_private =
Re: [PATCH v3 3/3] powerpc/module64: Use symbolic instructions names.
Christophe Leroy writes: > To increase readability/maintainability, replace hard coded > instructions values by symbolic names. > > Signed-off-by: Christophe Leroy > --- > v3: fixed warning by adding () in an 'if' around X | Y (unlike said in v2 > history, this change was forgotten in v2) > v2: rearranged comments > > arch/powerpc/kernel/module_64.c | 53 > +++-- > 1 file changed, 35 insertions(+), 18 deletions(-) > > diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c > index c2e1b06253b8..b33a5d5e2d35 100644 > --- a/arch/powerpc/kernel/module_64.c > +++ b/arch/powerpc/kernel/module_64.c > @@ -704,18 +711,21 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, ... > /* >* If found, replace it with: >* addis r2, r12, (.TOC.-func)@ha >* addi r2, r12, (.TOC.-func)@l >*/ > - ((uint32_t *)location)[0] = 0x3c4c + PPC_HA(value); > - ((uint32_t *)location)[1] = 0x3842 + PPC_LO(value); > + ((uint32_t *)location)[0] = PPC_INST_ADDIS | > __PPC_RT(R2) | > + __PPC_RA(R12) | > PPC_HA(value); > + ((uint32_t *)location)[1] = PPC_INST_ADDI | > __PPC_RT(R2) | > + __PPC_RA(R12) | > PPC_LO(value); > break; This was crashing and it's amazing how long you can stare at a disassembly and not see the difference between `r2` and `r12` :) Fixed now. cheers
Re: [PATCH] sched/core: Cache timer busy housekeeping target
Ping Frederic, Peterz, any comments? On Mon, 1 Jul 2019 at 20:24, Wanpeng Li wrote: > > From: Wanpeng Li > > Cache the busy housekeeping target for timer instead of researching each time. > This patch reduces the total time of get_nohz_timer_target() for busy > housekeeping > CPU from 2u~3us to less than 1us which can be observed by ftrace. > > Cc: Ingo Molnar > Cc: Peter Zijlstra > Cc: Frederic Weisbecker > Cc: Thomas Gleixner > Signed-off-by: Wanpeng Li > --- > include/linux/hrtimer.h| 1 + > include/linux/sched/nohz.h | 2 +- > kernel/sched/core.c| 6 +- > kernel/time/hrtimer.c | 6 -- > kernel/time/timer.c| 7 +-- > 5 files changed, 16 insertions(+), 6 deletions(-) > > diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h > index 2e8957e..0d8b271 100644 > --- a/include/linux/hrtimer.h > +++ b/include/linux/hrtimer.h > @@ -198,6 +198,7 @@ enum hrtimer_base_type { > struct hrtimer_cpu_base { > raw_spinlock_t lock; > unsigned intcpu; > + unsigned intlast_target_cpu; > unsigned intactive_bases; > unsigned intclock_was_set_seq; > unsigned inthres_active : 1, > diff --git a/include/linux/sched/nohz.h b/include/linux/sched/nohz.h > index 1abe91f..0afb094 100644 > --- a/include/linux/sched/nohz.h > +++ b/include/linux/sched/nohz.h > @@ -8,7 +8,7 @@ > > #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) > extern void nohz_balance_enter_idle(int cpu); > -extern int get_nohz_timer_target(void); > +extern int get_nohz_timer_target(unsigned int cpu); > #else > static inline void nohz_balance_enter_idle(int cpu) { } > #endif > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index 7968e0f..f4ba63e 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -549,11 +549,15 @@ void resched_cpu(int cpu) > * selecting an idle CPU will add more delays to the timers than intended > * (as that CPU's timer base may not be uptodate wrt jiffies etc). > */ > -int get_nohz_timer_target(void) > +int get_nohz_timer_target(unsigned int last_target_cpu) > { > int i, cpu = smp_processor_id(), default_cpu = -1; > struct sched_domain *sd; > > + if (!idle_cpu(last_target_cpu) && > + housekeeping_cpu(last_target_cpu, HK_FLAG_TIMER)) > + return last_target_cpu; > + > if (housekeeping_cpu(cpu, HK_FLAG_TIMER)) { > if (!idle_cpu(cpu)) > return cpu; > diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c > index 41dfff2..0d49bef 100644 > --- a/kernel/time/hrtimer.c > +++ b/kernel/time/hrtimer.c > @@ -195,8 +195,10 @@ struct hrtimer_cpu_base *get_target_base(struct > hrtimer_cpu_base *base, > int pinned) > { > #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) > - if (static_branch_likely(_migration_enabled) && !pinned) > - return _cpu(hrtimer_bases, get_nohz_timer_target()); > + if (static_branch_likely(_migration_enabled) && !pinned) { > + base->last_target_cpu = > get_nohz_timer_target(base->last_target_cpu); > + return _cpu(hrtimer_bases, base->last_target_cpu); > + } > #endif > return base; > } > diff --git a/kernel/time/timer.c b/kernel/time/timer.c > index 343c7ba..6ae045a 100644 > --- a/kernel/time/timer.c > +++ b/kernel/time/timer.c > @@ -199,6 +199,7 @@ struct timer_base { > unsigned long clk; > unsigned long next_expiry; > unsigned intcpu; > + unsigned intlast_target_cpu; > boolis_idle; > boolmust_forward_clk; > DECLARE_BITMAP(pending_map, WHEEL_SIZE); > @@ -865,8 +866,10 @@ get_target_base(struct timer_base *base, unsigned tflags) > { > #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) > if (static_branch_likely(_migration_enabled) && > - !(tflags & TIMER_PINNED)) > - return get_timer_cpu_base(tflags, get_nohz_timer_target()); > + !(tflags & TIMER_PINNED)) { > + base->last_target_cpu = > get_nohz_timer_target(base->last_target_cpu); > + return get_timer_cpu_base(tflags, base->last_target_cpu); > + } > #endif > return get_timer_this_cpu_base(tflags); > } > -- > 2.7.4 >
Re: [PATCH v2] tpm: tpm_ibm_vtpm: Fix unallocated banks
On 7/6/19 8:18 PM, Nayna Jain wrote: The nr_allocated_banks and allocated banks are initialized as part of tpm_chip_register. Currently, this is done as part of auto startup function. However, some drivers, like the ibm vtpm driver, do not run auto startup during initialization. This results in uninitialized memory issue and causes a kernel panic during boot. This patch moves the pcr allocation outside the auto startup function into tpm_chip_register. This ensures that allocated banks are initialized in any case. Fixes: 879b589210a9 ("tpm: retrieve digest size of unknown algorithms with PCR read") Reported-by: Michal Suchanek Signed-off-by: Nayna Jain Reviewed-by: Mimi Zohar Tested-by: Sachin Sant Tested-by: Michal Suchánek --- Changelog: v2: * Includes Jarkko's feedbacks * fixes the function name to tpm_get_pcr_allocation() * adds new function tpm1_get_pcr_allocation() * updates patch summary line * fixes alignment * adds Reported-by: Michal Suchanek * Includes Stefan's feedbacks * Fixes overwriting of return code * Fixes misplacing of tpm_chip_stop() * Adds Reviewed-by, Tested-by drivers/char/tpm/tpm-chip.c | 22 ++ drivers/char/tpm/tpm.h | 2 ++ drivers/char/tpm/tpm1-cmd.c | 36 drivers/char/tpm/tpm2-cmd.c | 6 +- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 8804c9e916fd..6589291df355 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -550,6 +550,22 @@ static int tpm_add_hwrng(struct tpm_chip *chip) return hwrng_register(>hwrng); } +/* + * tpm_get_pcr_allocation() - initialize the chip allocated banks for PCRs + * @chip: TPM chip to use. + */ +static int tpm_get_pcr_allocation(struct tpm_chip *chip) +{ + int rc; + + if (chip->flags & TPM_CHIP_FLAG_TPM2) + rc = tpm2_get_pcr_allocation(chip); For tpm2 case you need: if (rc > 0) rc = -ENODEV; Because tpm2_get_pcr_allocation(chip) returns ssize_t with return values from tpm_transmit_cmd > 0 indicating a TPM 2 error code... Stefan
Re: pagecache locking
On Sun, Jul 07, 2019 at 06:05:16PM +0300, Boaz Harrosh wrote: > On 06/07/2019 02:31, Dave Chinner wrote: > > > > > As long as the IO ranges to the same file *don't overlap*, it should > > be perfectly safe to take separate range locks (in read or write > > mode) on either side of the mmap_sem as non-overlapping range locks > > can be nested and will not self-deadlock. > > > > The "recursive lock problem" still arises with DIO and page faults > > inside gup, but it only occurs when the user buffer range overlaps > > the DIO range to the same file. IOWs, the application is trying to > > do something that has an undefined result and is likely to result in > > data corruption. So, in that case I plan to have the gup page faults > > fail and the DIO return -EDEADLOCK to userspace > > > > This sounds very cool. I now understand. I hope you put all the tools > for this in generic places so it will be easier to salvage. That's the plan, though I'm not really caring about anything outside XFS for the moment. > One thing I will be very curious to see is how you teach lockdep > about the "range locks can be nested" thing. I know its possible, > other places do it, but its something I never understood. The issue with lockdep is not nested locks, it's that there is no concept of ranges. e.g. This is fine: P0 P1 read_lock(A, 0, 1000) read_lock(B, 0, 1000) write_lock(B, 1001, 2000) write_lock(A, 1001, 2000) Because the read/write lock ranges on file A don't overlap and so can be held concurrently, similarly the ranges on file B. i.e. This lock pattern does not result in deadlock. However, this very similar lock pattern is not fine: P0 P1 read_lock(A, 0, 1000) read_lock(B, 0, 1000) write_lock(B, 500, 1500) write_lock(A, 900, 1900) i.e. it's an ABBA deadlock because the lock ranges partially overlap. IOWs, the problem with lockdep is not nesting read lock or nesting write locks (because that's valid, too), the problem is that it needs to be taught about ranges. Once it knows about ranges, nested read/write locking contexts don't require any special support... As it is, tracking overlapping lock ranges in lockdep will be interesting, given that I've been taking several thousand non-overlapping range locks concurrently on a single file in my testing. Tracking this sort of usage without completely killing the machine looking for conflicts and order violations likely makes lockdep validation of range locks a non-starter > [ Ha one more question if you have time: > > In one of the mails, and you also mentioned it before, you said about > the rw_read_lock not being able to scale well on mammoth machines > over 10ns of cores (maybe you said over 20). > I wonder why that happens. Is it because of the atomic operations, > or something in the lock algorithm. In my theoretical understanding, > as long as there are no write-lock-grabbers, why would the readers > interfere with each other? Concurrent shared read lock/unlock are still atomic counting operations. Hence they bounce exclusive cachelines from CPU to CPU... Cheers, Dave. -- Dave Chinner da...@fromorbit.com
Re: [PATCH] m68k/mac: Revisit floppy disc controller base addresses
Hi Geert, I just noticed that this patch didn't appear in v5.2. Would you please take a look? -- On Fri, 15 Feb 2019, Finn Thain wrote: > Rename floppy_type macros to make them more consistent with the scsi_type > macros, which are named after classes of models with similar memory maps. > > The documentation for LC-class machines has the IO devices at offsets > from $50F0 . Use these addresses (consistent with mac_scsi resources) > because they may not be aliased elsewhere in the memory map, e.g. at > offsets from $5000 . > > Add comments with controller type information from 'Designing Cards and > Drivers for the Macintosh Family', relevant Developer Notes and > http://mess.redump.net/mess/driver_info/mac_technical_notes > > Adopt phys_addr_t to avoid type casts. > > Cc: Laurent Vivier > Tested-by: Stan Johnson > Signed-off-by: Finn Thain > Acked-by: Laurent Vivier > --- > arch/m68k/include/asm/macintosh.h | 10 +-- > arch/m68k/mac/config.c| 128 +++--- > 2 files changed, 69 insertions(+), 69 deletions(-) >
Re: [PATCH 1/1] scsi: aacraid: resurrect correct arc ctrl checks for Series-6
Andrey, It is helpful to send your review to the patch author. I've added Konstantin to the Cc list, as well as Raghava (who introduced the regression addressed by Konstantin's patch). If I'm not mistaken, your review misunderstands the patch description. FWIW, Konstantin's patch might have been easier to follow if it was a simple 'git revert'. -- On Sun, 7 Jul 2019, Andrey Jr. Melnikov wrote: > In gmane.linux.scsi Konstantin Khorenko wrote: > > This partially reverts ms commit > > 395e5df79a95 ("scsi: aacraid: Remove reference to Series-9") > > > The patch above not only drops Series-9 cards checks but also > > changes logic for Series-6 controllers which leads to controller > > hangs/resets under high io load. > > > So revert to original arc ctrl checks for Series-6 controllers. > > > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1777586 > > https://bugzilla.redhat.com/show_bug.cgi?id=1724077 > > https://jira.sw.ru/browse/PSBM-95736 > > > Fixes: 395e5df79a95 ("scsi: aacraid: Remove reference to Series-9") > > Cc: sta...@vger.kernel.org > > > Signed-off-by: Konstantin Khorenko > > --- > > drivers/scsi/aacraid/aacraid.h | 11 --- > > drivers/scsi/aacraid/comminit.c | 14 ++ > > drivers/scsi/aacraid/commsup.c | 4 +++- > > drivers/scsi/aacraid/linit.c| 7 +-- > > 4 files changed, 18 insertions(+), 18 deletions(-) > > > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h > > index 3fa03230f6ba..b674fb645523 100644 > > --- a/drivers/scsi/aacraid/aacraid.h > > +++ b/drivers/scsi/aacraid/aacraid.h > > @@ -2729,17 +2729,6 @@ int _aac_rx_init(struct aac_dev *dev); > > int aac_rx_select_comm(struct aac_dev *dev, int comm); > > int aac_rx_deliver_producer(struct fib * fib); > > > > -static inline int aac_is_src(struct aac_dev *dev) > > -{ > > - u16 device = dev->pdev->device; > > - > > - if (device == PMC_DEVICE_S6 || > > - device == PMC_DEVICE_S7 || > > - device == PMC_DEVICE_S8) > > - return 1; > > - return 0; > > -} > > - > > Why remove helper? > > > static inline int aac_supports_2T(struct aac_dev *dev) > > { > > return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); > > diff --git a/drivers/scsi/aacraid/comminit.c > > b/drivers/scsi/aacraid/comminit.c > > index d4fcfa1e54e0..b8046b6c1239 100644 > > --- a/drivers/scsi/aacraid/comminit.c > > +++ b/drivers/scsi/aacraid/comminit.c > > @@ -41,7 +41,9 @@ static inline int aac_is_msix_mode(struct aac_dev *dev) > > { > > u32 status = 0; > > > > - if (aac_is_src(dev)) > > + if (dev->pdev->device == PMC_DEVICE_S6 || > > + dev->pdev->device == PMC_DEVICE_S7 || > > + dev->pdev->device == PMC_DEVICE_S8) > > status = src_readl(dev, MUnit.OMR); > > return (status & AAC_INT_MODE_MSIX); > > } > > @@ -349,7 +351,8 @@ int aac_send_shutdown(struct aac_dev * dev) > > /* FIB should be freed only after getting the response from the F/W > > */ > > if (status != -ERESTARTSYS) > > aac_fib_free(fibctx); > Fix this > > - if (aac_is_src(dev) && > > + if ((dev->pdev->device == PMC_DEVICE_S7 || > > +dev->pdev->device == PMC_DEVICE_S8) && > > dev->msi_enabled) > > aac_set_intx_mode(dev); > > return status; > > @@ -605,7 +608,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) > > dev->max_fib_size = status[1] & 0xFFE0; > > host->sg_tablesize = status[2] >> 16; > > dev->sg_tablesize = status[2] & 0x; > this one > > - if (aac_is_src(dev)) { > > + if (dev->pdev->device == PMC_DEVICE_S7 || > > + dev->pdev->device == PMC_DEVICE_S8) { > > if (host->can_queue > (status[3] >> 16) - > > AAC_NUM_MGT_FIB) > > host->can_queue = (status[3] >> 16) - > > @@ -624,7 +628,9 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) > > pr_warn("numacb=%d ignored\n", numacb); > > } > > > > - if (aac_is_src(dev)) > > + if (dev->pdev->device == PMC_DEVICE_S6 || > > + dev->pdev->device == PMC_DEVICE_S7 || > > + dev->pdev->device == PMC_DEVICE_S8) > > aac_define_int_mode(dev); > > /* > > * Ok now init the communication subsystem > > diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c > > index 2142a649e865..705e003caa95 100644 > > --- a/drivers/scsi/aacraid/commsup.c > > +++ b/drivers/scsi/aacraid/commsup.c > > @@ -2574,7 +2574,9 @@ void aac_free_irq(struct aac_dev *dev) > > { > > int i; > > > > - if (aac_is_src(dev)) { > > + if (dev->pdev->device == PMC_DEVICE_S6 || > > + dev->pdev->device == PMC_DEVICE_S7 || > > +
[PATCH v1 6/6] cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from all states
The Tegra's clocksource driver got some rework recently and now the internal/local CPU timers usage is discouraged on Tegra20/30 SoCs in a favor of the platform-specific timers that are assigned as per-CPU clocksources because they do not suffer from the CPU-freq changes and are always-ON during of CPU-idling. That happened in the commit f6d50ec5f85c ("clocksource/drivers/tegra: Support per-CPU timers on all Tegra's"). The Tegra's clocksource driver is the essential arch-driver that is guaranteed to always present on all Tegra SoCs up to Tegra124. Signed-off-by: Dmitry Osipenko --- drivers/cpuidle/cpuidle-tegra.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c index 464b2376905a..e2aa46231c05 100644 --- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -143,7 +143,6 @@ static struct cpuidle_driver tegra_idle_driver = { .exit_latency = 2000, .target_residency = 2200, .power_usage= 0, - .flags = CPUIDLE_FLAG_TIMER_STOP, .name = "powered-down", .desc = "CPU core powered-off", }, @@ -152,8 +151,7 @@ static struct cpuidle_driver tegra_idle_driver = { .exit_latency = 5000, .target_residency = 1, .power_usage= 0, - .flags = CPUIDLE_FLAG_COUPLED | - CPUIDLE_FLAG_TIMER_STOP, + .flags = CPUIDLE_FLAG_COUPLED, .name = "powered-down", .desc = "CPU cluster powered-off", }, -- 2.22.0
[PATCH v1 5/6] cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from Tegra114/124 idle-state
Local CPU timers are always-ON on the Tegra114/124 SoCs regardless of the CPU's idle state. Signed-off-by: Dmitry Osipenko --- drivers/cpuidle/cpuidle-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c index 31eeef22c0ff..464b2376905a 100644 --- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -163,7 +163,6 @@ static struct cpuidle_driver tegra_idle_driver = { .exit_latency = 500, .target_residency = 1000, .power_usage= 0, - .flags = CPUIDLE_FLAG_TIMER_STOP, .name = "powered-down", .desc = "CPU core power-gated", }, -- 2.22.0
[PATCH v1 1/6] ARM: tegra: Remove cpuidle drivers
Remove the old drivers to replace them cleanly with a new one later on. Signed-off-by: Dmitry Osipenko --- arch/arm/mach-tegra/Makefile | 13 -- arch/arm/mach-tegra/cpuidle-tegra114.c | 89 --- arch/arm/mach-tegra/cpuidle-tegra20.c | 212 - arch/arm/mach-tegra/cpuidle-tegra30.c | 132 --- arch/arm/mach-tegra/cpuidle.c | 50 -- arch/arm/mach-tegra/cpuidle.h | 21 --- arch/arm/mach-tegra/irq.c | 18 --- arch/arm/mach-tegra/irq.h | 11 -- arch/arm/mach-tegra/pm.c | 7 - arch/arm/mach-tegra/pm.h | 1 - arch/arm/mach-tegra/reset-handler.S| 11 -- arch/arm/mach-tegra/reset.h| 9 +- arch/arm/mach-tegra/sleep-tegra20.S| 190 +- arch/arm/mach-tegra/sleep.h| 12 -- arch/arm/mach-tegra/tegra.c| 3 - drivers/soc/tegra/Kconfig | 1 - include/soc/tegra/cpuidle.h| 4 - 17 files changed, 5 insertions(+), 779 deletions(-) delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c delete mode 100644 arch/arm/mach-tegra/cpuidle.c delete mode 100644 arch/arm/mach-tegra/cpuidle.h delete mode 100644 arch/arm/mach-tegra/irq.h diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 6c1dff2eccc2..5d93a0b36866 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -8,29 +8,16 @@ obj-y += reset.o obj-y += reset-handler.o obj-y += sleep.o obj-y += tegra.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC)+= sleep-tegra20.o obj-$(CONFIG_ARCH_TEGRA_2x_SOC)+= pm-tegra20.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_2x_SOC)+= cpuidle-tegra20.o -endif obj-$(CONFIG_ARCH_TEGRA_3x_SOC)+= sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC)+= pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_3x_SOC)+= cpuidle-tegra30.o -endif obj-$(CONFIG_SMP) += platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o -endif obj-$(CONFIG_ARCH_TEGRA_124_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_124_SOC) += pm-tegra30.o -ifeq ($(CONFIG_CPU_IDLE),y) -obj-$(CONFIG_ARCH_TEGRA_124_SOC) += cpuidle-tegra114.o -endif obj-$(CONFIG_ARCH_TEGRA_2x_SOC)+= board-paz00.o diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c deleted file mode 100644 index 5118f777fd66.. --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "cpuidle.h" -#include "pm.h" -#include "sleep.h" - -#ifdef CONFIG_PM_SLEEP -#define TEGRA114_MAX_STATES 2 -#else -#define TEGRA114_MAX_STATES 1 -#endif - -#ifdef CONFIG_PM_SLEEP -static int tegra114_idle_power_down(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - local_fiq_disable(); - - tegra_set_cpu_in_lp2(); - cpu_pm_enter(); - - call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2); - - /* Do suspend by ourselves if the firmware does not implement it */ - if (call_firmware_op(do_idle, 0) == -ENOSYS) - cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); - - cpu_pm_exit(); - tegra_clear_cpu_in_lp2(); - - local_fiq_enable(); - - return index; -} - -static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - tegra114_idle_power_down(dev, drv, index); -} -#endif - -static struct cpuidle_driver tegra_idle_driver = { - .name = "tegra_idle", - .owner = THIS_MODULE, - .state_count = TEGRA114_MAX_STATES, - .states = { - [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), -#ifdef CONFIG_PM_SLEEP - [1] = { - .enter = tegra114_idle_power_down, - .enter_s2idle = tegra114_idle_enter_s2idle, - .exit_latency = 500, -
[PATCH v1 0/6] Consolidate and improve NVIDIA Tegra CPUIDLE driver(s)
Hello, I was spending quite some time recently trying to hunt down CPU-suspend bug on Tegra30 SoC and in the end it was nailed. During that time I realized that the CPU Idle drivers could get some polish and gain new features, thus that's what this series does: 1. Unifies Tegra20/30/114 drivers into a single driver and moves it out into common drivers/cpuidle/ directory. 2. Enables CPU cluster power-down idling state on Tegra30. 3. Removes CPUIDLE_FLAG_TIMER_STOP from all of the states since that flag is not relevant anymore. In the end there is a quite nice clean up of the Terga CPUIDLE driver(s) and of the Tegra's arch code in general. Please review, thanks! Dmitry Osipenko (6): ARM: tegra: Remove cpuidle drivers ARM: tegra: Expose functions required for cpuidle driver cpuidle: Add unified driver for NVIDIA Tegra SoCs cpuidle: tegra: Support CPU cluster power-down on Tegra30 cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from Tegra114/124 idle-state cpuidle: tegra: Remove CPUIDLE_FLAG_TIMER_STOP from all states arch/arm/mach-tegra/Makefile | 15 +- arch/arm/mach-tegra/cpuidle-tegra114.c | 89 -- arch/arm/mach-tegra/cpuidle-tegra20.c | 212 -- arch/arm/mach-tegra/cpuidle-tegra30.c | 132 -- arch/arm/mach-tegra/cpuidle.c | 50 -- arch/arm/mach-tegra/cpuidle.h | 21 --- arch/arm/mach-tegra/irq.c | 18 -- arch/arm/mach-tegra/irq.h | 11 -- arch/arm/mach-tegra/platsmp.c | 2 - arch/arm/mach-tegra/pm.c | 27 +-- arch/arm/mach-tegra/pm.h | 4 - arch/arm/mach-tegra/reset-handler.S| 11 -- arch/arm/mach-tegra/reset.h| 9 +- arch/arm/mach-tegra/sleep-tegra20.S| 190 +--- arch/arm/mach-tegra/sleep.h| 13 -- arch/arm/mach-tegra/tegra.c| 7 +- drivers/cpuidle/Kconfig.arm| 8 + drivers/cpuidle/Makefile | 1 + drivers/cpuidle/cpuidle-tegra.c| 232 + drivers/soc/tegra/Kconfig | 1 - include/linux/clk/tegra.h | 13 ++ include/soc/tegra/cpuidle.h| 2 +- include/soc/tegra/pm.h | 28 +++ 23 files changed, 302 insertions(+), 794 deletions(-) delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra114.c delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra20.c delete mode 100644 arch/arm/mach-tegra/cpuidle-tegra30.c delete mode 100644 arch/arm/mach-tegra/cpuidle.c delete mode 100644 arch/arm/mach-tegra/cpuidle.h delete mode 100644 arch/arm/mach-tegra/irq.h create mode 100644 drivers/cpuidle/cpuidle-tegra.c -- 2.22.0
[PATCH v1 2/6] ARM: tegra: Expose functions required for cpuidle driver
The upcoming unified CPUIDLE driver will be added to the drivers/cpuidle/ directory and it will require all these Tegra PM-core functions. Signed-off-by: Dmitry Osipenko --- arch/arm/mach-tegra/Makefile | 2 +- arch/arm/mach-tegra/platsmp.c | 2 -- arch/arm/mach-tegra/pm.c | 16 +++- arch/arm/mach-tegra/pm.h | 3 --- arch/arm/mach-tegra/sleep.h | 1 - include/linux/clk/tegra.h | 13 + include/soc/tegra/pm.h| 28 7 files changed, 49 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 5d93a0b36866..27bd5d9865e3 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pm-tegra20.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC)+= sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_3x_SOC)+= pm-tegra30.o obj-$(CONFIG_SMP) += platsmp.o -obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o +obj-y += hotplug.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += sleep-tegra30.o obj-$(CONFIG_ARCH_TEGRA_114_SOC) += pm-tegra30.o diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index e6911a14c096..c8a63719a143 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -183,8 +183,6 @@ const struct smp_operations tegra_smp_ops __initconst = { .smp_prepare_cpus = tegra_smp_prepare_cpus, .smp_secondary_init = tegra_secondary_init, .smp_boot_secondary = tegra_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU .cpu_kill = tegra_cpu_kill, .cpu_die= tegra_cpu_die, -#endif }; diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 6aaacb5757e1..f9c9bce9e15d 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -123,11 +123,9 @@ void tegra_clear_cpu_in_lp2(void) spin_unlock(_lp2_lock); } -bool tegra_set_cpu_in_lp2(void) +void tegra_set_cpu_in_lp2(void) { int phy_cpu_id = cpu_logical_map(smp_processor_id()); - bool last_cpu = false; - cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask; u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; spin_lock(_lp2_lock); @@ -135,11 +133,7 @@ bool tegra_set_cpu_in_lp2(void) BUG_ON((*cpu_in_lp2 & BIT(phy_cpu_id))); *cpu_in_lp2 |= BIT(phy_cpu_id); - if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask)) - last_cpu = true; - spin_unlock(_lp2_lock); - return last_cpu; } static int tegra_sleep_cpu(unsigned long v2p) @@ -195,14 +189,16 @@ static void tegra_pm_set(enum tegra_suspend_mode mode) tegra_pmc_enter_suspend_mode(mode); } -void tegra_idle_lp2_last(void) +int tegra_idle_lp2_last(void) { + int err; + tegra_pm_set(TEGRA_SUSPEND_LP2); cpu_cluster_pm_enter(); suspend_cpu_complex(); - cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, _sleep_cpu); + err = cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, _sleep_cpu); /* * Resume L2 cache if it wasn't re-enabled early during resume, @@ -214,6 +210,8 @@ void tegra_idle_lp2_last(void) restore_cpu_complex(); cpu_cluster_pm_exit(); + + return err; } enum tegra_suspend_mode tegra_pm_validate_suspend_mode( diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index 1e51a9b636eb..81525f5f4a44 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h @@ -23,9 +23,6 @@ void tegra20_sleep_core_init(void); void tegra30_lp1_iram_hook(void); void tegra30_sleep_core_init(void); -void tegra_clear_cpu_in_lp2(void); -bool tegra_set_cpu_in_lp2(void); -void tegra_idle_lp2_last(void); extern void (*tegra_tear_down_cpu)(void); #ifdef CONFIG_PM_SLEEP diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h index d219872b7546..0d9956e9a8ea 100644 --- a/arch/arm/mach-tegra/sleep.h +++ b/arch/arm/mach-tegra/sleep.h @@ -124,7 +124,6 @@ void tegra30_hotplug_shutdown(void); #endif void tegra20_tear_down_cpu(void); -int tegra30_sleep_cpu_secondary_finish(unsigned long); void tegra30_tear_down_cpu(void); #endif diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index b8aef62cc3f5..cf0f2cb5e109 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -108,6 +108,19 @@ static inline void tegra_cpu_clock_resume(void) tegra_cpu_car_ops->resume(); } +#else +static inline bool tegra_cpu_rail_off_ready(void) +{ + return false; +} + +static inline void tegra_cpu_clock_suspend(void) +{ +} + +static inline void tegra_cpu_clock_resume(void) +{ +} #endif extern void tegra210_xusb_pll_hw_control_enable(void); diff --git a/include/soc/tegra/pm.h b/include/soc/tegra/pm.h index 951fcd738d55..fa18c2df5028 100644 --- a/include/soc/tegra/pm.h +++
[PATCH v1 4/6] cpuidle: tegra: Support CPU cluster power-down on Tegra30
The new CPU Idle driver has all necessary features in order to allow the deepest idling state on Tegra30 SoC where the whole CPU cluster is power-gated using the coupled idle state. Signed-off-by: Dmitry Osipenko --- Please note that outer_disable() has a WARN_ON(num_online_cpus > 1) and it doesn't know that we turned off those secondary CPUs, hence the outer_cache.disable() is now invoked directly. arch/arm/mach-tegra/pm.c| 4 ++-- drivers/cpuidle/cpuidle-tegra.c | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index f9c9bce9e15d..cc941b0c97e8 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -146,8 +146,8 @@ static int tegra_sleep_cpu(unsigned long v2p) * if any of secondary CPU's is online and this is the LP2-idle * code-path only for Tegra20/30. */ - if (trusted_foundations_registered()) - outer_disable(); + if (trusted_foundations_registered() && outer_cache.disable) + outer_cache.disable(); /* * Note that besides of setting up CPU reset vector this firmware diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c index 3fad4a0cbc78..31eeef22c0ff 100644 --- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -202,10 +202,8 @@ static int tegra_cpuidle_probe(struct platform_device *pdev) switch (tegra_get_chip_id()) { case TEGRA20: tegra_idle_driver.states[1].disabled = true; - tegra_idle_driver.states[3].disabled = true; - break; + /* fall through */ case TEGRA30: - tegra_idle_driver.states[2].disabled = true; tegra_idle_driver.states[3].disabled = true; break; case TEGRA114: -- 2.22.0
[PATCH v1 3/6] cpuidle: Add unified driver for NVIDIA Tegra SoCs
The new driver is based on the old CPU Idle drivers that are removed now from arm/arch/mach-tegra/ directory. Those removed drivers were reworked and squashed into a single unified driver that covers multiple hardware generations, starting from Tegra20 and ending with Tegra124. Signed-off-by: Dmitry Osipenko --- arch/arm/mach-tegra/tegra.c | 4 + drivers/cpuidle/Kconfig.arm | 8 ++ drivers/cpuidle/Makefile| 1 + drivers/cpuidle/cpuidle-tegra.c | 237 include/soc/tegra/cpuidle.h | 4 + 5 files changed, 254 insertions(+) create mode 100644 drivers/cpuidle/cpuidle-tegra.c diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index d9237769a37c..f1ce2857a251 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "board.h" @@ -92,6 +93,9 @@ static void __init tegra_dt_init_late(void) if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && of_machine_is_compatible("nvidia,tegra20")) platform_device_register_simple("tegra20-cpufreq", -1, NULL, 0); + + if (IS_ENABLED(CONFIG_ARM_TEGRA_CPUIDLE) && !psci_smp_available()) + platform_device_register_simple("tegra-cpuidle", -1, NULL, 0); } static const char * const tegra_dt_board_compat[] = { diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 48cb3d4bb7d1..d90861361f1d 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm @@ -76,3 +76,11 @@ config ARM_MVEBU_V7_CPUIDLE depends on ARCH_MVEBU && !ARM64 help Select this to enable cpuidle on Armada 370, 38x and XP processors. + +config ARM_TEGRA_CPUIDLE + bool "CPU Idle Driver for NVIDIA Tegra SoCs" + depends on ARCH_TEGRA && !ARM64 + select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP + select ARM_CPU_SUSPEND + help + Select this to enable cpuidle for NVIDIA Tegra20/30/114/124 SoCs. diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 9d7176cee3d3..470d17fa8746 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)+= cpuidle-exynos.o obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o +obj-$(CONFIG_ARM_TEGRA_CPUIDLE)+= cpuidle-tegra.o ### # MIPS drivers diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c new file mode 100644 index ..3fad4a0cbc78 --- /dev/null +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * CPU idle driver for Tegra CPUs + * + * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2011 Google, Inc. + * Author: Colin Cross + * Gary King + * + * Rework for 3.3 by Peter De Schrijver + * + * Tegra20-124 driver unification by Dmitry Osipenko + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +static atomic_t tegra_idle_barrier; + +static int tegra_shutdown_secondary_cpu(unsigned long cpu) +{ + tegra_cpu_die(cpu); + + return -EINVAL; +} + +static void tegra_await_secondary_cpus(void) +{ + /* +* The boot CPU shall await for the secondaries shutdown in order +* to power-off CPU's cluster safely. +*/ + while (!tegra_cpu_rail_off_ready()) + cpu_relax(); +} + +static void tegra_wake_up_secondary_cpus(void) +{ + unsigned int cpu, lcpu; + + for_each_cpu(lcpu, cpu_online_mask) { + cpu = cpu_logical_map(lcpu); + + if (cpu > 0) { + tegra_enable_cpu_clock(cpu); + tegra_cpu_out_of_reset(cpu); + flowctrl_write_cpu_halt(cpu, 0); + } + } +} + +static int tegra_cpu_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned int cpu = cpu_logical_map(dev->cpu); + int err; + + /* +* On Tegra30 CPU0 can't be power-gated while secondary CPUs +* are active because it gates the whole CPU cluster. +*/ + if (index == 1 && cpu == 0) + return arm_cpuidle_simple_enter(dev, drv, 0); + + local_fiq_disable(); + tegra_set_cpu_in_lp2(); + cpu_pm_enter(); + + switch (index) { + case 1: + err = cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); + break; + case 2: + cpuidle_coupled_parallel_barrier(dev, _idle_barrier); + + if (cpu == 0) { +
[PATCH v1] i2c: tegra: Compile PM functions unconditionally
The I2C driver fails to probe if CONFIG_PM_SLEEP=n because runtime PM doesn't depend on the PM sleep and in this case the runtime PM ops are not included in the driver, resulting in I2C clock not being enabled. It's much cleaner to simply allow compiler to remove the dead code instead of messing with the #ifdefs. This patch fixes such errors when CONFIG_PM_SLEEP=n: tegra-i2c 7000c400.i2c: timeout waiting for fifo flush tegra-i2c 7000c400.i2c: Failed to initialize i2c controller Signed-off-by: Dmitry Osipenko --- drivers/i2c/busses/i2c-tegra.c | 16 +--- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 9fcb13beeb8f..18f0ceed9f1b 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -636,7 +636,7 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev) dvc_writel(i2c_dev, val, DVC_CTRL_REG1); } -static int tegra_i2c_runtime_resume(struct device *dev) +static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); int ret; @@ -665,7 +665,7 @@ static int tegra_i2c_runtime_resume(struct device *dev) return 0; } -static int tegra_i2c_runtime_suspend(struct device *dev) +static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); @@ -1711,8 +1711,7 @@ static int tegra_i2c_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int tegra_i2c_suspend(struct device *dev) +static int __maybe_unused tegra_i2c_suspend(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); @@ -1721,7 +1720,7 @@ static int tegra_i2c_suspend(struct device *dev) return 0; } -static int tegra_i2c_resume(struct device *dev) +static int __maybe_unused tegra_i2c_resume(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); int err; @@ -1741,18 +1740,13 @@ static const struct dev_pm_ops tegra_i2c_pm = { NULL) }; -#define TEGRA_I2C_PM (_i2c_pm) -#else -#define TEGRA_I2C_PM NULL -#endif - static struct platform_driver tegra_i2c_driver = { .probe = tegra_i2c_probe, .remove = tegra_i2c_remove, .driver = { .name = "tegra-i2c", .of_match_table = tegra_i2c_of_match, - .pm= TEGRA_I2C_PM, + .pm= _i2c_pm, }, }; -- 2.22.0
Linux 5.2
So I was somewhat pre-disposed towards making an rc8, simply because of my travels and being entirely off the internet for a few days last week, and with spotty internet for a few days before that [*]. But there really doesn't seem to be any reason for another rc, since it's been very quiet. Yes, I had a few pull requests since rc7, but they were all small, and I had many more that are for the upcoming merge window. Part of it may be due to the July 4th week, of course, but whatever - I'll take the quiet week as a good sign. So despite a fairly late core revert, I don't see any real reason for another week of rc, and so we have a v5.2 with the normal release timing. There's no particular area that stands out there - the changes are so small that the sppended shortlog really is the best description of last week. A few small random changes all over: drivers, architectures, filesystem, mm, ... So with this, the merge window for 5.2 is open. Linus [*] Courtesy of the Ocean Hunter III in Palau. Because of blurry fish-butt, I don't carry a camera under water any more, but I guess can point you to some of Dirk's highlights: https://hohndel.name/palau-2019 --- Alex Deucher (1): drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE Ard Biesheuvel (1): arm64: kaslr: keep modules inside module region when KASAN is enabled Arnd Bergmann (2): soc: ti: fix irq-ti-sci link error devres: allow const resource arguments Bartosz Golaszewski (3): ARM: davinci: da830-evm: add missing regulator constraints for OHCI ARM: davinci: omapl138-hawk: add missing regulator constraints for OHCI ARM: davinci: da830-evm: fix GPIO lookup for OHCI Boris Brezillon (1): drm/panfrost: Fix a double-free error Cedric Hombourger (1): MIPS: have "plain" make calls build dtbs for selected platforms Chris Wilson (1): drm/i915/ringbuffer: EMIT_INVALIDATE *before* switch context Christian Brauner (1): fork: return proper negative error code Chuck Lever (1): svcrdma: Ignore source port when computing DRC hash Colin Ian King (2): ALSA: usb-audio: fix sign unintended sign extension on left shifts ALSA: seq: fix incorrect order of dest_client/dest_ports arguments Dan Carpenter (1): dmaengine: jz4780: Fix an endian bug in IRQ handler Dennis Wassenberg (1): ALSA: hda/realtek - Change front mic location for Lenovo M710q Dmitry Korotin (1): MIPS: Add missing EHB in mtc0 -> mfc0 sequence. Dmitry Osipenko (1): i2c: tegra: Add Dmitry as a reviewer Eiichi Tsukata (1): tracing/snapshot: Resize spare buffer if size changed Eric Biggers (3): vfs: move_mount: reject moving kernel internal mounts crypto: user - prevent operating on larval algorithms fs/userfaultfd.c: disable irqs for fault_pending and event locks Evan Green (1): ALSA: hda: Fix widget_mutex incomplete protection Evan Quan (1): drm/amd/powerplay: use hardware fan control if no powerplay fan table Frieder Schrempf (1): mtd: spinand: Fix max_bad_eraseblocks_per_lun info in memorg Geert Uytterhoeven (1): fs: VALIDATE_FS_PARSER should default to n Gerd Hoffmann (1): drm/virtio: move drm_connector_update_edid_property() call Greg Kroah-Hartman (1): blk-mq: fix up placement of debugfs directory of queue files Hauke Mehrtens (1): MIPS: Fix bounds check virt_addr_valid Herbert Xu (1): lib/mpi: Fix karactx leak in mpi_powm Jan Kara (1): dax: Fix xarray entry association for mixed mappings Jann Horn (1): ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME Jiri Kosina (1): ftrace/x86: Anotate text_mutex split between ftrace_arch_code_modify_post_process() and ftrace_arch_code_modify_prepare() Joshua Scott (1): ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node Juergen Gross (1): mm/page_alloc.c: fix regression with deferred struct page init Kevin Darbyshire-Bryant (1): MIPS: fix build on non-linux hosts Linus Torvalds (2): Revert "mm: page cache: store only head pages in i_pages" Linux 5.2 Linus Walleij (1): gpio/spi: Fix spi-gpio regression on active high CS Liran Alon (2): KVM: nVMX: Allow restore nested-state to enable eVMCS when vCPU in SMM KVM: nVMX: Change KVM_STATE_NESTED_EVMCS to signal vmcs12 is copied from eVMCS Lucas Stach (1): drm/etnaviv: add missing failure path to destroy suballoc Lyude Paul (1): drm/amdgpu: Don't skip display settings in hwmgr_resume() Matias Karhumaa (1): Bluetooth: Fix faulty expression for minimum encryption key size check Maurizio Lombardi (1): scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported Miquel Raynal (2): Revert "mtd: rawnand: sunxi: Add A23/A33 DMA support" mtd: rawnand: sunxi: Add A23/A33 DMA support with extra MBUS configuration Nathan Chancellor (1): arm64/efi: Mark