Re: [PATCH] habanalabs: fix up absolute include instructions

2020-07-28 Thread Greg Kroah-Hartman
On Wed, Jul 29, 2020 at 08:09:38AM +1000, Stephen Rothwell wrote:
> Hi Greg,
> 
> On Tue, 28 Jul 2020 19:18:51 +0200 Greg Kroah-Hartman 
>  wrote:
> >
> > diff --git a/drivers/misc/habanalabs/common/Makefile 
> > b/drivers/misc/habanalabs/common/Makefile
> > index 97d03b5c8683..b984bfa4face 100644
> > --- a/drivers/misc/habanalabs/common/Makefile
> > +++ b/drivers/misc/habanalabs/common/Makefile
> > @@ -1,6 +1,4 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> > -subdir-ccflags-y += -I$(src)/common
> 
> I've seen oter places use
> 
> subdir-ccflags-y += -I$(srcdir)/$(src)/common
> 
> which would probably work as well.  i.e. just change this in the
> Makefiles rather than every source file.

I hate seeing odd ccflags stuff in Makefiles as it can catch you "by
surprise" as to what exactly is happening when looking at .c code.

But yes, your change would also work.

thanks,

greg k-h


Re: [PATCH v2 1/1] Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary

2020-07-28 Thread Dmitry Torokhov
On Tue, Jul 28, 2020 at 12:16:37AM +0900, Jiada Wang wrote:
> From: Nick Dyer 
> 
> The workaround of reading all messages until an invalid is received is a
> way of forcing the CHG line high, which means that when using
> edge-triggered interrupts the interrupt can be acquired.
> 
> With level-triggered interrupts the workaround is unnecessary.
> 
> Also, most recent maXTouch chips have a feature called RETRIGEN which, when
> enabled, reasserts the interrupt line every cycle if there are messages
> waiting. This also makes the workaround unnecessary.
> 
> Note: the RETRIGEN feature is only in some firmware versions/chips, it's
> not valid simply to enable the bit.
> 
> Signed-off-by: Nick Dyer 
> Acked-by: Benson Leung 
> Acked-by: Yufeng Shen 
> (cherry picked from ndyer/linux/for-upstream commit 
> 1ae4e8281e491b22442cd5acdfca1862555f8ecb)
> [gdavis: Fix conflicts due to v4.6-rc7 commit eb43335c4095 ("Input:
>atmel_mxt_ts - use mxt_acquire_irq in mxt_soft_reset").]
> Signed-off-by: George G. Davis 
> [jiada: reset use_retrigen_workaround at beginning of mxt_check_retrigen()
>   call mxt_check_retrigen() after mxt_acquire_irq() in mxt_initialize()
>   replace white-spaces with tab for MXT_COMMS_RETRIGEN
>   Changed to check if IRQ is level type]
> Signed-off-by: Jiada Wang 

Applied, thank you.

-- 
Dmitry


Re: [PATCH V3 vhost next 00/10] VDPA support for Mellanox ConnectX devices

2020-07-28 Thread Eli Cohen
On Tue, Jul 28, 2020 at 02:53:34PM +0800, Jason Wang wrote:
> 
> Just notice Michael's vhost branch can not compile due to this commit:
> 
> commit fee8fe6bd8ccacd27e963b71b4f943be3721779e
> Author: Michael S. Tsirkin 
> Date:   Mon Jul 27 10:51:55 2020 -0400
> 
>     vdpa: make sure set_features in invoked for legacy
> 
> Let's wait for Michael to clarify the correct branch to use then.
>

Michael, are you going to send a path to a git tree that I can rebase my
series on top of it, or maybe you can just take my v3 and apply them on
the right tree? If you do, you can take Jason's patches from the series
he posted here https://lkml.org/lkml/2020/7/1/301 and take my 0003-0010
patches.

Let me know.


INFO: rcu detected stall in tc_modify_qdisc

2020-07-28 Thread syzbot
Hello,

syzbot found the following issue on:

HEAD commit:181964e6 fix a braino in cmsghdr_from_user_compat_to_kern()
git tree:   net
console output: https://syzkaller.appspot.com/x/log.txt?x=12925e3890
kernel config:  https://syzkaller.appspot.com/x/.config?x=f87a5e4232fdb267
dashboard link: https://syzkaller.appspot.com/bug?extid=9f78d5c664a8c33f4cce
compiler:   gcc (GCC) 10.1.0-syz 20200507
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=16587f8c90
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=15b2d79090

The issue was bisected to:

commit 5a781ccbd19e4664babcbe4b4ead7aa2b9283d22
Author: Vinicius Costa Gomes 
Date:   Sat Sep 29 00:59:43 2018 +

tc: Add support for configuring the taprio scheduler

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=160e1bac90
console output: https://syzkaller.appspot.com/x/log.txt?x=110e1bac90

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+9f78d5c664a8c33f4...@syzkaller.appspotmail.com
Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")

rcu: INFO: rcu_preempt self-detected stall on CPU
rcu:1-...!: (1 GPs behind) idle=6f6/1/0x4000 
softirq=10195/10196 fqs=1 
(t=27930 jiffies g=9233 q=413)
rcu: rcu_preempt kthread starved for 27901 jiffies! g9233 f0x0 
RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=0
rcu:Unless rcu_preempt kthread gets sufficient CPU time, OOM is now 
expected behavior.
rcu: RCU grace-period kthread stack dump:
rcu_preempt R  running task2911210  2 0x4000
Call Trace:
 context_switch kernel/sched/core.c:3458 [inline]
 __schedule+0x8ea/0x2210 kernel/sched/core.c:4219
 schedule+0xd0/0x2a0 kernel/sched/core.c:4294
 schedule_timeout+0x148/0x250 kernel/time/timer.c:1908
 rcu_gp_fqs_loop kernel/rcu/tree.c:1874 [inline]
 rcu_gp_kthread+0xae5/0x1b50 kernel/rcu/tree.c:2044
 kthread+0x3b5/0x4a0 kernel/kthread.c:291
 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:293
NMI backtrace for cpu 1
CPU: 1 PID: 6799 Comm: syz-executor494 Not tainted 5.8.0-rc6-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 
01/01/2011
Call Trace:
 
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x18f/0x20d lib/dump_stack.c:118
 nmi_cpu_backtrace.cold+0x70/0xb1 lib/nmi_backtrace.c:101
 nmi_trigger_cpumask_backtrace+0x1b3/0x223 lib/nmi_backtrace.c:62
 trigger_single_cpu_backtrace include/linux/nmi.h:164 [inline]
 rcu_dump_cpu_stacks+0x194/0x1cf kernel/rcu/tree_stall.h:320
 print_cpu_stall kernel/rcu/tree_stall.h:553 [inline]
 check_cpu_stall kernel/rcu/tree_stall.h:627 [inline]
 rcu_pending kernel/rcu/tree.c:3489 [inline]
 rcu_sched_clock_irq.cold+0x5b3/0xccc kernel/rcu/tree.c:2504
 update_process_times+0x25/0x60 kernel/time/timer.c:1737
 tick_sched_handle+0x9b/0x180 kernel/time/tick-sched.c:176
 tick_sched_timer+0x108/0x290 kernel/time/tick-sched.c:1320
 __run_hrtimer kernel/time/hrtimer.c:1520 [inline]
 __hrtimer_run_queues+0x1d5/0xfc0 kernel/time/hrtimer.c:1584
 hrtimer_interrupt+0x32a/0x930 kernel/time/hrtimer.c:1646
 local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1080 [inline]
 __sysvec_apic_timer_interrupt+0x142/0x5e0 arch/x86/kernel/apic/apic.c:1097
 asm_call_on_stack+0xf/0x20 arch/x86/entry/entry_64.S:711
 
 __run_on_irqstack arch/x86/include/asm/irq_stack.h:22 [inline]
 run_on_irqstack_cond arch/x86/include/asm/irq_stack.h:48 [inline]
 sysvec_apic_timer_interrupt+0xe0/0x120 arch/x86/kernel/apic/apic.c:1091
 asm_sysvec_apic_timer_interrupt+0x12/0x20 arch/x86/include/asm/idtentry.h:585
RIP: 0010:arch_local_irq_restore arch/x86/include/asm/paravirt.h:770 [inline]
RIP: 0010:__raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:160 
[inline]
RIP: 0010:_raw_spin_unlock_irqrestore+0x8c/0xe0 kernel/locking/spinlock.c:191
Code: 48 c7 c0 88 e0 b4 89 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 80 3c 10 
00 75 37 48 83 3d e3 52 cc 01 00 74 22 48 89 df 57 9d <0f> 1f 44 00 00 bf 01 00 
00 00 e8 35 e5 66 f9 65 8b 05 fe 70 19 78
RSP: 0018:c900016672c0 EFLAGS: 0282
RAX: 11369c11 RBX: 0282 RCX: 0002
RDX: dc00 RSI:  RDI: 0282
RBP: 888093a052e8 R08:  R09: 
R10: 0001 R11:  R12: 0282
R13: 0078100c35c3 R14: 888093a05000 R15: 
 spin_unlock_irqrestore include/linux/spinlock.h:408 [inline]
 taprio_change+0x1fdc/0x2960 net/sched/sch_taprio.c:1557
 taprio_init+0x52e/0x670 net/sched/sch_taprio.c:1670
 qdisc_create+0x4b6/0x12e0 net/sched/sch_api.c:1246
 tc_modify_qdisc+0x4c8/0x1990 net/sched/sch_api.c:1662
 rtnetlink_rcv_msg+0x44e/0xad0 net/core/rtnetlink.c:5461
 netlink_rcv_skb+0x15a/0x430 net/netlink/af_netlink.c:2469
 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline]
 netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1329
 netlink_sendmsg+0x856/0xd90 

Re: [PATCH] cpufreq: intel_pstate: Fix EPP setting via sysfs in active mode

2020-07-28 Thread Francisco Jerez
"Rafael J. Wysocki"  writes:

> From: Rafael J. Wysocki 
>
> Because intel_pstate_set_energy_pref_index() reads and writes the
> MSR_HWP_REQUEST register without using the cached value of it used by
> intel_pstate_hwp_boost_up() and intel_pstate_hwp_boost_down(), those
> functions may overwrite the value written by it and so the EPP value
> set via sysfs may be lost.
>
> To avoid that, make intel_pstate_set_energy_pref_index() take the
> cached value of MSR_HWP_REQUEST just like the other two routines
> mentioned above and update it with the new EPP value coming from
> user space in addition to updating the MSR.
>
> Note that the MSR itself still needs to be updated too in case
> hwp_boost is unset or the boosting mechanism is not active at the
> EPP change time.
>
> Fixes: e0efd5be63e8 ("cpufreq: intel_pstate: Add HWP boost utility and sched 
> util hooks")
> Reported-by: Francisco Jerez 
> Signed-off-by: Rafael J. Wysocki 

Reviewed-by: Francisco Jerez 

> ---
>
> This patch is on top of https://patchwork.kernel.org/patch/11689347/
>
> ---
>  drivers/cpufreq/intel_pstate.c |   17 -
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> Index: linux-pm/drivers/cpufreq/intel_pstate.c
> ===
> --- linux-pm.orig/drivers/cpufreq/intel_pstate.c
> +++ linux-pm/drivers/cpufreq/intel_pstate.c
> @@ -653,11 +653,12 @@ static int intel_pstate_set_energy_pref_
>   epp = cpu_data->epp_default;
>  
>   if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {
> - u64 value;
> -
> - ret = rdmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, );
> - if (ret)
> - return ret;
> + /*
> +  * Use the cached HWP Request MSR value, because the register
> +  * itself may be updated by intel_pstate_hwp_boost_up() or
> +  * intel_pstate_hwp_boost_down() at any time.
> +  */
> + u64 value = READ_ONCE(cpu_data->hwp_req_cached);
>  
>   value &= ~GENMASK_ULL(31, 24);
>  
> @@ -667,6 +668,12 @@ static int intel_pstate_set_energy_pref_
>   epp = epp_values[pref_index - 1];
>  
>   value |= (u64)epp << 24;
> + /*
> +  * The only other updater of hwp_req_cached in the active mode,
> +  * intel_pstate_hwp_set(), is called under the same lock as this
> +  * function, so it cannot run in parallel with the update below.
> +  */
> + WRITE_ONCE(cpu_data->hwp_req_cached, value);
>   ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value);
>   } else {
>   if (epp == -EINVAL)


signature.asc
Description: PGP signature


Re: [PATCH] staging: qlge: qlge_dbg: removed comment repition

2020-07-28 Thread Greg KH
A: http://en.wikipedia.org/wiki/Top_post
Q: Were do I find info about this thing called top-posting?
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

A: No.
Q: Should I include quotations after my reply?

http://daringfireball.net/2007/07/on_top

On Wed, Jul 29, 2020 at 11:06:56AM +0530, Dhiraj Sharma wrote:
> Hello,



It has been less than 24 hours for a simple comment cleanup patch.
Please give maintainers time, they deal with thousands of patches a
week.

Usually, if after 2 weeks, you have not gotten a response, you can
resend it.

>  I know that I should ask for reviews etc after a week but the change
> is for my eudyptula task and until it doesn't get merged little
> penguin will not pass the task for me so please look at it.

If you knew that you should wait for at least a week, and yet you did
not, that implies that you somehow feel this comment cleanup patch is
more important than everyone else, which is a bit rude, don't you think?

There are no such things as deadlines when it comes to upstream kernel
development, sorry.

greg k-h


Re: [PATCH] cpufreq: intel_pstate: Implement passive mode with HWP enabled

2020-07-28 Thread Francisco Jerez
"Rafael J. Wysocki"  writes:

> On Tuesday, July 28, 2020 4:32:22 AM CEST Francisco Jerez wrote:
>>
>> "Rafael J. Wysocki"  writes:
>> 
>> > On Tuesday, July 21, 2020 1:20:14 AM CEST Francisco Jerez wrote:
>> >
>> > [cut]
>> >
>> >> >
>> >> > However, in the active mode the only updater of hwp_req_cached is
>> >> > intel_pstate_hwp_set() and this patch doesn't introduce any
>> >> > differences in behavior in that case.
>> >> >
>> >>=20
>> >> intel_pstate_hwp_set() is the only updater, but there are other
>> >> consumers that can get out of sync with the HWP request value written by
>> >> intel_pstate_set_energy_pref_index().  intel_pstate_hwp_boost_up() seems
>> >> like the most concerning example I named earlier.
>> >>=20
>> >> >> > So there may be a short time window after the
>> >> >> > intel_pstate_set_energy_pref_index() invocation in which the new EPP
>> >> >> > value may not be in effect, but in general there is no guarantee th=
>> at
>> >> >> > the new EPP will take effect immediately after updating the MSR
>> >> >> > anyway, so that race doesn't matter.
>> >> >> >
>> >> >> > That said, that race is avoidable, but I was thinking that trying to
>> >> >> > avoid it might not be worth it.  Now I see a better way to avoid it,
>> >> >> > though, so I'm going to update the patch to that end.
>> >> >> >
>> >> >> >> Seems like a bug to me.
>> >> >> >
>> >> >> > It is racy, but not every race is a bug.
>> >> >> >
>> >> >>
>> >> >> Still seems like there is a bug in intel_pstate_set_energy_pref_index=
>> ()
>> >> >> AFAICT.
>> >> >
>> >> > If there is a bug, then what exactly is it, from the users' perspectiv=
>> e?
>> >> >
>> >>=20
>> >> It can be reproduced easily as follows:
>> >>=20
>> >> | echo 1 > /sys/devices/system/cpu/intel_pstate/hwp_dynamic_boost
>> >> | for p in /sys/devices/system/cpu/cpufreq/policy*/energy_performance_pr=
>> eference; do echo performance > $p; done
>> >
>> > Is this the active mode or the passive mode with the $subject patch appli=
>> ed?
>> >
>> > If the former, the issue is there regardless of the patch, so it needs to=
>>  be
>> > fixed.
>> >
>> > If the latter, there should be no effect of hwp_dynamic_boost (which was
>> > overlooked by me).
>> >
>> 
>> This seems to be a problem in active mode only, so yeah the bug exists
>> regardless of your patch, but the fix is likely to allow you to simplify
>> this series slightly if it allows you to take full advantage of
>> hwp_req_cached and drop the additional EPP cache.
>
> The additional EPP cache is there to avoid synchronizing the scheduler
> context directly with a random process running on another CPU and doing
> things that may take time.
>
> The difference between the active mode and the passive mode in this respect
> is that in the latter case hwp_req_cached generally needs to be updated from
> the scheduler context, whereas in the former case it does not.
>

Hm, that's unfortunate.  Though I'd be surprised to see any appreciable
performance penalty from synchronizing with a sysfs handler that should
hardly ever be called.  Anyway thanks for the fix.

> [cut]
>
>> >> No, I explicitly dismissed that in my previous reply.
>> >
>> > But at the same time you seem to agree that without the non-CPU component
>> > (or thermal pressure) the existing CPU performance scaling would be
>> > sufficient.
>> >
>> 
>> Yes, but not necessarily in order to allow the non-CPU component to draw
>> more power as you said above, but also because the existence of a
>> bottleneck in a non-CPU component gives us an opportunity to improve the
>> energy efficiency of the CPU, regardless of whether that allows the
>> workload to run faster.
>
> But why would the bottleneck be there otherwise?
>

Because some resource of the system (e.g. memory bandwidth, GPU fill
rate) may be close to 100% utilized, causing a bottleneck for reasons
unrelated to its energy usage.

>> > [cut]
>> >
>> >> > Yes, it is, and so I don't quite see the connection between it and my =
>> question.
>> >> >
>> >> > Apparently, the unmodified performance scaling governors are not
>> >> > sufficient, so there must be something beyond the above which allows
>> >> > you to determine the frequency in question and so I'm asking what that
>> >> > is.
>> >> >
>> >>=20
>> >> The underlying heuristic assumption is the same as I outlined above, but
>> >> in any implementation of such a heuristic there is necessarily a
>> >> trade-off between responsiveness to short-term fluctuations and
>> >> long-term energy usage.  This trade-off is a function of the somewhat
>> >> arbitrary time interval I was referring to as "immediate past" -- A
>> >> longer time parameter allows the controller to consider a greater
>> >> portion of the workload's history while computing the response with
>> >> optimal energy usage, at the cost of increasing its reaction time to
>> >> discontinuous changes in the behavior of the workload (AKA increased
>> >> latency).
>> >
>> > OK
>> >
>> >> One of the key 

Re: [PATCH] staging: qlge: qlge_dbg: removed comment repition

2020-07-28 Thread Dhiraj Sharma
Hello,

 I know that I should ask for reviews etc after a week but the change
is for my eudyptula task and until it doesn't get merged little
penguin will not pass the task for me so please look at it.


Thank You
Dhiraj Sharma

On Tue, Jul 28, 2020 at 11:56 PM Dhiraj Sharma
 wrote:
>
> Inside function ql_get_dump comment statement had a repition of word
> "to" which I removed and checkpatch.pl ouputs zero error or warnings
> now.
>
> Signed-off-by: Dhiraj Sharma 
> ---
>  drivers/staging/qlge/qlge_dbg.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/staging/qlge/qlge_dbg.c b/drivers/staging/qlge/qlge_dbg.c
> index 985a6c341294..a55bf0b3e9dc 100644
> --- a/drivers/staging/qlge/qlge_dbg.c
> +++ b/drivers/staging/qlge/qlge_dbg.c
> @@ -1298,7 +1298,7 @@ void ql_get_dump(struct ql_adapter *qdev, void *buff)
>  * If the dump has already been taken and is stored
>  * in our internal buffer and if force dump is set then
>  * just start the spool to dump it to the log file
> -* and also, take a snapshot of the general regs to
> +* and also, take a snapshot of the general regs
>  * to the user's buffer or else take complete dump
>  * to the user's buffer if force is not set.
>  */
> --
> 2.17.1
>


Re: [PATCH] thermal: core: Add thermal zone enable/disable notification

2020-07-28 Thread Amit Kucheria
On Tue, Jul 28, 2020 at 4:40 AM Daniel Lezcano
 wrote:
>
> Now the calls to enable/disable a thermal zone are centralized in a
> call to a function, we can add in these the corresponding netlink
> notifications.
>
> Signed-off-by: Daniel Lezcano 

Reviewed-by: Amit Kucheria 

> ---
>  drivers/thermal/thermal_core.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
> index 9748fbb9a3a1..72bf159bcecc 100644
> --- a/drivers/thermal/thermal_core.c
> +++ b/drivers/thermal/thermal_core.c
> @@ -509,6 +509,11 @@ static int thermal_zone_device_set_mode(struct 
> thermal_zone_device *tz,
>
> thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
>
> +   if (mode == THERMAL_DEVICE_ENABLED)
> +   thermal_notify_tz_enable(tz->id);
> +   else
> +   thermal_notify_tz_disable(tz->id);
> +
> return ret;
>  }
>
> --
> 2.17.1
>


Re: [PATCH v1 1/2] scsi: ufs: Introduce device quirk "DELAY_AFTER_LPM"

2020-07-28 Thread Can Guo

Hi Stanley,

On 2020-07-29 13:18, Stanley Chu wrote:

Some UFS devices require delay after VCC power rail is turned-off.
Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delays after
VCC power-off during suspend flow.



Just curious, I can understand if you want to add some delays before
turnning off VCC/VCCQ/VCCQ2, but what is the delay AFTER turnning
them off for? I mean the power has been cut by host from PMIC, how
can the delay benefit the UFS device?

Thanks,

Can Guo.


Signed-off-by: Andy Teng 
Signed-off-by: Peter Wang 
Signed-off-by: Stanley Chu 
---
 drivers/scsi/ufs/ufs_quirks.h |  7 +++
 drivers/scsi/ufs/ufshcd.c | 11 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/ufs/ufs_quirks.h 
b/drivers/scsi/ufs/ufs_quirks.h

index 2a0041493e30..07f559ac5883 100644
--- a/drivers/scsi/ufs/ufs_quirks.h
+++ b/drivers/scsi/ufs/ufs_quirks.h
@@ -109,4 +109,11 @@ struct ufs_dev_fix {
  */
 #define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10)

+/*
+ * Some UFS devices require delay after VCC power rail is turned-off.
+ * Enable this quirk to introduce 5ms delays after VCC power-off 
during

+ * suspend flow.
+ */
+#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM(1 << 11)
+
 #endif /* UFS_QUIRKS_H_ */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index acba2271c5d3..63f4e2f75aa1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -8111,6 +8111,8 @@ static int ufshcd_link_state_transition(struct
ufs_hba *hba,

 static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
 {
+   bool vcc_off = false;
+
/*
 * It seems some UFS devices may keep drawing more than sleep current
 * (atleast for 500us) from UFS rails (especially from VCCQ rail).
@@ -8139,13 +8141,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba 
*hba)

if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) &&
!hba->dev_info.is_lu_power_on_wp) {
ufshcd_setup_vreg(hba, false);
+   vcc_off = true;
} else if (!ufshcd_is_ufs_dev_active(hba)) {
ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false);
+   vcc_off = true;
if (!ufshcd_is_link_active(hba)) {
ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq);
ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2);
}
}
+
+   /*
+* Some UFS devices require delay after VCC power rail is turned-off.
+*/
+   if (vcc_off && hba->vreg_info.vcc &&
+   hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM)
+   usleep_range(5000, 5100);
 }

 static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)


Re: PROBLEM: 5.8-rc7 no video output with nouveau on NV36 (regression)

2020-07-28 Thread Nick Bowler
On 2020-07-29, Dave Airlie  wrote:
> On Wed, 29 Jul 2020 at 15:05, Nick Bowler  wrote:
>>
>> Hi,
>>
>> After installing Linux 5.8-rc7 I seem to get no video output on my
>> NV36 card once the nouveau module is loaded.  The display (connected
>> to the digital output) simply reports "No Signal".
>>
>> I bisected to the following commit, and reverting this commit on
>> top of 5.8-rc7 appears to correct the issue.
>
> Can you test the drm fixes pull I just sent to Linus
>
> https://patchwork.freedesktop.org/patch/381225/

Yes, pulling this seems to fix things.

Thanks,
  Nick


[PATCH] vt: Handle recursion in vc_do_resize().

2020-07-28 Thread Tetsuo Handa
syzbot is reporting OOB read bug in vc_do_resize() [1] caused by memcpy()
based on outdated old_{rows,row_size} values, for resize_screen() can
recurse into vc_do_resize() which changes vc->vc_{cols,rows} that outdates
old_{rows,row_size} values which were read before calling resize_screen().

Minimal fix might be to read vc->vc_{rows,size_row} after resize_screen().
A different fix might be to forbid recursive vc_do_resize() request.
I can't tell which fix is the better.

But since I guess that new_cols == vc->vc_cols && new_rows == vc->vc_rows
check could become true after returning from resize_screen(), and I assume
that not calling clear_selection() when resize_screen() will return error
is harmless, let's redo the check by moving resize_screen() earlier.

[1] 
https://syzkaller.appspot.com/bug?id=c70c88cfd16dcf6e1d3c7f0ab8648b3144b5b25e

Reported-by: syzbot 
Signed-off-by: Tetsuo Handa 
---
 drivers/tty/vt/vt.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 42d8c67..952a067 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1217,7 +1217,24 @@ static int vc_do_resize(struct tty_struct *tty, struct 
vc_data *vc,
 
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
return 0;
+   if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
+   return -EINVAL;
 
+   /*
+* Since fbcon_resize() from resize_screen() can recurse into
+* this function via fb_set_var(), handle recursion now.
+*/
+   err = resize_screen(vc, new_cols, new_rows, user);
+   if (err)
+   return err;
+   /* Reload values in case recursion changed vc->vc_{cols,rows}. */
+   new_cols = (cols ? cols : vc->vc_cols);
+   new_rows = (lines ? lines : vc->vc_rows);
+   new_row_size = new_cols << 1;
+   new_screen_size = new_row_size * new_rows;
+
+   if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
+   return 0;
if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
return -EINVAL;
newscreen = kzalloc(new_screen_size, GFP_USER);
@@ -1238,13 +1255,6 @@ static int vc_do_resize(struct tty_struct *tty, struct 
vc_data *vc,
old_rows = vc->vc_rows;
old_row_size = vc->vc_size_row;
 
-   err = resize_screen(vc, new_cols, new_rows, user);
-   if (err) {
-   kfree(newscreen);
-   vc_uniscr_free(new_uniscr);
-   return err;
-   }
-
vc->vc_rows = new_rows;
vc->vc_cols = new_cols;
vc->vc_size_row = new_row_size;
-- 
1.8.3.1



[PATCH v1 1/2] scsi: ufs: Introduce device quirk "DELAY_AFTER_LPM"

2020-07-28 Thread Stanley Chu
Some UFS devices require delay after VCC power rail is turned-off.
Introduce a device quirk "DELAY_AFTER_LPM" to add 5ms delays after
VCC power-off during suspend flow.

Signed-off-by: Andy Teng 
Signed-off-by: Peter Wang 
Signed-off-by: Stanley Chu 
---
 drivers/scsi/ufs/ufs_quirks.h |  7 +++
 drivers/scsi/ufs/ufshcd.c | 11 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h
index 2a0041493e30..07f559ac5883 100644
--- a/drivers/scsi/ufs/ufs_quirks.h
+++ b/drivers/scsi/ufs/ufs_quirks.h
@@ -109,4 +109,11 @@ struct ufs_dev_fix {
  */
 #define UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES (1 << 10)
 
+/*
+ * Some UFS devices require delay after VCC power rail is turned-off.
+ * Enable this quirk to introduce 5ms delays after VCC power-off during
+ * suspend flow.
+ */
+#define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM(1 << 11)
+
 #endif /* UFS_QUIRKS_H_ */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index acba2271c5d3..63f4e2f75aa1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -8111,6 +8111,8 @@ static int ufshcd_link_state_transition(struct ufs_hba 
*hba,
 
 static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
 {
+   bool vcc_off = false;
+
/*
 * It seems some UFS devices may keep drawing more than sleep current
 * (atleast for 500us) from UFS rails (especially from VCCQ rail).
@@ -8139,13 +8141,22 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba)
if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba) &&
!hba->dev_info.is_lu_power_on_wp) {
ufshcd_setup_vreg(hba, false);
+   vcc_off = true;
} else if (!ufshcd_is_ufs_dev_active(hba)) {
ufshcd_toggle_vreg(hba->dev, hba->vreg_info.vcc, false);
+   vcc_off = true;
if (!ufshcd_is_link_active(hba)) {
ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq);
ufshcd_config_vreg_lpm(hba, hba->vreg_info.vccq2);
}
}
+
+   /*
+* Some UFS devices require delay after VCC power rail is turned-off.
+*/
+   if (vcc_off && hba->vreg_info.vcc &&
+   hba->dev_quirks & UFS_DEVICE_QUIRK_DELAY_AFTER_LPM)
+   usleep_range(5000, 5100);
 }
 
 static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)
-- 
2.18.0


[PATCH v1 0/2] scsi: ufs: Introduce and apply DELAY_AFTER_LPM device quirk

2020-07-28 Thread Stanley Chu
Hi,
This patchset introduces and applies DELAY_AFTER_LPM device quirk in MediaTek 
platforms.

Stanley Chu (2):
  scsi: ufs: Introduce device quirk "DELAY_AFTER_LPM"
  scsi: ufs-mediatek: Apply DELAY_AFTER_LPM quirk to Micron devices

 drivers/scsi/ufs/ufs-mediatek.c |  2 ++
 drivers/scsi/ufs/ufs_quirks.h   |  7 +++
 drivers/scsi/ufs/ufshcd.c   | 11 +++
 3 files changed, 20 insertions(+)

-- 
2.18.0


[PATCH v1 2/2] scsi: ufs-mediatek: Apply DELAY_AFTER_LPM quirk to Micron devices

2020-07-28 Thread Stanley Chu
Micron UFS devices require DELAY_AFTER_LPM device quirk in
MediaTek platforms.

Signed-off-by: Andy Teng 
Signed-off-by: Peter Wang 
Signed-off-by: Stanley Chu 
---
 drivers/scsi/ufs/ufs-mediatek.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 31af8b3d2b53..7ff2682f481c 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -36,6 +36,8 @@
ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, high, res)
 
 static struct ufs_dev_fix ufs_mtk_dev_fixups[] = {
+   UFS_FIX(UFS_VENDOR_MICRON, UFS_ANY_MODEL,
+   UFS_DEVICE_QUIRK_DELAY_AFTER_LPM),
UFS_FIX(UFS_VENDOR_SKHYNIX, "H9HQ21AFAMZDAR",
UFS_DEVICE_QUIRK_SUPPORT_EXTENDED_FEATURES),
END_FIX
-- 
2.18.0


Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor

2020-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2020 at 10:40 AM Madhavan T. Venkataraman
 wrote:
>
>
>
> On 7/28/20 12:16 PM, Andy Lutomirski wrote:
>
> On Tue, Jul 28, 2020 at 9:32 AM Madhavan T. Venkataraman
>  wrote:
>
> Thanks. See inline..
>
> On 7/28/20 10:13 AM, David Laight wrote:
>
> From:  madve...@linux.microsoft.com
>
> Sent: 28 July 2020 14:11
>
> ...
>
> The kernel creates the trampoline mapping without any permissions. When
> the trampoline is executed by user code, a page fault happens and the
> kernel gets control. The kernel recognizes that this is a trampoline
> invocation. It sets up the user registers based on the specified
> register context, and/or pushes values on the user stack based on the
> specified stack context, and sets the user PC to the requested target
> PC. When the kernel returns, execution continues at the target PC.
> So, the kernel does the work of the trampoline on behalf of the
> application.
>
> Isn't the performance of this going to be horrid?
>
> It takes about the same amount of time as getpid(). So, it is
> one quick trip into the kernel. I expect that applications will
> typically not care about this extra overhead as long as
> they are able to run.
>
> What did you test this on?  A page fault on any modern x86_64 system
> is much, much, much, much slower than a syscall.
>
>
> I tested it in on a KVM guest running Ubuntu. So, when you say
> that a page fault is much slower, do you mean a regular page
> fault that is handled through the VM layer? Here is the relevant code
> in do_user_addr_fault():

I mean that x86 CPUs have reasonably SYSCALL and SYSRET instructions
(the former is used for 64-bit system calls on Linux and the latter is
mostly used to return from system calls), but hardware page fault
delivery and IRET (used to return from page faults) are very slow.


[RFC][PATCH 2/2] dma-heap: Add a system-uncached heap

2020-07-28 Thread John Stultz
This adds a heap that allocates non-contiguous buffers that are
marked as writecombined, so they are not cached by the CPU.

This is useful, as most graphics buffers are usually not touched
by the CPU or only written into once by the CPU. So when mapping
the buffer over and over between devices, we can skip the CPU
syncing, which saves a lot of cache management overhead, greatly
improving performance.

For folk using ION, there was a ION_FLAG_CACHED flag, which
signaled if the returned buffer should be CPU cacheable or not.
With DMA-BUF heaps, we have no such flag, and by default the
current heaps (system and cma) produce CPU cachable buffers.
So for folks transitioning from ION to DMA-BUF Heaps, this fills
in some of that missing functionality.

This does have a few "ugly" bits that were required to get
the buffer properly flushed out initially which I'd like to
improve. So feedback would be very welcome!

Many thanks to Liam Mark for his help to get this working.

Cc: Sumit Semwal 
Cc: Andrew F. Davis 
Cc: Benjamin Gaignard 
Cc: Liam Mark 
Cc: Laura Abbott 
Cc: Brian Starkey 
Cc: Hridya Valsaraju 
Cc: linux-me...@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: John Stultz 
---
 drivers/dma-buf/heaps/Kconfig|  10 +
 drivers/dma-buf/heaps/Makefile   |   1 +
 drivers/dma-buf/heaps/system_uncached_heap.c | 392 +++
 3 files changed, 403 insertions(+)
 create mode 100644 drivers/dma-buf/heaps/system_uncached_heap.c

diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
index a5eef06c4226..420b0ed0a512 100644
--- a/drivers/dma-buf/heaps/Kconfig
+++ b/drivers/dma-buf/heaps/Kconfig
@@ -5,6 +5,16 @@ config DMABUF_HEAPS_SYSTEM
  Choose this option to enable the system dmabuf heap. The system heap
  is backed by pages from the buddy allocator. If in doubt, say Y.
 
+config DMABUF_HEAPS_SYSTEM_UNCACHED
+   bool "DMA-BUF Uncached System Heap"
+   depends on DMABUF_HEAPS
+   help
+ Choose this option to enable the uncached system dmabuf heap. This
+ heap is backed by pages from the buddy allocator, but pages are setup
+ for write combining. This avoids cache management overhead, and can
+ be faster if pages are mostly untouched by the cpu.  If in doubt,
+ say Y.
+
 config DMABUF_HEAPS_CMA
bool "DMA-BUF CMA Heap"
depends on DMABUF_HEAPS && DMA_CMA
diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
index 6e54cdec3da0..085685ec478f 100644
--- a/drivers/dma-buf/heaps/Makefile
+++ b/drivers/dma-buf/heaps/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y  += heap-helpers.o
 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)  += system_heap.o
+obj-$(CONFIG_DMABUF_HEAPS_SYSTEM_UNCACHED) += system_uncached_heap.o
 obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o
diff --git a/drivers/dma-buf/heaps/system_uncached_heap.c 
b/drivers/dma-buf/heaps/system_uncached_heap.c
new file mode 100644
index ..d23908038376
--- /dev/null
+++ b/drivers/dma-buf/heaps/system_uncached_heap.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Uncached System DMA-Heap exporter
+ *
+ * Copyright (C) 2020 Linaro Ltd.
+ *
+ * Based off of Andrew Davis' SRAM heap:
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Andrew F. Davis 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct uncached_heap {
+   struct dma_heap *heap;
+};
+
+struct uncached_heap_buffer {
+   struct dma_heap *heap;
+   struct list_head attachments;
+   struct mutex lock;
+   unsigned long len;
+   struct sg_table sg_table;
+   int vmap_cnt;
+   void *vaddr;
+};
+
+struct dma_heap_attachment {
+   struct device *dev;
+   struct sg_table *table;
+   struct list_head list;
+};
+
+static struct sg_table *dup_sg_table(struct sg_table *table)
+{
+   struct sg_table *new_table;
+   int ret, i;
+   struct scatterlist *sg, *new_sg;
+
+   new_table = kzalloc(sizeof(*new_table), GFP_KERNEL);
+   if (!new_table)
+   return ERR_PTR(-ENOMEM);
+
+   ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL);
+   if (ret) {
+   kfree(new_table);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   new_sg = new_table->sgl;
+   for_each_sg(table->sgl, sg, table->nents, i) {
+   memcpy(new_sg, sg, sizeof(*sg));
+   new_sg->dma_address = 0;
+   new_sg = sg_next(new_sg);
+   }
+
+   return new_table;
+}
+
+static int dma_heap_attach(struct dma_buf *dmabuf,
+  struct dma_buf_attachment *attachment)
+{
+   struct uncached_heap_buffer *buffer = dmabuf->priv;
+   struct dma_heap_attachment *a;
+   struct sg_table *table;
+
+   a = kzalloc(sizeof(*a), GFP_KERNEL);
+   

[RFC][PATCH 1/2] dma-heap: Keep track of the heap device struct

2020-07-28 Thread John Stultz
Keep track of the heap device struct.

This will be useful for special DMA allocations
and actions.

Cc: Sumit Semwal 
Cc: Andrew F. Davis 
Cc: Benjamin Gaignard 
Cc: Liam Mark 
Cc: Laura Abbott 
Cc: Brian Starkey 
Cc: Hridya Valsaraju 
Cc: linux-me...@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: John Stultz 
---
 drivers/dma-buf/dma-heap.c | 33 +
 include/linux/dma-heap.h   |  9 +
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index afd22c9dbdcf..72c746755d89 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -30,6 +30,7 @@
  * @heap_devt  heap device node
  * @list   list head connecting to list of heaps
  * @heap_cdev  heap char device
+ * @heap_dev   heap device struct
  *
  * Represents a heap of memory from which buffers can be made.
  */
@@ -40,6 +41,7 @@ struct dma_heap {
dev_t heap_devt;
struct list_head list;
struct cdev heap_cdev;
+   struct device *heap_dev;
 };
 
 static LIST_HEAD(heap_list);
@@ -190,10 +192,21 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
return heap->priv;
 }
 
+/**
+ * dma_heap_get_dev() - get device struct for the heap
+ * @heap: DMA-Heap to retrieve device struct from
+ *
+ * Returns:
+ * The device struct for the heap.
+ */
+struct device *dma_heap_get_dev(struct dma_heap *heap)
+{
+   return heap->heap_dev;
+}
+
 struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
 {
struct dma_heap *heap, *h, *err_ret;
-   struct device *dev_ret;
unsigned int minor;
int ret;
 
@@ -247,16 +260,20 @@ struct dma_heap *dma_heap_add(const struct 
dma_heap_export_info *exp_info)
goto err1;
}
 
-   dev_ret = device_create(dma_heap_class,
-   NULL,
-   heap->heap_devt,
-   NULL,
-   heap->name);
-   if (IS_ERR(dev_ret)) {
+   heap->heap_dev = device_create(dma_heap_class,
+  NULL,
+  heap->heap_devt,
+  NULL,
+  heap->name);
+   if (IS_ERR(heap->heap_dev)) {
pr_err("dma_heap: Unable to create device\n");
-   err_ret = ERR_CAST(dev_ret);
+   err_ret = ERR_CAST(heap->heap_dev);
goto err2;
}
+
+   /* Make sure it doesn't disappear on us */
+   heap->heap_dev = get_device(heap->heap_dev);
+
/* Add heap to the list */
mutex_lock(_list_lock);
list_add(>list, _list);
diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
index 454e354d1ffb..82857e096910 100644
--- a/include/linux/dma-heap.h
+++ b/include/linux/dma-heap.h
@@ -50,6 +50,15 @@ struct dma_heap_export_info {
  */
 void *dma_heap_get_drvdata(struct dma_heap *heap);
 
+/**
+ * dma_heap_get_dev() - get device struct for the heap
+ * @heap: DMA-Heap to retrieve device struct from
+ *
+ * Returns:
+ * The device struct for the heap.
+ */
+struct device *dma_heap_get_dev(struct dma_heap *heap);
+
 /**
  * dma_heap_add - adds a heap to dmabuf heaps
  * @exp_info:  information needed to register this heap
-- 
2.17.1



[PATCH v2 2/4] dt-bindings: regulator: mp886x: support mps,switch-frequency

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

Both MP8867 and MP8869 support different switch frequency.

Signed-off-by: Jisheng Zhang 
---
 Documentation/devicetree/bindings/regulator/mp886x.txt | 4 
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/mp886x.txt 
b/Documentation/devicetree/bindings/regulator/mp886x.txt
index 551867829459..e747000cebba 100644
--- a/Documentation/devicetree/bindings/regulator/mp886x.txt
+++ b/Documentation/devicetree/bindings/regulator/mp886x.txt
@@ -9,6 +9,10 @@ Required properties:
 - mps,fb-voltage-divider: An array of two integers containing the resistor
   values R1 and R2 of the feedback voltage divider in kilo ohms.
 
+Optional properties:
+- mps,switch-frequency: The valid switch frequency in Hertz. Available values
+  are: 50, 75, 100, 125, 150
+
 Any property defined as part of the core regulator binding, defined in
 ./regulator.txt, can also be used.
 
-- 
2.28.0.rc1




[PATCH v2 4/4] dt-bindings: regulator: Convert mp886x to json-schema

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

Convert the mp886x binding to DT schema format using json-schema.

Signed-off-by: Jisheng Zhang 
---
 .../devicetree/bindings/regulator/mp886x.txt  | 31 --
 .../bindings/regulator/mps,mp886x.yaml| 58 +++
 2 files changed, 58 insertions(+), 31 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/regulator/mp886x.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/mps,mp886x.yaml

diff --git a/Documentation/devicetree/bindings/regulator/mp886x.txt 
b/Documentation/devicetree/bindings/regulator/mp886x.txt
deleted file mode 100644
index e747000cebba..
--- a/Documentation/devicetree/bindings/regulator/mp886x.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-Monolithic Power Systems MP8867/MP8869 voltage regulator
-
-Required properties:
-- compatible: Must be one of the following.
-   "mps,mp8867"
-   "mps,mp8869"
-- reg: I2C slave address.
-- enable-gpios: enable gpios.
-- mps,fb-voltage-divider: An array of two integers containing the resistor
-  values R1 and R2 of the feedback voltage divider in kilo ohms.
-
-Optional properties:
-- mps,switch-frequency: The valid switch frequency in Hertz. Available values
-  are: 50, 75, 100, 125, 150
-
-Any property defined as part of the core regulator binding, defined in
-./regulator.txt, can also be used.
-
-Example:
-
-   vcpu: regulator@62 {
-   compatible = "mps,mp8869";
-   regulator-name = "vcpu";
-   regulator-min-microvolt = <70>;
-   regulator-max-microvolt = <85>;
-   regulator-always-on;
-   regulator-boot-on;
-   enable-gpios = < 1 GPIO_ACTIVE_LOW>;
-   mps,fb-voltage-divider = <80 240>;
-   reg = <0x62>;
-   };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml 
b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
new file mode 100644
index ..991f2de7eda8
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/mps,mp886x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Monolithic Power Systems MP8867/MP8869 voltage regulator
+
+maintainers:
+  - Jisheng Zhang 
+
+properties:
+  compatible:
+enum:
+  - mps,mp8867
+  - mps,mp8869
+
+  reg:
+maxItems: 1
+
+  enable-gpios:
+description: GPIO to enable/disable the regulator.
+maxItems: 1
+
+  mps,fb-voltage-divider:
+description: An array of two integers containing the resistor
+  values R1 and R2 of the feedback voltage divider in kilo ohms.
+$ref: "/schemas/types.yaml#/definitions/uint32-array"
+
+  mps,switch-frequency:
+description: The valid switch frequency in Hertz.
+enum: [50, 75, 100, 125, 150]
+$ref: "/schemas/types.yaml#/definitions/uint32"
+
+required:
+  - compatible
+  - reg
+  - enable-gpios
+  - mps,fb-voltage-divider
+
+examples:
+  - |
+#include 
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+regulator@62 {
+  compatible = "mps,mp8869";
+  regulator-name = "vcpu";
+  regulator-min-microvolt = <80>;
+  regulator-max-microvolt = <115>;
+  enable-gpios = < 1 GPIO_ACTIVE_LOW>;
+  mps,fb-voltage-divider = <80 240>;
+  reg = <0x62>;
+};
+};
+
+...
-- 
2.28.0.rc1




[PATCH v2 3/4] regulator: mp886x: support setting switch freq

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

Both MP8867 and MP8869 support different switch frequency.

Signed-off-by: Jisheng Zhang 
---
 drivers/regulator/mp886x.c | 42 ++
 1 file changed, 42 insertions(+)

diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index 3c9a6605b115..e3c7813bed4b 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -22,10 +22,14 @@
 #define  MP886X_SLEW_MASK  (0x7 << MP886X_SLEW_SHIFT)
 #define  MP886X_GO (1 << 6)
 #define  MP886X_EN (1 << 7)
+#define MP8869_SYSCNTLREG2 0x02
 
 struct mp886x_cfg_info {
const struct regulator_ops *rops;
const int slew_rates[8];
+   const int switch_freq[4];
+   const u8 fs_reg;
+   const u8 fs_shift;
 };
 
 struct mp886x_device_info {
@@ -60,6 +64,24 @@ static int mp886x_set_ramp(struct regulator_dev *rdev, int 
ramp)
  MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT);
 }
 
+static void mp886x_set_switch_freq(struct mp886x_device_info *di,
+  struct regmap *regmap,
+  u32 freq)
+{
+   const struct mp886x_cfg_info *ci = di->ci;
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) {
+   if (freq == ci->switch_freq[i]) {
+   regmap_update_bits(regmap, ci->fs_reg,
+ 0x3 << ci->fs_shift, i << ci->fs_shift);
+   return;
+   }
+   }
+
+   dev_err(di->dev, "invalid frequency %d\n", freq);
+}
+
 static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode)
 {
switch (mode) {
@@ -162,6 +184,14 @@ static const struct mp886x_cfg_info mp8869_ci = {
1250,
625,
},
+   .switch_freq = {
+   50,
+   75,
+   100,
+   125,
+   },
+   .fs_reg = MP8869_SYSCNTLREG2,
+   .fs_shift = 4,
 };
 
 static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
@@ -233,6 +263,14 @@ static const struct mp886x_cfg_info mp8867_ci = {
1000,
500,
},
+   .switch_freq = {
+   50,
+   75,
+   100,
+   150,
+   },
+   .fs_reg = MP886X_SYSCNTLREG1,
+   .fs_shift = 1,
 };
 
 static int mp886x_regulator_register(struct mp886x_device_info *di,
@@ -274,6 +312,7 @@ static int mp886x_i2c_probe(struct i2c_client *client,
struct mp886x_device_info *di;
struct regulator_config config = { };
struct regmap *regmap;
+   u32 freq;
int ret;
 
di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL);
@@ -311,6 +350,9 @@ static int mp886x_i2c_probe(struct i2c_client *client,
config.driver_data = di;
config.of_node = np;
 
+   if (!of_property_read_u32(np, "mps,switch-frequency", ))
+   mp886x_set_switch_freq(di, regmap, freq);
+
ret = mp886x_regulator_register(di, );
if (ret < 0)
dev_err(dev, "Failed to register regulator!\n");
-- 
2.28.0.rc1




[PATCH v2 0/4] regulator: mp886x: two features and dt json convert

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

This is to improve the mp886x regulator driver support.
patch1 implments .set_ramp_delay
patch2 and patch3 support the switch freq setting
patch4 converts dt binding to json-schema

Since v2:
  - put any schema conversions at the end of the series as Mark
suggested.

Jisheng Zhang (4):
  regulator: mp886x: implement set_ramp_delay
  dt-bindings: regulator: mp886x: support mps,switch-frequency
  regulator: mp886x: support setting switch freq
  dt-bindings: regulator: Convert mp886x to json-schema

 .../devicetree/bindings/regulator/mp886x.txt  |  27 -
 .../bindings/regulator/mps,mp886x.yaml|  58 ++
 drivers/regulator/mp886x.c| 109 +-
 3 files changed, 164 insertions(+), 30 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/regulator/mp886x.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/mps,mp886x.yaml

-- 
2.28.0.rc1




[PATCHv3] coresight: etm4x: Fix etm4_count race by moving cpuhp callbacks to init

2020-07-28 Thread Sai Prakash Ranjan
etm4_count keeps track of number of ETMv4 registered and on some systems,
a race is observed on etm4_count variable which can lead to multiple calls
to cpuhp_setup_state_nocalls_cpuslocked(). This function internally calls
cpuhp_store_callbacks() which prevents multiple registrations of callbacks
for a given state and due to this race, it returns -EBUSY leading to ETM
probe failures like below.

 coresight-etm4x: probe of 704.etm failed with error -16

This race can easily be triggered with async probe by setting probe type
as PROBE_PREFER_ASYNCHRONOUS and with ETM power management property
"arm,coresight-loses-context-with-cpu".

Prevent this race by moving cpuhp callbacks to etm driver init since the
cpuhp callbacks doesn't have to depend on the etm4_count and can be once
setup during driver init. Similarly we move cpu_pm notifier registration
to driver init and completely remove etm4_count usage. Also now we can
use non cpuslocked version of cpuhp callbacks with this movement.

Fixes: 9b6a3f3633a5 ("coresight: etmv4: Fix CPU power management setup in 
probe() function")
Fixes: 58eb457be028 ("hwtracing/coresight-etm4x: Convert to hotplug state 
machine")
Suggested-by: Suzuki K Poulose 
Signed-off-by: Sai Prakash Ranjan 
---

Changes in v3:
 * Minor cleanups from v2 and change to device_initcall (Stephen Boyd)
 * Move to non cpuslocked cpuhp callbacks and rename to etm_pm_setup() (Mike 
Leach) 

Changes in v2:
 * Rearrange cpuhp callbacks and move them to driver init (Suzuki K Poulose)

---
 drivers/hwtracing/coresight/coresight-etm4x.c | 65 +--
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c
index 6d7d2169bfb2..fddfd93b9a7b 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -48,8 +48,6 @@ module_param(pm_save_enable, int, 0444);
 MODULE_PARM_DESC(pm_save_enable,
"Save/restore state on power down: 1 = never, 2 = self-hosted");
 
-/* The number of ETMv4 currently registered */
-static int etm4_count;
 static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
 static void etm4_set_default_config(struct etmv4_config *config);
 static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
@@ -1398,28 +1396,25 @@ static struct notifier_block etm4_cpu_pm_nb = {
.notifier_call = etm4_cpu_pm_notify,
 };
 
-/* Setup PM. Called with cpus locked. Deals with error conditions and counts */
-static int etm4_pm_setup_cpuslocked(void)
+/* Setup PM. Deals with error conditions and counts */
+static int __init etm4_pm_setup(void)
 {
int ret;
 
-   if (etm4_count++)
-   return 0;
-
ret = cpu_pm_register_notifier(_cpu_pm_nb);
if (ret)
-   goto reduce_count;
+   return ret;
 
-   ret = 
cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
-  "arm/coresight4:starting",
-  etm4_starting_cpu, 
etm4_dying_cpu);
+   ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING,
+   "arm/coresight4:starting",
+   etm4_starting_cpu, etm4_dying_cpu);
 
if (ret)
goto unregister_notifier;
 
-   ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
-  "arm/coresight4:online",
-  etm4_online_cpu, NULL);
+   ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
+   "arm/coresight4:online",
+   etm4_online_cpu, NULL);
 
/* HP dyn state ID returned in ret on success */
if (ret > 0) {
@@ -1428,21 +1423,15 @@ static int etm4_pm_setup_cpuslocked(void)
}
 
/* failed dyn state - remove others */
-   cpuhp_remove_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING);
+   cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
 
 unregister_notifier:
cpu_pm_unregister_notifier(_cpu_pm_nb);
-
-reduce_count:
-   --etm4_count;
return ret;
 }
 
-static void etm4_pm_clear(void)
+static void __init etm4_pm_clear(void)
 {
-   if (--etm4_count != 0)
-   return;
-
cpu_pm_unregister_notifier(_cpu_pm_nb);
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
if (hp_online) {
@@ -1498,22 +1487,12 @@ static int etm4_probe(struct amba_device *adev, const 
struct amba_id *id)
if (!desc.name)
return -ENOMEM;
 
-   cpus_read_lock();
etmdrvdata[drvdata->cpu] = drvdata;
 
if (smp_call_function_single(drvdata->cpu,
etm4_init_arch_data,  drvdata, 1))
dev_err(dev, "ETM arch init failed\n");
 
-   

[PATCH v2 1/4] regulator: mp886x: implement set_ramp_delay

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

Implement the .set_ramp_delay for MP8867 and MP8869. MP8867 and MP8869
could share the implementation, the only difference is the slew_rates
array.

Signed-off-by: Jisheng Zhang 
---
 drivers/regulator/mp886x.c | 67 --
 1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index 1786f7162019..3c9a6605b115 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -18,18 +18,48 @@
 #define  MP886X_V_BOOT (1 << 7)
 #define MP886X_SYSCNTLREG1 0x01
 #define  MP886X_MODE   (1 << 0)
+#define  MP886X_SLEW_SHIFT 3
+#define  MP886X_SLEW_MASK  (0x7 << MP886X_SLEW_SHIFT)
 #define  MP886X_GO (1 << 6)
 #define  MP886X_EN (1 << 7)
 
+struct mp886x_cfg_info {
+   const struct regulator_ops *rops;
+   const int slew_rates[8];
+};
+
 struct mp886x_device_info {
struct device *dev;
struct regulator_desc desc;
struct regulator_init_data *regulator;
struct gpio_desc *en_gpio;
+   const struct mp886x_cfg_info *ci;
u32 r[2];
unsigned int sel;
 };
 
+static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp)
+{
+   struct mp886x_device_info *di = rdev_get_drvdata(rdev);
+   const struct mp886x_cfg_info *ci = di->ci;
+   int reg = -1, i;
+
+   for (i = 0; i < ARRAY_SIZE(ci->slew_rates); i++) {
+   if (ramp <= ci->slew_rates[i])
+   reg = i;
+   else
+   break;
+   }
+
+   if (reg < 0) {
+   dev_err(di->dev, "unsupported ramp value %d\n", ramp);
+   return -EINVAL;
+   }
+
+   return regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1,
+ MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT);
+}
+
 static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode)
 {
switch (mode) {
@@ -117,6 +147,21 @@ static const struct regulator_ops mp8869_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
+   .set_ramp_delay = mp886x_set_ramp,
+};
+
+static const struct mp886x_cfg_info mp8869_ci = {
+   .rops = _regulator_ops,
+   .slew_rates = {
+   4,
+   3,
+   2,
+   1,
+   5000,
+   2500,
+   1250,
+   625,
+   },
 };
 
 static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
@@ -173,6 +218,21 @@ static const struct regulator_ops mp8867_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp886x_set_mode,
.get_mode = mp886x_get_mode,
+   .set_ramp_delay = mp886x_set_ramp,
+};
+
+static const struct mp886x_cfg_info mp8867_ci = {
+   .rops = _regulator_ops,
+   .slew_rates = {
+   64000,
+   32000,
+   16000,
+   8000,
+   4000,
+   2000,
+   1000,
+   500,
+   },
 };
 
 static int mp886x_regulator_register(struct mp886x_device_info *di,
@@ -183,7 +243,7 @@ static int mp886x_regulator_register(struct 
mp886x_device_info *di,
 
rdesc->name = "mp886x-reg";
rdesc->supply_name = "vin";
-   rdesc->ops = of_device_get_match_data(di->dev);
+   rdesc->ops = di->ci->rops;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->n_voltages = 128;
rdesc->enable_reg = MP886X_SYSCNTLREG1;
@@ -235,6 +295,7 @@ static int mp886x_i2c_probe(struct i2c_client *client,
if (IS_ERR(di->en_gpio))
return PTR_ERR(di->en_gpio);
 
+   di->ci = of_device_get_match_data(dev);
di->dev = dev;
 
regmap = devm_regmap_init_i2c(client, _regmap_config);
@@ -259,11 +320,11 @@ static int mp886x_i2c_probe(struct i2c_client *client,
 static const struct of_device_id mp886x_dt_ids[] = {
{
.compatible = "mps,mp8867",
-   .data = _regulator_ops
+   .data = _ci
},
{
.compatible = "mps,mp8869",
-   .data = _regulator_ops
+   .data = _ci
},
{ }
 };
-- 
2.28.0.rc1




Re: [PATCH 2/6] arch: x86: Wrap TIF_IA32 checks

2020-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2020 at 9:46 PM Gabriel Krisman Bertazi
 wrote:
>
> Andy Lutomirski  writes:
>
> > On Tue, Jul 28, 2020 at 1:22 PM Gabriel Krisman Bertazi
> >  wrote:
> >>
> >> In preparation to remove TIF_IA32, add wrapper that check the process
> >> has IA32 ABI without using the flag directly.
> >
> > Thank you for doing this, but let's please do it right.  There is,
> > fundamentally, no such thing as a "process with IA32 ABI".
>
> Hi Andy,
>
> Thanks a lot for your review.
>
> As you can see, I'm learning my way here. Can you clarify "there is no
> such a thing as a 'process with IA32 ABI'"?  I'm not sure if I confused
> the terminology or if (more worrisome for me) I got the concepts wrong.
>
> My understanding is that TIF_IA32 marks a thread that is running under
> the 32-bit compat mode, which would be running a 32-bit process (as in
> compiled with -m32, for instance), while TIF_X32 marks a process running
> under the X32 ABI.  Each process would have only one of these
> "personalities". This is what I meant by a process with IA32 ABI (which
> is wrong in any case).  Is there more to it, or is the problem the
> terminology I used?

There's more to it.

On sane architectures like Linux on ARM64, a process can be 32-bit or
64-bit.  If you are a 64-bit ARM process, you run in 64-bit mode,
period.  Anything other than execve() that lets you become 32-bit is a
bug.

Linux on x86 is nutty, though.  (IIRC Sparc is too.)  In particular,
it's entirely legal for a Linux program to switch between 32-bit and
64-bit mode all by itself.  This can be done with LJMP, LRET, IRET, or
a few other hacks.  It can also be done using any of the sigreturn
syscalls.  (SYSENTER comes to mind, but anyone who uses SYSENTER to
switch modes is *nuts*.)  Certain evil people named Andy Lutomirski
write kernel selftests that switch modes using sigreturn just to abuse
the kernel.  But some real programs do this too.  For example, I think
that CRIU restores 32-bit programs by starting out as a 64-bit
program, restoring everything, and then switching to 32-bit mode.
Keep in mind that most of these mode-switching tricks do not enter the
kernel at all.

The upshot is that kernel does not actually know what the running
program's ABI is.  For all the kernel knows, a process uses the
Linux/psABI 64-bit ABI, the ia32 ABI, the x32 ABI, the Windows 32-bit
ABI, the Windows 64-bit ABI, and some gnarly ABI from DOS or OS/2, all
in the same process.

So we really shouldn't be trying to keep track of what we think the
user program should be doing, and instead we should pay attention to
what the user program actually did in its interactions with the
kernel.  If we want to know whether a user task is running in 64-bit
mode right now, we can use user_64bit_mode(regs).  (And keep in mind
that syscalls like rt_sigreturn() and anything that gets ptraced can
*change* the outcome of user_64bit_mode(regs) mid-syscall.)  If we're
delivering a signal, we instead want to know the ABI of the signal's
handler, so we use is_ia32_frame(ksig) and is_x32_frame(ksig).  If we
want to know whether mmap() should return values above 2^32-1, we
currently use some hackery, but we really ought to be looking at
whether the call was 64-bit mmap() or compat mmap().  (I had some
really half-baked patches to fix this at one point, but the core code
was a real mess and I didn't finish it.)  If we still supported MPX in
the kernel, we'd have a real mess, because MPX malfunctions if user
programs switch bitness on us.  Good riddance!

>
> I don't have any comments on the other things you mentioned, except that
> I need to go through them and better understand your suggestions.  Would
> you prefer me to rework this patch series with what you suggested or is
> this something you want to take over and do yourself?  Both ways are
> fine by me.

Please rework it :)  I have seriously limited bandwidth right now.


Re: PROBLEM: 5.8-rc7 no video output with nouveau on NV36 (regression)

2020-07-28 Thread Dave Airlie
On Wed, 29 Jul 2020 at 15:05, Nick Bowler  wrote:
>
> Hi,
>
> After installing Linux 5.8-rc7 I seem to get no video output on my
> NV36 card once the nouveau module is loaded.  The display (connected
> to the digital output) simply reports "No Signal".
>
> I bisected to the following commit, and reverting this commit on
> top of 5.8-rc7 appears to correct the issue.

Can you test the drm fixes pull I just sent to Linus

https://patchwork.freedesktop.org/patch/381225/

Otherwise we are awaiting a fix from James for one other issue, should
be here today/tomorrow.

Dave.


Re: [PATCH] ASoC: Intel: Atom: use hardware counter to update hw_ptr

2020-07-28 Thread Cheng-yi Chiang
On Wed, Jul 29, 2020 at 1:31 AM Pierre-Louis Bossart
 wrote:
>
>
>
> On 7/28/20 12:02 PM, Lu, Brent wrote:
> >>
> >> So if there are already quirks in atom machine drivers to change the period
> >> size, why is this patch necessary?
> >>
> >
> > The story is: google implemented the constraint but doesn't know why it 
> > works
> > so asked us to explain. After checking the two counters I realized the 
> > increase of
> > ring buffer pointer follows the period size setting in hw_param (256) but 
> > the
> > period of interrupt is always 5ms instead of 5.33 so it's running little 
> > bit too fast.
> > It seems the LPE keeps tracking the difference of two counters. When the
> > difference exceeds 2160 samples, the next interrupt will be canceled so the
> > hardware counter could catch up a little.
> >
> > [   43.208299] intel_sst_acpi 808622A8:00: mrfld ring_buffer_counter 107520 
> > hardware_counter 98880 pcm delay 8640 (in bytes)
> > [   43.208306] intel_sst_acpi 808622A8:00: buffer ptr 26880 pcm_delay rep: 
> > 2160
> > [   43.208321] sound pcmC1D0p: [Q] pos 26880 hw_ptr 26880 appl_ptr 4 
> > avail 191680
> > => one interrupt is skipped.
> > [   43.218299] intel_sst_acpi 808622A8:00: mrfld ring_buffer_counter 108544 
> > hardware_counter 100800 pcm delay 7744 (in bytes)
> > [   43.218307] intel_sst_acpi 808622A8:00: buffer ptr 27136 pcm_delay rep: 
> > 1936
> > [   43.218336] sound pcmC1D0p: [Q] pos 27136 hw_ptr 27136 appl_ptr 4 
> > avail 191936
> >
> > So I think why not using the hardware counter? It increases 240 samples 
> > every 5ms
> > perfectly match the 48000 sample rate. The test result is good but I know 
> > there must
> > be a reason for the original designer to use ring buffer counter instead of 
> > hardware
> > counter. I uploaded this patch to see if anyone still remember the reason 
> > and share
> > some insight with me.
> >
> > I totally agree that we shouldn't touch this part of design. Do you think 
> > it make sense
> > to add a constraint to enforce the period size in machine driver? If yes 
> > then I would
> > upload patches for Chrome atom machines for google.
>
> I think it'd make sense to add this constraint, either in the machine
> driver or in the platform driver, so that we don't change the position
> updates and introduce more issues by accident by doing so. As you
> rightly said, I don't think anyone tested periods multiple of 256
> samples so it's not a regression, more aligning with the internal design.

Thanks for the explanation and discussion.
A slight correction in this thread is that CRAS does not set period size to 256.
It just uses whatever value that driver wants to use, which happens to be 256.
If the driver can limit the selection to only correct values that
would be the best.
Adding constraints in the machine driver or platform driver looks
good. Prefer to adding in platform driver so we don't need to add for
each machine driver.
Thanks!


Re: [PATCHv2] coresight: etm4x: Fix etm4_count race by moving cpuhp callbacks to init

2020-07-28 Thread Sai Prakash Ranjan

Hi Mike,

On 2020-07-29 01:46, Mike Leach wrote:

Hi Sai,

On Tue, 28 Jul 2020 at 08:51, Sai Prakash Ranjan
 wrote:


etm4_count keeps track of number of ETMv4 registered and on some 
systems,
a race is observed on etm4_count variable which can lead to multiple 
calls
to cpuhp_setup_state_nocalls_cpuslocked(). This function internally 
calls
cpuhp_store_callbacks() which prevents multiple registrations of 
callbacks
for a given state and due to this race, it returns -EBUSY leading to 
ETM

probe failures like below.

 coresight-etm4x: probe of 704.etm failed with error -16

This race can easily be triggered with async probe by setting probe 
type

as PROBE_PREFER_ASYNCHRONOUS and with ETM power management property
"arm,coresight-loses-context-with-cpu".

Prevent this race by moving cpuhp callbacks to etm driver init since 
the
cpuhp callbacks doesn't have to depend on the etm4_count and can be 
once
setup during driver init. Similarly we move cpu_pm notifier 
registration

to driver init and completely remove etm4_count usage.

Fixes: 9b6a3f3633a5 ("coresight: etmv4: Fix CPU power management setup 
in probe() function")
Fixes: 58eb457be028 ("hwtracing/coresight-etm4x: Convert to hotplug 
state machine")

Suggested-by: Suzuki K Poulose 
Signed-off-by: Sai Prakash Ranjan 
---

Changes in v2:
 * Rearrange cpuhp callbacks and move them to driver init (Suzuki K 
Poulose)


---
 drivers/hwtracing/coresight/coresight-etm4x.c | 51 
++-

 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c 
b/drivers/hwtracing/coresight/coresight-etm4x.c

index 6d7d2169bfb2..adb71987a1e3 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -48,8 +48,6 @@ module_param(pm_save_enable, int, 0444);
 MODULE_PARM_DESC(pm_save_enable,
"Save/restore state on power down: 1 = never, 2 = 
self-hosted");


-/* The number of ETMv4 currently registered */
-static int etm4_count;
 static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
 static void etm4_set_default_config(struct etmv4_config *config);
 static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
@@ -1403,12 +1401,9 @@ static int etm4_pm_setup_cpuslocked(void)
 {


consider renaming this to etm4_pm_setup() and handing any cpu locking
inside the function.
In the circumstances - as part of the driver init rather than probe it
may be sufficient to call the cpuhp_setup functions without the
_cpuslocked suffix and allow the calls to lock the cpus as they are
made.
i.e. cpuhp_setup_state_nocalls_cpuslocked() => 
cpuhp_setup_state_nocalls()


Sure, will make this change.




int ret;

-   if (etm4_count++)
-   return 0;
-
ret = cpu_pm_register_notifier(_cpu_pm_nb);
if (ret)
-   goto reduce_count;
+   return ret;

ret = 
cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
   
"arm/coresight4:starting",

@@ -1432,17 +1427,11 @@ static int etm4_pm_setup_cpuslocked(void)

 unregister_notifier:
cpu_pm_unregister_notifier(_cpu_pm_nb);
-
-reduce_count:
-   --etm4_count;
return ret;
 }

 static void etm4_pm_clear(void)
 {
-   if (--etm4_count != 0)
-   return;
-
cpu_pm_unregister_notifier(_cpu_pm_nb);
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
if (hp_online) {
@@ -1498,22 +1487,12 @@ static int etm4_probe(struct amba_device 
*adev, const struct amba_id *id)

if (!desc.name)
return -ENOMEM;

-   cpus_read_lock();
etmdrvdata[drvdata->cpu] = drvdata;

if (smp_call_function_single(drvdata->cpu,
etm4_init_arch_data,  drvdata, 1))
dev_err(dev, "ETM arch init failed\n");

-   ret = etm4_pm_setup_cpuslocked();
-   cpus_read_unlock();
-
-   /* etm4_pm_setup_cpuslocked() does its own cleanup - exit on 
error */

-   if (ret) {
-   etmdrvdata[drvdata->cpu] = NULL;
-   return ret;
-   }
-
if (etm4_arch_supported(drvdata->arch) == false) {
ret = -EINVAL;
goto err_arch_supported;
@@ -1560,7 +1539,6 @@ static int etm4_probe(struct amba_device *adev, 
const struct amba_id *id)


 err_arch_supported:
etmdrvdata[drvdata->cpu] = NULL;
-   etm4_pm_clear();
return ret;
 }

@@ -1598,4 +1576,29 @@ static struct amba_driver etm4x_driver = {
.probe  = etm4_probe,
.id_table   = etm4_ids,
 };
-builtin_amba_driver(etm4x_driver);
+
+static int __init etm4x_init(void)
+{
+   int ret;
+
+   cpus_read_lock();
+   ret = etm4_pm_setup_cpuslocked();
+   cpus_read_unlock();


See my comment above about rename and use of cpus_read_lock



Yes, thanks for the review Mike.

Thanks,
Sai

--
QUALCOMM INDIA, on behalf of Qualcomm Innovation 

PROBLEM: 5.8-rc7 no video output with nouveau on NV36 (regression)

2020-07-28 Thread Nick Bowler
Hi,

After installing Linux 5.8-rc7 I seem to get no video output on my
NV36 card once the nouveau module is loaded.  The display (connected
to the digital output) simply reports "No Signal".

I bisected to the following commit, and reverting this commit on
top of 5.8-rc7 appears to correct the issue.

  fa4f4c213f5f7807360c41f2501a3031a9940f3a is the first bad commit
  commit fa4f4c213f5f7807360c41f2501a3031a9940f3a
  Author: James Jones 
  Date:   Mon Feb 10 15:15:55 2020 -0800
  
  drm/nouveau/kms: Support NVIDIA format modifiers
  
  Allow setting the block layout of a nouveau FB
  object using DRM format modifiers.  When
  specified, the format modifier block layout and
  kind overrides the GEM buffer's implicit layout
  and kind.  The specified format modifier is
  validated against the list of modifiers supported
  by the target display hardware.
  
  v2: Used Tesla family instead of NV50 chipset compare
  v4: Do not cache kind, tile_mode in nouveau_framebuffer
  v5: Resolved against nouveau_framebuffer cleanup
  
  Signed-off-by: James Jones 
  Signed-off-by: Ben Skeggs 
  
   drivers/gpu/drm/nouveau/dispnv50/wndw.c   | 20 ---
   drivers/gpu/drm/nouveau/nouveau_display.c | 89 
++-
   drivers/gpu/drm/nouveau/nouveau_display.h |  4 ++
   3 files changed, 104 insertions(+), 9 deletions(-)

The dmesg output from loading the driver is identical except several
lines are missing in the non-working case, which I have marked with
"XXX" below:

  [  168.222926] PCI Interrupt Link [LNKE] enabled at IRQ 16
  [  168.223199] nouveau :01:00.0: vgaarb: deactivate vga console
  [  168.224379] Console: switching to colour dummy device 80x25
  [  168.224612] nouveau :01:00.0: NVIDIA NV36 (436200a1)
  [  168.324779] nouveau :01:00.0: bios: version 04.36.20.21.00
  [  168.325646] agpgart-amd64 :00:00.0: AGP 3.0 bridge
  [  168.325657] agpgart: modprobe tried to set rate=x12. Setting to AGP3 
x8 mode.
  [  168.325662] agpgart-amd64 :00:00.0: putting AGP V3 device into 8x 
mode
  [  168.325679] nouveau :01:00.0: putting AGP V3 device into 8x mode
  [  168.325908] agpgart-amd64 :00:00.0: AGP 3.0 bridge
  [  168.325914] agpgart: modprobe tried to set rate=x12. Setting to AGP3 
x8 mode.
  [  168.325918] agpgart-amd64 :00:00.0: putting AGP V3 device into 8x 
mode
  [  168.325933] nouveau :01:00.0: putting AGP V3 device into 8x mode
  [  168.325990] nouveau :01:00.0: tmr: unknown input clock freq
  [  168.326732] nouveau :01:00.0: fb: 256 MiB DDR1
  [  168.328174] [TTM] Zone  kernel: Available graphics memory: 1022540 KiB
  [  168.328175] [TTM] Initializing pool allocator
  [  168.328181] [TTM] Initializing DMA pool allocator
  [  168.328200] nouveau :01:00.0: DRM: VRAM: 255 MiB
  [  168.328201] nouveau :01:00.0: DRM: GART: 128 MiB
  [  168.328204] nouveau :01:00.0: DRM: BMP version 5.40
  [  168.328208] nouveau :01:00.0: DRM: DCB version 2.2
  [  168.328210] nouveau :01:00.0: DRM: DCB outp 00: 01000300 9c40
  [  168.328214] nouveau :01:00.0: DRM: DCB outp 01: 02010310 9c40
  [  168.328215] nouveau :01:00.0: DRM: DCB outp 02: 04000302 
  [  168.328217] nouveau :01:00.0: DRM: DCB outp 03: 02020321 0303
  [  168.328495] nouveau :01:00.0: DRM: Loading NV17 power sequencing 
microcode
  [  168.329691] nouveau :01:00.0: DRM: MM: using M2MF for buffer copies
  [  168.330258] nouveau :01:00.0: DRM: Saving VGA fonts
  [  168.389460] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
  [  168.391250] nouveau :01:00.0: DRM: Setting dpms mode 3 on TV 
encoder (output 3)
  XXX [  168.487647] nouveau :01:00.0: DRM: allocated 1920x1080 fb: 0x9000, 
bo ff426de1
  XXX [  168.491835] fbcon: nouveaudrmfb (fb0) is primary device
  XXX [  168.608512] nouveau :01:00.0: DRM: 0xE4FB: Parsing digital output 
script table
  XXX [  168.662451] Console: switching to colour frame buffer device 240x67
  XXX [  168.755987] nouveau :01:00.0: fb0: nouveaudrmfb frame buffer device
  [  168.763736] [drm] Initialized nouveau 1.3.1 20120801 for :01:00.0 
on minor 0

Let me know if you need any more info.

Cheers,
  Nick


RE: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence for wdog operations

2020-07-28 Thread Anson Huang
Hi, Guenter


> Subject: RE: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence
> for wdog operations
> 
> Hi, Guenter
> 
> 
> > Subject: Re: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the
> > sequence for wdog operations
> >
> > On 7/28/20 7:20 PM, Anson Huang wrote:
> > > According to reference manual, the i.MX7ULP WDOG's operations should
> > > follow below sequence:
> > >
> > > 1. disable global interrupts;
> > > 2. unlock the wdog and wait unlock bit set; 3. reconfigure the wdog
> > > and wait for reconfiguration bit set; 4. enabel global interrupts.
> > >
> > > Strictly follow the recommended sequence can make it more robust.
> > >
> > > Signed-off-by: Anson Huang 
> > > ---
> > > Changes since V1:
> > >   - use readl_poll_timeout_atomic() instead of usleep_ranges() since
> > > IRQ is
> > disabled.
> > > ---
> > >  drivers/watchdog/imx7ulp_wdt.c | 29 +
> > >  1 file changed, 29 insertions(+)
> > >
> > > diff --git a/drivers/watchdog/imx7ulp_wdt.c
> > > b/drivers/watchdog/imx7ulp_wdt.c index 7993c8c..7d2b12e 100644
> > > --- a/drivers/watchdog/imx7ulp_wdt.c
> > > +++ b/drivers/watchdog/imx7ulp_wdt.c
> > > @@ -5,6 +5,7 @@
> > >
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -36,6 +37,7 @@
> > >  #define DEFAULT_TIMEOUT  60
> > >  #define MAX_TIMEOUT  128
> > >  #define WDOG_CLOCK_RATE  1000
> > > +#define WDOG_WAIT_TIMEOUT1
> > >
> > >  static bool nowayout = WATCHDOG_NOWAYOUT;
> > module_param(nowayout,
> > > bool, ); @@ -48,17 +50,31 @@ struct imx7ulp_wdt_device {
> > >   struct clk *clk;
> > >  };
> > >
> > > +static inline void imx7ulp_wdt_wait(void __iomem *base, u32 mask) {
> > > + u32 val = readl(base + WDOG_CS);
> > > +
> > > + if (!(val & mask))
> > > + WARN_ON(readl_poll_timeout_atomic(base + WDOG_CS, val,
> > > +   val & mask, 0,
> > > +   WDOG_WAIT_TIMEOUT));
> >
> > I am not a friend of WARN_ON, especially in situations like this.
> > Please explain why this is needed, and why a return of -ETIMEDOUT is
> > not feasible.
> 
> OK, I will use return value of -ETIMEOUT and handle it in the caller.

After a further look, some of the imx7ulp_wdt_wait () callers are void 
function, so if want
to handle the return value, all those functions return type need to be changed. 
And, when
the return value is -ETIMEDOUT, the ONLY action is to print out some error 
message
for these void function, need to use pr_err() due to no dev pointer available, 
so
do you think it is acceptable to just replace the WARN_ON with pr_err() as 
below?

+   if (!(val & mask)) {
+   if (readl_poll_timeout_atomic(base + WDOG_CS, val,
+ val & mask, 0,
+ WDOG_WAIT_TIMEOUT))
+   pr_err("wdog wait timeout, mask 0x%x\n", mask);
+   }

Thanks,
Anson



[PATCH v2] dt-bindings: regulator: Convert sy8824x to json-schema

2020-07-28 Thread Jisheng Zhang
From: Jisheng Zhang 

Convert the sy8824x binding to DT schema format using json-schema.

Signed-off-by: Jisheng Zhang 
---

Since v1
  -It seems there's something wrong with my last email, so send out a v2 with
   another email account

 .../bindings/regulator/silergy,sy8824x.yaml   | 40 +++
 .../devicetree/bindings/regulator/sy8824x.txt | 24 ---
 2 files changed, 40 insertions(+), 24 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
 delete mode 100644 Documentation/devicetree/bindings/regulator/sy8824x.txt

diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml 
b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
new file mode 100644
index ..62a476c94111
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/silergy,sy8824x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: silergy sy8824c,sy8824e,sy20276 and sy20278 PMIC
+
+maintainers:
+  - Jisheng Zhang 
+
+properties:
+  compatible:
+enum:
+  - silergy,sy8824c
+  - silergy,sy8824e
+  - silergy,sy20276
+  - silergy,sy20278
+
+  reg:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+regulator@60 {
+  compatible = "silergy,sy8824c";
+  regulator-min-microvolt = <80>;
+  regulator-max-microvolt = <115>;
+  reg = <0x60>;
+};
+};
+
+...
diff --git a/Documentation/devicetree/bindings/regulator/sy8824x.txt 
b/Documentation/devicetree/bindings/regulator/sy8824x.txt
deleted file mode 100644
index c5e95850c427..
--- a/Documentation/devicetree/bindings/regulator/sy8824x.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-SY8824C/SY8824E/SY20276 Voltage regulator
-
-Required properties:
-- compatible: Must be one of the following.
-   "silergy,sy8824c"
-   "silergy,sy8824e"
-   "silergy,sy20276"
-   "silergy,sy20278"
-- reg: I2C slave address
-
-Any property defined as part of the core regulator binding, defined in
-./regulator.txt, can also be used.
-
-Example:
-
-   vcore: regulator@00 {
-   compatible = "silergy,sy8824c";
-   reg = <0x66>;
-   regulator-name = "vcore";
-   regulator-min-microvolt = <80>;
-   regulator-max-microvolt = <115>;
-   regulator-boot-on;
-   regulator-always-on;
-   };
-- 
2.28.0.rc0




Re: [PATCH 3/6] arch: x86: Wrap TIF_X32 checks

2020-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2020 at 1:22 PM Gabriel Krisman Bertazi
 wrote:
>
> In preparation to remove TIF_X32, add a wrapper that checks the process
> is using the X32 ABI without using the flag directly.

I'm not sure what the right solution here is, but all three of these
functions are in the ELF loading path, and the callers of all three
have access to the full ELF info.  Let's instead either stick enough
information into bprm to figure out what ABI is being loaded or pass
in a pointer to the ELF headers.  The latter might be a bit nasty due
to the way that the ELF headers have a different type for compat.

In any case, sticking this into per-task state (task_struct or
anything in it) is silly.  The full ABI info is on the call stack, and
there's no need to keep this particular bit around forever.

--Andy


Re: [PATCH] scsi: 3w-9xxx: Fix endianness issues found by sparse

2020-07-28 Thread Samuel Holland
On 7/27/20 2:18 PM, Arnd Bergmann wrote:
> On Sun, Jul 26, 2020 at 9:15 PM Samuel Holland  wrote:
>>
>> The main issue observed was at the call to scsi_set_resid, where the
>> byteswapped parameter would eventually trigger the alignment check at
>> drivers/scsi/sd.c:2009. At that point, the kernel would continuously
>> complain about an "Unaligned partial completion", and no further I/O
>> could occur.
>>
>> This gets the controller working on big endian powerpc64.
>>
>> Signed-off-by: Samuel Holland 
>> ---
>>  drivers/scsi/3w-9xxx.c | 35 +--
>>  drivers/scsi/3w-9xxx.h |  6 +-
>>  2 files changed, 22 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
>> index 3337b1e80412..95e25fda1f90 100644
>> --- a/drivers/scsi/3w-9xxx.c
>> +++ b/drivers/scsi/3w-9xxx.c
>> @@ -303,10 +303,10 @@ static int twa_aen_drain_queue(TW_Device_Extension 
>> *tw_dev, int no_check_reset)
>>
>> /* Initialize sglist */
>> memset(, 0, sizeof(TW_SG_Entry));
>> -   sglist[0].length = TW_SECTOR_SIZE;
>> -   sglist[0].address = tw_dev->generic_buffer_phys[request_id];
>> +   sglist[0].length = cpu_to_le32(TW_SECTOR_SIZE);
>> +   sglist[0].address = 
>> TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
> 
> This looks like it would add a sparse warning, not fix one, unless you also
> change the types of the target structure.

Yes, I meant to change the structure types as well. All of the command
structures sent to the card are little-endian. I pulled this bugfix patch out of
a series of unrelated changes, and I missed the header changes. I'll send a v2.

>> @@ -501,7 +501,7 @@ static void twa_aen_sync_time(TW_Device_Extension 
>> *tw_dev, int request_id)
>> Sunday 12:00AM */
>> local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 
>> 60));
>> div_u64_rem(local_time - (3 * 86400), 604800, );
>> -   schedulertime = cpu_to_le32(schedulertime % 604800);
>> +   cpu_to_le32p();
>>
>> memcpy(param->data, , sizeof(u32));
> 
> You dropped the '%' operation, and the result of the byteswap?

schedulertime is the remainder from the previous line, so it is <604800 already.
You're right about that being the wrong function -- I meant to use cpu_to_le32s
to swap it in place, to avoid needing a second variable.

>> @@ -1004,7 +1004,7 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, 
>> int request_id, int copy_
>>
>> full_command_packet->header.status_block.error,
>>error_str[0] == '\0' ?
>>twa_string_lookup(twa_error_table,
>> -
>> full_command_packet->header.status_block.error) : error_str,
>> +
>> le16_to_cpu(full_command_packet->header.status_block.error)) : error_str,
>>
>> full_command_packet->header.err_specific_desc);
>> else
> 
> This looks correct, but the error value has already been copied into the local
> 'error' variable, which you could use for simplification. As 'status_block' is
> defined as a native_endian structure, this also introduced a sparse warning.

I'll use 'error' in v2, thanks for the hint.

>> @@ -1012,7 +1012,7 @@ static int twa_fill_sense(TW_Device_Extension *tw_dev, 
>> int request_id, int copy_
>>
>> full_command_packet->header.status_block.error,
>>error_str[0] == '\0' ?
>>twa_string_lookup(twa_error_table,
>> -
>> full_command_packet->header.status_block.error) : error_str,
>> +
>> le16_to_cpu(full_command_packet->header.status_block.error)) : error_str,
> 
> Same here
> 
>Arnd
> 

Cheers,
Samuel


RE: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence for wdog operations

2020-07-28 Thread Anson Huang
Hi, Guenter


> Subject: Re: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence
> for wdog operations
> 
> On 7/28/20 7:20 PM, Anson Huang wrote:
> > According to reference manual, the i.MX7ULP WDOG's operations should
> > follow below sequence:
> >
> > 1. disable global interrupts;
> > 2. unlock the wdog and wait unlock bit set; 3. reconfigure the wdog
> > and wait for reconfiguration bit set; 4. enabel global interrupts.
> >
> > Strictly follow the recommended sequence can make it more robust.
> >
> > Signed-off-by: Anson Huang 
> > ---
> > Changes since V1:
> > - use readl_poll_timeout_atomic() instead of usleep_ranges() since IRQ 
> > is
> disabled.
> > ---
> >  drivers/watchdog/imx7ulp_wdt.c | 29 +
> >  1 file changed, 29 insertions(+)
> >
> > diff --git a/drivers/watchdog/imx7ulp_wdt.c
> > b/drivers/watchdog/imx7ulp_wdt.c index 7993c8c..7d2b12e 100644
> > --- a/drivers/watchdog/imx7ulp_wdt.c
> > +++ b/drivers/watchdog/imx7ulp_wdt.c
> > @@ -5,6 +5,7 @@
> >
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -36,6 +37,7 @@
> >  #define DEFAULT_TIMEOUT60
> >  #define MAX_TIMEOUT128
> >  #define WDOG_CLOCK_RATE1000
> > +#define WDOG_WAIT_TIMEOUT  1
> >
> >  static bool nowayout = WATCHDOG_NOWAYOUT;
> module_param(nowayout,
> > bool, ); @@ -48,17 +50,31 @@ struct imx7ulp_wdt_device {
> > struct clk *clk;
> >  };
> >
> > +static inline void imx7ulp_wdt_wait(void __iomem *base, u32 mask) {
> > +   u32 val = readl(base + WDOG_CS);
> > +
> > +   if (!(val & mask))
> > +   WARN_ON(readl_poll_timeout_atomic(base + WDOG_CS, val,
> > + val & mask, 0,
> > + WDOG_WAIT_TIMEOUT));
> 
> I am not a friend of WARN_ON, especially in situations like this.
> Please explain why this is needed, and why a return of -ETIMEDOUT is not
> feasible.

OK, I will use return value of -ETIMEOUT and handle it in the caller.

> 
> Also, I do not believe that a 10 milli-second timeout is warranted.
> This will need to be backed up by the datasheet.
> 

There is no such info provided in reference manual or datasheet, but I just did
an experiment, the unlock window is open in less than 1us after sending unlock 
command,
and ONLY last for ONLY 2~3 us then close, the reconfiguration status bit will 
be set in less than
1us after register write. So what do you recommend for this timeout value? 
100mS for safe?

Thanks,
Anson


Re: [PATCH 2/6] arch: x86: Wrap TIF_IA32 checks

2020-07-28 Thread Gabriel Krisman Bertazi
Andy Lutomirski  writes:

> On Tue, Jul 28, 2020 at 1:22 PM Gabriel Krisman Bertazi
>  wrote:
>>
>> In preparation to remove TIF_IA32, add wrapper that check the process
>> has IA32 ABI without using the flag directly.
>
> Thank you for doing this, but let's please do it right.  There is,
> fundamentally, no such thing as a "process with IA32 ABI".

Hi Andy,

Thanks a lot for your review.

As you can see, I'm learning my way here. Can you clarify "there is no
such a thing as a 'process with IA32 ABI'"?  I'm not sure if I confused
the terminology or if (more worrisome for me) I got the concepts wrong.

My understanding is that TIF_IA32 marks a thread that is running under
the 32-bit compat mode, which would be running a 32-bit process (as in
compiled with -m32, for instance), while TIF_X32 marks a process running
under the X32 ABI.  Each process would have only one of these
"personalities". This is what I meant by a process with IA32 ABI (which
is wrong in any case).  Is there more to it, or is the problem the
terminology I used?

I don't have any comments on the other things you mentioned, except that
I need to go through them and better understand your suggestions.  Would
you prefer me to rework this patch series with what you suggested or is
this something you want to take over and do yourself?  Both ways are
fine by me.

Thanks,

-- 
Gabriel Krisman Bertazi


[git pull] drm fixes for 5.8-rc8

2020-07-28 Thread Dave Airlie
Hi Linus,

I'm sending this out a bit early, just to give you a chance to reject
it or help decide on an rc8.

The nouveau fixes missed the last pull by a few hours, and we had a
few arm driver/panel/bridge fixes come in. This is possibly a bit more
than I'm comfortable sending at this stage, but I've looked at each
patch, the core + nouveau patches fix regressions, and the arm related
ones are all around screens turning on and working, and are mostly
trivial patches, the line count is mostly in comments.

If you feel this is too much I'm happy to respin with the
core/drm_fb_helper and nouveau fixes. we have one outstanding nouveau
regression fix, that I'll follow this up with in the next day or so
once Ben and James get it reviewed.

Dave.

This is possibly a bit

drm-fixes-2020-07-29:
drm fixes for 5.8-rc8

core:
- fix possible use-after-free

drm_fb_helper:
- regression fix to use memcpy_io on bochs' sparc64

nouveau:
- format modifiers fixes
- HDA regression fix
- turing modesetting race fix

of:
- fix a double free

dbi:
- fix SPI Type 1 transfer

mcde:
- fix screen stability crash

panel:
- panel: fix display noise on auo,kd101n80-45na
- panel: delay HPD checks for boe_nv133fhm_n61

bridge:
- bridge: drop connector check in nwl-dsi bridge
- bridge: set proper bridge type for adv7511
The following changes since commit 92ed301919932f13b9172e525674157e983d:

  Linux 5.8-rc7 (2020-07-26 14:14:06 -0700)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2020-07-29

for you to fetch changes up to a4a2739beb8933a19281bca077fdb852598803ed:

  Merge tag 'drm-misc-fixes-2020-07-28' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2020-07-29
12:46:58 +1000)


drm fixes for 5.8-rc8

core:
- fix possible use-after-free

drm_fb_helper:
- regression fix to use memcpy_io on bochs' sparc64

nouveau:
- format modifiers fixes
- HDA regression fix
- turing modesetting race fix

of:
- fix a double free
dbi:
- fix SPI Type 1 transfer

mcde:
- fix screen stability crash

panel:
- panel: fix display noise on auo,kd101n80-45na
- panel: delay HPD checks for boe_nv133fhm_n61

bridge:
- bridge: drop connector check in nwl-dsi bridge
- bridge: set proper bridge type for adv7511


Ben Skeggs (5):
  drm/nouveau/disp/gm200-: fix regression from HDA SOR selection changes
  drm/nouveau/kms/gf100: use correct format modifiers
  drm/nouveau/kms/tu102: wait for core update to complete when
assigning windows
  drm/nouveau/fbcon: fix module unload when fbcon init has failed
for some reason
  drm/nouveau/fbcon: zero-initialise the mode_cmd2 structure

Biju Das (1):
  drm: of: Fix double-free bug

Dave Airlie (2):
  Merge branch 'linux-5.8' of git://github.com/skeggsb/linux into drm-fixes
  Merge tag 'drm-misc-fixes-2020-07-28' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Douglas Anderson (1):
  drm: panel: simple: Delay HPD checking on boe_nv133fhm_n61 for 15 ms

Guido Günther (1):
  drm/bridge: nwl-dsi: Drop DRM_BRIDGE_ATTACH_NO_CONNECTOR check.

Jitao Shi (1):
  drm/panel: Fix auo, kd101n80-45na horizontal noise on edges of panel

Laurentiu Palcu (1):
  drm/bridge/adv7511: set the bridge type properly

Linus Walleij (1):
  drm/mcde: Fix stability issue

Paul Cercueil (1):
  drm/dbi: Fix SPI Type 1 (9-bit) transfer

Sam Ravnborg (1):
  drm/drm_fb_helper: fix fbdev with sparc64

Steve Cohen (1):
  drm: hold gem reference until object is no longer accessed

 drivers/gpu/drm/bochs/bochs_kms.c   |  1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c|  1 +
 drivers/gpu/drm/bridge/nwl-dsi.c|  5 -
 drivers/gpu/drm/drm_fb_helper.c |  6 -
 drivers/gpu/drm/drm_gem.c   | 10 -
 drivers/gpu/drm/drm_mipi_dbi.c  |  2 +-
 drivers/gpu/drm/drm_of.c|  4 +---
 drivers/gpu/drm/mcde/mcde_display.c | 11 ++---
 drivers/gpu/drm/nouveau/dispnv50/disp.c |  4 ++--
 drivers/gpu/drm/nouveau/nouveau_fbcon.c |  3 ++-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c | 30 +
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c  |  6 ++---
 drivers/gpu/drm/panel/panel-simple.c| 16 -
 include/drm/drm_mode_config.h   | 12 ++
 14 files changed, 76 insertions(+), 35 deletions(-)


Re: [PATCH 02/10] block: virtio-blk: check logical block size

2020-07-28 Thread Martin K. Petersen


Hi Maxim,

> Instead of this adding blk_is_valid_logical_block_size allowed me to
> trivially convert most of the uses.
>
> For RFC I converted only some drivers that I am more familiar with
> and/or can test but I can remove the driver's own checks in most other
> drivers with low chance of introducing a bug, even if I can't test the
> driver.
>
> What do you think?
>
> I can also both make blk_queue_logical_block_size return an error
> value, and have blk_is_valid_logical_block_size and use either of
> these checks, depending on the driver with eventual goal of
> un-exporting blk_is_valid_logical_block_size.

My concern is that blk_is_valid_logical_block_size() deviates from the
regular block layer convention where the function to set a given queue
limit will either adjust the passed value or print a warning.

I guess I won't entirely object to having the actual check in a helper
function that drivers with a peculiar initialization pattern can
use. And then make blk_queue_logical_block_size() call that helper as
well to validate the lbs.

But I do think that blk_queue_logical_block_size() should be the
preferred interface and that, where possible, drivers should be updated
to check the return value of that.

-- 
Martin K. Petersen  Oracle Linux Engineering


[PATCH] idr: Fix a typo in idr_alloc_cyclic()'s comment

2020-07-28 Thread Wang Long
This patch fix a typo in comment for function idr_alloc_cyclic().

Signed-off-by: Wang Long 
---
 lib/idr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/idr.c b/lib/idr.c
index c2cf2c5..47d203f 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -100,7 +100,7 @@ int idr_alloc(struct idr *idr, void *ptr, int start, int 
end, gfp_t gfp)
  * @end: The maximum ID (exclusive).
  * @gfp: Memory allocation flags.
  *
- * Allocates an unused ID in the range specified by @nextid and @end.  If
+ * Allocates an unused ID in the range specified by @start and @end.  If
  * @end is <= 0, it is treated as one larger than %INT_MAX.  This allows
  * callers to use @start + N as @end as long as N is within integer range.
  * The search for an unused ID will start at the last ID allocated and will
-- 
1.8.3.1






Re: [PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence for wdog operations

2020-07-28 Thread Guenter Roeck
On 7/28/20 7:20 PM, Anson Huang wrote:
> According to reference manual, the i.MX7ULP WDOG's operations should
> follow below sequence:
> 
> 1. disable global interrupts;
> 2. unlock the wdog and wait unlock bit set;
> 3. reconfigure the wdog and wait for reconfiguration bit set;
> 4. enabel global interrupts.
> 
> Strictly follow the recommended sequence can make it more robust.
> 
> Signed-off-by: Anson Huang 
> ---
> Changes since V1:
>   - use readl_poll_timeout_atomic() instead of usleep_ranges() since IRQ 
> is disabled.
> ---
>  drivers/watchdog/imx7ulp_wdt.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
> index 7993c8c..7d2b12e 100644
> --- a/drivers/watchdog/imx7ulp_wdt.c
> +++ b/drivers/watchdog/imx7ulp_wdt.c
> @@ -5,6 +5,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -36,6 +37,7 @@
>  #define DEFAULT_TIMEOUT  60
>  #define MAX_TIMEOUT  128
>  #define WDOG_CLOCK_RATE  1000
> +#define WDOG_WAIT_TIMEOUT1
>  
>  static bool nowayout = WATCHDOG_NOWAYOUT;
>  module_param(nowayout, bool, );
> @@ -48,17 +50,31 @@ struct imx7ulp_wdt_device {
>   struct clk *clk;
>  };
>  
> +static inline void imx7ulp_wdt_wait(void __iomem *base, u32 mask)
> +{
> + u32 val = readl(base + WDOG_CS);
> +
> + if (!(val & mask))
> + WARN_ON(readl_poll_timeout_atomic(base + WDOG_CS, val,
> +   val & mask, 0,
> +   WDOG_WAIT_TIMEOUT));

I am not a friend of WARN_ON, especially in situations like this.
Please explain why this is needed, and why a return of -ETIMEDOUT
is not feasible.

Also, I do not believe that a 10 milli-second timeout is warranted.
This will need to be backed up by the datasheet.

Guenter

> +}
> +
>  static void imx7ulp_wdt_enable(struct watchdog_device *wdog, bool enable)
>  {
>   struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
>  
>   u32 val = readl(wdt->base + WDOG_CS);
>  
> + local_irq_disable();
>   writel(UNLOCK, wdt->base + WDOG_CNT);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
>   if (enable)
>   writel(val | WDOG_CS_EN, wdt->base + WDOG_CS);
>   else
>   writel(val & ~WDOG_CS_EN, wdt->base + WDOG_CS);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
> + local_irq_enable();
>  }
>  
>  static bool imx7ulp_wdt_is_enabled(void __iomem *base)
> @@ -72,7 +88,12 @@ static int imx7ulp_wdt_ping(struct watchdog_device *wdog)
>  {
>   struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
>  
> + local_irq_disable();
> + writel(UNLOCK, wdt->base + WDOG_CNT);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
>   writel(REFRESH, wdt->base + WDOG_CNT);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
> + local_irq_enable();
>  
>   return 0;
>  }
> @@ -98,8 +119,12 @@ static int imx7ulp_wdt_set_timeout(struct watchdog_device 
> *wdog,
>   struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
>   u32 val = WDOG_CLOCK_RATE * timeout;
>  
> + local_irq_disable();
>   writel(UNLOCK, wdt->base + WDOG_CNT);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
>   writel(val, wdt->base + WDOG_TOVAL);
> + imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
> + local_irq_enable();
>  
>   wdog->timeout = timeout;
>  
> @@ -140,15 +165,19 @@ static void imx7ulp_wdt_init(void __iomem *base, 
> unsigned int timeout)
>  {
>   u32 val;
>  
> + local_irq_disable();
>   /* unlock the wdog for reconfiguration */
>   writel_relaxed(UNLOCK_SEQ0, base + WDOG_CNT);
>   writel_relaxed(UNLOCK_SEQ1, base + WDOG_CNT);
> + imx7ulp_wdt_wait(base, WDOG_CS_ULK);
>  
>   /* set an initial timeout value in TOVAL */
>   writel(timeout, base + WDOG_TOVAL);
>   /* enable 32bit command sequence and reconfigure */
>   val = WDOG_CS_CMD32EN | WDOG_CS_CLK | WDOG_CS_UPDATE;
>   writel(val, base + WDOG_CS);
> + imx7ulp_wdt_wait(base, WDOG_CS_RCS);
> + local_irq_enable();
>  }
>  
>  static void imx7ulp_wdt_action(void *data)
> 



Re: [PATCH] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-07-28 Thread Martin K. Petersen
On Mon, 15 Jun 2020 16:12:26 +0800, Jing Xiangfeng wrote:

> If scsi_host_lookup() failes we will jump to put_host, which may
> cause panic. Jump to exit_set_fnode to fix it.

Applied to 5.9/scsi-queue, thanks!

[1/1] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()
  https://git.kernel.org/mkp/scsi/c/68e12e5f6135

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH v1] scsi: ufs-mediatek: Prevent LPM operation on undeclared VCC

2020-07-28 Thread Martin K. Petersen
On Fri, 24 Jul 2020 22:16:27 +0800, Stanley Chu wrote:

> In some platforms, VCC regulator may not be declared in device tree
> to keep itself "always-on". In this case, hba->vreg_info.vcc is NULL
> and shall not be operated during any flow.
> 
> Prevent possible NULL hba->vreg_info.vcc access in LPM mode by checking
> if it is valid first.

Applied to 5.9/scsi-queue, thanks!

[1/1] scsi: ufs-mediatek: Prevent LPM operation on undeclared VCC
  https://git.kernel.org/mkp/scsi/c/0255b1e3d849

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH v17 17/21] mm/lru: replace pgdat lru_lock with lruvec lock

2020-07-28 Thread Alex Shi
rewrite the commit log.

>From 5e9340444632d69cf10c8db521577d0637819c5f Mon Sep 17 00:00:00 2001
From: Alex Shi 
Date: Tue, 26 May 2020 17:27:52 +0800
Subject: [PATCH v17 17/23] mm/lru: replace pgdat lru_lock with lruvec lock

This patch moves per node lru_lock into lruvec, thus bring a lru_lock for
each of memcg per node. So on a large machine, each of memcg don't
have to suffer from per node pgdat->lru_lock competition. They could go
fast with their self lru_lock.

After move memcg charge before lru inserting, page isolation could
serialize page's memcg, then per memcg lruvec lock is stable and could
replace per node lru lock.

In func isolate_migratepages_block, compact_unlock_should_abort is
opend, and lock_page_lruvec logical is embedded for tight process.
Also add a debug func in locking which may give some clues if there are
sth out of hands.

According to Daniel Jordan's suggestion, I run 208 'dd' with on 104
containers on a 2s * 26cores * HT box with a modefied case:
https://git.kernel.org/pub/scm/linux/kernel/git/wfg/vm-scalability.git/tree/case-lru-file-readtwice

With this and later patches, the readtwice performance increases about
80% within concurrent containers.

On a large but non memcg machine, the extra recheck if page's lruvec
should be changed in few place, that increase a little lock holding
time, and a little regression.

Hugh Dickins helped on patch polish, thanks!

Reported-by: kernel test robot 
Signed-off-by: Alex Shi 
Cc: Hugh Dickins 
Cc: Andrew Morton 
Cc: Johannes Weiner 
Cc: Michal Hocko 
Cc: Vladimir Davydov 
Cc: Yang Shi 
Cc: Matthew Wilcox 
Cc: Konstantin Khlebnikov 
Cc: Tejun Heo 
Cc: linux-kernel@vger.kernel.org
Cc: linux...@kvack.org
Cc: cgro...@vger.kernel.org
---
 include/linux/memcontrol.h |  58 +
 include/linux/mmzone.h |   2 +
 mm/compaction.c|  67 ++---
 mm/huge_memory.c   |  11 ++---
 mm/memcontrol.c|  63 ++-
 mm/mlock.c |  47 +---
 mm/mmzone.c|   1 +
 mm/swap.c  | 104 +
 mm/vmscan.c|  70 --
 9 files changed, 288 insertions(+), 135 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index e77197a62809..258901021c6c 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -411,6 +411,19 @@ static inline struct lruvec *mem_cgroup_lruvec(struct 
mem_cgroup *memcg,
 
 struct mem_cgroup *get_mem_cgroup_from_page(struct page *page);
 
+struct lruvec *lock_page_lruvec(struct page *page);
+struct lruvec *lock_page_lruvec_irq(struct page *page);
+struct lruvec *lock_page_lruvec_irqsave(struct page *page,
+   unsigned long *flags);
+
+#ifdef CONFIG_DEBUG_VM
+void lruvec_memcg_debug(struct lruvec *lruvec, struct page *page);
+#else
+static inline void lruvec_memcg_debug(struct lruvec *lruvec, struct page *page)
+{
+}
+#endif
+
 static inline
 struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css){
return css ? container_of(css, struct mem_cgroup, css) : NULL;
@@ -892,6 +905,31 @@ static inline void mem_cgroup_put(struct mem_cgroup *memcg)
 {
 }
 
+static inline struct lruvec *lock_page_lruvec(struct page *page)
+{
+   struct pglist_data *pgdat = page_pgdat(page);
+
+   spin_lock(>__lruvec.lru_lock);
+   return >__lruvec;
+}
+
+static inline struct lruvec *lock_page_lruvec_irq(struct page *page)
+{
+   struct pglist_data *pgdat = page_pgdat(page);
+
+   spin_lock_irq(>__lruvec.lru_lock);
+   return >__lruvec;
+}
+
+static inline struct lruvec *lock_page_lruvec_irqsave(struct page *page,
+   unsigned long *flagsp)
+{
+   struct pglist_data *pgdat = page_pgdat(page);
+
+   spin_lock_irqsave(>__lruvec.lru_lock, *flagsp);
+   return >__lruvec;
+}
+
 static inline struct mem_cgroup *
 mem_cgroup_iter(struct mem_cgroup *root,
struct mem_cgroup *prev,
@@ -1126,6 +1164,10 @@ static inline void count_memcg_page_event(struct page 
*page,
 void count_memcg_event_mm(struct mm_struct *mm, enum vm_event_item idx)
 {
 }
+
+static inline void lruvec_memcg_debug(struct lruvec *lruvec, struct page *page)
+{
+}
 #endif /* CONFIG_MEMCG */
 
 /* idx can be of type enum memcg_stat_item or node_stat_item */
@@ -1255,6 +1297,22 @@ static inline struct lruvec *parent_lruvec(struct lruvec 
*lruvec)
return mem_cgroup_lruvec(memcg, lruvec_pgdat(lruvec));
 }
 
+static inline void unlock_page_lruvec(struct lruvec *lruvec)
+{
+   spin_unlock(>lru_lock);
+}
+
+static inline void unlock_page_lruvec_irq(struct lruvec *lruvec)
+{
+   spin_unlock_irq(>lru_lock);
+}
+
+static inline void unlock_page_lruvec_irqrestore(struct lruvec *lruvec,
+   unsigned long flags)
+{
+   spin_unlock_irqrestore(>lru_lock, flags);
+}
+
 #ifdef 

Re: [PATCH v17 13/21] mm/lru: introduce TestClearPageLRU

2020-07-28 Thread Alex Shi
rewrite the commit log.

>From 9310c359b0049e3cc9827b771dc583d504bbf022 Mon Sep 17 00:00:00 2001
From: Alex Shi 
Date: Sat, 25 Apr 2020 12:03:30 +0800
Subject: [PATCH v17 13/23] mm/lru: introduce TestClearPageLRU

Currently lru_lock still guards both lru list and page's lru bit, that's
ok. but if we want to use specific lruvec lock on the page, we need to
pin down the page's lruvec/memcg during locking. Just taking lruvec
lock first may be undermined by the page's memcg charge/migration. To
fix this problem, we could clear the lru bit out of locking and use
it as pin down action to block the page isolation in memcg changing.

So now a standard steps of page isolation is following:
1, get_page(); #pin the page avoid to be free
2, TestClearPageLRU(); #block other isolation like memcg change
3, spin_lock on lru_lock; #serialize lru list access
4, delete page from lru list;
The step 2 could be optimzed/replaced in scenarios which page is
unlikely be accessed or be moved between memcgs.

This patch start with the first part: TestClearPageLRU, which combines
PageLRU check and ClearPageLRU into a macro func TestClearPageLRU. This
function will be used as page isolation precondition to prevent other
isolations some where else. Then there are may !PageLRU page on lru
list, need to remove BUG() checking accordingly.

There 2 rules for lru bit now:
1, the lru bit still indicate if a page on lru list, just in some
   temporary moment(isolating), the page may have no lru bit when
   it's on lru list.  but the page still must be on lru list when the
   lru bit set.
2, have to remove lru bit before delete it from lru list.

Hugh Dickins pointed that when a page is in free path and no one is
possible to take it, non atomic lru bit clearing is better, like in
__page_cache_release and release_pages.
And no need get_page() before lru bit clear in isolate_lru_page,
since it '(1) Must be called with an elevated refcount on the page'.

As Andrew Morton mentioned this change would dirty cacheline for page
isn't on LRU. But the lost would be acceptable with Rong Chen
 report:
https://lkml.org/lkml/2020/3/4/173

Suggested-by: Johannes Weiner 
Signed-off-by: Alex Shi 
Cc: Hugh Dickins 
Cc: Johannes Weiner 
Cc: Michal Hocko 
Cc: Vladimir Davydov 
Cc: Andrew Morton 
Cc: linux-kernel@vger.kernel.org
Cc: cgro...@vger.kernel.org
Cc: linux...@kvack.org
---
 include/linux/page-flags.h |  1 +
 mm/mlock.c |  3 +--
 mm/swap.c  |  6 ++
 mm/vmscan.c| 18 +++---
 4 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 6be1aa559b1e..9554ed1387dc 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -326,6 +326,7 @@ static inline void page_init_poison(struct page *page, 
size_t size)
 PAGEFLAG(Dirty, dirty, PF_HEAD) TESTSCFLAG(Dirty, dirty, PF_HEAD)
__CLEARPAGEFLAG(Dirty, dirty, PF_HEAD)
 PAGEFLAG(LRU, lru, PF_HEAD) __CLEARPAGEFLAG(LRU, lru, PF_HEAD)
+   TESTCLEARFLAG(LRU, lru, PF_HEAD)
 PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
TESTCLEARFLAG(Active, active, PF_HEAD)
 PAGEFLAG(Workingset, workingset, PF_HEAD)
diff --git a/mm/mlock.c b/mm/mlock.c
index f8736136fad7..228ba5a8e0a5 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -108,13 +108,12 @@ void mlock_vma_page(struct page *page)
  */
 static bool __munlock_isolate_lru_page(struct page *page, bool getpage)
 {
-   if (PageLRU(page)) {
+   if (TestClearPageLRU(page)) {
struct lruvec *lruvec;
 
lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page));
if (getpage)
get_page(page);
-   ClearPageLRU(page);
del_page_from_lru_list(page, lruvec, page_lru(page));
return true;
}
diff --git a/mm/swap.c b/mm/swap.c
index f645965fde0e..5092fe9c8c47 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -83,10 +83,9 @@ static void __page_cache_release(struct page *page)
struct lruvec *lruvec;
unsigned long flags;
 
+   __ClearPageLRU(page);
spin_lock_irqsave(>lru_lock, flags);
lruvec = mem_cgroup_page_lruvec(page, pgdat);
-   VM_BUG_ON_PAGE(!PageLRU(page), page);
-   __ClearPageLRU(page);
del_page_from_lru_list(page, lruvec, page_off_lru(page));
spin_unlock_irqrestore(>lru_lock, flags);
}
@@ -878,9 +877,8 @@ void release_pages(struct page **pages, int nr)
spin_lock_irqsave(_pgdat->lru_lock, 
flags);
}
 
-   lruvec = mem_cgroup_page_lruvec(page, locked_pgdat);
-   VM_BUG_ON_PAGE(!PageLRU(page), page);
__ClearPageLRU(page);
+   lruvec = mem_cgroup_page_lruvec(page, locked_pgdat);

Re: [PATCH v10 4/5] arm64: kdump: fix kdump broken with ZONE_DMA reintroduced

2020-07-28 Thread chenzhou
Hi  Catalin,


On 2020/7/28 1:30, Catalin Marinas wrote:
> On Fri, Jul 03, 2020 at 11:58:15AM +0800, Chen Zhou wrote:
>> commit 1a8e1cef7603 ("arm64: use both ZONE_DMA and ZONE_DMA32")
>> broken the arm64 kdump. If the memory reserved for crash dump kernel
>> falled in ZONE_DMA32, the devices in crash dump kernel need to use
>> ZONE_DMA will alloc fail.
>>
>> This patch addressed the above issue based on "reserving crashkernel
>> above 4G". Originally, we reserve low memory below 4G, and now just need
>> to adjust memory limit to arm64_dma_phys_limit in reserve_crashkernel_low
>> if ZONE_DMA is enabled. That is, if there are devices need to use ZONE_DMA
>> in crash dump kernel, it is a good choice to use parameters
>> "crashkernel=X crashkernel=Y,low".
>>
>> Signed-off-by: Chen Zhou 
>> ---
>>  kernel/crash_core.c | 7 ++-
>>  1 file changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>> index a7580d291c37..e8ecbbc761a3 100644
>> --- a/kernel/crash_core.c
>> +++ b/kernel/crash_core.c
>> @@ -320,6 +320,7 @@ int __init reserve_crashkernel_low(void)
>>  unsigned long long base, low_base = 0, low_size = 0;
>>  unsigned long total_low_mem;
>>  int ret;
>> +phys_addr_t crash_max = 1ULL << 32;
>>  
>>  total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
>>  
>> @@ -352,7 +353,11 @@ int __init reserve_crashkernel_low(void)
>>  return 0;
>>  }
>>  
>> -low_base = memblock_find_in_range(0, 1ULL << 32, low_size, CRASH_ALIGN);
>> +#ifdef CONFIG_ARM64
>> +if (IS_ENABLED(CONFIG_ZONE_DMA))
>> +crash_max = arm64_dma_phys_limit;
>> +#endif
>> +low_base = memblock_find_in_range(0, crash_max, low_size, CRASH_ALIGN);
>>  if (!low_base) {
>>  pr_err("Cannot reserve %ldMB crashkernel low memory, please try 
>> smaller size.\n",
>> (unsigned long)(low_size >> 20));
> Given the number of #ifdefs we end up with in this function, I think
> it's better to simply copy to the code to arch/arm64 and tailor it
> accordingly.
>
> Anyway, there are two series solving slightly different issues with
> kdump reservations:
>
> 1. This series which relaxes the crashkernel= allocation to go anywhere
>in the accessible space while having a dedicated crashkernel=X,low
>option for ZONE_DMA.
>
> 2. Bhupesh's series [1] forcing crashkernel=X allocations only from
>ZONE_DMA.
>
> For RPi4 support, we limited ZONE_DMA allocations to the 1st GB.
> Existing crashkernel= uses may no longer work, depending on where the
> allocation falls. Option (2) above is a quick fix assuming that the
> crashkernel reservation is small enough. What's a typical crashkernel
> option here? That series is probably more prone to reservation failures.
>
> Option (1), i.e. this series, doesn't solve the problem raised by
> Bhupesh unless one uses the crashkernel=X,low argument. It can actually
> make it worse even for ZONE_DMA32 since the allocation can go above 4G
> (assuming that we change the ZONE_DMA configuration to only limit it to
> 1GB on RPi4).
>
> I'm more inclined to keep the crashkernel= behaviour to ZONE_DMA
> allocations. If this is too small for typical kdump, we can look into
> expanding ZONE_DMA to 4G on non-RPi4 hardware (we had patches on the
> list). In addition, if Chen thinks allocations above 4G are still needed
> or if RPi4 needs a sufficiently large crashkernel=, I'd rather have a
> ",high" option to explicitly require such access.
Thanks for your reply and exhaustive explanation.

In our ARM servers, we need to to reserve a large chunk for kdump(512M or 1G),
there is no enough low memory. So we proposed this patch series
"support reserving crashkernel above 4G on arm64 kdump" In April 2019.

I introduce parameters "crashkernel=X,[high,low]" as x86_64 does in earlier 
versions.
Suggested by James, to simplify, we call reserve_crashkernel_low() at the 
beginning of
reserve_crashkernel() and then relax the arm64_dma32_phys_limit if 
reserve_crashkernel_low()
allocated something.
That is, just the parameter "crashkernel=X,low" is ok and i deleted 
"crashkernel=X,high".

After the ZONE_DMA introduced in December 2019, the issue occurred as you said 
above.
In fact, we didn't have RPi4 machine. Originally, i suggested to fix this based 
on this patch series
and used the dedicated option.

According to your clarify, for typical kdump, there are other solutions. In 
this case,
"keep the crashkernel= behaviour to ZONE_DMA allocations" looks much better.

How about like this:
1. For ZONE_DMA issue, use Bhupesh's solution, keep the crashkernel= behaviour 
to ZONE_DMA allocations.
2. For this patch series, make the reserve_crashkernel_low() to ZONE_DMA 
allocations.

Thanks,
Chen Zhou
> [1] http://lists.infradead.org/pipermail/kexec/2020-July/020777.html
>




Re: [char-misc-next] Revert "mei: hdcp: Replace one-element array with flexible-array member"

2020-07-28 Thread Gustavo A. R. Silva



On 7/28/20 18:16, Gustavo A. R. Silva wrote:
> 
> 
> On 7/28/20 18:04, Gustavo A. R. Silva wrote:
>> Tomas,
>>
>> Please, see some comments below...
>>
>> On 7/28/20 17:29, Winkler, Tomas wrote:
>>>
>>> Hi Tomas,
>>>
>>> On 7/28/20 16:41, Tomas Winkler wrote:
 Greg please revert, this commit it changes size of struct
 wired_cmd_repeater_auth_stream_req_in, this is not what firmware
 is expecting.
>>>

Instead of reverting that commit, I think this patch should be applied
to fix it, if Tomas consider this is the appropiate solution:

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index d1d3e025ca0e..852374565cba 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -572,12 +572,12 @@ static int mei_hdcp_verify_mprime(struct device *dev,
   HDCP_2_2_MPRIME_LEN);
drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
memcpy(verify_mprime_in.streams, data->streams,
-  array_size(data->k, sizeof(*data->streams)));
+  flex_array_size(_mprime_in, streams, data->k));

verify_mprime_in.k = cpu_to_be16(data->k);

byte = mei_cldev_send(cldev, (u8 *)_mprime_in,
- sizeof(verify_mprime_in));
+ struct_size(_mprime_in, streams, data->k));
if (byte < 0) {
dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
return byte;

I'll write up a proper patch after getting some feedback.

Thanks
--
Gustavo

>>> Could you elaborate on what's the firmware expecting, exactly?
>> struct wired_cmd_repeater_auth_stream_req_in {
>>   -  struct hdcp2_streamid_type  streams[1];
>>   +  struct hdcp2_streamid_type  streams[];
>> }
>>
>> But then you have, which you haven't changed to + 1 byte =
>> mei_cldev_send(cldev, (u8 *)_mprime_in,
>>   sizeof(verify_mprime_in));
>>
>>
>> I don't think the fix for this is to add 1 byte, if any, it seems
>> to be sizeof(*data->streams), or sizeof(struct hdcp2_streamid_type)
>> what needs to be added.
>>
>> But it might be better to code something like this, instead:
>>
>> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c 
>> b/drivers/misc/mei/hdcp/mei_hdcp.c
>> index e6c3dc595617..7fe63c915548 100644
>> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
>> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
>> @@ -572,12 +572,12 @@ static int mei_hdcp_verify_mprime(struct device *dev,
>>HDCP_2_2_MPRIME_LEN);
>> drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
>> memcpy(verify_mprime_in.streams, data->streams,
>> -  (data->k * sizeof(struct hdcp2_streamid_type)));
>> +  (data->k * sizeof(*data->streams)));
>>
>> verify_mprime_in.k = cpu_to_be16(data->k);
>>
>> byte = mei_cldev_send(cldev, (u8 *)_mprime_in,
>> - sizeof(verify_mprime_in));
>> + struct_size(_mprime_in, streams, 
>> data->k));
>> if (byte < 0) {
>> dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
>> return byte;
>>
>> struct_size(_mprime_in, streams, data->k) will give us the size, in 
>> bytes,
>> of struct wired_cmd_repeater_auth_stream_req_in plus the size in bytes for
>> the streams[] flexible-array, which is determined by struct 
>> hdcp2_streamid_type and
>> data->k.
>>
>> What do you think?
>>
> 
> This is even better:
> 
> diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c 
> b/drivers/misc/mei/hdcp/mei_hdcp.c
> index e6c3dc595617..852374565cba 100644
> --- a/drivers/misc/mei/hdcp/mei_hdcp.c
> +++ b/drivers/misc/mei/hdcp/mei_hdcp.c
> @@ -572,12 +572,12 @@ static int mei_hdcp_verify_mprime(struct device *dev,
>HDCP_2_2_MPRIME_LEN);
> drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
> memcpy(verify_mprime_in.streams, data->streams,
> -  (data->k * sizeof(struct hdcp2_streamid_type)));
> +  flex_array_size(_mprime_in, streams, data->k));
> 
> verify_mprime_in.k = cpu_to_be16(data->k);
> 
> byte = mei_cldev_send(cldev, (u8 *)_mprime_in,
> - sizeof(verify_mprime_in));
> + struct_size(_mprime_in, streams, 
> data->k));
> if (byte < 0) {
> dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> return byte;
> 
> the flex_array_size() is a new helper that was designed for this situations. 
> :)
> It calculates the size of a flexible array member within an enclosing 
> structure,
> which is exactly the case.
> 
> Thanks
> --
> Gustavo
> 
>> See more comments below...
>>
>
> I see, this is the kind of feedback I need from people that knows the
> code better. Thanks!
>
>> But that's not the major point. Point is that we should 

[PATCH v4 3/4] docs: Add documentation for userspace client interface

2020-07-28 Thread Hemant Kumar
MHI userspace client driver is creating device file node
for user application to perform file operations. File
operations are handled by MHI core driver. Currently
Loopback MHI channel is supported by this driver.

Signed-off-by: Hemant Kumar 
---
 Documentation/mhi/index.rst |  1 +
 Documentation/mhi/uci.rst   | 39 +++
 2 files changed, 40 insertions(+)
 create mode 100644 Documentation/mhi/uci.rst

diff --git a/Documentation/mhi/index.rst b/Documentation/mhi/index.rst
index 1d8dec3..c75a371 100644
--- a/Documentation/mhi/index.rst
+++ b/Documentation/mhi/index.rst
@@ -9,6 +9,7 @@ MHI
 
mhi
topology
+   uci
 
 .. only::  subproject and html
 
diff --git a/Documentation/mhi/uci.rst b/Documentation/mhi/uci.rst
new file mode 100644
index 000..5d92939
--- /dev/null
+++ b/Documentation/mhi/uci.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Userspace Client Interface (UCI)
+=
+
+UCI driver enables userspace clients to communicate to external MHI devices
+like modem and WLAN. It creates standard character device file nodes for user
+space clients to perform open, read, write, poll and close file operations.
+
+Device file node is created with format:-
+
+/dev/mhi__
+
+controller_name is the name of underlying bus used to transfer data.
+mhi_device_name is the name of the MHI channel being used by MHI client in
+userspace to send or receive data using MHI protocol.
+
+There is a separate character device file node created for each channel 
specified
+in mhi device id table. MHI channels are statically defined by MHI 
specification.
+Driver currently supports LOOPBACK channel 0 (Host to device) and 1 (Device to 
Host).
+
+LOOPBACK Channel
+
+
+Userspace MHI client using LOOPBACK channel opens device file node. As part of
+open operation TREs to transfer ring of LOOPBACK channel 1 gets queued and 
channel
+doorbell is rung. When userspace MHI client performs write operation on device 
node,
+data buffer gets queued as a TRE to transfer ring of LOOPBACK channel 0. MHI 
Core
+driver rings the channel doorbell for MHI device to move data over underlying 
bus.
+When userspace MHI client driver performs read operation, same data gets 
looped back
+to MHI host using LOOPBACK channel 1. LOOPBACK channel is used to verify data 
path
+and data integrity between MHI Host and MHI device.
+
+Other Use Cases
+---
+
+Getting MHI device specific diagnostics information to userspace MHI diag 
client
+using DIAG channel 4 (Host to device) and 5 (Device to Host).
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 1/4] bus: mhi: core: Add helper API to return number of free TREs

2020-07-28 Thread Hemant Kumar
Introduce mhi_get_no_free_descriptors() API to return number
of TREs available to queue buffer. MHI clients can use this
API to know before hand if ring is full without calling queue
API.

Signed-off-by: Hemant Kumar 
---
 drivers/bus/mhi/core/main.c | 12 
 include/linux/mhi.h |  9 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
index 2cff5dd..0599e7d 100644
--- a/drivers/bus/mhi/core/main.c
+++ b/drivers/bus/mhi/core/main.c
@@ -258,6 +258,18 @@ int mhi_destroy_device(struct device *dev, void *data)
return 0;
 }
 
+int mhi_get_no_free_descriptors(struct mhi_device *mhi_dev,
+   enum dma_data_direction dir)
+{
+   struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;
+   struct mhi_chan *mhi_chan = (dir == DMA_TO_DEVICE) ?
+   mhi_dev->ul_chan : mhi_dev->dl_chan;
+   struct mhi_ring *tre_ring = _chan->tre_ring;
+
+   return get_nr_avail_ring_elements(mhi_cntrl, tre_ring);
+}
+EXPORT_SYMBOL_GPL(mhi_get_no_free_descriptors);
+
 void mhi_notify(struct mhi_device *mhi_dev, enum mhi_callback cb_reason)
 {
struct mhi_driver *mhi_drv;
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index a35d876..6565528 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -600,6 +600,15 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl,
 void mhi_notify(struct mhi_device *mhi_dev, enum mhi_callback cb_reason);
 
 /**
+ * mhi_get_no_free_descriptors - Get transfer ring length
+ * Get # of TD available to queue buffers
+ * @mhi_dev: Device associated with the channels
+ * @dir: Direction of the channel
+ */
+int mhi_get_no_free_descriptors(struct mhi_device *mhi_dev,
+   enum dma_data_direction dir);
+
+/**
  * mhi_prepare_for_power_up - Do pre-initialization before power up.
  *This is optional, call this before power up if
  *the controller does not want bus framework to
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[RFC PATCH] arm64: defconfig: Disable fine-grained task level IRQ time accounting

2020-07-28 Thread Alison Wang
In the current arm64 defconfig, CONFIG_IRQ_TIME_ACCOUNTING is enabled as
default. According to my tests on NXP's LayerScape and i.MX platforms,
the system hangs when running the command "stress-ng --hrtimers 1" with
CONFIG_IRQ_TIME_ACCOUNTING enabled. Disabling this option, the issue
disappears. CONFIG_IRQ_TIME_ACCOUNTING causes serious performance impact
when running hrtimer stress test at the same time.

Signed-off-by: Alison Wang 
---
 arch/arm64/configs/defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e0f33826819f..ff1c11d8b10b 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -4,7 +4,6 @@ CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
-CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_TASK_XACCT=y
-- 
2.17.1



[PATCH v4 0/4] user space client interface driver

2020-07-28 Thread Hemant Kumar
V4:
- Fix locking to protect proper struct members.
- Updated documentation describing uci client driver use cases.
- Fixed uci ref counting in mhi_uci_open for error case.
- Addressed style related review comments.

V3: Added documentation for MHI UCI driver.

V2: Added mutex lock to prevent multiple readers to access same
mhi buffer which can result into use after free.

Hemant Kumar (4):
  bus: mhi: core: Add helper API to return number of free TREs
  bus: mhi: core: Move MHI_MAX_MTU to external header file
  docs: Add documentation for userspace client interface
  bus: mhi: clients: Add userspace client interface driver

 Documentation/mhi/index.rst  |   1 +
 Documentation/mhi/uci.rst|  39 +++
 drivers/bus/mhi/Kconfig  |   6 +
 drivers/bus/mhi/Makefile |   1 +
 drivers/bus/mhi/clients/Kconfig  |  15 +
 drivers/bus/mhi/clients/Makefile |   3 +
 drivers/bus/mhi/clients/uci.c| 690 +++
 drivers/bus/mhi/core/internal.h  |   1 -
 drivers/bus/mhi/core/main.c  |  12 +
 include/linux/mhi.h  |  12 +
 10 files changed, 779 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/mhi/uci.rst
 create mode 100644 drivers/bus/mhi/clients/Kconfig
 create mode 100644 drivers/bus/mhi/clients/Makefile
 create mode 100644 drivers/bus/mhi/clients/uci.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 2/4] bus: mhi: core: Move MHI_MAX_MTU to external header file

2020-07-28 Thread Hemant Kumar
Currently this macro is defined in internal MHI header as
a TRE length mask. Moving it to external header allows MHI
client drivers to set this upper bound for the transmit
buffer size.

Signed-off-by: Hemant Kumar 
---
 drivers/bus/mhi/core/internal.h | 1 -
 include/linux/mhi.h | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
index 7989269..4abf0cf 100644
--- a/drivers/bus/mhi/core/internal.h
+++ b/drivers/bus/mhi/core/internal.h
@@ -453,7 +453,6 @@ enum mhi_pm_state {
 #define CMD_EL_PER_RING128
 #define PRIMARY_CMD_RING   0
 #define MHI_DEV_WAKE_DB127
-#define MHI_MAX_MTU0x
 #define MHI_RANDOM_U32_NONZERO(bmsk)   (prandom_u32_max(bmsk) + 1)
 
 enum mhi_er_type {
diff --git a/include/linux/mhi.h b/include/linux/mhi.h
index 6565528..610f3b0 100644
--- a/include/linux/mhi.h
+++ b/include/linux/mhi.h
@@ -16,6 +16,9 @@
 #include 
 #include 
 
+/* MHI client drivers to set this upper bound for tx buffer */
+#define MHI_MAX_MTU 0x
+
 #define MHI_MAX_OEM_PK_HASH_SEGMENTS 16
 
 struct mhi_chan;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



[PATCH v4 4/4] bus: mhi: clients: Add userspace client interface driver

2020-07-28 Thread Hemant Kumar
This MHI client driver allows userspace clients to transfer
raw data between MHI device and host using standard file operations.
Device file node is created with format

/dev/mhi__

Currently it supports LOOPBACK channel.

Signed-off-by: Hemant Kumar 
---
 drivers/bus/mhi/Kconfig  |   6 +
 drivers/bus/mhi/Makefile |   1 +
 drivers/bus/mhi/clients/Kconfig  |  15 +
 drivers/bus/mhi/clients/Makefile |   3 +
 drivers/bus/mhi/clients/uci.c| 690 +++
 5 files changed, 715 insertions(+)
 create mode 100644 drivers/bus/mhi/clients/Kconfig
 create mode 100644 drivers/bus/mhi/clients/Makefile
 create mode 100644 drivers/bus/mhi/clients/uci.c

diff --git a/drivers/bus/mhi/Kconfig b/drivers/bus/mhi/Kconfig
index 6a217ff..927c392 100644
--- a/drivers/bus/mhi/Kconfig
+++ b/drivers/bus/mhi/Kconfig
@@ -20,3 +20,9 @@ config MHI_BUS_DEBUG
 Enable debugfs support for use with the MHI transport. Allows
 reading and/or modifying some values within the MHI controller
 for debug and test purposes.
+
+if MHI_BUS
+
+source "drivers/bus/mhi/clients/Kconfig"
+
+endif
diff --git a/drivers/bus/mhi/Makefile b/drivers/bus/mhi/Makefile
index 19e6443..48f6028 100644
--- a/drivers/bus/mhi/Makefile
+++ b/drivers/bus/mhi/Makefile
@@ -1,2 +1,3 @@
 # core layer
 obj-y += core/
+obj-y += clients/
diff --git a/drivers/bus/mhi/clients/Kconfig b/drivers/bus/mhi/clients/Kconfig
new file mode 100644
index 000..37aaf51
--- /dev/null
+++ b/drivers/bus/mhi/clients/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menu "MHI clients support"
+
+config MHI_UCI
+   tristate "MHI UCI"
+   depends on MHI_BUS
+   help
+MHI based userspace client interface driver is used for transferring
+raw data between host and device using standard file operations from
+userspace. Open, read, write, and close operations are supported
+by this driver. Please check mhi_uci_match_table for all supported
+channels that are exposed to userspace.
+
+endmenu
diff --git a/drivers/bus/mhi/clients/Makefile b/drivers/bus/mhi/clients/Makefile
new file mode 100644
index 000..cd34282
--- /dev/null
+++ b/drivers/bus/mhi/clients/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_MHI_UCI) += uci.o
diff --git a/drivers/bus/mhi/clients/uci.c b/drivers/bus/mhi/clients/uci.c
new file mode 100644
index 000..3ddf017
--- /dev/null
+++ b/drivers/bus/mhi/clients/uci.c
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.*/
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEVICE_NAME "mhi"
+#define MHI_UCI_DRIVER_NAME "mhi_uci"
+#define MAX_UCI_DEVICES (64)
+
+/**
+ * struct uci_chan - MHI channel for a uci device
+ * @wq: wait queue for reader/writer
+ * @lock: spin lock
+ * @pending: list of rx buffers userspace is waiting to read
+ * @cur_buf: current buffer userspace is reading
+ * @rx_size: size of the current rx buffer userspace is reading
+ */
+struct uci_chan {
+   wait_queue_head_t wq;
+
+   /* protects pending and cur_buf members */
+   spinlock_t lock;
+
+   struct list_head pending;
+   struct uci_buf *cur_buf;
+   size_t rx_size;
+};
+
+/**
+ * struct uci_buf - uci buffer
+ * @data: data buffer
+ * @len: length of data buffer
+ * @node: list node of the uci buffer
+ */
+struct uci_buf {
+   void *data;
+   size_t len;
+   struct list_head node;
+};
+
+/**
+ * struct mhi_uci_drv - MHI uci driver
+ * @head: list head of a uci device nodes
+ * @lock: mutex lock
+ * @class: current buffer userspace is reading
+ * @major: major number for uci driver
+ * @devt: dev_t object to hold major and minor info
+ */
+struct mhi_uci_drv {
+   struct list_head head;
+
+   /* protects mhi_uci_drv struct members */
+   struct mutex lock;
+
+   struct class *class;
+   int major;
+   dev_t devt;
+};
+
+/**
+ * struct uci_dev - MHI uci device
+ * @node: uci device node
+ * @devt: dev_t object to hold major and minor info
+ * @dev: uci device object
+ * @mhi_dev: associated mhi device object
+ * @chan: MHI channel name
+ * @lock: mutex lock
+ * @ul_chan: uplink uci channel object
+ * @dl_chan: downlink uci channel object
+ * @mtu: max tx buffer length
+ * @actual_mtu: maximum size of incoming buffer
+ * @ref_count: uci_dev reference count
+ * @enabled: uci device node accessibility
+ */
+struct uci_dev {
+   struct list_head node;
+   dev_t devt;
+   struct device *dev;
+   struct mhi_device *mhi_dev;
+   const char *chan;
+
+   /* protects uci_dev struct members */
+   struct mutex lock;
+
+   struct uci_chan ul_chan;
+   struct uci_chan dl_chan;
+   size_t mtu;
+   size_t actual_mtu;
+   int ref_count;
+   bool enabled;
+};
+
+static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
+static struct mhi_uci_drv 

Re: [PATCH 4/6] arch: x86: Expose psABI on thread_info

2020-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2020 at 1:22 PM Gabriel Krisman Bertazi
 wrote:
>
> Expose psABI in thread_info, in preparation for the TIF_IA32 and
> TIF_X32 flags removal.

NAK.  Linux threads don't have a user ABI like this.  See my other comments :)

--Andy


[PATCH] dax: Fix wrong error-number passed into xas_set_err()

2020-07-28 Thread Hao Li
The error-number passed into xas_set_err() should be negative. Otherwise,
the xas_error() will return 0, and grab_mapping_entry() will return the
found entry instead of a SIGBUS error when the entry is not a value.
And then, the subsequent code path would be wrong.

Signed-off-by: Hao Li 
---
 fs/dax.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/dax.c b/fs/dax.c
index 11b16729b86f..acac675fe7a6 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -488,7 +488,7 @@ static void *grab_mapping_entry(struct xa_state *xas,
if (dax_is_conflict(entry))
goto fallback;
if (!xa_is_value(entry)) {
-   xas_set_err(xas, EIO);
+   xas_set_err(xas, -EIO);
goto out_unlock;
}
 
-- 
2.28.0





Re: [PATCH 2/6] arch: x86: Wrap TIF_IA32 checks

2020-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2020 at 1:22 PM Gabriel Krisman Bertazi
 wrote:
>
> In preparation to remove TIF_IA32, add wrapper that check the process
> has IA32 ABI without using the flag directly.

Thank you for doing this, but let's please do it right.  There is,
fundamentally, no such thing as a "process with IA32 ABI".

>
> Signed-off-by: Gabriel Krisman Bertazi 
> ---
>  arch/x86/events/core.c | 2 +-
>  arch/x86/events/intel/ds.c | 2 +-
>  arch/x86/events/intel/lbr.c| 2 +-
>  arch/x86/include/asm/compat.h  | 2 +-
>  arch/x86/include/asm/thread_info.h | 2 ++
>  arch/x86/kernel/perf_regs.c| 2 +-
>  arch/x86/oprofile/backtrace.c  | 2 +-
>  7 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
> index 4103665c6e03..42dff74c6197 100644
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -2491,7 +2491,7 @@ perf_callchain_user32(struct pt_regs *regs, struct 
> perf_callchain_entry_ctx *ent
> struct stack_frame_ia32 frame;
> const struct stack_frame_ia32 __user *fp;
>
> -   if (!test_thread_flag(TIF_IA32))
> +   if (!TASK_IA32(current))
> return 0;

if (user_64bit_mode(regs))
  return 0;

>
> cs_base = get_segment_base(regs->cs);
> diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
> index dc43cc124e09..27d1cc1f3d05 100644
> --- a/arch/x86/events/intel/ds.c
> +++ b/arch/x86/events/intel/ds.c
> @@ -1261,7 +1261,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
> old_to = to;
>
>  #ifdef CONFIG_X86_64
> -   is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32);
> +   is_64bit = kernel_ip(to) || !TASK_IA32(current);

PeterZ, does PEBS not give us a CPL?  Is it really just IP?

Anyway, this should probably be:

is_64bit = kernel_ip(to) || user_64bit_mode(regs) || !user_mode(regs);


>  #ifdef CONFIG_X86_64
> -   is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
> +   is64 = kernel_ip((unsigned long)addr) || !TASK_IA32(current);

Same as above.

> diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
> index d4edf281fff4..d39f9b3ae683 100644
> --- a/arch/x86/include/asm/compat.h
> +++ b/arch/x86/include/asm/compat.h
> @@ -181,7 +181,7 @@ static inline void __user 
> *arch_compat_alloc_user_space(long len)
>  {
> compat_uptr_t sp;
>
> -   if (test_thread_flag(TIF_IA32)) {
> +   if (TASK_IA32(current)) {
> sp = task_pt_regs(current)->sp;

Christoph, you spend a *lot* more time looking at this stuff lately
than I do, but this looks totally wrong.  Shouldn't this be either:

sp = task_pt_regs(current)->sp;

/* This might be a compat syscall issued via int $0x80 from 64-bit-ABI code. */
if (user_64bit_mode(task_pt_regs(current))
  sp -= 128;

Or perhaps the same thing without the user_64bit_mode() check at all?
There shouldn't be much if any harm done by respecting the redzone
unnecessarily.

> --- a/arch/x86/kernel/perf_regs.c
> +++ b/arch/x86/kernel/perf_regs.c
> @@ -123,7 +123,7 @@ int perf_reg_validate(u64 mask)
>
>  u64 perf_reg_abi(struct task_struct *task)
>  {
> -   if (test_tsk_thread_flag(task, TIF_IA32))
> +   if (TASK_IA32(task))
> return PERF_SAMPLE_REGS_ABI_32;
> else
> return PERF_SAMPLE_REGS_ABI_64;

Surely this should be:

if (user_64bit_mode(task_pt_regs(regs))
  return PERF_SAMPLE_REGS_ABI_64;
else
  return PERF_SAMPLE_REGS_ABI_32;

> diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
> index a2488b6e27d6..3f1086afa297 100644
> --- a/arch/x86/oprofile/backtrace.c
> +++ b/arch/x86/oprofile/backtrace.c
> @@ -49,7 +49,7 @@ x86_backtrace_32(struct pt_regs * const regs, unsigned int 
> depth)
> struct stack_frame_ia32 *head;
>
> /* User process is IA32 */
> -   if (!current || !test_thread_flag(TIF_IA32))
> +   if (!current || !TASK_IA32(current))
> return 0;

if (user_64bit_mode(regs))
  return 0;


And now you don't need the TASK_IA32 macro :)

All of the above being said, I'm wondering how many of these profiling
users remember to check whether the task is a kernel thread.  And I
have no idea what task_pt_regs(current) contains in a kernel thread.

--Andy


Re: [PATCH RESEND 1/2] scsi: megaraid: Remove pci-dma-compat wrapper APIs.

2020-07-28 Thread Martin K. Petersen


Hello Suraj!

> The legacy API wrappers in include/linux/pci-dma-compat.h
> should go away as it creates unnecessary midlayering
> for include/linux/dma-mapping.h APIs, instead use dma-mapping.h
> APIs directly.

Instead of all these individual patches, please submit a combined patch
series for the changes under SCSI.

Each patch should fix a single driver. Please don't mix changes to
completely different drivers such as hpsa and dc395x in a single
commit. And please don't split semantically identical changes to the
same driver into multiple commits (megaraid [2/2]).

Thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


[RFC PATCH 1/6] mm/memory_hotplug: remove redundant memory block size alignment check

2020-07-28 Thread Jia He
The alignment check has been done by check_hotplug_memory_range(). Hence
the redundant one in create_memory_block_devices() can be removed.

The similar redundant check is removed in remove_memory_block_devices().

Signed-off-by: Jia He 
---
 drivers/base/memory.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 2b09b68b9f78..4a1691664c6c 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -642,10 +642,6 @@ int create_memory_block_devices(unsigned long start, 
unsigned long size)
unsigned long block_id;
int ret = 0;
 
-   if (WARN_ON_ONCE(!IS_ALIGNED(start, memory_block_size_bytes()) ||
-!IS_ALIGNED(size, memory_block_size_bytes(
-   return -EINVAL;
-
for (block_id = start_block_id; block_id != end_block_id; block_id++) {
ret = init_memory_block(, block_id, MEM_OFFLINE);
if (ret)
@@ -678,10 +674,6 @@ void remove_memory_block_devices(unsigned long start, 
unsigned long size)
struct memory_block *mem;
unsigned long block_id;
 
-   if (WARN_ON_ONCE(!IS_ALIGNED(start, memory_block_size_bytes()) ||
-!IS_ALIGNED(size, memory_block_size_bytes(
-   return;
-
for (block_id = start_block_id; block_id != end_block_id; block_id++) {
mem = find_memory_block_by_id(block_id);
if (WARN_ON_ONCE(!mem))
-- 
2.17.1



[RFC PATCH 2/6] resource: export find_next_iomem_res() helper

2020-07-28 Thread Jia He
The helper is to find the lowest iomem resource that covers part of
[@start..@end]

It is useful when relaxing the alignment check for dax pmem kmem.

Signed-off-by: Jia He 
---
 include/linux/ioport.h | 3 +++
 kernel/resource.c  | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 6c2b06fe8beb..203fd16c9f45 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -247,6 +247,9 @@ extern struct resource * __request_region(struct resource *,
 
 extern void __release_region(struct resource *, resource_size_t,
resource_size_t);
+extern int find_next_iomem_res(resource_size_t start, resource_size_t end,
+  unsigned long flags, unsigned long desc,
+  bool first_lvl, struct resource *res);
 #ifdef CONFIG_MEMORY_HOTREMOVE
 extern int release_mem_region_adjustable(struct resource *, resource_size_t,
resource_size_t);
diff --git a/kernel/resource.c b/kernel/resource.c
index 841737bbda9e..57e6a6802a3d 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -338,7 +338,7 @@ EXPORT_SYMBOL(release_resource);
  * @first_lvl: walk only the first level children, if set
  * @res:   return ptr, if resource found
  */
-static int find_next_iomem_res(resource_size_t start, resource_size_t end,
+int find_next_iomem_res(resource_size_t start, resource_size_t end,
   unsigned long flags, unsigned long desc,
   bool first_lvl, struct resource *res)
 {
@@ -391,6 +391,7 @@ static int find_next_iomem_res(resource_size_t start, 
resource_size_t end,
read_unlock(_lock);
return p ? 0 : -ENODEV;
 }
+EXPORT_SYMBOL(find_next_iomem_res);
 
 static int __walk_iomem_res_desc(resource_size_t start, resource_size_t end,
 unsigned long flags, unsigned long desc,
-- 
2.17.1



[RFC PATCH 3/6] mm/memory_hotplug: allow pmem kmem not to align with memory_block_size

2020-07-28 Thread Jia He
When dax pmem is probed as RAM device on arm64, previously, kmem_start in
dev_dax_kmem_probe() should be aligned with 1G memblock size on arm64 due
to SECTION_SIZE_BITS(30).

There will be some meta data at the beginning/end of the iomem space, e.g.
namespace info and nvdimm label:
24000-33fdf : Persistent Memory
  24000-2403f : namespace0.0
  28000-2bfff : dax0.0
28000-2bfff : System RAM

Hence it makes the whole kmem space not aligned with memory_block_size for
both start addr and end addr. Hence there is a big gap when kmem is added
into memory block which causes big memory space wasting.

This changes it by relaxing the alignment check for dax pmem kmem in the
path of online/offline memory blocks.

Signed-off-by: Jia He 
---
 drivers/base/memory.c | 16 
 mm/memory_hotplug.c   | 39 ++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 4a1691664c6c..3d2a94f3b1d9 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -334,6 +334,22 @@ static ssize_t valid_zones_show(struct device *dev,
 * online nodes otherwise the page_zone is not reliable
 */
if (mem->state == MEM_ONLINE) {
+#ifdef CONFIG_ZONE_DEVICE
+   struct resource res;
+   int ret;
+
+   /* adjust start_pfn for dax pmem kmem */
+   ret = find_next_iomem_res(start_pfn << PAGE_SHIFT,
+   ((start_pfn + nr_pages) << PAGE_SHIFT) 
- 1,
+   IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
+   IORES_DESC_PERSISTENT_MEMORY,
+   false, );
+   if (!ret && PFN_UP(res.start) > start_pfn) {
+   nr_pages -= PFN_UP(res.start) - start_pfn;
+   start_pfn = PFN_UP(res.start);
+   }
+#endif
+
/*
 * The block contains more than one zone can not be offlined.
 * This can happen e.g. for ZONE_DMA and ZONE_DMA32
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index a53103dc292b..25745f67b680 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -999,6 +999,20 @@ int try_online_node(int nid)
 
 static int check_hotplug_memory_range(u64 start, u64 size)
 {
+#ifdef CONFIG_ZONE_DEVICE
+   struct resource res;
+   int ret;
+
+   /* Allow pmem kmem not to align with block size */
+   ret = find_next_iomem_res(start, start + size - 1,
+   IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
+   IORES_DESC_PERSISTENT_MEMORY,
+   false, );
+   if (!ret) {
+   return 0;
+   }
+#endif
+
/* memory range must be block size aligned */
if (!size || !IS_ALIGNED(start, memory_block_size_bytes()) ||
!IS_ALIGNED(size, memory_block_size_bytes())) {
@@ -1481,19 +1495,42 @@ static int __ref __offline_pages(unsigned long 
start_pfn,
mem_hotplug_begin();
 
/*
-* Don't allow to offline memory blocks that contain holes.
+* Don't allow to offline memory blocks that contain holes except
+* for pmem.
 * Consequently, memory blocks with holes can never get onlined
 * via the hotplug path - online_pages() - as hotplugged memory has
 * no holes. This way, we e.g., don't have to worry about marking
 * memory holes PG_reserved, don't need pfn_valid() checks, and can
 * avoid using walk_system_ram_range() later.
+* When dax pmem is used as RAM (kmem), holes at the beginning is
+* allowed.
 */
walk_system_ram_range(start_pfn, end_pfn - start_pfn, _pages,
  count_system_ram_pages_cb);
if (nr_pages != end_pfn - start_pfn) {
+#ifdef CONFIG_ZONE_DEVICE
+   struct resource res;
+
+   /* Allow pmem kmem not to align with block size */
+   ret = find_next_iomem_res(start_pfn << PAGE_SHIFT,
+   (end_pfn << PAGE_SHIFT) - 1,
+   IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
+   IORES_DESC_PERSISTENT_MEMORY,
+   false, );
+   if (ret) {
+   ret = -EINVAL;
+   reason = "memory holes";
+   goto failed_removal;
+   }
+
+   /* adjust start_pfn for dax pmem kmem */
+   start_pfn = PFN_UP(res.start);
+   end_pfn = PFN_DOWN(res.end + 1);
+#else
ret = -EINVAL;
reason = "memory holes";
goto failed_removal;
+#endif
}
 
/* This makes hotplug much easier...and readable.
-- 
2.17.1



[RFC PATCH 6/6] arm64: fall back to vmemmap_populate_basepages if not aligned with PMD_SIZE

2020-07-28 Thread Jia He
In dax pmem kmem (dax pmem used as RAM device) case, the start address
might not be aligned with PMD_SIZE
e.g.
24000-33fdf : Persistent Memory
  24000-2421f : namespace0.0
  24240-2bfff : dax0.0
24240-2bfff : System RAM (kmem)
pfn_to_page(0x24240) is fe0007e9.

Without this patch, vmemmap_populate(fe0007e9, ...) will incorrectly
create a pmd mapping [fe0007e0, fe000800] which contains
fe0007e9.

This adds the check and then falls back to vmemmap_populate_basepages()

Signed-off-by: Jia He 
---
 arch/arm64/mm/mmu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index d69feb2cfb84..3b21bd47e801 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1102,6 +1102,10 @@ int __meminit vmemmap_populate(unsigned long start, 
unsigned long end, int node,
 
do {
next = pmd_addr_end(addr, end);
+   if (next - addr < PMD_SIZE) {
+   vmemmap_populate_basepages(start, next, node, altmap);
+   continue;
+   }
 
pgdp = vmemmap_pgd_populate(addr, node);
if (!pgdp)
-- 
2.17.1



[RFC PATCH 4/6] mm/page_alloc: adjust the start,end in dax pmem kmem case

2020-07-28 Thread Jia He
There are 3 cases when doing online pages:
 - normal RAM, should be aligned with memory block size
 - persistent memory with ZONE_DEVICE
 - persistent memory used as normal RAM (kmem) with ZONE_NORMAL, this patch
   tries to adjust the start_pfn/end_pfn after finding the corresponding
   resource range.

Without this patch, the check of __init_single_page when doing online memory
will be failed because those pages haven't been mapped in mmu(not present
from mmu's point of view).

Signed-off-by: Jia He 
---
 mm/page_alloc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e028b87ce294..13216ab3623f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5971,6 +5971,20 @@ void __meminit memmap_init_zone(unsigned long size, int 
nid, unsigned long zone,
if (start_pfn == altmap->base_pfn)
start_pfn += altmap->reserve;
end_pfn = altmap->base_pfn + vmem_altmap_offset(altmap);
+   } else {
+   struct resource res;
+   int ret;
+
+   /* adjust the start,end in dax pmem kmem case */
+   ret = find_next_iomem_res(start_pfn << PAGE_SHIFT,
+   (end_pfn << PAGE_SHIFT) - 1,
+   IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
+   IORES_DESC_PERSISTENT_MEMORY,
+   false, );
+   if (!ret) {
+   start_pfn = PFN_UP(res.start);
+   end_pfn = PFN_DOWN(res.end + 1);
+   }
}
 #endif
 
-- 
2.17.1



[RFC PATCH 5/6] device-dax: relax the memblock size alignment for kmem_start

2020-07-28 Thread Jia He
Previously, kmem_start in dev_dax_kmem_probe should be aligned with
SECTION_SIZE_BITS(30), i.e. 1G memblock size on arm64. Even with Dan
Williams' sub-section patch series, it was not helpful when adding the
dax pmem kmem to memblock:
$ndctl create-namespace -e namespace0.0 --mode=devdax --map=dev -s 2g -f -a 2M
$echo dax0.0 > /sys/bus/dax/drivers/device_dax/unbind
$echo dax0.0 > /sys/bus/dax/drivers/kmem/new_id
$cat /proc/iomem
...
23c00-23fff : System RAM
  23dd4-23fec : reserved
  23fed-23fff : reserved
24000-33fdf : Persistent Memory
  24000-2403f : namespace0.0
  28000-2bfff : dax0.0  <- boundary are aligned with 1G
28000-2bfff : System RAM (kmem)
$ lsmem
RANGE SIZE  STATE REMOVABLE BLOCK
0x4000-0x00023fff   8G online   yes   1-8
0x00028000-0x0002bfff   1G online   yes10

Memory block size: 1G
Total online memory:   9G
Total offline memory:  0B
...
Hence there is a big gap between 0x2403f and 0x28000 due to the 1G
alignment on arm64. More than that, only 1G memory is returned while 2G is
requested.

On x86, the gap is relatively small due to SECTION_SIZE_BITS(27).

Besides descreasing SECTION_SIZE_BITS on arm64, we can relax the alignment
when adding the kmem.
After this patch:
24000-33fdf : Persistent Memory
  24000-2421f : namespace0.0
  24240-2bfff : dax0.0
24240-2bfff : System RAM (kmem)
$ lsmem
RANGE SIZE  STATE REMOVABLE BLOCK
0x4000-0x0002bfff  10G online   yes  1-10

Memory block size: 1G
Total online memory:  10G
Total offline memory:  0B

Notes, block 9-10 are the newly hotplug added.

This patches remove the tight alignment constraint of
memory_block_size_bytes(), but still keep the constraint from
online_pages_range().

Signed-off-by: Jia He 
---
 drivers/dax/kmem.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c
index d77786dc0d92..849d0706dfe0 100644
--- a/drivers/dax/kmem.c
+++ b/drivers/dax/kmem.c
@@ -30,9 +30,20 @@ int dev_dax_kmem_probe(struct device *dev)
const char *new_res_name;
int numa_node;
int rc;
+   int order;
 
-   /* Hotplug starting at the beginning of the next block: */
-   kmem_start = ALIGN(res->start, memory_block_size_bytes());
+   /* kmem_start needn't be aligned with memory_block_size_bytes().
+* But given the constraint in online_pages_range(), adjust the
+* alignment of kmem_start and kmem_size
+*/
+   kmem_size = resource_size(res);
+   order = min_t(int, MAX_ORDER - 1, get_order(kmem_size));
+   kmem_start = ALIGN(res->start, 1ul << (order + PAGE_SHIFT));
+   /* Adjust the size down to compensate for moving up kmem_start: */
+   kmem_size -= kmem_start - res->start;
+   /* Align the size down to cover only complete blocks: */
+   kmem_size &= ~((1ul << (order + PAGE_SHIFT)) - 1);
+   kmem_end = kmem_start + kmem_size;
 
/*
 * Ensure good NUMA information for the persistent memory.
@@ -48,13 +59,6 @@ int dev_dax_kmem_probe(struct device *dev)
numa_node, res);
}
 
-   kmem_size = resource_size(res);
-   /* Adjust the size down to compensate for moving up kmem_start: */
-   kmem_size -= kmem_start - res->start;
-   /* Align the size down to cover only complete blocks: */
-   kmem_size &= ~(memory_block_size_bytes() - 1);
-   kmem_end = kmem_start + kmem_size;
-
new_res_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!new_res_name)
return -ENOMEM;
-- 
2.17.1



[RFC PATCH 0/6] decrease unnecessary gap due to pmem kmem alignment

2020-07-28 Thread Jia He
When enabling dax pmem as RAM device on arm64, I noticed that kmem_start
addr in dev_dax_kmem_probe() should be aligned w/ SECTION_SIZE_BITS(30),i.e.
1G memblock size. Even Dan Williams' sub-section patch series [1] had been
upstream merged, it was not helpful due to hard limitation of kmem_start:
$ndctl create-namespace -e namespace0.0 --mode=devdax --map=dev -s 2g -f -a 2M
$echo dax0.0 > /sys/bus/dax/drivers/device_dax/unbind
$echo dax0.0 > /sys/bus/dax/drivers/kmem/new_id
$cat /proc/iomem
...
23c00-23fff : System RAM
  23dd4-23fec : reserved
  23fed-23fff : reserved
24000-33fdf : Persistent Memory
  24000-2403f : namespace0.0
  28000-2bfff : dax0.0  <- aligned with 1G boundary
28000-2bfff : System RAM
Hence there is a big gap between 0x2403f and 0x28000 due to the 1G
alignment.
 
Without this series, if qemu creates a 4G bytes nvdimm device, we can only
use 2G bytes for dax pmem(kmem) in the worst case.
e.g.
24000-33fdf : Persistent Memory 
We can only use the memblock between [24000, 2] due to the hard
limitation. It wastes too much memory space.

Decreasing the SECTION_SIZE_BITS on arm64 might be an alternative, but there
are too many concerns from other constraints, e.g. PAGE_SIZE, hugetlb,
SPARSEMEM_VMEMMAP, page bits in struct page ...

Beside decreasing the SECTION_SIZE_BITS, we can also relax the kmem alignment
with memory_block_size_bytes().

Tested on arm64 guest and x86 guest, qemu creates a 4G pmem device. dax pmem
can be used as ram with smaller gap. Also the kmem hotplug add/remove are both
tested on arm64/x86 guest.

This patch series (mainly patch6/6) is based on the fixing patch, ~v5.8-rc5 [2].

[1] https://lkml.org/lkml/2019/6/19/67
[2] https://lkml.org/lkml/2020/7/8/1546
Jia He (6):
  mm/memory_hotplug: remove redundant memory block size alignment check
  resource: export find_next_iomem_res() helper
  mm/memory_hotplug: allow pmem kmem not to align with memory_block_size
  mm/page_alloc: adjust the start,end in dax pmem kmem case
  device-dax: relax the memblock size alignment for kmem_start
  arm64: fall back to vmemmap_populate_basepages if not aligned  with
PMD_SIZE

 arch/arm64/mm/mmu.c|  4 
 drivers/base/memory.c  | 24 
 drivers/dax/kmem.c | 22 +-
 include/linux/ioport.h |  3 +++
 kernel/resource.c  |  3 ++-
 mm/memory_hotplug.c| 39 ++-
 mm/page_alloc.c| 14 ++
 7 files changed, 90 insertions(+), 19 deletions(-)

-- 
2.17.1



[PATCH V3] dt-bindings: pci: convert QCOM pci bindings to YAML

2020-07-28 Thread Sivaprakash Murugesan
Convert QCOM pci bindings to YAML schema

Reviewed-by: Rob Herring 
Signed-off-by: Sivaprakash Murugesan 
---
[V3]
 * Rebased V2 including recent patches from Ansuel
 * Addressed Review comments from Rob
 * Apart from properties commented by Rob interrupt-map is also
   removed as it is documented in pci-bus.yaml and throwing error when
   included
 * check patch warning 
   "Use of 'slave' is deprecated, please '(secondary|target|...)', instead."
   is not addressed in this patch as it requires changes in code and dts
 .../devicetree/bindings/pci/qcom,pcie.txt  | 337 
 .../devicetree/bindings/pci/qcom,pcie.yaml | 437 +
 2 files changed, 437 insertions(+), 337 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt 
b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
deleted file mode 100644
index 02bc81b..000
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
+++ /dev/null
@@ -1,337 +0,0 @@
-* Qualcomm PCI express root complex
-
-- compatible:
-   Usage: required
-   Value type: 
-   Definition: Value should contain
-   - "qcom,pcie-ipq8064" for ipq8064
-   - "qcom,pcie-ipq8064-v2" for ipq8064 rev 2 or ipq8065
-   - "qcom,pcie-apq8064" for apq8064
-   - "qcom,pcie-apq8084" for apq8084
-   - "qcom,pcie-msm8996" for msm8996 or apq8096
-   - "qcom,pcie-ipq4019" for ipq4019
-   - "qcom,pcie-ipq8074" for ipq8074
-   - "qcom,pcie-qcs404" for qcs404
-   - "qcom,pcie-sdm845" for sdm845
-
-- reg:
-   Usage: required
-   Value type: 
-   Definition: Register ranges as listed in the reg-names property
-
-- reg-names:
-   Usage: required
-   Value type: 
-   Definition: Must include the following entries
-   - "parf"   Qualcomm specific registers
-   - "dbi"DesignWare PCIe registers
-   - "elbi"   External local bus interface registers
-   - "config" PCIe configuration space
-
-- device_type:
-   Usage: required
-   Value type: 
-   Definition: Should be "pci". As specified in designware-pcie.txt
-
-- #address-cells:
-   Usage: required
-   Value type: 
-   Definition: Should be 3. As specified in designware-pcie.txt
-
-- #size-cells:
-   Usage: required
-   Value type: 
-   Definition: Should be 2. As specified in designware-pcie.txt
-
-- ranges:
-   Usage: required
-   Value type: 
-   Definition: As specified in designware-pcie.txt
-
-- interrupts:
-   Usage: required
-   Value type: 
-   Definition: MSI interrupt
-
-- interrupt-names:
-   Usage: required
-   Value type: 
-   Definition: Should contain "msi"
-
-- #interrupt-cells:
-   Usage: required
-   Value type: 
-   Definition: Should be 1. As specified in designware-pcie.txt
-
-- interrupt-map-mask:
-   Usage: required
-   Value type: 
-   Definition: As specified in designware-pcie.txt
-
-- interrupt-map:
-   Usage: required
-   Value type: 
-   Definition: As specified in designware-pcie.txt
-
-- clocks:
-   Usage: required
-   Value type: 
-   Definition: List of phandle and clock specifier pairs as listed
-   in clock-names property
-
-- clock-names:
-   Usage: required
-   Value type: 
-   Definition: Should contain the following entries
-   - "iface"   Configuration AHB clock
-
-- clock-names:
-   Usage: required for ipq/apq8064
-   Value type: 
-   Definition: Should contain the following entries
-   - "core"Clocks the pcie hw block
-   - "phy" Clocks the pcie PHY block
-   - "aux" Clocks the pcie AUX block
-   - "ref" Clocks the pcie ref block
-- clock-names:
-   Usage: required for apq8084/ipq4019
-   Value type: 
-   Definition: Should contain the following entries
-   - "aux" Auxiliary (AUX) clock
-   - "bus_master"  Master AXI clock
-   - "bus_slave"   Slave AXI clock
-
-- clock-names:
-   Usage: required for msm8996/apq8096
-   Value type: 
-   Definition: Should contain the following entries
-   - "pipe"Pipe Clock driving internal logic
-   - "aux" Auxiliary (AUX) clock
-   - "cfg" Configuration clock
-   - "bus_master"  Master AXI clock
-   - "bus_slave"   Slave AXI clock
-
-- clock-names:
-   Usage: required for 

[PATCH 1/5] block: Move bio merge related functions into blk-merge.c

2020-07-28 Thread Baolin Wang
It's better to move bio merge related functions into blk-merge.c,
which contains all merge related functions.

Signed-off-by: Baolin Wang 
---
 block/blk-core.c  | 156 -
 block/blk-merge.c | 157 ++
 2 files changed, 157 insertions(+), 156 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index d9d6326..ed79109 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -642,162 +642,6 @@ void blk_put_request(struct request *req)
 }
 EXPORT_SYMBOL(blk_put_request);
 
-static void blk_account_io_merge_bio(struct request *req)
-{
-   if (!blk_do_io_stat(req))
-   return;
-
-   part_stat_lock();
-   part_stat_inc(req->part, merges[op_stat_group(req_op(req))]);
-   part_stat_unlock();
-}
-
-bool bio_attempt_back_merge(struct request *req, struct bio *bio,
-   unsigned int nr_segs)
-{
-   const int ff = bio->bi_opf & REQ_FAILFAST_MASK;
-
-   if (!ll_back_merge_fn(req, bio, nr_segs))
-   return false;
-
-   trace_block_bio_backmerge(req->q, req, bio);
-   rq_qos_merge(req->q, req, bio);
-
-   if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
-   blk_rq_set_mixed_merge(req);
-
-   req->biotail->bi_next = bio;
-   req->biotail = bio;
-   req->__data_len += bio->bi_iter.bi_size;
-
-   bio_crypt_free_ctx(bio);
-
-   blk_account_io_merge_bio(req);
-   return true;
-}
-
-bool bio_attempt_front_merge(struct request *req, struct bio *bio,
-   unsigned int nr_segs)
-{
-   const int ff = bio->bi_opf & REQ_FAILFAST_MASK;
-
-   if (!ll_front_merge_fn(req, bio, nr_segs))
-   return false;
-
-   trace_block_bio_frontmerge(req->q, req, bio);
-   rq_qos_merge(req->q, req, bio);
-
-   if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
-   blk_rq_set_mixed_merge(req);
-
-   bio->bi_next = req->bio;
-   req->bio = bio;
-
-   req->__sector = bio->bi_iter.bi_sector;
-   req->__data_len += bio->bi_iter.bi_size;
-
-   bio_crypt_do_front_merge(req, bio);
-
-   blk_account_io_merge_bio(req);
-   return true;
-}
-
-bool bio_attempt_discard_merge(struct request_queue *q, struct request *req,
-   struct bio *bio)
-{
-   unsigned short segments = blk_rq_nr_discard_segments(req);
-
-   if (segments >= queue_max_discard_segments(q))
-   goto no_merge;
-   if (blk_rq_sectors(req) + bio_sectors(bio) >
-   blk_rq_get_max_sectors(req, blk_rq_pos(req)))
-   goto no_merge;
-
-   rq_qos_merge(q, req, bio);
-
-   req->biotail->bi_next = bio;
-   req->biotail = bio;
-   req->__data_len += bio->bi_iter.bi_size;
-   req->nr_phys_segments = segments + 1;
-
-   blk_account_io_merge_bio(req);
-   return true;
-no_merge:
-   req_set_nomerge(q, req);
-   return false;
-}
-
-/**
- * blk_attempt_plug_merge - try to merge with %current's plugged list
- * @q: request_queue new bio is being queued at
- * @bio: new bio being queued
- * @nr_segs: number of segments in @bio
- * @same_queue_rq: pointer to  request that gets filled in when
- * another request associated with @q is found on the plug list
- * (optional, may be %NULL)
- *
- * Determine whether @bio being queued on @q can be merged with a request
- * on %current's plugged list.  Returns %true if merge was successful,
- * otherwise %false.
- *
- * Plugging coalesces IOs from the same issuer for the same purpose without
- * going through @q->queue_lock.  As such it's more of an issuing mechanism
- * than scheduling, and the request, while may have elvpriv data, is not
- * added on the elevator at this point.  In addition, we don't have
- * reliable access to the elevator outside queue lock.  Only check basic
- * merging parameters without querying the elevator.
- *
- * Caller must ensure !blk_queue_nomerges(q) beforehand.
- */
-bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
-   unsigned int nr_segs, struct request **same_queue_rq)
-{
-   struct blk_plug *plug;
-   struct request *rq;
-   struct list_head *plug_list;
-
-   plug = blk_mq_plug(q, bio);
-   if (!plug)
-   return false;
-
-   plug_list = >mq_list;
-
-   list_for_each_entry_reverse(rq, plug_list, queuelist) {
-   bool merged = false;
-
-   if (rq->q == q && same_queue_rq) {
-   /*
-* Only blk-mq multiple hardware queues case checks the
-* rq in the same queue, there should be only one such
-* rq in a queue
-**/
-   *same_queue_rq = rq;
-   }
-
-   if (rq->q != q || !blk_rq_merge_ok(rq, bio))
-   continue;
-
-   switch (blk_try_merge(rq, bio)) {
-   case 

[PATCH 2/5] block: Remove redundant blk_mq_sched_allow_merge() validation

2020-07-28 Thread Baolin Wang
Only software queue and kyber IO scheduler will call blk_mq_bio_list_merge()
to merge a bio, and kyber IO scheduler did not implement the ops->allow_merge().
Thus we can remove the redundant blk_mq_sched_allow_merge() in
blk_mq_bio_list_merge() function.

Signed-off-by: Baolin Wang 
---
 block/blk-mq-sched.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index b8db72c..cc34f69 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -403,14 +403,10 @@ bool blk_mq_bio_list_merge(struct request_queue *q, 
struct list_head *list,
 
switch (blk_try_merge(rq, bio)) {
case ELEVATOR_BACK_MERGE:
-   if (blk_mq_sched_allow_merge(q, rq, bio))
-   merged = bio_attempt_back_merge(rq, bio,
-   nr_segs);
+   merged = bio_attempt_back_merge(rq, bio, nr_segs);
break;
case ELEVATOR_FRONT_MERGE:
-   if (blk_mq_sched_allow_merge(q, rq, bio))
-   merged = bio_attempt_front_merge(rq, bio,
-   nr_segs);
+   merged = bio_attempt_front_merge(rq, bio, nr_segs);
break;
case ELEVATOR_DISCARD_MERGE:
merged = bio_attempt_discard_merge(q, rq, bio);
-- 
1.8.3.1



[PATCH 0/5] Some clean-ups for bio merge

2020-07-28 Thread Baolin Wang
Hi,

There are some duplicated code when trying to merge bio from pluged list
and software queue, thus this patch set did some clean-ups when merging
a bio. Any comments are welcome. Thanks.

Baolin Wang (5):
  block: Move bio merge related functions into blk-merge.c
  block: Remove redundant blk_mq_sched_allow_merge() validation
  block: Add a new helper to attempt to merge a bio
  block: Remove blk_mq_attempt_merge() function
  block: Remove __blk_mq_sched_bio_merge() helper

 block/blk-core.c | 156 ---
 block/blk-merge.c| 168 +++
 block/blk-mq-sched.c |  64 ++--
 block/blk-mq-sched.h |  13 +---
 block/blk.h  |   9 +++
 5 files changed, 197 insertions(+), 213 deletions(-)

-- 
1.8.3.1



[PATCH 5/5] block: Remove __blk_mq_sched_bio_merge() helper

2020-07-28 Thread Baolin Wang
The blk_mq_sched_bio_merge() just wrap the __blk_mq_sched_bio_merge(), and
no other places will use __blk_mq_sched_bio_merge(). Thus we can combine
these 2 similar functions into one function.

Signed-off-by: Baolin Wang 
---
 block/blk-mq-sched.c |  5 -
 block/blk-mq-sched.h | 13 ++---
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 4e3eef5..f7ae74a 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -408,7 +408,7 @@ bool blk_mq_bio_list_merge(struct request_queue *q, struct 
list_head *list,
 }
 EXPORT_SYMBOL_GPL(blk_mq_bio_list_merge);
 
-bool __blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
+bool blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
unsigned int nr_segs)
 {
struct elevator_queue *e = q->elevator;
@@ -417,6 +417,9 @@ bool __blk_mq_sched_bio_merge(struct request_queue *q, 
struct bio *bio,
bool ret = false;
enum hctx_type type;
 
+   if (blk_queue_nomerges(q) || !bio_mergeable(bio))
+   return false;
+
if (e && e->type->ops.bio_merge)
return e->type->ops.bio_merge(hctx, bio, nr_segs);
 
diff --git a/block/blk-mq-sched.h b/block/blk-mq-sched.h
index 126021f..65151de 100644
--- a/block/blk-mq-sched.h
+++ b/block/blk-mq-sched.h
@@ -13,8 +13,6 @@ void blk_mq_sched_free_hctx_data(struct request_queue *q,
 void blk_mq_sched_request_inserted(struct request *rq);
 bool blk_mq_sched_try_merge(struct request_queue *q, struct bio *bio,
unsigned int nr_segs, struct request **merged_request);
-bool __blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
-   unsigned int nr_segs);
 bool blk_mq_sched_try_insert_merge(struct request_queue *q, struct request 
*rq);
 void blk_mq_sched_mark_restart_hctx(struct blk_mq_hw_ctx *hctx);
 void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx);
@@ -31,15 +29,8 @@ void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx,
 void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e);
 void blk_mq_sched_free_requests(struct request_queue *q);
 
-static inline bool
-blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
-   unsigned int nr_segs)
-{
-   if (blk_queue_nomerges(q) || !bio_mergeable(bio))
-   return false;
-
-   return __blk_mq_sched_bio_merge(q, bio, nr_segs);
-}
+bool blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
+   unsigned int nr_segs);
 
 static inline bool
 blk_mq_sched_allow_merge(struct request_queue *q, struct request *rq,
-- 
1.8.3.1



[PATCH 3/5] block: Add a new helper to attempt to merge a bio

2020-07-28 Thread Baolin Wang
There are lots of duplicated code when trying to merge a bio from
plug list and sw queue, we can introduce a new helper to attempt
to merge a bio, which can simplify the blk_mq_bio_list_merge()
and blk_attempt_plug_merge().

Signed-off-by: Baolin Wang 
---
 block/blk-merge.c| 47 +--
 block/blk-mq-sched.c | 22 --
 block/blk.h  |  9 +
 3 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index 1993e6a..feaee53 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -975,6 +975,33 @@ bool bio_attempt_discard_merge(struct request_queue *q, 
struct request *req,
return false;
 }
 
+enum bio_merge_status blk_attempt_bio_merge(struct request_queue *q,
+   struct request *rq,
+   struct bio *bio,
+   unsigned int nr_segs)
+{
+   bool merged = false;
+
+   if (!blk_rq_merge_ok(rq, bio))
+   return BIO_MERGE_NONE;
+
+   switch (blk_try_merge(rq, bio)) {
+   case ELEVATOR_BACK_MERGE:
+   merged = bio_attempt_back_merge(rq, bio, nr_segs);
+   break;
+   case ELEVATOR_FRONT_MERGE:
+   merged = bio_attempt_front_merge(rq, bio, nr_segs);
+   break;
+   case ELEVATOR_DISCARD_MERGE:
+   merged = bio_attempt_discard_merge(q, rq, bio);
+   break;
+   default:
+   return BIO_MERGE_NONE;
+   }
+
+   return merged ? BIO_MERGE_OK : BIO_MERGE_FAILED;
+}
+
 /**
  * blk_attempt_plug_merge - try to merge with %current's plugged list
  * @q: request_queue new bio is being queued at
@@ -1011,8 +1038,6 @@ bool blk_attempt_plug_merge(struct request_queue *q, 
struct bio *bio,
plug_list = >mq_list;
 
list_for_each_entry_reverse(rq, plug_list, queuelist) {
-   bool merged = false;
-
if (rq->q == q && same_queue_rq) {
/*
 * Only blk-mq multiple hardware queues case checks the
@@ -1022,24 +1047,10 @@ bool blk_attempt_plug_merge(struct request_queue *q, 
struct bio *bio,
*same_queue_rq = rq;
}
 
-   if (rq->q != q || !blk_rq_merge_ok(rq, bio))
+   if (rq->q != q)
continue;
 
-   switch (blk_try_merge(rq, bio)) {
-   case ELEVATOR_BACK_MERGE:
-   merged = bio_attempt_back_merge(rq, bio, nr_segs);
-   break;
-   case ELEVATOR_FRONT_MERGE:
-   merged = bio_attempt_front_merge(rq, bio, nr_segs);
-   break;
-   case ELEVATOR_DISCARD_MERGE:
-   merged = bio_attempt_discard_merge(q, rq, bio);
-   break;
-   default:
-   break;
-   }
-
-   if (merged)
+   if (blk_attempt_bio_merge(q, rq, bio, nr_segs) == BIO_MERGE_OK)
return true;
}
 
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index cc34f69..24d5078 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -391,31 +391,17 @@ bool blk_mq_bio_list_merge(struct request_queue *q, 
struct list_head *list,
 {
struct request *rq;
int checked = 8;
+   enum bio_merge_status merge;
 
list_for_each_entry_reverse(rq, list, queuelist) {
-   bool merged = false;
-
if (!checked--)
break;
 
-   if (!blk_rq_merge_ok(rq, bio))
+   merge = blk_attempt_bio_merge(q, rq, bio, nr_segs);
+   if (merge == BIO_MERGE_NONE)
continue;
 
-   switch (blk_try_merge(rq, bio)) {
-   case ELEVATOR_BACK_MERGE:
-   merged = bio_attempt_back_merge(rq, bio, nr_segs);
-   break;
-   case ELEVATOR_FRONT_MERGE:
-   merged = bio_attempt_front_merge(rq, bio, nr_segs);
-   break;
-   case ELEVATOR_DISCARD_MERGE:
-   merged = bio_attempt_discard_merge(q, rq, bio);
-   break;
-   default:
-   continue;
-   }
-
-   return merged;
+   return merge == BIO_MERGE_OK ? true: false;
}
 
return false;
diff --git a/block/blk.h b/block/blk.h
index 49e2928..a6c54e1 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -234,6 +234,15 @@ int blk_attempt_req_merge(struct request_queue *q, struct 
request *rq,
 bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
 enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
 
+enum bio_merge_status {
+   BIO_MERGE_OK,
+   BIO_MERGE_NONE,
+   BIO_MERGE_FAILED,

[PATCH 4/5] block: Remove blk_mq_attempt_merge() function

2020-07-28 Thread Baolin Wang
The small blk_mq_attempt_merge() function is only called by
__blk_mq_sched_bio_merge(), just open code it.

Signed-off-by: Baolin Wang 
---
 block/blk-mq-sched.c | 33 ++---
 1 file changed, 10 insertions(+), 23 deletions(-)

diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index 24d5078..4e3eef5 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -408,28 +408,6 @@ bool blk_mq_bio_list_merge(struct request_queue *q, struct 
list_head *list,
 }
 EXPORT_SYMBOL_GPL(blk_mq_bio_list_merge);
 
-/*
- * Reverse check our software queue for entries that we could potentially
- * merge with. Currently includes a hand-wavy stop count of 8, to not spend
- * too much time checking for merges.
- */
-static bool blk_mq_attempt_merge(struct request_queue *q,
-struct blk_mq_hw_ctx *hctx,
-struct blk_mq_ctx *ctx, struct bio *bio,
-unsigned int nr_segs)
-{
-   enum hctx_type type = hctx->type;
-
-   lockdep_assert_held(>lock);
-
-   if (blk_mq_bio_list_merge(q, >rq_lists[type], bio, nr_segs)) {
-   ctx->rq_merged++;
-   return true;
-   }
-
-   return false;
-}
-
 bool __blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio,
unsigned int nr_segs)
 {
@@ -447,7 +425,16 @@ bool __blk_mq_sched_bio_merge(struct request_queue *q, 
struct bio *bio,
!list_empty_careful(>rq_lists[type])) {
/* default per sw-queue merge */
spin_lock(>lock);
-   ret = blk_mq_attempt_merge(q, hctx, ctx, bio, nr_segs);
+   /*
+* Reverse check our software queue for entries that we could
+* potentially merge with. Currently includes a hand-wavy stop
+* count of 8, to not spend too much time checking for merges.
+*/
+   if (blk_mq_bio_list_merge(q, >rq_lists[type], bio, 
nr_segs)) {
+   ctx->rq_merged++;
+   ret = true;
+   }
+
spin_unlock(>lock);
}
 
-- 
1.8.3.1



[PATCH] fat: Add newline after declarations

2020-07-28 Thread Coleman Kane
Add a newline after declarations in muliple places within the fat driver
where checkpatch.pl identified this problem.

Signed-off-by: Coleman Kane 
---
 fs/fat/cache.c   |  1 +
 fs/fat/dir.c |  6 ++
 fs/fat/fatent.c  |  8 
 fs/fat/file.c|  2 ++
 fs/fat/inode.c   | 14 ++
 fs/fat/misc.c|  2 ++
 fs/fat/namei_msdos.c |  1 +
 fs/fat/namei_vfat.c  |  4 
 fs/fat/nfs.c |  3 +++
 9 files changed, 41 insertions(+)

diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 738e427e2d21..8031e5ca15d1 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -167,6 +167,7 @@ static void fat_cache_add(struct inode *inode, struct 
fat_cache_id *new)
cache = tmp;
} else {
struct list_head *p = MSDOS_I(inode)->cache_lru.prev;
+
cache = list_entry(p, struct fat_cache, cache_list);
}
cache->fcluster = new->fcluster;
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index b4ddf48fa444..50b8b88d68c7 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -182,6 +182,7 @@ static inline int fat_uni_to_x8(struct super_block *sb, 
const wchar_t *uni,
unsigned char *buf, int size)
 {
struct msdos_sb_info *sbi = MSDOS_SB(sb);
+
if (sbi->options.utf8)
return utf16s_to_utf8s(uni, FAT_MAX_UNI_CHARS,
UTF16_HOST_ENDIAN, buf, size);
@@ -431,6 +432,7 @@ static int fat_parse_short(struct super_block *sb,
uni_len = j;
if (isvfat) {
int offset = min(chl, MSDOS_NAME-k);
+
k += offset;
i += offset;
} else {
@@ -669,6 +671,7 @@ static int __fat_readdir(struct inode *inode, struct file 
*file,
unsigned long inum;
loff_t i_pos = fat_make_i_pos(sb, bh, de);
struct inode *tmp = fat_iget(sb, i_pos);
+
if (tmp) {
inum = tmp->i_ino;
iput(tmp);
@@ -1343,6 +1346,7 @@ int fat_add_entries(struct inode *dir, void *slots, int 
nr_slots,
/* Fill the long name slots. */
for (i = 0; i < long_bhs; i++) {
int copy = min_t(int, sb->s_blocksize - offset, size);
+
memcpy(bhs[i]->b_data + offset, slots, copy);
mark_buffer_dirty_inode(bhs[i], dir);
offset = 0;
@@ -1353,7 +1357,9 @@ int fat_add_entries(struct inode *dir, void *slots, int 
nr_slots,
err = fat_sync_bhs(bhs, long_bhs);
if (!err && i < nr_bhs) {
/* Fill the short name slot. */
+
int copy = min_t(int, sb->s_blocksize - offset, size);
+
memcpy(bhs[i]->b_data + offset, slots, copy);
mark_buffer_dirty_inode(bhs[i], dir);
if (IS_DIRSYNC(dir))
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index bbfe18c07417..872550ffbc9b 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -24,6 +24,7 @@ static void fat12_ent_blocknr(struct super_block *sb, int 
entry,
 {
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int bytes = entry + (entry >> 1);
+
WARN_ON(!fat_valid_entry(sbi, entry));
*offset = bytes & (sb->s_blocksize - 1);
*blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
@@ -34,6 +35,7 @@ static void fat_ent_blocknr(struct super_block *sb, int entry,
 {
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int bytes = (entry << sbi->fatent_shift);
+
WARN_ON(!fat_valid_entry(sbi, entry));
*offset = bytes & (sb->s_blocksize - 1);
*blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
@@ -42,6 +44,7 @@ static void fat_ent_blocknr(struct super_block *sb, int entry,
 static void fat12_ent_set_ptr(struct fat_entry *fatent, int offset)
 {
struct buffer_head **bhs = fatent->bhs;
+
if (fatent->nr_bhs == 1) {
WARN_ON(offset >= (bhs[0]->b_size - 1));
fatent->u.ent12_p[0] = bhs[0]->b_data + offset;
@@ -136,6 +139,7 @@ static int fat12_ent_get(struct fat_entry *fatent)
 static int fat16_ent_get(struct fat_entry *fatent)
 {
int next = le16_to_cpu(*fatent->u.ent16_p);
+
WARN_ON((unsigned long)fatent->u.ent16_p & (2 - 1));
if (next >= BAD_FAT16)
next = FAT_ENT_EOF;
@@ -145,6 +149,7 @@ static int fat16_ent_get(struct fat_entry *fatent)
 static int fat32_ent_get(struct fat_entry *fatent)
 {
int next = le32_to_cpu(*fatent->u.ent32_p) & 0x0fff;
+
WARN_ON((unsigned long)fatent->u.ent32_p & (4 - 1));
if (next >= BAD_FAT32)
next = FAT_ENT_EOF;
@@ -226,6 +231,7 @@ static int fat12_ent_next(struct fat_entry *fatent)
 

[PATCH v18 1/3] MAINTAINERS: da7280 updates to the Dialog Semiconductor search terms

2020-07-28 Thread Roy Im
This patch adds the da7280 bindings doc and driver to the Dialog
Semiconductor support list.

Signed-off-by: Roy Im 

---
v18: No changes.
v17: No changes.
v16: No changes.
v15: No changes.
v14: No changes.
v13: No changes.
v12: Corrected file list order.
v11: No changes.
v10: No changes.
v9: No changes.
v8: No changes.
v7: No changes.
v6: No changes.
v5: No changes.
v4: No changes.
v3: No changes.
v2: No changes.


 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f0569cf..6d76a80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5003,6 +5003,7 @@ M:Support Opensource 

 S: Supported
 W: http://www.dialog-semiconductor.com/products
 F: Documentation/devicetree/bindings/input/da90??-onkey.txt
+F: Documentation/devicetree/bindings/input/dlg,da72??.txt
 F: Documentation/devicetree/bindings/mfd/da90*.txt
 F: Documentation/devicetree/bindings/regulator/da92*.txt
 F: Documentation/devicetree/bindings/regulator/slg51000.txt
@@ -5013,6 +5014,7 @@ F:Documentation/hwmon/da90??.rst
 F: drivers/gpio/gpio-da90??.c
 F: drivers/hwmon/da90??-hwmon.c
 F: drivers/iio/adc/da91??-*.c
+F: drivers/input/misc/da72??.[ch]
 F: drivers/input/misc/da90??_onkey.c
 F: drivers/input/touchscreen/da9052_tsi.c
 F: drivers/leds/leds-da90??.c
-- 
end-of-patch for PATCH v18



[PATCH v18 3/3] Input: new da7280 haptic driver

2020-07-28 Thread Roy Im
Adds support for the Dialog DA7280 LRA/ERM Haptic Driver with
multiple mode and integrated waveform memory and wideband support.
It communicates via an I2C bus to the device.

Reviewed-by: Jes Sorensen .

Signed-off-by: Roy Im 

---
v18:
- Corrected comments in Kconfig
- Updated to preferred style for multi line comments in c file.
v17:
- fixed an issue.
v16:
- Corrected some code and updated description in Kconfig.
v15:
- Removed some defines and updated some comments.
v14:
- Updated pwm related code, alignments and comments.
v13:
- Updated some conditions in pwm function and alignments.
v12: No changes.
v11: 
- Updated the pwm related code, comments and typo.
v10: 
- Updated the pwm related function and added some comments.
v9: 
- Removed the header file and put the definitions into the c file.
- Updated the pwm code and error logs with %pE
v8: 
- Added changes to support FF_PERIODIC/FF_CUSTOM and FF_CONSTANT.
- Updated the dt-related code.
- Removed memless related functions.
v7: 
- Added more attributes to handle one value per file.
- Replaced and updated the dt-related code and functions called.
- Fixed error/functions.
v6: No changes.
v5: Fixed errors in Kconfig file.
v4: Updated code as dt-bindings are changed.
v3: No changes.
v2: Fixed kbuild error/warning


 drivers/input/misc/Kconfig  |   12 +
 drivers/input/misc/Makefile |1 +
 drivers/input/misc/da7280.c | 1845 +++
 3 files changed, 1858 insertions(+)
 create mode 100644 drivers/input/misc/da7280.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 362e8a0..d38b466 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -869,4 +869,16 @@ config INPUT_STPMIC1_ONKEY
  To compile this driver as a module, choose M here: the
  module will be called stpmic1_onkey.
 
+config INPUT_DA7280_HAPTICS
+   tristate "Dialog Semiconductor DA7280 haptics support"
+   depends on INPUT && I2C
+   select REGMAP_I2C
+   help
+ Say Y to enable support for the Dialog DA7280 haptics driver.
+ The haptics can be controlled by PWM or GPIO
+ with I2C communication.
+
+ To compile this driver as a module, choose M here: the
+ module will be called da7280.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index a48e5f2..9cfd6ab 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_CMA3000)   += cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)+= cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)+= cobalt_btns.o
 obj-$(CONFIG_INPUT_CPCAP_PWRBUTTON)+= cpcap-pwrbutton.o
+obj-$(CONFIG_INPUT_DA7280_HAPTICS) += da7280.o
 obj-$(CONFIG_INPUT_DA9052_ONKEY)   += da9052_onkey.o
 obj-$(CONFIG_INPUT_DA9055_ONKEY)   += da9055_onkey.o
 obj-$(CONFIG_INPUT_DA9063_ONKEY)   += da9063_onkey.o
diff --git a/drivers/input/misc/da7280.c b/drivers/input/misc/da7280.c
new file mode 100644
index 000..ecc8428
--- /dev/null
+++ b/drivers/input/misc/da7280.c
@@ -0,0 +1,1845 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DA7280 Haptic device driver
+ *
+ * Copyright (c) 2020 Dialog Semiconductor.
+ * Author: Roy Im 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Registers */
+#define DA7280_IRQ_EVENT1 0x03
+#define DA7280_IRQ_EVENT_WARNING_DIAG 0x04
+#define DA7280_IRQ_EVENT_SEQ_DIAG 0x05
+#define DA7280_IRQ_STATUS10x06
+#define DA7280_IRQ_MASK1  0x07
+#define DA7280_FRQ_LRA_PER_H  0x0A
+#define DA7280_FRQ_LRA_PER_L  0x0B
+#define DA7280_ACTUATOR1  0x0C
+#define DA7280_ACTUATOR2  0x0D
+#define DA7280_ACTUATOR3  0x0E
+#define DA7280_CALIB_V2I_H0x0F
+#define DA7280_CALIB_V2I_L0x10
+#define DA7280_TOP_CFG1   0x13
+#define DA7280_TOP_CFG2   0x14
+#define DA7280_TOP_CFG4   0x16
+#define DA7280_TOP_INT_CFG1   0x17
+#define DA7280_TOP_CTL1   0x22
+#define DA7280_TOP_CTL2   0x23
+#define DA7280_SEQ_CTL2   0x28
+#define DA7280_GPI_0_CTL  0x29
+#define DA7280_GPI_1_CTL  0x2A
+#define DA7280_GPI_2_CTL  0x2B
+#define DA7280_MEM_CTL1   0x2C
+#define DA7280_MEM_CTL2   0x2D
+#define DA7280_TOP_CFG5   0x6E
+#define DA7280_IRQ_MASK2  0x83
+#define DA7280_SNP_MEM_99 0xE7
+
+/* Register field */
+

[PATCH v18 2/3] dt-bindings: input: Add document bindings for DA7280

2020-07-28 Thread Roy Im
Add device tree binding information for DA7280 haptic driver.
Example bindings for DA7280 are added.

Reviewed-by: Rob Herring .

Signed-off-by: Roy Im 

---
v18: No changes.
v17: No changes.
v16: No changes.
v15: No changes.
v14: No changes.
v13: No changes.
v12: No changes.
v11: No changes.
v10: No changes.
v9: No changes.
v8: Updated descriptions for new properties.
v7: No changes.
v6: No changes.
v5: Updated descriptions and fixed errors.
v4: Fixed commit message, properties.
v3: Fixed subject format.
v2: No changes


 .../devicetree/bindings/input/dlg,da7280.txt   | 109 +
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/dlg,da7280.txt

diff --git a/Documentation/devicetree/bindings/input/dlg,da7280.txt 
b/Documentation/devicetree/bindings/input/dlg,da7280.txt
new file mode 100644
index 000..e6b719d
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/dlg,da7280.txt
@@ -0,0 +1,109 @@
+Dialog Semiconductor DA7280 Haptics bindings
+
+Required properties:
+- compatible: Should be "dlg,da7280".
+- reg: Specifies the I2C slave address.
+
+- interrupt-parent : Specifies the phandle of the interrupt controller to
+  which the IRQs from DA7280 are delivered to.
+
+- dlg,actuator-type: Set Actuator type. it should be one of:
+  "LRA" - Linear Resonance Actuator type.
+  "ERM-bar" - Bar type Eccentric Rotating Mass.
+  "ERM-coin" - Coin type Eccentric Rotating Mass.
+
+- dlg,const-op-mode: Haptic operation mode for FF_CONSTANT.
+  Possible values:
+   1 - Direct register override(DRO) mode triggered by i2c(default),
+   2 - PWM data source mode controlled by PWM duty,
+- dlg,periodic-op-mode: Haptic operation mode for FF_PERIODIC.
+  Possible values:
+   1 - Register triggered waveform memory(RTWM) mode, the pattern
+   assigned to the PS_SEQ_ID played as much times as PS_SEQ_LOOP,
+   2 - Edge triggered waveform memory(ETWM) mode, external GPI(N)
+   control are required to enable/disable and it needs to keep
+   device enabled by sending magnitude (X > 0),
+   the pattern is assigned to the GPI(N)_SEQUENCE_ID below.
+   The default value is 1 for both of the operation modes.
+   For more details, please see the datasheet.
+
+- dlg,nom-microvolt: Nominal actuator voltage rating.
+  Valid values: 0 - 600.
+- dlg,abs-max-microvolt: Absolute actuator maximum voltage rating.
+  Valid values: 0 - 600.
+- dlg,imax-microamp: Actuator max current rating.
+  Valid values: 0 - 252000.
+  Default: 13.
+- dlg,impd-micro-ohms: the impedance of the actuator in micro ohms.
+  Valid values: 0 - 15.
+
+Optional properties:
+- pwms : phandle to the physical PWM(Pulse Width Modulation) device.
+  PWM properties should be named "pwms". And number of cell is different
+  for each pwm device.
+  (See Documentation/devicetree/bindings/pwm/pwm.txt
+   for further information relating to pwm properties)
+
+- dlg,ps-seq-id: the PS_SEQ_ID(pattern ID in waveform memory inside chip)
+  to play back when RTWM-MODE is enabled.
+  Valid range: 0 - 15.
+- dlg,ps-seq-loop: the PS_SEQ_LOOP, Number of times the pre-stored sequence
+  pointed to by PS_SEQ_ID or GPI(N)_SEQUENCE_ID is repeated.
+  Valid range: 0 - 15.
+- dlg,gpiN-seq-id: the GPI(N)_SEQUENCE_ID, pattern to play
+  when gpi0 is triggered, 'N' must be 0 - 2.
+  Valid range: 0 - 15.
+- dlg,gpiN-mode: the pattern mode which can select either
+  "Single-pattern" or "Multi-pattern", 'N' must be 0 - 2.
+- dlg,gpiN-polarity: gpiN polarity which can be chosen among
+  "Rising-edge", "Falling-edge" and "Both-edge",
+  'N' must be 0 - 2
+  Haptic will work by this edge option in case of ETWM mode.
+
+- dlg,resonant-freq-hz: use in case of LRA.
+  the frequency range: 50 - 300.
+  Default: 205.
+
+- dlg,bemf-sens-enable: Enable for internal loop computations.
+- dlg,freq-track-enable: Enable for resonant frequency tracking.
+- dlg,acc-enable: Enable for active acceleration.
+- dlg,rapid-stop-enable: Enable for rapid stop.
+- dlg,amp-pid-enable: Enable for the amplitude PID.
+- dlg,mem-array: Customized waveform memory(patterns) data downloaded to
+  the device during initialization. This is an array of 100 values(u8).
+
+For further information, see device datasheet.
+
+==
+
+Example:
+
+   haptics: da7280-haptics@4a {
+   compatible = "dlg,da7280";
+   reg = <0x4a>;
+   interrupt-parent = <>;
+   interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+   dlg,actuator-type = "LRA";
+   dlg,dlg,const-op-mode = <1>;
+   dlg,dlg,periodic-op-mode = <1>;
+   dlg,nom-microvolt = <200>;
+   dlg,abs-max-microvolt = <200>;
+   dlg,imax-microamp = <17>;
+   dlg,resonant-freq-hz = <180>;
+   dlg,impd-micro-ohms = <1050>;
+   dlg,freq-track-enable;
+   dlg,rapid-stop-enable;
+ 

[PATCH v18 0/3] da7280: haptic driver submission

2020-07-28 Thread Roy Im
This patch adds support for the Dialog DA7280 Haptic driver IC.

In this patch set the following is provided:

[PATCH v18 1/3] MAINTAINERS file update for DA7280
[PATCH v18 2/3] DA7280 DT Binding
[PATCH v18 3/3] DA7280 Driver

This patch applies against linux-next and v5.8-rc7

Thank you,
Roy Im, Dialog Semiconductor Ltd.

Roy Im (3):
  MAINTAINERS: da7280 updates to the Dialog Semiconductor search terms
  dt-bindings: input: Add document bindings for DA7280
  Input: new da7280 haptic driver

 .../devicetree/bindings/input/dlg,da7280.txt   |  109 ++
 MAINTAINERS|2 +
 drivers/input/misc/Kconfig |   12 +
 drivers/input/misc/Makefile|1 +
 drivers/input/misc/da7280.c| 1845 
 5 files changed, 1969 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/dlg,da7280.txt
 create mode 100644 drivers/input/misc/da7280.c

-- 
end-of-patch for PATCH v18



[PATCH 2/2] kbuild: sort hostprogs before passing it to ifneq

2020-07-28 Thread Masahiro Yamada
The conditional:

  ifneq ($(hostprogs),)

... is evaluated to true if $(hostprogs) does not contain any word but
whitespace characters.

  ifneq ($(strip $(hostprogs)),)

... is a safe way to avoid interpreting whitespace as a non-empty value,
but I'd rather want to use the side-effect of $(sort ...) to do the
equivalent.

$(sort ...) is used in scripts/Makefile.host in order to drop duplication
in $(hostprogs). It is also useful to strip excessive spaces.

Move $(sort ...) before evaluating the ifneq.

Signed-off-by: Masahiro Yamada 
---

 scripts/Makefile.build |  5 -
 scripts/Makefile.host  | 10 --
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d41c1cd453b9..e0b6b5db11c2 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -45,12 +45,15 @@ include $(kbuild-file)
 
 include scripts/Makefile.lib
 
-# Do not include hostprogs rules unless needed
+# Do not include hostprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
+hostprogs := $(sort $(hostprogs))
 ifneq ($(hostprogs),)
 include scripts/Makefile.host
 endif
 
 # Do not include userprogs rules unless needed.
+# $(sort ...) is used here to remove duplicated words and excessive spaces.
 userprogs := $(sort $(userprogs))
 ifneq ($(userprogs),)
 include scripts/Makefile.userprogs
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 687ca3f309e9..278b4d6ac945 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -38,24 +38,22 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
 # Will compile qconf as a C++ program, and menu as a C program.
 # They are linked as C++ code to the executable qconf
 
-__hostprogs := $(sort $(hostprogs))
-
 # C code
 # Executables compiled from a single .c file
-host-csingle   := $(foreach m,$(__hostprogs), \
+host-csingle   := $(foreach m,$(hostprogs), \
$(if $($(m)-objs)$($(m)-cxxobjs),,$(m)))
 
 # C executables linked based on several .o files
-host-cmulti:= $(foreach m,$(__hostprogs),\
+host-cmulti:= $(foreach m,$(hostprogs),\
   $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m
 
 # Object (.o) files compiled from .c files
-host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
+host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
 
 # C++ code
 # C++ executables compiled from at least one .cc file
 # and zero or more .c files
-host-cxxmulti  := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
+host-cxxmulti  := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m)))
 
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs   := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
-- 
2.25.1



linux-next: manual merge of the net-next tree with the risc-v tree

2020-07-28 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the net-next tree got a conflict in:

  lib/Kconfig

between commit:

  1a479f783857 ("lib: Add a generic version of devmem_is_allowed()")

from the risc-v tree and commit:

  b8265621f488 ("Add pldmfw library for PLDM firmware update")

from the net-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 lib/Kconfig
index 610c16ecbb7c,3ffbca6998e5..
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@@ -677,5 -677,6 +677,9 @@@ config GENERIC_LIB_CMPDI
  config GENERIC_LIB_UCMPDI2
bool
  
 +config GENERIC_LIB_DEVMEM_IS_ALLOWED
 +  bool
++
+ config PLDMFW
+   bool
+   default n


pgpZamCHwqAQ7.pgp
Description: OpenPGP digital signature


[PATCH] extract-cert: add static to local data

2020-07-28 Thread Masahiro Yamada
Fix the following warning from sparse:

  scripts/extract-cert.c:74:5: warning: symbol 'kbuild_verbose' was not 
declared. Should it be static?

Signed-off-by: Masahiro Yamada 
---

 scripts/extract-cert.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/extract-cert.c b/scripts/extract-cert.c
index b071bf476fea..3bc48c726c41 100644
--- a/scripts/extract-cert.c
+++ b/scripts/extract-cert.c
@@ -71,7 +71,7 @@ static void drain_openssl_errors(void)
 static const char *key_pass;
 static BIO *wb;
 static char *cert_dst;
-int kbuild_verbose;
+static int kbuild_verbose;
 
 static void write_cert(X509 *x509)
 {
-- 
2.25.1



[PATCH] kconfig: add 'static' to some file-local data

2020-07-28 Thread Masahiro Yamada
Fix some warnings from sparce like follows:

  warning: symbol '...' was not declared. Should it be static?

Signed-off-by: Masahiro Yamada 
---

 scripts/kconfig/lexer.l  |  2 +-
 scripts/kconfig/symbol.c | 14 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index 6354c905b006..98daac3bc829 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -36,7 +36,7 @@ struct buffer {
YY_BUFFER_STATE state;
 };
 
-struct buffer *current_buf;
+static struct buffer *current_buf;
 
 static int last_ts, first_ts;
 
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 9363e37b8870..ffa3ec65cc90 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -15,15 +15,21 @@ struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_mod = {
+};
+
+struct symbol symbol_mod = {
.name = "m",
.curr = { "m", mod },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_no = {
+};
+
+struct symbol symbol_no = {
.name = "n",
.curr = { "n", no },
.flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_empty = {
+};
+
+static struct symbol symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
@@ -31,7 +37,7 @@ struct symbol symbol_yes = {
 
 struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
-tristate modules_val;
+static tristate modules_val;
 
 enum symbol_type sym_get_type(struct symbol *sym)
 {
-- 
2.25.1



Re: [PATCH v3 2/2] soc: mediatek: add mtk-devapc driver

2020-07-28 Thread Neal Liu
On Wed, 2020-07-29 at 10:22 +0800, Chun-Kuang Hu wrote:
> Neal Liu  於 2020年7月29日 週三 上午10:10寫道:
> >
> > Hi Chun-Kuang,
> >
> > On Tue, 2020-07-28 at 23:35 +0800, Chun-Kuang Hu wrote:
> > > Hi, Neal:
> > >
> > > Neal Liu  於 2020年7月28日 週二 上午11:52寫道:
> > > >
> > > > Hi Chun-Kuang,
> > > >
> > > > On Mon, 2020-07-27 at 22:47 +0800, Chun-Kuang Hu wrote:
> > > > > Hi, Neal:
> > > > >
> > > > > Neal Liu  於 2020年7月27日 週一 上午11:06寫道:
> > > > > >
> > > > > > Hi Chun-Kuang,
> > > > > >
> > > > > > On Fri, 2020-07-24 at 23:55 +0800, Chun-Kuang Hu wrote:
> > > > > > > Hi, Neal:
> > > > > > >
> > > > > > > Neal Liu  於 2020年7月24日 週五 下午2:55寫道:
> > > > > > > >
> > > > > > > > Hi Chun-Kuang,
> > > > > > > >
> > > > > > > > On Fri, 2020-07-24 at 00:32 +0800, Chun-Kuang Hu wrote:
> > > > > > > > > Hi, Neal:
> > > > > > > > >
> > > > > > > > > Neal Liu  於 2020年7月23日 週四 下午2:11寫道:
> > > > > > > > > >
> > > > > > > > > > Hi Chun-Kuang,
> > > > > > > > > >
> > > > > > > > > > On Wed, 2020-07-22 at 22:25 +0800, Chun-Kuang Hu wrote:
> > > > > > > > > > > Hi, Neal:
> > > > > > > > > > >
> > > > > > > > > > > Neal Liu  於 2020年7月22日 週三 
> > > > > > > > > > > 上午11:49寫道:
> > > > > > > > > > > >
> > > > > > > > > > > > Hi Chun-Kuang,
> > > > > > > > > > > >
> > > > > > > > > > > > On Wed, 2020-07-22 at 07:21 +0800, Chun-Kuang Hu wrote:
> > > > > > > > > > > > > Hi, Neal:
> > > > > > > > > > > > >
> > > > > > > > > > > > > Neal Liu  於 2020年7月21日 週二 
> > > > > > > > > > > > > 下午12:00寫道:
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +/*
> > > > > > > > > > > > > > + * mtk_devapc_dump_vio_dbg - get the violation 
> > > > > > > > > > > > > > index and dump the full violation
> > > > > > > > > > > > > > + *   debug information.
> > > > > > > > > > > > > > + */
> > > > > > > > > > > > > > +static bool mtk_devapc_dump_vio_dbg(struct 
> > > > > > > > > > > > > > mtk_devapc_context *ctx, u32 vio_idx)
> > > > > > > > > > > > > > +{
> > > > > > > > > > > > > > +   u32 shift_bit;
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   if (check_vio_mask(ctx, vio_idx))
> > > > > > > > > > > > > > +   return false;
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   if (!check_vio_status(ctx, vio_idx))
> > > > > > > > > > > > > > +   return false;
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   shift_bit = get_shift_group(ctx, vio_idx);
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   if (sync_vio_dbg(ctx, shift_bit))
> > > > > > > > > > > > > > +   return false;
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   devapc_extract_vio_dbg(ctx);
> > > > > > > > > > > > >
> > > > > > > > > > > > > I think get_shift_group(), sync_vio_dbg(), and
> > > > > > > > > > > > > devapc_extract_vio_dbg() should be moved out of 
> > > > > > > > > > > > > vio_idx for-loop (the
> > > > > > > > > > > > > loop in devapc_violation_irq()) because these three 
> > > > > > > > > > > > > function is not
> > > > > > > > > > > > > related to vio_idx.
> > > > > > > > > > > > > Another question: when multiple vio_idx violation 
> > > > > > > > > > > > > occur, vio_addr is
> > > > > > > > > > > > > related to which one vio_idx? The latest happened one?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > Actually, it's related to vio_idx. But we don't use it 
> > > > > > > > > > > > directly on these
> > > > > > > > > > > > function. I think below snip code might be better way 
> > > > > > > > > > > > to understand it.
> > > > > > > > > > > >
> > > > > > > > > > > > for (...)
> > > > > > > > > > > > {
> > > > > > > > > > > > check_vio_mask()
> > > > > > > > > > > > check_vio_status()
> > > > > > > > > > > >
> > > > > > > > > > > > // if get vio_idx, mask it temporarily
> > > > > > > > > > > > mask_module_irq(true)
> > > > > > > > > > > > clear_vio_status()
> > > > > > > > > > > >
> > > > > > > > > > > > // dump violation info
> > > > > > > > > > > > get_shift_group()
> > > > > > > > > > > > sync_vio_dbg()
> > > > > > > > > > > > devapc_extract_vio_dbg()
> > > > > > > > > > > >
> > > > > > > > > > > > // unmask
> > > > > > > > > > > > mask_module_irq(false)
> > > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > This snip code does not explain any thing. I could 
> > > > > > > > > > > rewrite this code as:
> > > > > > > > > > >
> > > > > > > > > > > for (...)
> > > > > > > > > > > {
> > > > > > > > > > > check_vio_mask()
> > > > > > > > > > > check_vio_status()
> > > > > > > > > > >
> > > > > > > > > > > // if get vio_idx, mask it temporarily
> > > > > > > > > > > mask_module_irq(true)
> > > > > > > > > > > clear_vio_status()
> > > > > > > > > > > // unmask
> > > > > > > > > > > mask_module_irq(false)
> > > > > > > > > > > }
> > > > > > 

[PATCH 1/2] kbuild: move shared library build rules to scripts/gcc-plugins/Makefile

2020-07-28 Thread Masahiro Yamada
The shared library build rules are currently implemented in
scripts/Makefile.host, but actually GCC-plugin is the only user of
them. Hence, they do not need to be treewide available.

Move all the relevant build rules to scripts/gcc-plugins/Makefile.

I also optimized the build steps so *.so is directly built from .c
because every upstream plugin is compiled from a single source file.

I am still keeping the infrastructure to build a plugin from multiple
files because Kees suggested to do so in my previous attempt.
(https://lkml.org/lkml/2019/1/11/1107)

If the plugin, foo.so, is compiled from two files foo.c and foo2.c,
then you can do like follows:

  foo-objs := foo.o foo2.o

Single-file plugins do not need the *-objs notation.

Signed-off-by: Masahiro Yamada 
---

 scripts/Makefile.build   |  4 +--
 scripts/Makefile.clean   |  3 +-
 scripts/Makefile.host| 30 ++
 scripts/gcc-plugins/Makefile | 61 +---
 4 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 2e8810b7e5ed..d41c1cd453b9 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -45,8 +45,8 @@ include $(kbuild-file)
 
 include scripts/Makefile.lib
 
-# Do not include host rules unless needed
-ifneq ($(hostprogs)$(hostcxxlibs-y)$(hostcxxlibs-m),)
+# Do not include hostprogs rules unless needed
+ifneq ($(hostprogs),)
 include scripts/Makefile.host
 endif
 
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index e2c76122319d..3cdf31218198 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -29,8 +29,7 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
 
 __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
   $(always) $(always-y) $(always-m) $(always-) $(targets) 
$(clean-files)   \
-  $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) 
$(userprogs) \
-  $(hostcxxlibs-y) $(hostcxxlibs-m)
+  $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) 
$(userprogs)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index c8a4a033dc3e..687ca3f309e9 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -39,7 +39,6 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
 # They are linked as C++ code to the executable qconf
 
 __hostprogs := $(sort $(hostprogs))
-host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
 
 # C code
 # Executables compiled from a single .c file
@@ -61,16 +60,11 @@ host-cxxmulti   := $(foreach m,$(__hostprogs),$(if 
$($(m)-cxxobjs),$(m)))
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs   := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
 
-# Object (.o) files used by the shared libaries
-host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs
-
 host-csingle   := $(addprefix $(obj)/,$(host-csingle))
 host-cmulti:= $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti  := $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs   := $(addprefix $(obj)/,$(host-cxxobjs))
-host-cxxshlib  := $(addprefix $(obj)/,$(host-cxxshlib))
-host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
 
 #
 # Handle options to gcc. Support building with separate output directory
@@ -136,25 +130,5 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
 $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
 
-# Compile .c file, create position independent .o file
-# Note that plugin capable gcc versions can be either C or C++ based
-# therefore plugin source files have to be compilable in both C and C++ mode.
-# This is why a C++ compiler is invoked on a .c file.
-# host-cxxshobjs -> .o
-quiet_cmd_host-cxxshobjs   = HOSTCXX -fPIC $@
-  cmd_host-cxxshobjs   = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
-$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
-   $(call if_changed_dep,host-cxxshobjs)
-
-# Link a shared library, based on position independent .o files
-# *.o -> .so shared library (host-cxxshlib)
-quiet_cmd_host-cxxshlib= HOSTLLD -shared $@
-  cmd_host-cxxshlib= $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o 
$@ \
- $(addprefix $(obj)/, $($(target-stem)-objs)) \
- $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so)
-$(host-cxxshlib): FORCE
-   $(call if_changed,host-cxxshlib)
-$(call multi_depend, $(host-cxxshlib), .so, -objs)
-
-targets += $(host-csingle)  $(host-cmulti) $(host-cobjs)\
-  $(host-cxxmulti) $(host-cxxobjs) $(host-cxxshlib) $(host-cxxshobjs)
+targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
+  $(host-cxxmulti) $(host-cxxobjs)
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 4014ba7e2fbd..d66949bfeba4 100644
--- 

Re: [PATCH] i2c: mv64xxx: Add bus error recovery

2020-07-28 Thread Chris Packham
Hi Mark,

On 8/07/20 9:10 am, Mark Tomlinson wrote:
> This adds i2c bus recovery to the mv64xxx driver.
>
> Implement bus recovery to recover from SCL/SDA stuck low.
>
> This uses the generic recovery function, setting the clock/data lines as
> GPIO pins, and sending 9 clocks to try and recover the bus.
>
> Signed-off-by: Mark Tomlinson 

Reviewed-by: Chris Packham 

One additional comment below

> ---
>   drivers/i2c/busses/i2c-mv64xxx.c | 77 +++-
>   1 file changed, 76 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c 
> b/drivers/i2c/busses/i2c-mv64xxx.c
> index 829b8c98ae51..e58853ba3ef0 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -21,6 +21,7 @@
>   #include 
>   #include 
>   #include 
> +#include 
>   #include 
>   #include 
>   #include 
> @@ -147,6 +148,10 @@ struct mv64xxx_i2c_data {
>   boolirq_clear_inverted;
>   /* Clk div is 2 to the power n, not 2 to the power n + 1 */
>   boolclk_n_base_0;
> + struct pinctrl  *pinctrl;
> + struct i2c_bus_recovery_inforinfo;
> + struct pinctrl_state*pin_default_state;
> + struct pinctrl_state*pin_gpio_state;
>   };
>   
>   static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
> @@ -325,7 +330,8 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 
> status)
>drv_data->msg->flags);
>   drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
>   mv64xxx_i2c_hw_init(drv_data);
> - drv_data->rc = -EIO;
> + i2c_recover_bus(_data->adapter);
> + drv_data->rc = -EAGAIN;
>   }
>   }
>   
> @@ -563,6 +569,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data 
> *drv_data)
>   "time_left: %d\n", drv_data->block,
>   (int)time_left);
>   mv64xxx_i2c_hw_init(drv_data);
> + i2c_recover_bus(_data->adapter);
>   }
>   } else
>   spin_unlock_irqrestore(_data->lock, flags);
> @@ -872,6 +879,69 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
>   }
>   #endif /* CONFIG_OF */
>   
> +/*
> + * Switch to bit bang mode to prepare for i2c generic recovery.
> + */
> +static void mv64xxx_i2c_prepare_recovery(struct i2c_adapter *adap)
> +{
> + struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
> +
> + pinctrl_select_state(drv_data->pinctrl, drv_data->pin_gpio_state);
> +}
> +
> +/*
> + * Return to normal i2c operation following recovery.
> + */
> +static void mv64xxx_i2c_unprepare_recovery(struct i2c_adapter *adap)
> +{
> + struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
> +
> + pinctrl_select_state(drv_data->pinctrl, drv_data->pin_default_state);
> +}
> +
> +static int mv64xxx_i2c_init_recovery_info(struct mv64xxx_i2c_data *drv_data,
> +   struct platform_device *pd)
> +{
> + struct i2c_bus_recovery_info *rinfo = _data->rinfo;
> + struct device *dev = >dev;
> +
> + drv_data->pinctrl = devm_pinctrl_get(dev);
> + if (!drv_data->pinctrl || IS_ERR(drv_data->pinctrl)) {
> + dev_err(dev, "can't get pinctrl, bus recovery not supported\n");
> + return PTR_ERR(drv_data->pinctrl);
> + }
> +
> + drv_data->pin_default_state = pinctrl_lookup_state(drv_data->pinctrl,
> + PINCTRL_STATE_DEFAULT);
> + drv_data->pin_gpio_state = pinctrl_lookup_state(drv_data->pinctrl,
> + "gpio");
> + rinfo->scl_gpiod = devm_gpiod_get(dev, "scl",
> +   GPIOD_OUT_HIGH_OPEN_DRAIN);
> + rinfo->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_IN);

Should these be mentioned in 
Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml?

> + if (PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER ||
> + PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> +
> + if (IS_ERR(rinfo->sda_gpiod) ||
> + IS_ERR(rinfo->scl_gpiod) ||
> + IS_ERR(drv_data->pin_default_state) ||
> + IS_ERR(drv_data->pin_gpio_state)) {
> + dev_dbg(dev, "recovery information incomplete\n");
> + return 0;
> + }
> +
> + dev_dbg(dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
> + rinfo->scl_gpiod ? desc_to_gpio(rinfo->scl_gpiod) : -1,
> + rinfo->sda_gpiod ? desc_to_gpio(rinfo->sda_gpiod) : -1);
> +
> + rinfo->prepare_recovery = mv64xxx_i2c_prepare_recovery;
> + rinfo->unprepare_recovery = mv64xxx_i2c_unprepare_recovery;
> + rinfo->recover_bus = i2c_generic_scl_recovery;
> + drv_data->adapter.bus_recovery_info = rinfo;
> +
> + return 0;
> +}
> +
>   static int
>   mv64xxx_i2c_probe(struct platform_device *pd)
>   {
> @@ -939,6 +1009,10 @@ mv64xxx_i2c_probe(struct platform_device *pd)
>   
> 

[PATCH] net: nixge: fix potential memory leak in nixge_probe()

2020-07-28 Thread Lu Wei
If some processes in nixge_probe() fail, free_netdev(dev)
needs to be called to aviod a memory leak.

Fixes: 87ab207981ec ("net: nixge: Separate ctrl and dma resources")
Fixes: abcd3d6fc640 ("net: nixge: Fix error path for obtaining mac address")
Reported-by: Hulk Robot 
Signed-off-by: Lu Wei 
---
 drivers/net/ethernet/ni/nixge.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index d2708a57f2ff..4075f5e59955 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -1299,19 +1299,21 @@ static int nixge_probe(struct platform_device *pdev)
netif_napi_add(ndev, >napi, nixge_poll, NAPI_POLL_WEIGHT);
err = nixge_of_get_resources(pdev);
if (err)
-   return err;
+   goto free_netdev;
__nixge_hw_set_mac_address(ndev);
 
priv->tx_irq = platform_get_irq_byname(pdev, "tx");
if (priv->tx_irq < 0) {
netdev_err(ndev, "could not find 'tx' irq");
-   return priv->tx_irq;
+   err = priv->tx_irq;
+   goto free_netdev;
}
 
priv->rx_irq = platform_get_irq_byname(pdev, "rx");
if (priv->rx_irq < 0) {
netdev_err(ndev, "could not find 'rx' irq");
-   return priv->rx_irq;
+   err = priv->rx_irq;
+   goto free_netdev;
}
 
priv->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
-- 
2.17.1



Re: [PATCH RFC] x86/bus_lock: Enable bus lock detection

2020-07-28 Thread Sean Christopherson
On Fri, Jul 17, 2020 at 02:35:00PM -0700, Fenghua Yu wrote:
> A bus lock [1] is acquired either through split locked access to writeback 
> (WB)
> memory or by using locks to uncacheable (UC) memory (e.g. direct device

Does SLD not detect the lock to UC memory?

> assignment). This is typically >1000 cycles slower than an atomic operation
> within a cache line. It also disrupts performance on other cores.
> 
> Although split lock can be detected by #AC trap, the trap is triggered
> before the instruction acquires bus lock. This makes it difficult to
> mitigate bus lock (e.g. throttle the user application).

Mitigate _in a non-fatal way_.  The #AC makes it very easy to mitigate split
locks, it just has the side effect of SIGBUGS or killing the KVM guest.

> Some CPUs have ability to notify the kernel by an #DB trap after the
> instruction acquires a bus lock and is executed. This allows the kernel
> to enforce user application throttling or mitigations and also provides
> a better environment to debug kernel split lock issues since the kernel
> can continue instead of crashing.
> 
> #DB for bus lock detect fixes all issues in #AC for split lock detect:

Fixes "all" issues... and creates some new ones, e.g. there are use cases
where preventing the split lock from happening in the first place is
strongly desired.  It's why that train wreck exists.

> 1) It's architectural ... just need to look at one CPUID bit to know it
>exists
> 2) The IA32_DEBUGCTL MSR, which reports bus lock in #DB, is per-thread.
>So each process or guest can have different behavior.
> 3) It has support for VMM/guests (new VMEXIT codes, etc).
> 
> Use the existing kernel command line option "split_lock_detect=" to handle
> #DB for bus lock:

Are SLD and BLD mutually exclusive?  Can we even guarantee that given the
track record of SLD?  If not, we'll likely want to allow the user to choose
between SDL and BLD via split_lock_detect.

> split_lock_detect=
>   #AC for split lock  #DB for bus lock
> 
> off   Do nothing  Do nothing
> 
> warn  Kernel OOPs Kernel warns rate limited
>   Warn once per task and  and continues to run.
>   disable future checking Warn once per task and
>   and continue to run.
>   When both features are
>   supported, warn in #DB
> 
> fatal Kernel OOPs Kernel warn rate limited

Unless the lock to UC #DB is new behavior, why would we revert to allowing
split locks in the kernel?

>   Send SIGBUS to user Send SIGBUS to user
>   When both features are
>   supported, fatal in #AC.
> 
> ratelimit:N   Do nothing  Kernel warns rate limited

This should be more than "Do nothing" for #AC, e.g. fall back to warn or
at least print a loud error.

>   and continue to run.
>   Limit bus lock rate to
>   N per second in the
>   current non root user.
> 
> On systems that support #DB for bus lock detection the default is "warn".
> 
> [1] Chapter 8 
> https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
> 
> Signed-off-by: Fenghua Yu 
> Reviewed-by: Tony Luck 
> ---
>  .../admin-guide/kernel-parameters.txt |  48 +-
>  arch/x86/include/asm/cpu.h|  16 +-
>  arch/x86/include/asm/cpufeatures.h|   1 +
>  arch/x86/include/asm/msr-index.h  |   1 +
>  arch/x86/include/uapi/asm/debugreg.h  |   3 +-
>  arch/x86/kernel/cpu/common.c  |   2 +-
>  arch/x86/kernel/cpu/intel.c   | 156 +++---
>  arch/x86/kernel/traps.c   |  10 ++
>  include/linux/sched/user.h|   4 +-
>  kernel/user.c |   7 +
>  10 files changed, 214 insertions(+), 34 deletions(-)

Maybe it's just me, but it'd be nice to break this into multiple patches
so that the SLD refactoring is separate from the introduction of BLD.  As
is, I find it hard to review as I can't easily distinguish refactoring from
new functionality.

> diff --git a/Documentation/admin-guide/kernel-parameters.txt 
> b/Documentation/admin-guide/kernel-parameters.txt
> index fb95fad81c79..7a1cb6fe8b8e 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -4816,27 +4816,59 @@
>   spia_peddr=
>  
>   split_lock_detect=
> - [X86] Enable split lock detection
> + [X86] Enable split lock detection or bus lock detection
>  
>

[PATCH] net: ethernet: fix potential memory leak in gemini_ethernet_port_probe()

2020-07-28 Thread Lu Wei
If some processes in gemini_ethernet_port_probe() fail,
free_netdev(dev) needs to be called to avoid a memory leak.

Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Reported-by: Hulk Robot 
Signed-off-by: Lu Wei 
---
 drivers/net/ethernet/cortina/gemini.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c 
b/drivers/net/ethernet/cortina/gemini.c
index 8d13ea370db1..5e93a1a570b6 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2407,37 +2407,48 @@ static int gemini_ethernet_port_probe(struct 
platform_device *pdev)
dmares = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!dmares) {
dev_err(dev, "no DMA resource\n");
+   free_netdev(netdev);
return -ENODEV;
}
port->dma_base = devm_ioremap_resource(dev, dmares);
-   if (IS_ERR(port->dma_base))
+   if (IS_ERR(port->dma_base)) {
+   free_netdev(netdev);
return PTR_ERR(port->dma_base);
+   }
 
/* GMAC config memory */
gmacres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!gmacres) {
dev_err(dev, "no GMAC resource\n");
+   free_netdev(netdev);
return -ENODEV;
}
port->gmac_base = devm_ioremap_resource(dev, gmacres);
-   if (IS_ERR(port->gmac_base))
+   if (IS_ERR(port->gmac_base)) {
+   free_netdev(netdev);
return PTR_ERR(port->gmac_base);
+   }
 
/* Interrupt */
irq = platform_get_irq(pdev, 0);
-   if (irq <= 0)
+   if (irq <= 0) {
+   free_netdev(netdev);
return irq ? irq : -ENODEV;
+   }
port->irq = irq;
 
/* Clock the port */
port->pclk = devm_clk_get(dev, "PCLK");
if (IS_ERR(port->pclk)) {
dev_err(dev, "no PCLK\n");
+   free_netdev(netdev);
return PTR_ERR(port->pclk);
}
ret = clk_prepare_enable(port->pclk);
-   if (ret)
+   if (ret) {
+   free_netdev(netdev);
return ret;
+   }
 
/* Maybe there is a nice ethernet address we should use */
gemini_port_save_mac_addr(port);
@@ -2446,6 +2457,7 @@ static int gemini_ethernet_port_probe(struct 
platform_device *pdev)
port->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(port->reset)) {
dev_err(dev, "no reset\n");
+   free_netdev(netdev);
return PTR_ERR(port->reset);
}
reset_control_reset(port->reset);
@@ -2501,8 +2513,10 @@ static int gemini_ethernet_port_probe(struct 
platform_device *pdev)
IRQF_SHARED,
port_names[port->id],
port);
-   if (ret)
+   if (ret) {
+   free_netdev(netdev);
return ret;
+   }
 
ret = register_netdev(netdev);
if (!ret) {
-- 
2.17.1



Re: [PATCH 0/9] arm64: Stolen time support

2020-07-28 Thread zhukeqian
Hi Steven,

On 2020/7/27 18:48, Steven Price wrote:
> On 21/07/2020 04:26, zhukeqian wrote:
>> Hi Steven,
> 
> Hi Keqian,
> 
>> On 2019/8/2 22:50, Steven Price wrote:
>>> This series add support for paravirtualized time for arm64 guests and
>>> KVM hosts following the specification in Arm's document DEN 0057A:
>>>
>>> https://developer.arm.com/docs/den0057/a
>>>
>>> It implements support for stolen time, allowing the guest to
>>> identify time when it is forcibly not executing.
>>>
>>> It doesn't implement support for Live Physical Time (LPT) as there are
>>> some concerns about the overheads and approach in the above
>> Do you plan to pick up LPT support? As there is demand of cross-frequency 
>> migration
>> (from older platform to newer platform).
> 
> I don't have any plans to pick up the LPT support at the moment - feel free 
> to pick it up! ;)
> 
>> I am not clear about the overheads and approach problem here, could you 
>> please
>> give some detail information? Maybe we can work together to solve these 
>> concerns. :-)
> 
> Fundamentally the issue here is that LPT only solves one small part of 
> migration between different hosts. To successfully migrate between hosts with 
> different CPU implementations it is also necessary to be able to virtualise 
> various ID registers (e.g. MIDR_EL1, REVIDR_EL1, AIDR_EL1) which we have no 
> support for currently.
> 
Yeah, currently we are trying to do both timer freq virtualization and CPU 
feature virtualization.

> The problem with just virtualising the registers is how you handle errata. 
> The guest will currently use those (and other) ID registers to decide whether 
> to enable specific errata workarounds. But what errata should be enabled for 
> a guest which might migrate to another host?
> 
Thanks for pointing this out.

I think the most important thing is that we should introduce a concept named 
CPU baseline which represents a standard platform.
If we bring up a guest with a specific CPU baseline, then this guest can only 
run on a platform that is compatible with this CPU baseline.
So "baseline" and "compatible" are the key point to promise successful 
cross-platform migration.


> What we ideally need is a mechanism to communicate to the guest what 
> workarounds are required to successfully run on any of the hosts that the 
> guest may be migrated to. You may also have the situation where the 
> workarounds required for two hosts are mutually incompatible - something 
> needs to understand this and do the "right thing" (most likely just reject 
> this situation, i.e. prevent the migration).
> 
> There are various options here: e.g. a para-virtualised interface to describe 
> the workarounds (but this is hard to do in an OS-agnostic way), or virtual-ID 
> registers describing an idealised environment where no workarounds are 
> required (and only hosts that have no errata affecting a guest would be able 
> to provide this).
> 
My idea is similar with the "idealised environment", but errata workaround 
still exists.
We do not provide para-virtualised interface, and migration is restricted 
between platforms that are compatible with baseline.

Baseline should has two aspects: CPU feature and errata. These platforms that 
are compatible with a specific baseline should have the corresponding CPU 
feature and errata.

> Given the above complexity and the fact that Armv8.6-A standardises the 
> frequency to 1GHz this didn't seem worth continuing with. So LPT was dropped 
> from the spec and patches to avoid holding up the stolen time support.
> 
> However, if you have a use case which doesn't require such a generic 
> migration (e.g. perhaps old and new platforms are based on the same IP) then 
> it might be worth looking at bring this back. But to make the problem 
> solvable it either needs to be restricted to platforms which are 
> substantially the same (so the errata list will be identical), or there's 
> work to be done in preparation to deal with migrating a guest successfully 
> between hosts with potentially different errata requirements.
> 
> Can you share more details about the hosts that you are interested in 
> migrating between?
Here we have new platform with 1GHz timer, and old platform is 100MHZ, so we 
want to solve the cross-platform migration firstly.

Thanks,
Keqian
> 
> Thanks,
> 
> Steve
> .
> 


Re: [PATCH] kunit: tool: adjust parse regex

2020-07-28 Thread David Gow
On Wed, Jul 29, 2020 at 10:42 AM Marcelo Schmitt
 wrote:
>
> kunit config subcommand terminates with error if .config has a
> configuration assigned with a string, for instance:
>
> CONFIG_CC_VERSION_TEXT="gcc (distro package version) ..."
>
> This patch adjusts the parse regex to consider such string assignments.
>
> Signed-off-by: Marcelo Schmitt 
> ---

Thanks, Marcelo.

I think we've actually already got a fix for this upstream:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3f37d14b8a3152441f36b6bc74000996679f0998

Cheers,
-- David


Re: [PATCH V2] dt-bindings: pci: convert QCOM pci bindings to YAML

2020-07-28 Thread Sivaprakash Murugesan

Hi Rob,

On 7/28/2020 9:24 PM, Rob Herring wrote:

On Tue, Jul 28, 2020 at 9:27 AM Rob Herring  wrote:

On Sun, Jul 26, 2020 at 9:07 AM Sivaprakash Murugesan
 wrote:

From: Sivaprakash Murugesan 

Convert QCOM pci bindings to YAML schema

Signed-off-by: Sivaprakash Murugesan 
---
[v2]
   - Referenced pci-bus.yaml
   - removed duplicate properties already referenced by pci-bus.yaml
   - Addressed comments from Rob
  .../devicetree/bindings/pci/qcom,pcie.txt  | 330 ---
  .../devicetree/bindings/pci/qcom,pcie.yaml | 447 +
  2 files changed, 447 insertions(+), 330 deletions(-)
  delete mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.txt
  create mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.yaml



diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml 
b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
new file mode 100644
index ..ddb84f49ac1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
@@ -0,0 +1,447 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/pci/qcom,pcie.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Qualcomm PCI express root complex
+
+maintainers:
+  - Sivaprakash Murugesan 
+
+description:
+  QCOM PCIe controller uses Designware IP with Qualcomm specific hardware
+  wrappers.
+
+properties:
+  compatible:
+enum:
+  - qcom,pcie-apq8064
+  - qcom,pcie-apq8084
+  - qcom,pcie-ipq4019
+  - qcom,pcie-ipq8064
+  - qcom,pcie-ipq8074
+  - qcom,pcie-msm8996
+  - qcom,pcie-qcs404
+  - qcom,pcie-sdm845
+
+  reg:
+description: Register ranges as listed in the reg-names property

Can drop this.


+maxItems: 4
+
+  reg-names:
+items:
+  - const: dbi
+  - const: elbi
+  - const: parf
+  - const: config
+
+  ranges:
+maxItems: 2
+
+  interrupts:
+items:
+  - description: MSI interrupts
+
+  interrupt-names:
+const: msi
+
+  "#interrupt-cells":

In pci-bus.yaml, so you can drop.


I am getting the below error if I remove #interrupt-cells alone.

properties: '#interrupt-cells' is a dependency of 'interrupt-map'

interrupt-map is also documented in pci-bus.yaml hence dropping that as 
well.





PROBLEM: IO lockup on reiserfs FS.

2020-07-28 Thread David Niklas
Hello,

When running rtorrent (in sync to file mode), my kernel eventually will
not write to the disk causing all access to md7 to hang and eventually the
kernel will become totally unresponsive.

EDIT: I have since gotten a response in the bug tracker and I am filing
thins to the reiserfs maintainers.

 (I'd find the file and report to the
correct maintainer, but the docs are incomplete when it comes to
discovering the source of the hung tasks in my case. I have filed bugs to
correct this.) 
I still have no clue how to get gdb to print out where exactly this is
happening. It can't find the __schedule function in the kernel or in the
reiserfs.ko object file. I'm not even sure __schedule is the problem as
it seems to be lock related which would point to __mutex_lock.isra.

EDIT: I've managed to verify that all disks are accessible (smartctl
-a /dev/sdX) and that the RAID array is working and accessible (mdadm
--detail and echo-ing check/idle to the array and seeing progress).

Keywords: Hung tasks, Lockup, reiserfs, RAID.

Linux version 4.14.184-nopreempt-AMDGPU-dav9 (root@Phenom-II-x6) (gcc
version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)) #1 SMP Fri Jun 19
17:02:34 UTC 2020

I didn't have Internet before 4.9.X so I can't say if any version of the
Linux kernel didn't have this problem.

[68812.480459]   Not tainted 4.14.184-nopreempt-AMDGPU-dav9 #1
[68812.480464] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message. [68812.480469] CacheThread_Blo D0  9414   9082
0x0080 [68812.480476] Call Trace:
[68812.480494]  __schedule+0x29e/0x6c0
[68812.480505]  schedule+0x32/0x80
[68812.480513]  schedule_preempt_disabled+0xa/0x10
[68812.480520]  __mutex_lock.isra.1+0x26b/0x4e0
[68812.480550]  ? do_journal_begin_r+0xbe/0x390 [reiserfs]
[68812.480570]  do_journal_begin_r+0xbe/0x390 [reiserfs]
[68812.480586]  ? __switch_to_asm+0x35/0x70
[68812.480588]  ? __switch_to_asm+0x41/0x70
[68812.480590]  ? __switch_to_asm+0x35/0x70
[68812.480592]  ? __switch_to_asm+0x41/0x70
[68812.480593]  ? __switch_to_asm+0x35/0x70
[68812.480595]  ? __switch_to_asm+0x41/0x70
[68812.480597]  ? __switch_to_asm+0x35/0x70
[68812.480601]  journal_begin+0x80/0x140 [reiserfs]
[68812.480606]  reiserfs_dirty_inode+0x3d/0xa0 [reiserfs]
[68812.480609]  ? __switch_to+0x1ee/0x3f0
[68812.480610]  ? __switch_to+0x1ee/0x3f0
[68812.480612]  __mark_inode_dirty+0x163/0x350
[68812.480615]  generic_update_time+0x79/0xc0
[68812.480617]  ? current_time+0x38/0x70
[68812.480619]  file_update_time+0xbe/0x110
[68812.480622]  __generic_file_write_iter+0x99/0x1b0
[68812.480624]  generic_file_write_iter+0xe2/0x1c0
[68812.480626]  __vfs_write+0x102/0x180
[68812.480628]  vfs_write+0xb0/0x190
[68812.480630]  SyS_pwrite64+0x90/0xb0
[68812.480632]  do_syscall_64+0x6e/0x110
[68812.480634]  entry_SYSCALL_64_after_hwframe+0x41/0xa6
[68812.480637] RIP: 0033:0x7f8a92976983
[68812.480638] RSP: 002b:7f8a779e1630 EFLAGS: 0293 ORIG_RAX:
0012 [68812.480640] RAX: ffda RBX:
7f8a779e1640 RCX: 7f8a92976983 [68812.480641] RDX:
0128 RSI: 01790ddf3c00 RDI: 0040
[68812.480642] RBP: 7f8a779e16f0 R08: 7f8a779e1558 R09:
0001 [68812.480643] R10: 2000 R11:
0293 R12: 2000 [68812.480644] R13:
01790a6b8dd0 R14: 01790ddf3c00 R15: 0128
[68812.480647] INFO: task ThreadPoolSingl:9908 blocked for more than 480
seconds. [68812.480648]   Not tainted 4.14.184-nopreempt-AMDGPU-dav9
#1 [68812.480649] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message. [68812.480650] ThreadPoolSingl D0  9908   9082
0x0080 [68812.480651] Call Trace: [68812.480653]
__schedule+0x29e/0x6c0 [68812.480655]  schedule+0x32/0x80 [68812.480657]
schedule_preempt_disabled+0xa/0x10 [68812.480658]
__mutex_lock.isra.1+0x26b/0x4e0 [68812.480664]  ?
do_journal_begin_r+0xbe/0x390 [reiserfs] [68812.480668]
do_journal_begin_r+0xbe/0x390 [reiserfs] [68812.480672]  ?
reiserfs_lookup+0xb5/0x160 [reiserfs] [68812.480677]
journal_begin+0x80/0x140 [reiserfs] [68812.480681]
reiserfs_create+0xfc/0x210 [reiserfs] [68812.480685]
path_openat+0x1419/0x14d0 [68812.480687]  ? futex_wake+0x91/0x170
[68812.480689]  do_filp_open+0x99/0x110
[68812.480693]  ? __check_object_size+0xfa/0x1a0
[68812.480695]  ? __alloc_fd+0x3d/0x160
[68812.480696]  ? do_sys_open+0x12e/0x210
[68812.480698]  do_sys_open+0x12e/0x210
[68812.480700]  do_syscall_64+0x6e/0x110
[68812.480702]  entry_SYSCALL_64_after_hwframe+0x41/0xa6
[68812.480703] RIP: 0033:0x7f8a8c48770d
[68812.480704] RSP: 002b:7f8a73eeb220 EFLAGS: 0293 ORIG_RAX:
0002 [68812.480706] RAX: ffda RBX:
 RCX: 7f8a8c48770d [68812.480707] RDX:
0180 RSI: 00c2 RDI: 0179286b1ae0
[68812.480708] RBP: 0003a2f8 R08: c0c1 R09:
01792b1b04e0 [68812.480709] R10:  R11:
0293 R12: 0179286b1b1a [68812.480710] 

Re: PROBLEM: IO lockup on reiserfs FS.

2020-07-28 Thread David Niklas
I should add that in chasing down this bug I have tried all the IO
schedulers available (noop deadline and cfq). Cfq is the one I'm now
using to reproduce this.

Also, I don't know if it makes a difference, but when the system first
starts up it takes 20m to get from the login manager to having my web
browsers restart and get all their pages from online. It might be because
there is a lot of IO going on or it might be that there are several
stalls in the scheduling; just not bad enough to cause a hung task
problem like above.


[PATCH] kunit: tool: adjust parse regex

2020-07-28 Thread Marcelo Schmitt
kunit config subcommand terminates with error if .config has a
configuration assigned with a string, for instance:

CONFIG_CC_VERSION_TEXT="gcc (distro package version) ..."

This patch adjusts the parse regex to consider such string assignments.

Signed-off-by: Marcelo Schmitt 
---
 tools/testing/kunit/kunit_config.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/kunit/kunit_config.py 
b/tools/testing/kunit/kunit_config.py
index e75063d603b5..8e55693fe812 100644
--- a/tools/testing/kunit/kunit_config.py
+++ b/tools/testing/kunit/kunit_config.py
@@ -10,7 +10,7 @@ import collections
 import re
 
 CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$'
-CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+)$'
+CONFIG_PATTERN = r'^CONFIG_(\w+)=((\S+)|(".*"))$'
 
 KconfigEntryBase = collections.namedtuple('KconfigEntry', ['name', 'value'])
 
-- 
2.27.0



Re: [PATCH] block: fix possible race on blk_get_queue()

2020-07-28 Thread Bart Van Assche
On 2020-07-28 18:51, Luis Chamberlain wrote:
> diff --git a/block/blk-core.c b/block/blk-core.c
> index d9d632639bd1..febdd8e8d409 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -605,12 +605,18 @@ EXPORT_SYMBOL(blk_alloc_queue);
>   */
>  bool blk_get_queue(struct request_queue *q)
>  {
> - if (likely(!blk_queue_dying(q))) {
> - __blk_get_queue(q);
> - return true;
> + struct kobject *obj;
> +
> + obj = __blk_get_queue(q);
> + if (!obj)
> + return false;
> +
> + if (unlikely(blk_queue_dying(q))) {
> + blk_put_queue(q);
> + return false;
>   }
>  
> - return false;
> + return true;
>  }

This change is not sufficient to prevent that the QUEUE_FLAG_DYING flag
is set immediately after this function returns. I propose not to modify
this function but instead to add a comment that is the responsibility of
the caller to prevent that such a race condition occurs.

> -static inline void __blk_get_queue(struct request_queue *q)
> +static inline struct kobject * __must_check
> +__blk_get_queue(struct request_queue *q)
>  {
> - kobject_get(>kobj);
> + return kobject_get_unless_zero(>kobj);
>  }

If a function passes a queue pointer to another function that calls
blk_get_queue() then the caller should guarantee that 'q' is valid
during the entire duration of the call. In other words, I'm not sure the
above change is an improvement.

Thanks,

Bart.


[PATCH v2] scsi: ufs: Fix possible infinite loop in ufshcd_hold

2020-07-28 Thread Stanley Chu
In ufshcd_suspend(), after clk-gating is suspended and link is set
as Hibern8 state, ufshcd_hold() is still possibly invoked before
ufshcd_suspend() returns. For example, MediaTek's suspend vops may
issue UIC commands which would call ufshcd_hold() during the command
issuing flow.

Now if UFSHCD_CAP_HIBERN8_WITH_CLK_GATING capability is enabled,
then ufshcd_hold() may enter infinite loops because there is no
clk-ungating work scheduled or pending. In this case, ufshcd_hold()
shall just bypass, and keep the link as Hibern8 state.

Signed-off-by: Stanley Chu 
Signed-off-by: Andy Teng 

---

Changes since v1:
- Fix return value: Use unique bool variable to get the result of flush_work(). 
Thcan prevent incorrect returned value, i.e., rc, if flush_work() returns true
- Fix commit message

---
 drivers/scsi/ufs/ufshcd.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 577cc0d7487f..acba2271c5d3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1561,6 +1561,7 @@ static void ufshcd_ungate_work(struct work_struct *work)
 int ufshcd_hold(struct ufs_hba *hba, bool async)
 {
int rc = 0;
+   bool flush_result;
unsigned long flags;
 
if (!ufshcd_is_clkgating_allowed(hba))
@@ -1592,7 +1593,9 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
break;
}
spin_unlock_irqrestore(hba->host->host_lock, flags);
-   flush_work(>clk_gating.ungate_work);
+   flush_result = flush_work(>clk_gating.ungate_work);
+   if (hba->clk_gating.is_suspended && !flush_result)
+   goto out;
spin_lock_irqsave(hba->host->host_lock, flags);
goto start;
}
-- 
2.18.0


Re: WARNING: suspicious RCU usage - while installing a VM on a CPU listed under nohz_full

2020-07-28 Thread Wanpeng Li
Hi Nitesh,
On Wed, 29 Jul 2020 at 09:00, Wanpeng Li  wrote:
>
> On Tue, 28 Jul 2020 at 22:40, Nitesh Narayan Lal  wrote:
> >
> > Hi,
> >
> > I have recently come across an RCU trace with the 5.8-rc7 kernel that has 
> > the
> > debug configs enabled while installing a VM on a CPU that is listed under
> > nohz_full.
> >
> > Based on some of the initial debugging, my impression is that the issue is
> > triggered because of the fastpath that is meant to optimize the writes to 
> > x2APIC
> > ICR that eventually leads to a virtual IPI in fixed delivery mode, is 
> > getting
> > invoked from the quiescent state.

Could you try latest linux-next tree? I guess maybe some patches are
pending in linux-next tree, I can't reproduce against linux-next tree.


Re: [PATCH v2 05/18] gpiolib: cdev: support GPIO_GET_LINE_IOCTL and GPIOLINE_GET_VALUES_IOCTL

2020-07-28 Thread Kent Gibson
On Sun, Jul 26, 2020 at 09:12:44AM +0800, Kent Gibson wrote:
> On Sat, Jul 25, 2020 at 11:51:54PM +0300, Andy Shevchenko wrote:
> > On Sat, Jul 25, 2020 at 7:24 AM Kent Gibson  wrote:
> > >

[ snip ]

> > > +   test_bit(line_idx, (unsigned long 
> > > *)lc->attrs[i].mask))
> > 
> > This casting is not good. What about BE 32-bit architecture?
> > 
> 
> I agree the casting is hideous, but I thought the outcome was correct
> as it is manipulating addresses, not data.
> You think the address of a 64-bit differs based on endian??
> Happy to change it - but not sure what to.
> 

You are right - using bitops on u64 is problematic for BE-32 - the 32-bit
words will be swapped if userspace treats the flags as the u64 it is
defined as.

I'll rework that for v3.

Cheers,
Kent.



Re: [PATCH v17 17/21] mm/lru: replace pgdat lru_lock with lruvec lock

2020-07-28 Thread Alex Shi



在 2020/7/29 上午9:27, Alexander Duyck 写道:
> On Tue, Jul 28, 2020 at 6:00 PM Alex Shi  wrote:
>>
>>
>>
>> 在 2020/7/28 下午10:54, Alexander Duyck 写道:
>>> On Tue, Jul 28, 2020 at 4:20 AM Alex Shi  wrote:



 在 2020/7/28 上午7:34, Alexander Duyck 写道:
>> @@ -1876,6 +1876,12 @@ static unsigned noinline_for_stack 
>> move_pages_to_lru(struct lruvec *lruvec,
>>  *
>> list_add(>lru,)
>>  * list_add(>lru,) //corrupt
>>  */
>> +   new_lruvec = mem_cgroup_page_lruvec(page, 
>> page_pgdat(page));
>> +   if (new_lruvec != lruvec) {
>> +   if (lruvec)
>> +   spin_unlock_irq(>lru_lock);
>> +   lruvec = lock_page_lruvec_irq(page);
>> +   }
>> SetPageLRU(page);
>>
>> if (unlikely(put_page_testzero(page))) {
> I was going through the code of the entire patch set and I noticed
> these changes in move_pages_to_lru. What is the reason for adding the
> new_lruvec logic? My understanding is that we are moving the pages to
> the lruvec provided are we not?If so why do we need to add code to get
> a new lruvec? The code itself seems to stand out from the rest of the
> patch as it is introducing new code instead of replacing existing
> locking code, and it doesn't match up with the description of what
> this function is supposed to do since it changes the lruvec.

 this new_lruvec is the replacement of removed line, as following code:
>> -   lruvec = mem_cgroup_page_lruvec(page, pgdat);
 This recheck is for the page move the root memcg, otherwise it cause the 
 bug:
>>>
>>> Okay, now I see where the issue is. You moved this code so now it has
>>> a different effect than it did before. You are relocking things before
>>> you needed to. Don't forget that when you came into this function you
>>> already had the lock. In addition the patch is broken as it currently
>>> stands as you aren't using similar logic in the code just above this
>>> addition if you encounter an evictable page. As a result this is
>>> really difficult to review as there are subtle bugs here.
>>
>> Why you think its a bug? the relock only happens if locked lruvec is 
>> different.
>> and unlock the old one.
> 
> The section I am talking about with the bug is this section here:
>while (!list_empty(list)) {
> +   struct lruvec *new_lruvec = NULL;
> +
> page = lru_to_page(list);
> VM_BUG_ON_PAGE(PageLRU(page), page);
> list_del(>lru);
> if (unlikely(!page_evictable(page))) {
> -   spin_unlock_irq(>lru_lock);
> +   spin_unlock_irq(>lru_lock);
> putback_lru_page(page);
> -   spin_lock_irq(>lru_lock);
> +   spin_lock_irq(>lru_lock);

It would be still fine. The lruvec->lru_lock will be checked again before
we take and use it. 
And this lock will optimized in patch 19th which did by Hugh Dickins.

> continue;
> }
> 
> Basically it probably is not advisable to be retaking the
> lruvec->lru_lock directly as the lruvec may have changed so it
> wouldn't be correct for the next page. It would make more sense to be
> using your API and calling unlock_page_lruvec_irq and
> lock_page_lruvec_irq instead of using the lock directly.
> 
>>>
>>> I suppose the correct fix is to get rid of this line, but  it should
>>> be placed everywhere the original function was calling
>>> spin_lock_irq().
>>>
>>> In addition I would consider changing the arguments/documentation for
>>> move_pages_to_lru. You aren't moving the pages to lruvec, so there is
>>> probably no need to pass that as an argument. Instead I would pass
>>> pgdat since that isn't going to be moving and is the only thing you
>>> actually derive based on the original lruvec.
>>
>> yes, The comments should be changed with the line was introduced from long 
>> ago. :)
>> Anyway, I am wondering if it worth a v18 version resend?
> 
> So I have been looking over the function itself and I wonder if it
> isn't worth looking at rewriting this to optimize the locking behavior
> to minimize the number of times we have to take the LRU lock. I have
> some code I am working on that I plan to submit as an RFC in the next
> day or so after I can get it smoke tested. The basic idea would be to
> defer returning the evictiable pages or freeing the compound pages
> until after we have processed the pages that can be moved while still
> holding the lock. I would think it should reduce the lock contention
> significantly while improving the throughput.
> 

I had tried once, but the freeing page cross onto release_pages which hard to 
deal with.
I am very glad to 

RE: [PATCH v6 01/15] vfio/type1: Refactor vfio_iommu_type1_ioctl()

2020-07-28 Thread Liu, Yi L
> From: Alex Williamson 
> Sent: Tuesday, July 28, 2020 11:54 PM
> 
> On Mon, 27 Jul 2020 23:27:30 -0700
> Liu Yi L  wrote:
> 
> > This patch refactors the vfio_iommu_type1_ioctl() to use switch
> > instead of if-else, and each command got a helper function.
> >
> > Cc: Kevin Tian 
> > CC: Jacob Pan 
> > Cc: Alex Williamson 
> > Cc: Eric Auger 
> > Cc: Jean-Philippe Brucker 
> > Cc: Joerg Roedel 
> > Cc: Lu Baolu 
> > Reviewed-by: Eric Auger 
> > Suggested-by: Christoph Hellwig 
> > Signed-off-by: Liu Yi L 
> > ---
> 
> FYI, this commit is already in my next branch and linux-next as of today, you 
> can
> drop it from future series.  Thanks,

got it. thanks. :-)

Regards,
Yi Liu

> Alex
> 
> > v4 -> v5:
> > *) address comments from Eric Auger, add r-b from Eric.
> > ---
> >  drivers/vfio/vfio_iommu_type1.c | 394
> > ++--
> >  1 file changed, 213 insertions(+), 181 deletions(-)
> >
> > diff --git a/drivers/vfio/vfio_iommu_type1.c
> > b/drivers/vfio/vfio_iommu_type1.c index 5e556ac..3bd70ff 100644
> > --- a/drivers/vfio/vfio_iommu_type1.c
> > +++ b/drivers/vfio/vfio_iommu_type1.c
> > @@ -2453,6 +2453,23 @@ static int vfio_domains_have_iommu_cache(struct
> vfio_iommu *iommu)
> > return ret;
> >  }
> >
> > +static int vfio_iommu_type1_check_extension(struct vfio_iommu *iommu,
> > +   unsigned long arg)
> > +{
> > +   switch (arg) {
> > +   case VFIO_TYPE1_IOMMU:
> > +   case VFIO_TYPE1v2_IOMMU:
> > +   case VFIO_TYPE1_NESTING_IOMMU:
> > +   return 1;
> > +   case VFIO_DMA_CC_IOMMU:
> > +   if (!iommu)
> > +   return 0;
> > +   return vfio_domains_have_iommu_cache(iommu);
> > +   default:
> > +   return 0;
> > +   }
> > +}
> > +
> >  static int vfio_iommu_iova_add_cap(struct vfio_info_cap *caps,
> >  struct vfio_iommu_type1_info_cap_iova_range *cap_iovas,
> >  size_t size)
> > @@ -2529,241 +2546,256 @@ static int vfio_iommu_migration_build_caps(struct
> vfio_iommu *iommu,
> > return vfio_info_add_capability(caps, _mig.header,
> > sizeof(cap_mig));  }
> >
> > -static long vfio_iommu_type1_ioctl(void *iommu_data,
> > -  unsigned int cmd, unsigned long arg)
> > +static int vfio_iommu_type1_get_info(struct vfio_iommu *iommu,
> > +unsigned long arg)
> >  {
> > -   struct vfio_iommu *iommu = iommu_data;
> > +   struct vfio_iommu_type1_info info;
> > unsigned long minsz;
> > +   struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> > +   unsigned long capsz;
> > +   int ret;
> >
> > -   if (cmd == VFIO_CHECK_EXTENSION) {
> > -   switch (arg) {
> > -   case VFIO_TYPE1_IOMMU:
> > -   case VFIO_TYPE1v2_IOMMU:
> > -   case VFIO_TYPE1_NESTING_IOMMU:
> > -   return 1;
> > -   case VFIO_DMA_CC_IOMMU:
> > -   if (!iommu)
> > -   return 0;
> > -   return vfio_domains_have_iommu_cache(iommu);
> > -   default:
> > -   return 0;
> > -   }
> > -   } else if (cmd == VFIO_IOMMU_GET_INFO) {
> > -   struct vfio_iommu_type1_info info;
> > -   struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> > -   unsigned long capsz;
> > -   int ret;
> > -
> > -   minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
> > +   minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
> >
> > -   /* For backward compatibility, cannot require this */
> > -   capsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
> > +   /* For backward compatibility, cannot require this */
> > +   capsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
> >
> > -   if (copy_from_user(, (void __user *)arg, minsz))
> > -   return -EFAULT;
> > +   if (copy_from_user(, (void __user *)arg, minsz))
> > +   return -EFAULT;
> >
> > -   if (info.argsz < minsz)
> > -   return -EINVAL;
> > +   if (info.argsz < minsz)
> > +   return -EINVAL;
> >
> > -   if (info.argsz >= capsz) {
> > -   minsz = capsz;
> > -   info.cap_offset = 0; /* output, no-recopy necessary */
> > -   }
> > +   if (info.argsz >= capsz) {
> > +   minsz = capsz;
> > +   info.cap_offset = 0; /* output, no-recopy necessary */
> > +   }
> >
> > -   mutex_lock(>lock);
> > -   info.flags = VFIO_IOMMU_INFO_PGSIZES;
> > +   mutex_lock(>lock);
> > +   info.flags = VFIO_IOMMU_INFO_PGSIZES;
> >
> > -   info.iova_pgsizes = iommu->pgsize_bitmap;
> > +   info.iova_pgsizes = iommu->pgsize_bitmap;
> >
> > -   ret = vfio_iommu_migration_build_caps(iommu, );
> > +   ret = vfio_iommu_migration_build_caps(iommu, );
> >
> > -   if (!ret)
> > -   ret = vfio_iommu_iova_build_caps(iommu, );
> > +   if 

RE: [PATCH 1/2] watchdog: imx7ulp: Strictly follow the sequence for wdog operations

2020-07-28 Thread Anson Huang
Hi, Guenter


> Subject: RE: [PATCH 1/2] watchdog: imx7ulp: Strictly follow the sequence for
> wdog operations
> 
> Hi, Guenter
> 
> 
> > Subject: Re: [PATCH 1/2] watchdog: imx7ulp: Strictly follow the
> > sequence for wdog operations
> >
> > On 7/27/20 11:42 PM, Anson Huang wrote:
> > > According to reference manual, the i.MX7ULP WDOG's operations should
> > > follow below sequence:
> > >
> > > 1. disable global interrupts;
> > > 2. unlock the wdog and wait unlock bit set; 3. reconfigure the wdog
> > > and wait for reconfiguration bit set; 4. enabel global interrupts.
> > >
> > > Strictly follow the recommended sequence can make it more robust.
> > >
> > > Signed-off-by: Anson Huang 
> > > ---
> > >  drivers/watchdog/imx7ulp_wdt.c | 29 +
> > >  1 file changed, 29 insertions(+)
> > >
> > > diff --git a/drivers/watchdog/imx7ulp_wdt.c
> > > b/drivers/watchdog/imx7ulp_wdt.c index 7993c8c..b414ecf 100644
> > > --- a/drivers/watchdog/imx7ulp_wdt.c
> > > +++ b/drivers/watchdog/imx7ulp_wdt.c
> > > @@ -4,6 +4,7 @@
> > >   */
> > >
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -48,17 +49,32 @@ struct imx7ulp_wdt_device {
> > >   struct clk *clk;
> > >  };
> > >
> > > +static inline void imx7ulp_wdt_wait(void __iomem *base, u32 mask) {
> > > + int retries = 100;
> > > +
> > > + do {
> > > + if (readl_relaxed(base + WDOG_CS) & mask)
> > > + return;
> > > + usleep_range(200, 1000);
> > > + } while (retries--);
> >
> > Sleep with interrupts disabled ? I can not imagine that this works
> > well in a single CPU system. On top of that, it seems quite pointless.
> > Either you don't want to be interrupted or you do, but sleeping with
> > interrupts disabled really doesn't make sense. And does it really take
> > 200-1000 uS for the watchdog subsystem to react, and sometimes up to
> > 200 * 100 = 20 mS ? That seems highly unlikely. If such a delay loop
> > is indeed needed, it should be limited by a time, not by number of
> repetitions.
> >
> > Unless there is evidence that there is a problem that needs to be
> > solved, I am not going to accept this code.
> >
> 
> Oops, this is a mistake of using sleep with interrupt disabled, sorry for 
> that.
> The best option is to use readl_relaxed_poll_timeout_atomic() to poll the
> status bit, however, the i.MX7ULP watchdog is very special that the unlock
> window ONLY open for several cycles, that means the unlock status bit will be
> set and then clear automatically after those cycles, using
> readl_relaxed_poll_timeout_atomic() will fail since there are many timeout
> handle code in it and the unlock window is open and close during this timeout
> handle interval, so it fail to catch the unlock bit.
> 
> The ideal option is using atomic polling without any other timeout check to
> make sure the unlock window is NOT missed, but I think Linux kernel will NOT
> accept a while loop without timeout, and that is why I tried to use
> usleep_ranges(), but obviously I made a mistake of using it with IRQ disabled.
> 
> Do you have any suggestion of how to handle such case? If the hardware ONLY
> unlock the register for a small window, how to poll the status bit with 
> timeout
> handle and also make sure the timeout handle code as quick as possible to
> NOT miss the window?
> 

I did more experiment and found that below readl_poll_timeout_atomic() is 
actually
working, so I sent a V2 with it, please help review, thank you.


+   u32 val = readl(base + WDOG_CS);
+
+   if (!(val & mask))
+   WARN_ON(readl_poll_timeout_atomic(base + WDOG_CS, val,
+ val & mask, 0,
+ WDOG_WAIT_TIMEOUT));

Thanks,
Anson
 



[PATCH] drm/vkms: Fix soft lockup.

2020-07-28 Thread Xu Qiang
A soft deadlock occurs when call hrtimer_cancel in softirq context:

a) The main frequency of the machine is very slow
b) output->period_ns is very small, even only 1 ns

The problem can be solved in the following way: Setting a hrtimer exit flag
in the vkms_disable_vblank function and checking the flag in the
vkms_vblank_simulate function. If the flag is set, the hrtimer is not added
to hrtimer queue again,the hrtimer_cancel function can exit quickly
without deadlock.

watchdog: BUG: soft lockup - CPU#2 stuck for 134s! [syz-executor.2:18027]
Modules linked in:
CPU: 2 PID: 18027 Comm: syz-executor.2 Tainted: GW 
5.8.0-rc2-csan #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Ubuntu-1.8.2-1ubuntu1 04/01/2014
RIP: 0010:csd_lock_wait kernel/smp.c:108 [inline]
RIP: 0010:smp_call_function_many_cond+0x40c/0x470 kernel/smp.c:555
RSP: 0018:c900028d3a88 EFLAGS: 0297
RAX: 0002 RBX: 888237cacc80 RCX: 813240fc
RDX: 0001 RSI:  RDI: 0005
RBP: 0001 R08: 8881f497d000 R09: 
R10:  R11: 0100 R12: 888237cf6fc0
R13: 0003 R14: 888237cacc88 R15: 0001
FS:  7fa6314a9700() GS:888237c8() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 00513c80 CR3: 0001e3df3002 CR4: 000626e0
Call Trace:
 smp_call_function_many kernel/smp.c:577 [inline]
 smp_call_function+0x40/0x80 kernel/smp.c:599
 on_each_cpu+0x2a/0xc0 kernel/smp.c:717
 __purge_vmap_area_lazy+0x7c/0xbc0 mm/vmalloc.c:1367
 _vm_unmap_aliases.part.0+0x126/0x180 mm/vmalloc.c:1800
 _vm_unmap_aliases mm/vmalloc.c:1769 [inline]
 vm_unmap_aliases+0x2f/0x40 mm/vmalloc.c:1823
 change_page_attr_set_clr+0x10a/0x4a0 arch/x86/mm/pat/set_memory.c:1732
 change_page_attr_clear arch/x86/mm/pat/set_memory.c:1789 [inline]
 set_memory_ro+0x2b/0x40 arch/x86/mm/pat/set_memory.c:1935
 bpf_jit_binary_lock_ro include/linux/filter.h:815 [inline]
 bpf_int_jit_compile+0x54f/0x663 arch/x86/net/bpf_jit_comp.c:1929
 bpf_prog_select_runtime+0x1cc/0x2c0 kernel/bpf/core.c:1807
 bpf_migrate_filter net/core/filter.c:1264 [inline]
 bpf_prepare_filter net/core/filter.c:1312 [inline]
 bpf_prepare_filter+0x518/0x620 net/core/filter.c:1278
 __get_filter+0x107/0x160 net/core/filter.c:1481
 sk_attach_filter+0x19/0xa0 net/core/filter.c:1496
 sock_setsockopt+0x1208/0x1230 net/core/sock.c:1080
 __sys_setsockopt+0x248/0x270 net/socket.c:2123
 __do_sys_setsockopt net/socket.c:2143 [inline]
 __se_sys_setsockopt net/socket.c:2140 [inline]
 __x64_sys_setsockopt+0x22/0x30 net/socket.c:2140
 do_syscall_64+0x48/0xb0 arch/x86/entry/common.c:359
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Sending NMI from CPU 2 to CPUs 0-1,3-5:
NMI backtrace for cpu 4 skipped: idling at native_safe_halt+0xe/0x10 
arch/x86/include/asm/irqflags.h:60
NMI backtrace for cpu 0 skipped: idling at native_safe_halt+0xe/0x10 
arch/x86/include/asm/irqflags.h:60
NMI backtrace for cpu 1
NMI backtrace for cpu 3
CPU: 3 PID: 0 Comm: swapper/3 Tainted: GW 5.8.0-rc2-csan #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Ubuntu-1.8.2-1ubuntu1 04/01/2014
RIP: 0010:preempt_count arch/x86/include/asm/preempt.h:26 [inline]
RIP: 0010:preempt_count_sub+0xa/0x90 kernel/sched/core.c:3874
RSP: 0018:c912cdd0 EFLAGS: 0046
RAX: 0001 RBX: 88822ecb8fb0 RCX: 
RDX:  RSI: 0086 RDI: 0001
RBP: 888237d5edc0 R08: 888236ddc000 R09: 
R10:  R11:  R12: 
R13: 0086 R14: 888237d5edc0 R15: 85bc6d60
FS:  () GS:888237cc() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 7f35cc47adb8 CR3: 05a23006 CR4: 000626e0
Call Trace:
 
 __raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:161 [inline]
 _raw_spin_unlock_irqrestore+0x2f/0x50 kernel/locking/spinlock.c:191
 unlock_hrtimer_base kernel/time/hrtimer.c:898 [inline]
 hrtimer_try_to_cancel kernel/time/hrtimer.c:1171 [inline]
 hrtimer_try_to_cancel+0xbd/0x1b0 kernel/time/hrtimer.c:1151
 hrtimer_cancel+0x13/0x40 kernel/time/hrtimer.c:1278
 __disable_vblank drivers/gpu/drm/drm_vblank.c:429 [inline]
 drm_vblank_disable_and_save+0x122/0x140 drivers/gpu/drm/drm_vblank.c:470
 vblank_disable_fn+0x96/0xa0 drivers/gpu/drm/drm_vblank.c:487
 call_timer_fn+0x3a/0x230 kernel/time/timer.c:1404
 expire_timers kernel/time/timer.c:1449 [inline]
 __run_timers kernel/time/timer.c:1773 [inline]
 __run_timers kernel/time/timer.c:1740 [inline]
 run_timer_softirq+0x2b8/0x840 kernel/time/timer.c:1786
 __do_softirq+0x118/0x344 kernel/softirq.c:292
 asm_call_on_stack+0xf/0x20 arch/x86/entry/entry_64.S:711
 
 __run_on_irqstack arch/x86/include/asm/irq_stack.h:22 [inline]
 run_on_irqstack_cond 

[PATCH V2 2/2] watchdog: imx7ulp: Watchdog should continue running for wait/stop mode

2020-07-28 Thread Anson Huang
When kernel idle, system will enter wait/stop mode, wdog should continue
running in this scenario, and the refresh thread can wake up system from
wait/stop mode.

Signed-off-by: Anson Huang 
---
no change.
---
 drivers/watchdog/imx7ulp_wdt.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
index 7d2b12e..2b4ff43 100644
--- a/drivers/watchdog/imx7ulp_wdt.c
+++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -22,6 +22,8 @@
 #define WDOG_CS_CLK(LPO_CLK << LPO_CLK_SHIFT)
 #define WDOG_CS_EN BIT(7)
 #define WDOG_CS_UPDATE BIT(5)
+#define WDOG_CS_WAIT   BIT(1)
+#define WDOG_CS_STOP   BIT(0)
 
 #define WDOG_CNT   0x4
 #define WDOG_TOVAL 0x8
@@ -174,7 +176,8 @@ static void imx7ulp_wdt_init(void __iomem *base, unsigned 
int timeout)
/* set an initial timeout value in TOVAL */
writel(timeout, base + WDOG_TOVAL);
/* enable 32bit command sequence and reconfigure */
-   val = WDOG_CS_CMD32EN | WDOG_CS_CLK | WDOG_CS_UPDATE;
+   val = WDOG_CS_CMD32EN | WDOG_CS_CLK | WDOG_CS_UPDATE |
+ WDOG_CS_WAIT | WDOG_CS_STOP;
writel(val, base + WDOG_CS);
imx7ulp_wdt_wait(base, WDOG_CS_RCS);
local_irq_enable();
-- 
2.7.4



[PATCH V2 1/2] watchdog: imx7ulp: Strictly follow the sequence for wdog operations

2020-07-28 Thread Anson Huang
According to reference manual, the i.MX7ULP WDOG's operations should
follow below sequence:

1. disable global interrupts;
2. unlock the wdog and wait unlock bit set;
3. reconfigure the wdog and wait for reconfiguration bit set;
4. enabel global interrupts.

Strictly follow the recommended sequence can make it more robust.

Signed-off-by: Anson Huang 
---
Changes since V1:
- use readl_poll_timeout_atomic() instead of usleep_ranges() since IRQ 
is disabled.
---
 drivers/watchdog/imx7ulp_wdt.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c
index 7993c8c..7d2b12e 100644
--- a/drivers/watchdog/imx7ulp_wdt.c
+++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -5,6 +5,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -36,6 +37,7 @@
 #define DEFAULT_TIMEOUT60
 #define MAX_TIMEOUT128
 #define WDOG_CLOCK_RATE1000
+#define WDOG_WAIT_TIMEOUT  1
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, bool, );
@@ -48,17 +50,31 @@ struct imx7ulp_wdt_device {
struct clk *clk;
 };
 
+static inline void imx7ulp_wdt_wait(void __iomem *base, u32 mask)
+{
+   u32 val = readl(base + WDOG_CS);
+
+   if (!(val & mask))
+   WARN_ON(readl_poll_timeout_atomic(base + WDOG_CS, val,
+ val & mask, 0,
+ WDOG_WAIT_TIMEOUT));
+}
+
 static void imx7ulp_wdt_enable(struct watchdog_device *wdog, bool enable)
 {
struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
 
u32 val = readl(wdt->base + WDOG_CS);
 
+   local_irq_disable();
writel(UNLOCK, wdt->base + WDOG_CNT);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
if (enable)
writel(val | WDOG_CS_EN, wdt->base + WDOG_CS);
else
writel(val & ~WDOG_CS_EN, wdt->base + WDOG_CS);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
+   local_irq_enable();
 }
 
 static bool imx7ulp_wdt_is_enabled(void __iomem *base)
@@ -72,7 +88,12 @@ static int imx7ulp_wdt_ping(struct watchdog_device *wdog)
 {
struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
 
+   local_irq_disable();
+   writel(UNLOCK, wdt->base + WDOG_CNT);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
writel(REFRESH, wdt->base + WDOG_CNT);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
+   local_irq_enable();
 
return 0;
 }
@@ -98,8 +119,12 @@ static int imx7ulp_wdt_set_timeout(struct watchdog_device 
*wdog,
struct imx7ulp_wdt_device *wdt = watchdog_get_drvdata(wdog);
u32 val = WDOG_CLOCK_RATE * timeout;
 
+   local_irq_disable();
writel(UNLOCK, wdt->base + WDOG_CNT);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_ULK);
writel(val, wdt->base + WDOG_TOVAL);
+   imx7ulp_wdt_wait(wdt->base, WDOG_CS_RCS);
+   local_irq_enable();
 
wdog->timeout = timeout;
 
@@ -140,15 +165,19 @@ static void imx7ulp_wdt_init(void __iomem *base, unsigned 
int timeout)
 {
u32 val;
 
+   local_irq_disable();
/* unlock the wdog for reconfiguration */
writel_relaxed(UNLOCK_SEQ0, base + WDOG_CNT);
writel_relaxed(UNLOCK_SEQ1, base + WDOG_CNT);
+   imx7ulp_wdt_wait(base, WDOG_CS_ULK);
 
/* set an initial timeout value in TOVAL */
writel(timeout, base + WDOG_TOVAL);
/* enable 32bit command sequence and reconfigure */
val = WDOG_CS_CMD32EN | WDOG_CS_CLK | WDOG_CS_UPDATE;
writel(val, base + WDOG_CS);
+   imx7ulp_wdt_wait(base, WDOG_CS_RCS);
+   local_irq_enable();
 }
 
 static void imx7ulp_wdt_action(void *data)
-- 
2.7.4



  1   2   3   4   5   6   7   8   9   10   >