Re: [PATCH v1 1/2] remoteproc: dt: Provide bindings for iMX6SX/7D Remote Processor Controller driver

2017-07-23 Thread Oleksij Rempel
Am 18.07.2017 um 18:38 schrieb Bjorn Andersson:
> On Tue 18 Jul 01:45 PDT 2017, Oleksij Rempel wrote:
> 
>> Hallo Bjorn,
>>
>> On 11.07.2017 00:14, Bjorn Andersson wrote:
>>> On Mon 10 Jul 07:42 PDT 2017, Oleksij Rempel wrote:
>>>
 Signed-off-by: Oleksij Rempel 
 ---
  .../devicetree/bindings/remoteproc/imx-rproc.txt   | 44 
 ++
  1 file changed, 44 insertions(+)
  create mode 100644 
 Documentation/devicetree/bindings/remoteproc/imx-rproc.txt

 diff --git a/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt 
 b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt
 new file mode 100644
 index ..e7c61993e1b8
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt
 @@ -0,0 +1,44 @@
 +NXP iMX6SX/iMX7D Co-Processor Bindings
 +
 +
 +This binding provides support for ARM Cortex M4 Co-processor found on some
 +NXP iMX SoCs.
 +
 +Required properties:
 +- compatible  Should be one of:
 +  "fsl,imx7d-rproc"
 +  "fsl,imx6sx-rproc"
 +- clocks  Clock for co-processor (See: 
 ../clock/clock-bindings.txt)
 +- syscfg  Phandle to syscon block which provide access to
>>>
>>> This is called "syscon" in the code and the example.
>>
>> done.
>>
 +  System Reset Controller
 +
 +Optional properties:
 +- reg:Should contain the address ranges for some of 
 internal
 +  memory regions.
>>>
>>> Something less hand-wavy, like: "Should list the memory regions for the
>>> remoteproc"
>>>
 +- reg-names:  Contains the corresponding names for the memory
 +  regions. These should be named "ddr", "ocram", 
 "ocram-s",
 +  "ocram-epdc" or "ocram-pxp".
>>>
>>> Make this comment define which memory regions are required for each of
>>> the systems.
>>
>> done.
>>
 +Fallowing memory ranges are expected:
 +- For "fsl,imx7d-rproc"
 +  <0x0090 0x0002> - "ocram"
 +  <0x0092 0x0002> - "ocram-epdc"
 +  <0x0094 0x8000> - "ocram-pxp"
 +  <0x8000 0x0FFF> - "ddr" (code area)
 +  <0x8000 0x6000> - "ddr" (data area)
>>>
>>> There's no reason to list the actual regions in the binding
>>> document. Just list the requires regions for each system.
>>>
 +- For "fsl,imx6sx-rproc"
 +  <0x008F8000 0x4000> - "ocram-s"
 +  <0x8000 0x0FFF8000> - "ddr" (code area)
 +  <0x8000 0x6000> - "ddr" (data area)
 +
 +Note: the "ddr" code and data ranges are overlapping. Code area is smaller
 +than data area.  So this range should be carefully chosen according to 
 your
 +system and application requirements.
 +
>>>
>>> This is a source of future issues as this indicates that I should have
>>> reg-names list "ddr" twice.
>>
>> Then I will name it:
>> "ddri" (incstruction/code area),
>> "ddrd" (data area)
>>
>> unless there are other suggestions.
>>
> 
> But are you saying that it's correct that these two memory regions
> should overlap?

Yes, from Cortex-m4 the same memory regions are aliased to different
address ranges to provide different cache optimizations.
From Cortex-A7 side - not. But on this side we don't care about meaning
of it, it is just some memory region.


>>> Also, as you warn about the user needing to pick the values for "ddr",
>>> does that mean that it's a carveout of System RAM?
>>
>> Yes, it is a part of System RAM.
>>
> 
> Then there will be an associated reserved-memory region for the
> region(s), you should add a label to this and use "memory-region" to get
> hold of the addresses instead.

Ok. Should only system memory region be assigned over reserved-memory or
all of named regions?

-- 
Regards,
Oleksij



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v1 1/2] remoteproc: dt: Provide bindings for iMX6SX/7D Remote Processor Controller driver

2017-07-23 Thread Oleksij Rempel
Am 18.07.2017 um 18:38 schrieb Bjorn Andersson:
> On Tue 18 Jul 01:45 PDT 2017, Oleksij Rempel wrote:
> 
>> Hallo Bjorn,
>>
>> On 11.07.2017 00:14, Bjorn Andersson wrote:
>>> On Mon 10 Jul 07:42 PDT 2017, Oleksij Rempel wrote:
>>>
 Signed-off-by: Oleksij Rempel 
 ---
  .../devicetree/bindings/remoteproc/imx-rproc.txt   | 44 
 ++
  1 file changed, 44 insertions(+)
  create mode 100644 
 Documentation/devicetree/bindings/remoteproc/imx-rproc.txt

 diff --git a/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt 
 b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt
 new file mode 100644
 index ..e7c61993e1b8
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt
 @@ -0,0 +1,44 @@
 +NXP iMX6SX/iMX7D Co-Processor Bindings
 +
 +
 +This binding provides support for ARM Cortex M4 Co-processor found on some
 +NXP iMX SoCs.
 +
 +Required properties:
 +- compatible  Should be one of:
 +  "fsl,imx7d-rproc"
 +  "fsl,imx6sx-rproc"
 +- clocks  Clock for co-processor (See: 
 ../clock/clock-bindings.txt)
 +- syscfg  Phandle to syscon block which provide access to
>>>
>>> This is called "syscon" in the code and the example.
>>
>> done.
>>
 +  System Reset Controller
 +
 +Optional properties:
 +- reg:Should contain the address ranges for some of 
 internal
 +  memory regions.
>>>
>>> Something less hand-wavy, like: "Should list the memory regions for the
>>> remoteproc"
>>>
 +- reg-names:  Contains the corresponding names for the memory
 +  regions. These should be named "ddr", "ocram", 
 "ocram-s",
 +  "ocram-epdc" or "ocram-pxp".
>>>
>>> Make this comment define which memory regions are required for each of
>>> the systems.
>>
>> done.
>>
 +Fallowing memory ranges are expected:
 +- For "fsl,imx7d-rproc"
 +  <0x0090 0x0002> - "ocram"
 +  <0x0092 0x0002> - "ocram-epdc"
 +  <0x0094 0x8000> - "ocram-pxp"
 +  <0x8000 0x0FFF> - "ddr" (code area)
 +  <0x8000 0x6000> - "ddr" (data area)
>>>
>>> There's no reason to list the actual regions in the binding
>>> document. Just list the requires regions for each system.
>>>
 +- For "fsl,imx6sx-rproc"
 +  <0x008F8000 0x4000> - "ocram-s"
 +  <0x8000 0x0FFF8000> - "ddr" (code area)
 +  <0x8000 0x6000> - "ddr" (data area)
 +
 +Note: the "ddr" code and data ranges are overlapping. Code area is smaller
 +than data area.  So this range should be carefully chosen according to 
 your
 +system and application requirements.
 +
>>>
>>> This is a source of future issues as this indicates that I should have
>>> reg-names list "ddr" twice.
>>
>> Then I will name it:
>> "ddri" (incstruction/code area),
>> "ddrd" (data area)
>>
>> unless there are other suggestions.
>>
> 
> But are you saying that it's correct that these two memory regions
> should overlap?

Yes, from Cortex-m4 the same memory regions are aliased to different
address ranges to provide different cache optimizations.
From Cortex-A7 side - not. But on this side we don't care about meaning
of it, it is just some memory region.


>>> Also, as you warn about the user needing to pick the values for "ddr",
>>> does that mean that it's a carveout of System RAM?
>>
>> Yes, it is a part of System RAM.
>>
> 
> Then there will be an associated reserved-memory region for the
> region(s), you should add a label to this and use "memory-region" to get
> hold of the addresses instead.

Ok. Should only system memory region be assigned over reserved-memory or
all of named regions?

-- 
Regards,
Oleksij



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] usb: dwc3: Support the dwc3 host suspend/resume

2017-07-23 Thread Baolin Wang
Hi,

On 21 July 2017 at 17:13, Manu Gautam  wrote:
> Hi,
>
> On 7/21/2017 2:31 PM, Baolin Wang wrote:
>> On 21 July 2017 at 16:45, Manu Gautam  wrote:
>>> Hi,
>>>
>>>
>>> On 7/21/2017 12:28 PM, Baolin Wang wrote:
 For some mobile devices with strict power management, we also want to
 suspend the host when the slave was detached for power saving. Thus
 adding the host suspend/resume functions to support this requirement.
>>>
>>> USB/PM core already takes care of suspending root-HUB/XHCI when
>>> no device connected.
>> Correct, but what I mean is we can power off the dwc3 controller when
>> there are no device connected.
>>
 We will issue the pm_suspend_ignore_children() for the dwc3 device,
 since we will resume the child device (xHCI device) in runtime resume
 callback (dwc3_host_resume()) of dwc3 device, now the dwc3 device's
 runtime state is not RPM_ACTIVE, which will block to resume its
 child device (xHCI device). Add ignore children flag can avoid this
 situation.
>>> This defeats the basic purpose of runtime PM. Without ignore_children
>>> once USB bus is suspended, dwc3 gets suspended and then dwc3 glue device.
>>> Only requirement I see from the patch is to resume XHCI/root-hub on
>>> dwc3 resume. I am sure there must be other way to deal with that e.g.
>>> doing same from glue driver by using a wq or use pm_request_resume()
>> Ah, I will try pm_request_resume().
>>
 Signed-off-by: Baolin Wang 
 ---
  drivers/usb/dwc3/core.c |   26 +-
  drivers/usb/dwc3/core.h |7 +++
  drivers/usb/dwc3/host.c |   15 +++
  3 files changed, 47 insertions(+), 1 deletion(-)

 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
 index 326b302..2be7ddc 100644
 --- a/drivers/usb/dwc3/core.c
 +++ b/drivers/usb/dwc3/core.c
 @@ -1193,6 +1193,7 @@ static int dwc3_probe(struct platform_device *pdev)
   pm_runtime_use_autosuspend(dev);
   pm_runtime_set_autosuspend_delay(dev, 
 DWC3_DEFAULT_AUTOSUSPEND_DELAY);
   pm_runtime_enable(dev);
 + pm_suspend_ignore_children(dev, true);
   ret = pm_runtime_get_sync(dev);
   if (ret < 0)
   goto err1;
 @@ -1292,15 +1293,27 @@ static int dwc3_remove(struct platform_device 
 *pdev)
  static int dwc3_suspend_common(struct dwc3 *dwc)
>>> What is the trigger for runtime suspend now that you have ignore_children 
>>> set.
  {
   unsigned long   flags;
 + int ret;

   switch (dwc->dr_mode) {
   case USB_DR_MODE_PERIPHERAL:
 + spin_lock_irqsave(>lock, flags);
 + dwc3_gadget_suspend(dwc);
 + spin_unlock_irqrestore(>lock, flags);
 + break;
   case USB_DR_MODE_OTG:
 + ret = dwc3_host_suspend(dwc);
>>> With DRD/OTG, if current mode is device and dwc3->xhci won't be valid.
>> If current mode is device, then xHCI device is always in suspend state.
> dwc->xhci is allocated in dwc3_host_init. And dwc->xhci device is unregistred
> from dwc3_host_exit that is called from __dwc3_set_mode.

Yes, you are right. I think I need check the dwc->current_dr_role to
identify host or device mode.

>>
>>> You can refer to the patch that I pushed to address this.
>>>
 + if (ret)
 + return ret;
 +
   spin_lock_irqsave(>lock, flags);
   dwc3_gadget_suspend(dwc);
   spin_unlock_irqrestore(>lock, flags);
   break;
   case USB_DR_MODE_HOST:
 + ret = dwc3_host_suspend(dwc);
 + if (ret)
 + return ret;
   default:
   /* do nothing */
   break;
 @@ -1322,12 +1335,23 @@ static int dwc3_resume_common(struct dwc3 *dwc)

   switch (dwc->dr_mode) {
   case USB_DR_MODE_PERIPHERAL:
 + spin_lock_irqsave(>lock, flags);
 + dwc3_gadget_resume(dwc);
 + spin_unlock_irqrestore(>lock, flags);
 + break;
   case USB_DR_MODE_OTG:
 + ret = dwc3_host_resume(dwc);
 + if (ret)
 + return ret;
 +
   spin_lock_irqsave(>lock, flags);
   dwc3_gadget_resume(dwc);
   spin_unlock_irqrestore(>lock, flags);
 - /* FALLTHROUGH */
 + break;
   case USB_DR_MODE_HOST:
 + ret = dwc3_host_resume(dwc);
 + if (ret)
 + return ret;
   default:
   /* do nothing */
   break;
 diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
 index ea910ac..9b5a4eb 100644
 --- 

Re: [PATCH] usb: dwc3: Support the dwc3 host suspend/resume

2017-07-23 Thread Baolin Wang
Hi,

On 21 July 2017 at 17:13, Manu Gautam  wrote:
> Hi,
>
> On 7/21/2017 2:31 PM, Baolin Wang wrote:
>> On 21 July 2017 at 16:45, Manu Gautam  wrote:
>>> Hi,
>>>
>>>
>>> On 7/21/2017 12:28 PM, Baolin Wang wrote:
 For some mobile devices with strict power management, we also want to
 suspend the host when the slave was detached for power saving. Thus
 adding the host suspend/resume functions to support this requirement.
>>>
>>> USB/PM core already takes care of suspending root-HUB/XHCI when
>>> no device connected.
>> Correct, but what I mean is we can power off the dwc3 controller when
>> there are no device connected.
>>
 We will issue the pm_suspend_ignore_children() for the dwc3 device,
 since we will resume the child device (xHCI device) in runtime resume
 callback (dwc3_host_resume()) of dwc3 device, now the dwc3 device's
 runtime state is not RPM_ACTIVE, which will block to resume its
 child device (xHCI device). Add ignore children flag can avoid this
 situation.
>>> This defeats the basic purpose of runtime PM. Without ignore_children
>>> once USB bus is suspended, dwc3 gets suspended and then dwc3 glue device.
>>> Only requirement I see from the patch is to resume XHCI/root-hub on
>>> dwc3 resume. I am sure there must be other way to deal with that e.g.
>>> doing same from glue driver by using a wq or use pm_request_resume()
>> Ah, I will try pm_request_resume().
>>
 Signed-off-by: Baolin Wang 
 ---
  drivers/usb/dwc3/core.c |   26 +-
  drivers/usb/dwc3/core.h |7 +++
  drivers/usb/dwc3/host.c |   15 +++
  3 files changed, 47 insertions(+), 1 deletion(-)

 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
 index 326b302..2be7ddc 100644
 --- a/drivers/usb/dwc3/core.c
 +++ b/drivers/usb/dwc3/core.c
 @@ -1193,6 +1193,7 @@ static int dwc3_probe(struct platform_device *pdev)
   pm_runtime_use_autosuspend(dev);
   pm_runtime_set_autosuspend_delay(dev, 
 DWC3_DEFAULT_AUTOSUSPEND_DELAY);
   pm_runtime_enable(dev);
 + pm_suspend_ignore_children(dev, true);
   ret = pm_runtime_get_sync(dev);
   if (ret < 0)
   goto err1;
 @@ -1292,15 +1293,27 @@ static int dwc3_remove(struct platform_device 
 *pdev)
  static int dwc3_suspend_common(struct dwc3 *dwc)
>>> What is the trigger for runtime suspend now that you have ignore_children 
>>> set.
  {
   unsigned long   flags;
 + int ret;

   switch (dwc->dr_mode) {
   case USB_DR_MODE_PERIPHERAL:
 + spin_lock_irqsave(>lock, flags);
 + dwc3_gadget_suspend(dwc);
 + spin_unlock_irqrestore(>lock, flags);
 + break;
   case USB_DR_MODE_OTG:
 + ret = dwc3_host_suspend(dwc);
>>> With DRD/OTG, if current mode is device and dwc3->xhci won't be valid.
>> If current mode is device, then xHCI device is always in suspend state.
> dwc->xhci is allocated in dwc3_host_init. And dwc->xhci device is unregistred
> from dwc3_host_exit that is called from __dwc3_set_mode.

Yes, you are right. I think I need check the dwc->current_dr_role to
identify host or device mode.

>>
>>> You can refer to the patch that I pushed to address this.
>>>
 + if (ret)
 + return ret;
 +
   spin_lock_irqsave(>lock, flags);
   dwc3_gadget_suspend(dwc);
   spin_unlock_irqrestore(>lock, flags);
   break;
   case USB_DR_MODE_HOST:
 + ret = dwc3_host_suspend(dwc);
 + if (ret)
 + return ret;
   default:
   /* do nothing */
   break;
 @@ -1322,12 +1335,23 @@ static int dwc3_resume_common(struct dwc3 *dwc)

   switch (dwc->dr_mode) {
   case USB_DR_MODE_PERIPHERAL:
 + spin_lock_irqsave(>lock, flags);
 + dwc3_gadget_resume(dwc);
 + spin_unlock_irqrestore(>lock, flags);
 + break;
   case USB_DR_MODE_OTG:
 + ret = dwc3_host_resume(dwc);
 + if (ret)
 + return ret;
 +
   spin_lock_irqsave(>lock, flags);
   dwc3_gadget_resume(dwc);
   spin_unlock_irqrestore(>lock, flags);
 - /* FALLTHROUGH */
 + break;
   case USB_DR_MODE_HOST:
 + ret = dwc3_host_resume(dwc);
 + if (ret)
 + return ret;
   default:
   /* do nothing */
   break;
 diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
 index ea910ac..9b5a4eb 100644
 --- a/drivers/usb/dwc3/core.h
 +++ b/drivers/usb/dwc3/core.h
 @@ -1193,11 +1193,18 @@ 

Is it possible to use ftrace to measure secondary CPU bootup time

2017-07-23 Thread Huang, Ying
Hi, Steven,

We are working on parallelizing secondary CPU bootup.   So we need to
measure the bootup time of secondary CPU, that is, measure time spent in
smp_init() and its callees.  But we found that ftrace now doesn't
support measure time spent in smp_init() because it is called too early
(before core_initcall()?).  So, do you think it is possible to use
ftrace to measure secondary CPU bootup time?

Thanks,
Huang, Ying


Is it possible to use ftrace to measure secondary CPU bootup time

2017-07-23 Thread Huang, Ying
Hi, Steven,

We are working on parallelizing secondary CPU bootup.   So we need to
measure the bootup time of secondary CPU, that is, measure time spent in
smp_init() and its callees.  But we found that ftrace now doesn't
support measure time spent in smp_init() because it is called too early
(before core_initcall()?).  So, do you think it is possible to use
ftrace to measure secondary CPU bootup time?

Thanks,
Huang, Ying


[PATCH] cpufreq: intel_pstate: Fix cpuinfo_cur_freq after performance governor changes

2017-07-23 Thread Huaisheng HS1 Ye
After commit 82b4e03e01bc (intel_pstate: skip scheduler hook when
in "performance" mode) Software P-state control modes couldn't get
dynamic value during performance mode, and it still in last value from
powersave mode, so clear its value to get same behavior as Hardware
P-state to avoid confusion.

Signed-off-by: Huaisheng Ye 
---
 drivers/cpufreq/intel_pstate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6cd5035..c675626 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2050,6 +2050,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy 
*policy)
 */
intel_pstate_clear_update_util_hook(policy->cpu);
intel_pstate_max_within_limits(cpu);
+   cpu->sample.core_avg_perf = 0;
} else {
intel_pstate_set_update_util_hook(policy->cpu);
}
-- 
1.8.3.1


[PATCH] cpufreq: intel_pstate: Fix cpuinfo_cur_freq after performance governor changes

2017-07-23 Thread Huaisheng HS1 Ye
After commit 82b4e03e01bc (intel_pstate: skip scheduler hook when
in "performance" mode) Software P-state control modes couldn't get
dynamic value during performance mode, and it still in last value from
powersave mode, so clear its value to get same behavior as Hardware
P-state to avoid confusion.

Signed-off-by: Huaisheng Ye 
---
 drivers/cpufreq/intel_pstate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6cd5035..c675626 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -2050,6 +2050,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy 
*policy)
 */
intel_pstate_clear_update_util_hook(policy->cpu);
intel_pstate_max_within_limits(cpu);
+   cpu->sample.core_avg_perf = 0;
} else {
intel_pstate_set_update_util_hook(policy->cpu);
}
-- 
1.8.3.1


[PATCH -mm -v3 08/12] memcg, THP, swap: Support move mem cgroup charge for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

PTE mapped THP (Transparent Huge Page) will be ignored when moving
memory cgroup charge.  But for THP which is in the swap cache, the
memory cgroup charge for the swap of a tail-page may be moved in
current implementation.  That isn't correct, because the swap charge
for all sub-pages of a THP should be moved together.  Following the
processing of the PTE mapped THP, the mem cgroup charge moving for the
swap entry for a tail-page of a THP is ignored too.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3df3c04d73ab..c2618bd8ebdd 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4616,8 +4616,11 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
if (!ret || !target)
put_page(page);
}
-   /* There is a swap entry and a page doesn't exist or isn't charged */
-   if (ent.val && !ret &&
+   /*
+* There is a swap entry and a page doesn't exist or isn't charged.
+* But we cannot move a tail-page in a THP.
+*/
+   if (ent.val && !ret && (!page || !PageTransCompound(page)) &&
mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
ret = MC_TARGET_SWAP;
if (target)
-- 
2.13.2



[PATCH -mm -v3 08/12] memcg, THP, swap: Support move mem cgroup charge for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

PTE mapped THP (Transparent Huge Page) will be ignored when moving
memory cgroup charge.  But for THP which is in the swap cache, the
memory cgroup charge for the swap of a tail-page may be moved in
current implementation.  That isn't correct, because the swap charge
for all sub-pages of a THP should be moved together.  Following the
processing of the PTE mapped THP, the mem cgroup charge moving for the
swap entry for a tail-page of a THP is ignored too.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3df3c04d73ab..c2618bd8ebdd 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4616,8 +4616,11 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
if (!ret || !target)
put_page(page);
}
-   /* There is a swap entry and a page doesn't exist or isn't charged */
-   if (ent.val && !ret &&
+   /*
+* There is a swap entry and a page doesn't exist or isn't charged.
+* But we cannot move a tail-page in a THP.
+*/
+   if (ent.val && !ret && (!page || !PageTransCompound(page)) &&
mem_cgroup_id(mc.from) == lookup_swap_cgroup_id(ent)) {
ret = MC_TARGET_SWAP;
if (target)
-- 
2.13.2



[PATCH -mm -v3 11/12] mm, THP, swap: Delay splitting THP after swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

In this patch, splitting transparent huge page (THP) during swapping
out is delayed from after adding the THP into the swap cache to after
swapping out finishes.  After the patch, more operations for the
anonymous THP reclaiming, such as writing the THP to the swap device,
removing the THP from the swap cache could be batched.  So that the
performance of anonymous THP swapping out could be improved.

This is the second step for the THP swap support.  The plan is to
delay splitting the THP step by step and avoid splitting the THP
finally.

With the patchset, the swap out throughput improves 42% (from about
5.81GB/s to about 8.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  At the same time, the IPI (reflect TLB flushing)
reduced about 78.9%.  The test is done on a Xeon E5 v3 system.  The
swap device used is a RAM simulated PMEM (persistent memory) device.
To test the sequential swapping out, the test case creates 8
processes, which sequentially allocate and write to the anonymous
pages until the RAM and part of the swap device is used up.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
Cc: Michal Hocko 
---
 mm/vmscan.c | 95 +
 1 file changed, 52 insertions(+), 43 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index efc9da21c5e6..7472ddafc14a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -535,7 +535,9 @@ static inline int is_page_cache_freeable(struct page *page)
 * that isolated the page, the page cache radix tree and
 * optional buffer heads at page->private.
 */
-   return page_count(page) - page_has_private(page) == 2;
+   int radix_pins = PageTransHuge(page) && PageSwapCache(page) ?
+   HPAGE_PMD_NR : 1;
+   return page_count(page) - page_has_private(page) == 1 + radix_pins;
 }
 
 static int may_write_to_inode(struct inode *inode, struct scan_control *sc)
@@ -665,6 +667,7 @@ static int __remove_mapping(struct address_space *mapping, 
struct page *page,
bool reclaimed)
 {
unsigned long flags;
+   int refcount;
 
BUG_ON(!PageLocked(page));
BUG_ON(mapping != page_mapping(page));
@@ -695,11 +698,15 @@ static int __remove_mapping(struct address_space 
*mapping, struct page *page,
 * Note that if SetPageDirty is always performed via set_page_dirty,
 * and thus under tree_lock, then this ordering is not required.
 */
-   if (!page_ref_freeze(page, 2))
+   if (unlikely(PageTransHuge(page)) && PageSwapCache(page))
+   refcount = 1 + HPAGE_PMD_NR;
+   else
+   refcount = 2;
+   if (!page_ref_freeze(page, refcount))
goto cannot_free;
/* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */
if (unlikely(PageDirty(page))) {
-   page_ref_unfreeze(page, 2);
+   page_ref_unfreeze(page, refcount);
goto cannot_free;
}
 
@@ -1121,58 +1128,56 @@ static unsigned long shrink_page_list(struct list_head 
*page_list,
 * Try to allocate it some swap space here.
 * Lazyfree page could be freed directly
 */
-   if (PageAnon(page) && PageSwapBacked(page) &&
-   !PageSwapCache(page)) {
-   if (!(sc->gfp_mask & __GFP_IO))
-   goto keep_locked;
-   if (PageTransHuge(page)) {
-   /* cannot split THP, skip it */
-   if (!can_split_huge_page(page, NULL))
-   goto activate_locked;
-   /*
-* Split pages without a PMD map right
-* away. Chances are some or all of the
-* tail pages can be freed without IO.
-*/
-   if (!compound_mapcount(page) &&
-   split_huge_page_to_list(page, page_list))
-   goto activate_locked;
-   }
-   if (!add_to_swap(page)) {
-   if (!PageTransHuge(page))
-   goto activate_locked;
-   /* Split THP and swap individual base pages */
-   if (split_huge_page_to_list(page, page_list))
-   goto activate_locked;
-   if 

[PATCH -mm -v3 11/12] mm, THP, swap: Delay splitting THP after swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

In this patch, splitting transparent huge page (THP) during swapping
out is delayed from after adding the THP into the swap cache to after
swapping out finishes.  After the patch, more operations for the
anonymous THP reclaiming, such as writing the THP to the swap device,
removing the THP from the swap cache could be batched.  So that the
performance of anonymous THP swapping out could be improved.

This is the second step for the THP swap support.  The plan is to
delay splitting the THP step by step and avoid splitting the THP
finally.

With the patchset, the swap out throughput improves 42% (from about
5.81GB/s to about 8.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  At the same time, the IPI (reflect TLB flushing)
reduced about 78.9%.  The test is done on a Xeon E5 v3 system.  The
swap device used is a RAM simulated PMEM (persistent memory) device.
To test the sequential swapping out, the test case creates 8
processes, which sequentially allocate and write to the anonymous
pages until the RAM and part of the swap device is used up.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
Cc: Michal Hocko 
---
 mm/vmscan.c | 95 +
 1 file changed, 52 insertions(+), 43 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index efc9da21c5e6..7472ddafc14a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -535,7 +535,9 @@ static inline int is_page_cache_freeable(struct page *page)
 * that isolated the page, the page cache radix tree and
 * optional buffer heads at page->private.
 */
-   return page_count(page) - page_has_private(page) == 2;
+   int radix_pins = PageTransHuge(page) && PageSwapCache(page) ?
+   HPAGE_PMD_NR : 1;
+   return page_count(page) - page_has_private(page) == 1 + radix_pins;
 }
 
 static int may_write_to_inode(struct inode *inode, struct scan_control *sc)
@@ -665,6 +667,7 @@ static int __remove_mapping(struct address_space *mapping, 
struct page *page,
bool reclaimed)
 {
unsigned long flags;
+   int refcount;
 
BUG_ON(!PageLocked(page));
BUG_ON(mapping != page_mapping(page));
@@ -695,11 +698,15 @@ static int __remove_mapping(struct address_space 
*mapping, struct page *page,
 * Note that if SetPageDirty is always performed via set_page_dirty,
 * and thus under tree_lock, then this ordering is not required.
 */
-   if (!page_ref_freeze(page, 2))
+   if (unlikely(PageTransHuge(page)) && PageSwapCache(page))
+   refcount = 1 + HPAGE_PMD_NR;
+   else
+   refcount = 2;
+   if (!page_ref_freeze(page, refcount))
goto cannot_free;
/* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */
if (unlikely(PageDirty(page))) {
-   page_ref_unfreeze(page, 2);
+   page_ref_unfreeze(page, refcount);
goto cannot_free;
}
 
@@ -1121,58 +1128,56 @@ static unsigned long shrink_page_list(struct list_head 
*page_list,
 * Try to allocate it some swap space here.
 * Lazyfree page could be freed directly
 */
-   if (PageAnon(page) && PageSwapBacked(page) &&
-   !PageSwapCache(page)) {
-   if (!(sc->gfp_mask & __GFP_IO))
-   goto keep_locked;
-   if (PageTransHuge(page)) {
-   /* cannot split THP, skip it */
-   if (!can_split_huge_page(page, NULL))
-   goto activate_locked;
-   /*
-* Split pages without a PMD map right
-* away. Chances are some or all of the
-* tail pages can be freed without IO.
-*/
-   if (!compound_mapcount(page) &&
-   split_huge_page_to_list(page, page_list))
-   goto activate_locked;
-   }
-   if (!add_to_swap(page)) {
-   if (!PageTransHuge(page))
-   goto activate_locked;
-   /* Split THP and swap individual base pages */
-   if (split_huge_page_to_list(page, page_list))
-   goto activate_locked;
-   if (!add_to_swap(page))
-   goto activate_locked;
-   }
-
-   /* XXX: We don't support THP writes */
-   if (PageTransHuge(page) &&
-   

[PATCH -mm -v3 10/12] memcg, THP, swap: Make mem_cgroup_swapout() support THP

2017-07-23 Thread Huang, Ying
From: Huang Ying 

This patch makes mem_cgroup_swapout() works for the transparent huge
page (THP).  Which will move the memory cgroup charge from memory to
swap for a THP.

This will be used for the THP swap support.  Where a THP may be
swapped out as a whole to a set of (HPAGE_PMD_NR) continuous swap
slots on the swap device.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a627b0fd67ea..b92f3327aca2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4631,8 +4631,8 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 /*
- * We don't consider swapping or file mapped pages because THP does not
- * support them for now.
+ * We don't consider PMD mapped swapping or file mapped pages because THP does
+ * not support them for now.
  * Caller should make sure that pmd_trans_huge(pmd) is true.
  */
 static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma,
@@ -5890,6 +5890,7 @@ static struct mem_cgroup *mem_cgroup_id_get_online(struct 
mem_cgroup *memcg)
 void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
 {
struct mem_cgroup *memcg, *swap_memcg;
+   unsigned int nr_entries;
unsigned short oldid;
 
VM_BUG_ON_PAGE(PageLRU(page), page);
@@ -5910,19 +5911,24 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t 
entry)
 * ancestor for the swap instead and transfer the memory+swap charge.
 */
swap_memcg = mem_cgroup_id_get_online(memcg);
-   oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), 1);
+   nr_entries = hpage_nr_pages(page);
+   /* Get references for the tail pages, too */
+   if (nr_entries > 1)
+   mem_cgroup_id_get_many(swap_memcg, nr_entries - 1);
+   oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg),
+  nr_entries);
VM_BUG_ON_PAGE(oldid, page);
-   mem_cgroup_swap_statistics(swap_memcg, 1);
+   mem_cgroup_swap_statistics(swap_memcg, nr_entries);
 
page->mem_cgroup = NULL;
 
if (!mem_cgroup_is_root(memcg))
-   page_counter_uncharge(>memory, 1);
+   page_counter_uncharge(>memory, nr_entries);
 
if (memcg != swap_memcg) {
if (!mem_cgroup_is_root(swap_memcg))
-   page_counter_charge(_memcg->memsw, 1);
-   page_counter_uncharge(>memsw, 1);
+   page_counter_charge(_memcg->memsw, nr_entries);
+   page_counter_uncharge(>memsw, nr_entries);
}
 
/*
@@ -5932,7 +5938,8 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t 
entry)
 * only synchronisation we have for udpating the per-CPU variables.
 */
VM_BUG_ON(!irqs_disabled());
-   mem_cgroup_charge_statistics(memcg, page, false, -1);
+   mem_cgroup_charge_statistics(memcg, page, PageTransHuge(page),
+-nr_entries);
memcg_check_events(memcg, page);
 
if (!mem_cgroup_is_root(memcg))
-- 
2.13.2



[PATCH -mm -v3 07/12] mm, THP, swap: Support to split THP for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

After adding swapping out support for THP (Transparent Huge Page), it
is possible that a THP in swap cache (partly swapped out) need to be
split.  To split such a THP, the swap cluster backing the THP need to
be split too, that is, the CLUSTER_FLAG_HUGE flag need to be cleared
for the swap cluster.  The patch implemented this.

And because the THP swap writing needs the THP keeps as huge page
during writing.  The PageWriteback flag is checked before splitting.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 include/linux/swap.h |  9 +
 mm/huge_memory.c | 10 +-
 mm/swapfile.c| 15 +++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 7176ba780e83..461cf107ad52 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -527,6 +527,15 @@ static inline swp_entry_t get_swap_page(struct page *page)
 
 #endif /* CONFIG_SWAP */
 
+#ifdef CONFIG_THP_SWAP
+extern int split_swap_cluster(swp_entry_t entry);
+#else
+static inline int split_swap_cluster(swp_entry_t entry)
+{
+   return 0;
+}
+#endif
+
 #ifdef CONFIG_MEMCG
 static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 7392ba184126..409e9dd28e0c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2452,6 +2452,9 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(!PageCompound(page), page);
 
+   if (PageWriteback(page))
+   return -EBUSY;
+
if (PageAnon(head)) {
/*
 * The caller does not necessarily hold an mmap_sem that would
@@ -2529,7 +2532,12 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
__dec_node_page_state(page, NR_SHMEM_THPS);
spin_unlock(>split_queue_lock);
__split_huge_page(page, list, flags);
-   ret = 0;
+   if (PageSwapCache(head)) {
+   swp_entry_t entry = { .val = page_private(head) };
+
+   ret = split_swap_cluster(entry);
+   } else
+   ret = 0;
} else {
if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) {
pr_alert("total_mapcount: %u, page_count(): %u\n",
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 21cbdecbc19a..1af21311a672 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1216,6 +1216,21 @@ static void swapcache_free_cluster(swp_entry_t entry)
}
}
 }
+
+int split_swap_cluster(swp_entry_t entry)
+{
+   struct swap_info_struct *si;
+   struct swap_cluster_info *ci;
+   unsigned long offset = swp_offset(entry);
+
+   si = _swap_info_get(entry);
+   if (!si)
+   return -EBUSY;
+   ci = lock_cluster(si, offset);
+   cluster_clear_huge(ci);
+   unlock_cluster(ci);
+   return 0;
+}
 #else
 static inline void swapcache_free_cluster(swp_entry_t entry)
 {
-- 
2.13.2



[PATCH -mm -v3 10/12] memcg, THP, swap: Make mem_cgroup_swapout() support THP

2017-07-23 Thread Huang, Ying
From: Huang Ying 

This patch makes mem_cgroup_swapout() works for the transparent huge
page (THP).  Which will move the memory cgroup charge from memory to
swap for a THP.

This will be used for the THP swap support.  Where a THP may be
swapped out as a whole to a set of (HPAGE_PMD_NR) continuous swap
slots on the swap device.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a627b0fd67ea..b92f3327aca2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4631,8 +4631,8 @@ static enum mc_target_type get_mctgt_type(struct 
vm_area_struct *vma,
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 /*
- * We don't consider swapping or file mapped pages because THP does not
- * support them for now.
+ * We don't consider PMD mapped swapping or file mapped pages because THP does
+ * not support them for now.
  * Caller should make sure that pmd_trans_huge(pmd) is true.
  */
 static enum mc_target_type get_mctgt_type_thp(struct vm_area_struct *vma,
@@ -5890,6 +5890,7 @@ static struct mem_cgroup *mem_cgroup_id_get_online(struct 
mem_cgroup *memcg)
 void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
 {
struct mem_cgroup *memcg, *swap_memcg;
+   unsigned int nr_entries;
unsigned short oldid;
 
VM_BUG_ON_PAGE(PageLRU(page), page);
@@ -5910,19 +5911,24 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t 
entry)
 * ancestor for the swap instead and transfer the memory+swap charge.
 */
swap_memcg = mem_cgroup_id_get_online(memcg);
-   oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg), 1);
+   nr_entries = hpage_nr_pages(page);
+   /* Get references for the tail pages, too */
+   if (nr_entries > 1)
+   mem_cgroup_id_get_many(swap_memcg, nr_entries - 1);
+   oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg),
+  nr_entries);
VM_BUG_ON_PAGE(oldid, page);
-   mem_cgroup_swap_statistics(swap_memcg, 1);
+   mem_cgroup_swap_statistics(swap_memcg, nr_entries);
 
page->mem_cgroup = NULL;
 
if (!mem_cgroup_is_root(memcg))
-   page_counter_uncharge(>memory, 1);
+   page_counter_uncharge(>memory, nr_entries);
 
if (memcg != swap_memcg) {
if (!mem_cgroup_is_root(swap_memcg))
-   page_counter_charge(_memcg->memsw, 1);
-   page_counter_uncharge(>memsw, 1);
+   page_counter_charge(_memcg->memsw, nr_entries);
+   page_counter_uncharge(>memsw, nr_entries);
}
 
/*
@@ -5932,7 +5938,8 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t 
entry)
 * only synchronisation we have for udpating the per-CPU variables.
 */
VM_BUG_ON(!irqs_disabled());
-   mem_cgroup_charge_statistics(memcg, page, false, -1);
+   mem_cgroup_charge_statistics(memcg, page, PageTransHuge(page),
+-nr_entries);
memcg_check_events(memcg, page);
 
if (!mem_cgroup_is_root(memcg))
-- 
2.13.2



[PATCH -mm -v3 07/12] mm, THP, swap: Support to split THP for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

After adding swapping out support for THP (Transparent Huge Page), it
is possible that a THP in swap cache (partly swapped out) need to be
split.  To split such a THP, the swap cluster backing the THP need to
be split too, that is, the CLUSTER_FLAG_HUGE flag need to be cleared
for the swap cluster.  The patch implemented this.

And because the THP swap writing needs the THP keeps as huge page
during writing.  The PageWriteback flag is checked before splitting.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 include/linux/swap.h |  9 +
 mm/huge_memory.c | 10 +-
 mm/swapfile.c| 15 +++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 7176ba780e83..461cf107ad52 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -527,6 +527,15 @@ static inline swp_entry_t get_swap_page(struct page *page)
 
 #endif /* CONFIG_SWAP */
 
+#ifdef CONFIG_THP_SWAP
+extern int split_swap_cluster(swp_entry_t entry);
+#else
+static inline int split_swap_cluster(swp_entry_t entry)
+{
+   return 0;
+}
+#endif
+
 #ifdef CONFIG_MEMCG
 static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 7392ba184126..409e9dd28e0c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2452,6 +2452,9 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(!PageCompound(page), page);
 
+   if (PageWriteback(page))
+   return -EBUSY;
+
if (PageAnon(head)) {
/*
 * The caller does not necessarily hold an mmap_sem that would
@@ -2529,7 +2532,12 @@ int split_huge_page_to_list(struct page *page, struct 
list_head *list)
__dec_node_page_state(page, NR_SHMEM_THPS);
spin_unlock(>split_queue_lock);
__split_huge_page(page, list, flags);
-   ret = 0;
+   if (PageSwapCache(head)) {
+   swp_entry_t entry = { .val = page_private(head) };
+
+   ret = split_swap_cluster(entry);
+   } else
+   ret = 0;
} else {
if (IS_ENABLED(CONFIG_DEBUG_VM) && mapcount) {
pr_alert("total_mapcount: %u, page_count(): %u\n",
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 21cbdecbc19a..1af21311a672 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1216,6 +1216,21 @@ static void swapcache_free_cluster(swp_entry_t entry)
}
}
 }
+
+int split_swap_cluster(swp_entry_t entry)
+{
+   struct swap_info_struct *si;
+   struct swap_cluster_info *ci;
+   unsigned long offset = swp_offset(entry);
+
+   si = _swap_info_get(entry);
+   if (!si)
+   return -EBUSY;
+   ci = lock_cluster(si, offset);
+   cluster_clear_huge(ci);
+   unlock_cluster(ci);
+   return 0;
+}
 #else
 static inline void swapcache_free_cluster(swp_entry_t entry)
 {
-- 
2.13.2



[PATCH -mm -v3 12/12] mm, THP, swap: Add THP swapping out fallback counting

2017-07-23 Thread Huang, Ying
From: Huang Ying 

When swapping out THP (Transparent Huge Page), instead of swapping out
the THP as a whole, sometimes we have to fallback to split the THP
into normal pages before swapping, because no free swap clusters are
available, or cgroup limit is exceeded, etc.  To count the number of
the fallback, a new VM event THP_SWPOUT_FALLBACK is added, and counted
when we fallback to split the THP.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
Cc: Michal Hocko 
---
 include/linux/vm_event_item.h | 1 +
 mm/vmscan.c   | 3 +++
 mm/vmstat.c   | 1 +
 3 files changed, 5 insertions(+)

diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index c75024e80eed..e02820fc2861 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -86,6 +86,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
THP_ZERO_PAGE_ALLOC,
THP_ZERO_PAGE_ALLOC_FAILED,
THP_SWPOUT,
+   THP_SWPOUT_FALLBACK,
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
BALLOON_INFLATE,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7472ddafc14a..4f7212f8ca00 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1153,6 +1153,9 @@ static unsigned long shrink_page_list(struct list_head 
*page_list,
if (split_huge_page_to_list(page,
page_list))
goto activate_locked;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+   count_vm_event(THP_SWPOUT_FALLBACK);
+#endif
if (!add_to_swap(page))
goto activate_locked;
}
diff --git a/mm/vmstat.c b/mm/vmstat.c
index bccf426453cd..e131b51654c7 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1072,6 +1072,7 @@ const char * const vmstat_text[] = {
"thp_zero_page_alloc",
"thp_zero_page_alloc_failed",
"thp_swpout",
+   "thp_swpout_fallback",
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
"balloon_inflate",
-- 
2.13.2



[PATCH -mm -v3 12/12] mm, THP, swap: Add THP swapping out fallback counting

2017-07-23 Thread Huang, Ying
From: Huang Ying 

When swapping out THP (Transparent Huge Page), instead of swapping out
the THP as a whole, sometimes we have to fallback to split the THP
into normal pages before swapping, because no free swap clusters are
available, or cgroup limit is exceeded, etc.  To count the number of
the fallback, a new VM event THP_SWPOUT_FALLBACK is added, and counted
when we fallback to split the THP.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
Cc: Michal Hocko 
---
 include/linux/vm_event_item.h | 1 +
 mm/vmscan.c   | 3 +++
 mm/vmstat.c   | 1 +
 3 files changed, 5 insertions(+)

diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index c75024e80eed..e02820fc2861 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -86,6 +86,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
THP_ZERO_PAGE_ALLOC,
THP_ZERO_PAGE_ALLOC_FAILED,
THP_SWPOUT,
+   THP_SWPOUT_FALLBACK,
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
BALLOON_INFLATE,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7472ddafc14a..4f7212f8ca00 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1153,6 +1153,9 @@ static unsigned long shrink_page_list(struct list_head 
*page_list,
if (split_huge_page_to_list(page,
page_list))
goto activate_locked;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+   count_vm_event(THP_SWPOUT_FALLBACK);
+#endif
if (!add_to_swap(page))
goto activate_locked;
}
diff --git a/mm/vmstat.c b/mm/vmstat.c
index bccf426453cd..e131b51654c7 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1072,6 +1072,7 @@ const char * const vmstat_text[] = {
"thp_zero_page_alloc",
"thp_zero_page_alloc_failed",
"thp_swpout",
+   "thp_swpout_fallback",
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
"balloon_inflate",
-- 
2.13.2



[PATCH -mm -v3 09/12] memcg, THP, swap: Avoid to duplicated charge THP in swap cache

2017-07-23 Thread Huang, Ying
From: Huang Ying 

For a THP (Transparent Huge Page), tail_page->mem_cgroup is NULL.  So
to check whether the page is charged already, we need to check the
head page.  This is not an issue before because it is impossible for a
THP to be in the swap cache before.  But after we add delaying
splitting THP after swapped out support, it is possible now.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c2618bd8ebdd..a627b0fd67ea 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5407,7 +5407,7 @@ int mem_cgroup_try_charge(struct page *page, struct 
mm_struct *mm,
 * in turn serializes uncharging.
 */
VM_BUG_ON_PAGE(!PageLocked(page), page);
-   if (page->mem_cgroup)
+   if (compound_head(page)->mem_cgroup)
goto out;
 
if (do_swap_account) {
-- 
2.13.2



[PATCH -mm -v3 09/12] memcg, THP, swap: Avoid to duplicated charge THP in swap cache

2017-07-23 Thread Huang, Ying
From: Huang Ying 

For a THP (Transparent Huge Page), tail_page->mem_cgroup is NULL.  So
to check whether the page is charged already, we need to check the
head page.  This is not an issue before because it is impossible for a
THP to be in the swap cache before.  But after we add delaying
splitting THP after swapped out support, it is possible now.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 mm/memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c2618bd8ebdd..a627b0fd67ea 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5407,7 +5407,7 @@ int mem_cgroup_try_charge(struct page *page, struct 
mm_struct *mm,
 * in turn serializes uncharging.
 */
VM_BUG_ON_PAGE(!PageLocked(page), page);
-   if (page->mem_cgroup)
+   if (compound_head(page)->mem_cgroup)
goto out;
 
if (do_swap_account) {
-- 
2.13.2



[PATCH -mm -v3 04/12] mm, THP, swap: Don't allocate huge cluster for file backed swap device

2017-07-23 Thread Huang, Ying
From: Huang Ying 

It's hard to write a whole transparent huge page (THP) to a file
backed swap device during swapping out and the file backed swap device
isn't very popular.  So the huge cluster allocation for the file
backed swap device is disabled.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 mm/swapfile.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index b110faf3c82a..21cbdecbc19a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -948,9 +948,10 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t 
swp_entries[])
spin_unlock(>lock);
goto nextsi;
}
-   if (cluster)
-   n_ret = swap_alloc_cluster(si, swp_entries);
-   else
+   if (cluster) {
+   if (!(si->flags & SWP_FILE))
+   n_ret = swap_alloc_cluster(si, swp_entries);
+   } else
n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE,
n_goal, swp_entries);
spin_unlock(>lock);
-- 
2.13.2



[PATCH -mm -v3 04/12] mm, THP, swap: Don't allocate huge cluster for file backed swap device

2017-07-23 Thread Huang, Ying
From: Huang Ying 

It's hard to write a whole transparent huge page (THP) to a file
backed swap device during swapping out and the file backed swap device
isn't very popular.  So the huge cluster allocation for the file
backed swap device is disabled.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 mm/swapfile.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index b110faf3c82a..21cbdecbc19a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -948,9 +948,10 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t 
swp_entries[])
spin_unlock(>lock);
goto nextsi;
}
-   if (cluster)
-   n_ret = swap_alloc_cluster(si, swp_entries);
-   else
+   if (cluster) {
+   if (!(si->flags & SWP_FILE))
+   n_ret = swap_alloc_cluster(si, swp_entries);
+   } else
n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE,
n_goal, swp_entries);
spin_unlock(>lock);
-- 
2.13.2



[PATCH -mm -v3 06/12] Test code to write THP to swap device as a whole

2017-07-23 Thread Huang, Ying
From: Huang Ying 

To support to delay splitting THP (Transparent Huge Page) after
swapped out.  We need to enhance swap writing code to support to write
a THP as a whole.  This will improve swap write IO performance.  As
Ming Lei  pointed out, this should be based on
multipage bvec support, which hasn't been merged yet.  So this patch
is only for testing the functionality of the other patches in the
series.  And will be reimplemented after multipage bvec support is
merged.

Signed-off-by: "Huang, Ying" 
---
 include/linux/bio.h   |  8 
 include/linux/page-flags.h|  4 ++--
 include/linux/vm_event_item.h |  1 +
 mm/page_io.c  | 21 -
 mm/vmstat.c   |  1 +
 5 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7b1cf4ba0902..1f0720de8990 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -38,7 +38,15 @@
 #define BIO_BUG_ON
 #endif
 
+#ifdef CONFIG_THP_SWAP
+#if HPAGE_PMD_NR > 256
+#define BIO_MAX_PAGES  HPAGE_PMD_NR
+#else
 #define BIO_MAX_PAGES  256
+#endif
+#else
+#define BIO_MAX_PAGES  256
+#endif
 
 #define bio_prio(bio)  (bio)->bi_ioprio
 #define bio_set_prio(bio, prio)((bio)->bi_ioprio = prio)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index d33e3280c8ad..ba2d470d2d0a 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -303,8 +303,8 @@ PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
  * Only test-and-set exist for PG_writeback.  The unconditional operators are
  * risky: they bypass page accounting.
  */
-TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
-   TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)
+TESTPAGEFLAG(Writeback, writeback, PF_NO_TAIL)
+   TESTSCFLAG(Writeback, writeback, PF_NO_TAIL)
 PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL)
 
 /* PG_readahead is only used for reads; PG_reclaim is only for writes */
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 37e8d31a4632..c75024e80eed 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -85,6 +85,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 #endif
THP_ZERO_PAGE_ALLOC,
THP_ZERO_PAGE_ALLOC_FAILED,
+   THP_SWPOUT,
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
BALLOON_INFLATE,
diff --git a/mm/page_io.c b/mm/page_io.c
index b6c4ac388209..d5d9871a14e5 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -27,16 +27,18 @@
 static struct bio *get_swap_bio(gfp_t gfp_flags,
struct page *page, bio_end_io_t end_io)
 {
+   int i, nr = hpage_nr_pages(page);
struct bio *bio;
 
-   bio = bio_alloc(gfp_flags, 1);
+   bio = bio_alloc(gfp_flags, nr);
if (bio) {
bio->bi_iter.bi_sector = map_swap_page(page, >bi_bdev);
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
bio->bi_end_io = end_io;
 
-   bio_add_page(bio, page, PAGE_SIZE, 0);
-   BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE);
+   for (i = 0; i < nr; i++)
+   bio_add_page(bio, page + i, PAGE_SIZE, 0);
+   VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr);
}
return bio;
 }
@@ -260,6 +262,15 @@ static sector_t swap_page_sector(struct page *page)
return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9);
 }
 
+static inline void count_swpout_vm_event(struct page *page)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+   if (unlikely(PageTransHuge(page)))
+   count_vm_event(THP_SWPOUT);
+#endif
+   count_vm_events(PSWPOUT, hpage_nr_pages(page));
+}
+
 int __swap_writepage(struct page *page, struct writeback_control *wbc,
bio_end_io_t end_write_func)
 {
@@ -311,7 +322,7 @@ int __swap_writepage(struct page *page, struct 
writeback_control *wbc,
 
ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
if (!ret) {
-   count_vm_event(PSWPOUT);
+   count_swpout_vm_event(page);
return 0;
}
 
@@ -324,7 +335,7 @@ int __swap_writepage(struct page *page, struct 
writeback_control *wbc,
goto out;
}
bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
-   count_vm_event(PSWPOUT);
+   count_swpout_vm_event(page);
set_page_writeback(page);
unlock_page(page);
submit_bio(bio);
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 9a4441bbeef2..bccf426453cd 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1071,6 +1071,7 @@ const char * const vmstat_text[] = {
 #endif
"thp_zero_page_alloc",
"thp_zero_page_alloc_failed",
+   "thp_swpout",
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
"balloon_inflate",
-- 
2.13.2



[PATCH -mm -v3 05/12] block, THP: Make block_device_operations.rw_page support THP

2017-07-23 Thread Huang, Ying
From: Huang Ying 

The .rw_page in struct block_device_operations is used by the swap
subsystem to read/write the page contents from/into the corresponding
swap slot in the swap device.  To support the THP (Transparent Huge
Page) swap optimization, the .rw_page is enhanced to support to
read/write THP if possible.

Signed-off-by: "Huang, Ying" 
Reviewed-by: Ross Zwisler  [for brd.c, zram_drv.c, 
pmem.c]
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Dan Williams 
Cc: Vishal L Verma 
Cc: Jens Axboe 
Cc: linux-nvd...@lists.01.org
---
 drivers/block/brd.c   |  6 +-
 drivers/block/zram/zram_drv.c |  2 ++
 drivers/nvdimm/btt.c  |  4 +++-
 drivers/nvdimm/pmem.c | 41 ++---
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 104b71c0490d..5d9ed0616413 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -326,7 +326,11 @@ static int brd_rw_page(struct block_device *bdev, sector_t 
sector,
   struct page *page, bool is_write)
 {
struct brd_device *brd = bdev->bd_disk->private_data;
-   int err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector);
+   int err;
+
+   if (PageTransHuge(page))
+   return -ENOTSUPP;
+   err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector);
page_endio(page, is_write, err);
return err;
 }
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 856d5dc02451..e2a305b41cd4 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -927,6 +927,8 @@ static int zram_rw_page(struct block_device *bdev, sector_t 
sector,
struct zram *zram;
struct bio_vec bv;
 
+   if (PageTransHuge(page))
+   return -ENOTSUPP;
zram = bdev->bd_disk->private_data;
 
if (!valid_io_request(zram, sector, PAGE_SIZE)) {
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 14323faf8bd9..60491641a8d6 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1241,8 +1241,10 @@ static int btt_rw_page(struct block_device *bdev, 
sector_t sector,
 {
struct btt *btt = bdev->bd_disk->private_data;
int rc;
+   unsigned int len;
 
-   rc = btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
+   len = hpage_nr_pages(page) * PAGE_SIZE;
+   rc = btt_do_bvec(btt, NULL, page, len, 0, is_write, sector);
if (rc == 0)
page_endio(page, is_write, 0);
 
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index f7099adaabc0..e9aa453da50c 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -80,22 +80,40 @@ static blk_status_t pmem_clear_poison(struct pmem_device 
*pmem,
 static void write_pmem(void *pmem_addr, struct page *page,
unsigned int off, unsigned int len)
 {
-   void *mem = kmap_atomic(page);
-
-   memcpy_flushcache(pmem_addr, mem + off, len);
-   kunmap_atomic(mem);
+   unsigned int chunk;
+   void *mem;
+
+   while (len) {
+   mem = kmap_atomic(page);
+   chunk = min_t(unsigned int, len, PAGE_SIZE);
+   memcpy_flushcache(pmem_addr, mem + off, chunk);
+   kunmap_atomic(mem);
+   len -= chunk;
+   off = 0;
+   page++;
+   pmem_addr += PAGE_SIZE;
+   }
 }
 
 static blk_status_t read_pmem(struct page *page, unsigned int off,
void *pmem_addr, unsigned int len)
 {
+   unsigned int chunk;
int rc;
-   void *mem = kmap_atomic(page);
-
-   rc = memcpy_mcsafe(mem + off, pmem_addr, len);
-   kunmap_atomic(mem);
-   if (rc)
-   return BLK_STS_IOERR;
+   void *mem;
+
+   while (len) {
+   mem = kmap_atomic(page);
+   chunk = min_t(unsigned int, len, PAGE_SIZE);
+   rc = memcpy_mcsafe(mem + off, pmem_addr, chunk);
+   kunmap_atomic(mem);
+   if (rc)
+   return BLK_STS_IOERR;
+   len -= chunk;
+   off = 0;
+   page++;
+   pmem_addr += PAGE_SIZE;
+   }
return BLK_STS_OK;
 }
 
@@ -188,7 +206,8 @@ static int pmem_rw_page(struct block_device *bdev, sector_t 
sector,
struct pmem_device *pmem = bdev->bd_queue->queuedata;
blk_status_t rc;
 
-   rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, is_write, sector);
+   rc = pmem_do_bvec(pmem, page, hpage_nr_pages(page) * PAGE_SIZE,
+ 0, is_write, sector);
 
/*
 * The ->rw_page interface is subtle and tricky.  The core
-- 
2.13.2



[PATCH -mm -v3 03/12] mm, THP, swap: Make reuse_swap_page() works for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

After supporting to delay THP (Transparent Huge Page) splitting after
swapped out, it is possible that some page table mappings of the THP
are turned into swap entries.  So reuse_swap_page() need to check the
swap count in addition to the map count as before.  This patch done
that.

In the huge PMD write protect fault handler, in addition to the page
map count, the swap count need to be checked too, so the page lock
need to be acquired too when calling reuse_swap_page() in addition to
the page table lock.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 include/linux/swap.h |   4 +-
 mm/huge_memory.c |  16 +++-
 mm/memory.c  |   6 +--
 mm/swapfile.c| 102 ++-
 4 files changed, 113 insertions(+), 15 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 964b4f1fba4a..7176ba780e83 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -510,8 +510,8 @@ static inline int swp_swapcount(swp_entry_t entry)
return 0;
 }
 
-#define reuse_swap_page(page, total_mapcount) \
-   (page_trans_huge_mapcount(page, total_mapcount) == 1)
+#define reuse_swap_page(page, total_map_swapcount) \
+   (page_trans_huge_mapcount(page, total_map_swapcount) == 1)
 
 static inline int try_to_free_swap(struct page *page)
 {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 86975dec0ba1..7392ba184126 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1226,15 +1226,29 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t 
orig_pmd)
 * We can only reuse the page if nobody else maps the huge page or it's
 * part.
 */
-   if (page_trans_huge_mapcount(page, NULL) == 1) {
+   if (!trylock_page(page)) {
+   get_page(page);
+   spin_unlock(vmf->ptl);
+   lock_page(page);
+   spin_lock(vmf->ptl);
+   if (unlikely(!pmd_same(*vmf->pmd, orig_pmd))) {
+   unlock_page(page);
+   put_page(page);
+   goto out_unlock;
+   }
+   put_page(page);
+   }
+   if (reuse_swap_page(page, NULL)) {
pmd_t entry;
entry = pmd_mkyoung(orig_pmd);
entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry,  1))
update_mmu_cache_pmd(vma, vmf->address, vmf->pmd);
ret |= VM_FAULT_WRITE;
+   unlock_page(page);
goto out_unlock;
}
+   unlock_page(page);
get_page(page);
spin_unlock(vmf->ptl);
 alloc:
diff --git a/mm/memory.c b/mm/memory.c
index 0e517be91a89..8e7452c619bc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2541,7 +2541,7 @@ static int do_wp_page(struct vm_fault *vmf)
 * not dirty accountable.
 */
if (PageAnon(vmf->page) && !PageKsm(vmf->page)) {
-   int total_mapcount;
+   int total_map_swapcount;
if (!trylock_page(vmf->page)) {
get_page(vmf->page);
pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -2556,8 +2556,8 @@ static int do_wp_page(struct vm_fault *vmf)
}
put_page(vmf->page);
}
-   if (reuse_swap_page(vmf->page, _mapcount)) {
-   if (total_mapcount == 1) {
+   if (reuse_swap_page(vmf->page, _map_swapcount)) {
+   if (total_map_swapcount == 1) {
/*
 * The page is all ours. Move it to
 * our anon_vma so the rmap code will
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 7db19846f8c7..b110faf3c82a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1405,9 +1405,89 @@ static bool page_swapped(struct page *page)
return swap_page_trans_huge_swapped(si, entry);
return false;
 }
+
+static int page_trans_huge_map_swapcount(struct page *page, int 
*total_mapcount,
+int *total_swapcount)
+{
+   int i, map_swapcount, _total_mapcount, _total_swapcount;
+   unsigned long offset;
+   struct swap_info_struct *si;
+   struct swap_cluster_info *ci = NULL;
+   unsigned char *map = NULL;
+   int mapcount, swapcount = 0;
+
+   /* hugetlbfs shouldn't call it */
+   VM_BUG_ON_PAGE(PageHuge(page), page);
+
+   if (likely(!PageTransCompound(page))) {
+   mapcount = atomic_read(>_mapcount) + 1;
+   if 

[PATCH -mm -v3 06/12] Test code to write THP to swap device as a whole

2017-07-23 Thread Huang, Ying
From: Huang Ying 

To support to delay splitting THP (Transparent Huge Page) after
swapped out.  We need to enhance swap writing code to support to write
a THP as a whole.  This will improve swap write IO performance.  As
Ming Lei  pointed out, this should be based on
multipage bvec support, which hasn't been merged yet.  So this patch
is only for testing the functionality of the other patches in the
series.  And will be reimplemented after multipage bvec support is
merged.

Signed-off-by: "Huang, Ying" 
---
 include/linux/bio.h   |  8 
 include/linux/page-flags.h|  4 ++--
 include/linux/vm_event_item.h |  1 +
 mm/page_io.c  | 21 -
 mm/vmstat.c   |  1 +
 5 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7b1cf4ba0902..1f0720de8990 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -38,7 +38,15 @@
 #define BIO_BUG_ON
 #endif
 
+#ifdef CONFIG_THP_SWAP
+#if HPAGE_PMD_NR > 256
+#define BIO_MAX_PAGES  HPAGE_PMD_NR
+#else
 #define BIO_MAX_PAGES  256
+#endif
+#else
+#define BIO_MAX_PAGES  256
+#endif
 
 #define bio_prio(bio)  (bio)->bi_ioprio
 #define bio_set_prio(bio, prio)((bio)->bi_ioprio = prio)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index d33e3280c8ad..ba2d470d2d0a 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -303,8 +303,8 @@ PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
  * Only test-and-set exist for PG_writeback.  The unconditional operators are
  * risky: they bypass page accounting.
  */
-TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
-   TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)
+TESTPAGEFLAG(Writeback, writeback, PF_NO_TAIL)
+   TESTSCFLAG(Writeback, writeback, PF_NO_TAIL)
 PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL)
 
 /* PG_readahead is only used for reads; PG_reclaim is only for writes */
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 37e8d31a4632..c75024e80eed 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -85,6 +85,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
 #endif
THP_ZERO_PAGE_ALLOC,
THP_ZERO_PAGE_ALLOC_FAILED,
+   THP_SWPOUT,
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
BALLOON_INFLATE,
diff --git a/mm/page_io.c b/mm/page_io.c
index b6c4ac388209..d5d9871a14e5 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -27,16 +27,18 @@
 static struct bio *get_swap_bio(gfp_t gfp_flags,
struct page *page, bio_end_io_t end_io)
 {
+   int i, nr = hpage_nr_pages(page);
struct bio *bio;
 
-   bio = bio_alloc(gfp_flags, 1);
+   bio = bio_alloc(gfp_flags, nr);
if (bio) {
bio->bi_iter.bi_sector = map_swap_page(page, >bi_bdev);
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
bio->bi_end_io = end_io;
 
-   bio_add_page(bio, page, PAGE_SIZE, 0);
-   BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE);
+   for (i = 0; i < nr; i++)
+   bio_add_page(bio, page + i, PAGE_SIZE, 0);
+   VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr);
}
return bio;
 }
@@ -260,6 +262,15 @@ static sector_t swap_page_sector(struct page *page)
return (sector_t)__page_file_index(page) << (PAGE_SHIFT - 9);
 }
 
+static inline void count_swpout_vm_event(struct page *page)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+   if (unlikely(PageTransHuge(page)))
+   count_vm_event(THP_SWPOUT);
+#endif
+   count_vm_events(PSWPOUT, hpage_nr_pages(page));
+}
+
 int __swap_writepage(struct page *page, struct writeback_control *wbc,
bio_end_io_t end_write_func)
 {
@@ -311,7 +322,7 @@ int __swap_writepage(struct page *page, struct 
writeback_control *wbc,
 
ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
if (!ret) {
-   count_vm_event(PSWPOUT);
+   count_swpout_vm_event(page);
return 0;
}
 
@@ -324,7 +335,7 @@ int __swap_writepage(struct page *page, struct 
writeback_control *wbc,
goto out;
}
bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
-   count_vm_event(PSWPOUT);
+   count_swpout_vm_event(page);
set_page_writeback(page);
unlock_page(page);
submit_bio(bio);
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 9a4441bbeef2..bccf426453cd 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1071,6 +1071,7 @@ const char * const vmstat_text[] = {
 #endif
"thp_zero_page_alloc",
"thp_zero_page_alloc_failed",
+   "thp_swpout",
 #endif
 #ifdef CONFIG_MEMORY_BALLOON
"balloon_inflate",
-- 
2.13.2



[PATCH -mm -v3 05/12] block, THP: Make block_device_operations.rw_page support THP

2017-07-23 Thread Huang, Ying
From: Huang Ying 

The .rw_page in struct block_device_operations is used by the swap
subsystem to read/write the page contents from/into the corresponding
swap slot in the swap device.  To support the THP (Transparent Huge
Page) swap optimization, the .rw_page is enhanced to support to
read/write THP if possible.

Signed-off-by: "Huang, Ying" 
Reviewed-by: Ross Zwisler  [for brd.c, zram_drv.c, 
pmem.c]
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Dan Williams 
Cc: Vishal L Verma 
Cc: Jens Axboe 
Cc: linux-nvd...@lists.01.org
---
 drivers/block/brd.c   |  6 +-
 drivers/block/zram/zram_drv.c |  2 ++
 drivers/nvdimm/btt.c  |  4 +++-
 drivers/nvdimm/pmem.c | 41 ++---
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 104b71c0490d..5d9ed0616413 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -326,7 +326,11 @@ static int brd_rw_page(struct block_device *bdev, sector_t 
sector,
   struct page *page, bool is_write)
 {
struct brd_device *brd = bdev->bd_disk->private_data;
-   int err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector);
+   int err;
+
+   if (PageTransHuge(page))
+   return -ENOTSUPP;
+   err = brd_do_bvec(brd, page, PAGE_SIZE, 0, is_write, sector);
page_endio(page, is_write, err);
return err;
 }
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 856d5dc02451..e2a305b41cd4 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -927,6 +927,8 @@ static int zram_rw_page(struct block_device *bdev, sector_t 
sector,
struct zram *zram;
struct bio_vec bv;
 
+   if (PageTransHuge(page))
+   return -ENOTSUPP;
zram = bdev->bd_disk->private_data;
 
if (!valid_io_request(zram, sector, PAGE_SIZE)) {
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 14323faf8bd9..60491641a8d6 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1241,8 +1241,10 @@ static int btt_rw_page(struct block_device *bdev, 
sector_t sector,
 {
struct btt *btt = bdev->bd_disk->private_data;
int rc;
+   unsigned int len;
 
-   rc = btt_do_bvec(btt, NULL, page, PAGE_SIZE, 0, is_write, sector);
+   len = hpage_nr_pages(page) * PAGE_SIZE;
+   rc = btt_do_bvec(btt, NULL, page, len, 0, is_write, sector);
if (rc == 0)
page_endio(page, is_write, 0);
 
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index f7099adaabc0..e9aa453da50c 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -80,22 +80,40 @@ static blk_status_t pmem_clear_poison(struct pmem_device 
*pmem,
 static void write_pmem(void *pmem_addr, struct page *page,
unsigned int off, unsigned int len)
 {
-   void *mem = kmap_atomic(page);
-
-   memcpy_flushcache(pmem_addr, mem + off, len);
-   kunmap_atomic(mem);
+   unsigned int chunk;
+   void *mem;
+
+   while (len) {
+   mem = kmap_atomic(page);
+   chunk = min_t(unsigned int, len, PAGE_SIZE);
+   memcpy_flushcache(pmem_addr, mem + off, chunk);
+   kunmap_atomic(mem);
+   len -= chunk;
+   off = 0;
+   page++;
+   pmem_addr += PAGE_SIZE;
+   }
 }
 
 static blk_status_t read_pmem(struct page *page, unsigned int off,
void *pmem_addr, unsigned int len)
 {
+   unsigned int chunk;
int rc;
-   void *mem = kmap_atomic(page);
-
-   rc = memcpy_mcsafe(mem + off, pmem_addr, len);
-   kunmap_atomic(mem);
-   if (rc)
-   return BLK_STS_IOERR;
+   void *mem;
+
+   while (len) {
+   mem = kmap_atomic(page);
+   chunk = min_t(unsigned int, len, PAGE_SIZE);
+   rc = memcpy_mcsafe(mem + off, pmem_addr, chunk);
+   kunmap_atomic(mem);
+   if (rc)
+   return BLK_STS_IOERR;
+   len -= chunk;
+   off = 0;
+   page++;
+   pmem_addr += PAGE_SIZE;
+   }
return BLK_STS_OK;
 }
 
@@ -188,7 +206,8 @@ static int pmem_rw_page(struct block_device *bdev, sector_t 
sector,
struct pmem_device *pmem = bdev->bd_queue->queuedata;
blk_status_t rc;
 
-   rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, is_write, sector);
+   rc = pmem_do_bvec(pmem, page, hpage_nr_pages(page) * PAGE_SIZE,
+ 0, is_write, sector);
 
/*
 * The ->rw_page interface is subtle and tricky.  The core
-- 
2.13.2



[PATCH -mm -v3 03/12] mm, THP, swap: Make reuse_swap_page() works for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

After supporting to delay THP (Transparent Huge Page) splitting after
swapped out, it is possible that some page table mappings of the THP
are turned into swap entries.  So reuse_swap_page() need to check the
swap count in addition to the map count as before.  This patch done
that.

In the huge PMD write protect fault handler, in addition to the page
map count, the swap count need to be checked too, so the page lock
need to be acquired too when calling reuse_swap_page() in addition to
the page table lock.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
Cc: Andrea Arcangeli 
Cc: "Kirill A . Shutemov" 
---
 include/linux/swap.h |   4 +-
 mm/huge_memory.c |  16 +++-
 mm/memory.c  |   6 +--
 mm/swapfile.c| 102 ++-
 4 files changed, 113 insertions(+), 15 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 964b4f1fba4a..7176ba780e83 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -510,8 +510,8 @@ static inline int swp_swapcount(swp_entry_t entry)
return 0;
 }
 
-#define reuse_swap_page(page, total_mapcount) \
-   (page_trans_huge_mapcount(page, total_mapcount) == 1)
+#define reuse_swap_page(page, total_map_swapcount) \
+   (page_trans_huge_mapcount(page, total_map_swapcount) == 1)
 
 static inline int try_to_free_swap(struct page *page)
 {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 86975dec0ba1..7392ba184126 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1226,15 +1226,29 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t 
orig_pmd)
 * We can only reuse the page if nobody else maps the huge page or it's
 * part.
 */
-   if (page_trans_huge_mapcount(page, NULL) == 1) {
+   if (!trylock_page(page)) {
+   get_page(page);
+   spin_unlock(vmf->ptl);
+   lock_page(page);
+   spin_lock(vmf->ptl);
+   if (unlikely(!pmd_same(*vmf->pmd, orig_pmd))) {
+   unlock_page(page);
+   put_page(page);
+   goto out_unlock;
+   }
+   put_page(page);
+   }
+   if (reuse_swap_page(page, NULL)) {
pmd_t entry;
entry = pmd_mkyoung(orig_pmd);
entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry,  1))
update_mmu_cache_pmd(vma, vmf->address, vmf->pmd);
ret |= VM_FAULT_WRITE;
+   unlock_page(page);
goto out_unlock;
}
+   unlock_page(page);
get_page(page);
spin_unlock(vmf->ptl);
 alloc:
diff --git a/mm/memory.c b/mm/memory.c
index 0e517be91a89..8e7452c619bc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2541,7 +2541,7 @@ static int do_wp_page(struct vm_fault *vmf)
 * not dirty accountable.
 */
if (PageAnon(vmf->page) && !PageKsm(vmf->page)) {
-   int total_mapcount;
+   int total_map_swapcount;
if (!trylock_page(vmf->page)) {
get_page(vmf->page);
pte_unmap_unlock(vmf->pte, vmf->ptl);
@@ -2556,8 +2556,8 @@ static int do_wp_page(struct vm_fault *vmf)
}
put_page(vmf->page);
}
-   if (reuse_swap_page(vmf->page, _mapcount)) {
-   if (total_mapcount == 1) {
+   if (reuse_swap_page(vmf->page, _map_swapcount)) {
+   if (total_map_swapcount == 1) {
/*
 * The page is all ours. Move it to
 * our anon_vma so the rmap code will
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 7db19846f8c7..b110faf3c82a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1405,9 +1405,89 @@ static bool page_swapped(struct page *page)
return swap_page_trans_huge_swapped(si, entry);
return false;
 }
+
+static int page_trans_huge_map_swapcount(struct page *page, int 
*total_mapcount,
+int *total_swapcount)
+{
+   int i, map_swapcount, _total_mapcount, _total_swapcount;
+   unsigned long offset;
+   struct swap_info_struct *si;
+   struct swap_cluster_info *ci = NULL;
+   unsigned char *map = NULL;
+   int mapcount, swapcount = 0;
+
+   /* hugetlbfs shouldn't call it */
+   VM_BUG_ON_PAGE(PageHuge(page), page);
+
+   if (likely(!PageTransCompound(page))) {
+   mapcount = atomic_read(>_mapcount) + 1;
+   if (total_mapcount)
+   *total_mapcount = mapcount;
+   if (PageSwapCache(page))
+   swapcount = page_swapcount(page);
+   if 

[PATCH -mm -v3 00/12] mm, THP, swap: Delay splitting THP after swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

Hi, Andrew, could you help me to check whether the overall design is
reasonable?

Hi, Johannes and Minchan, Thanks a lot for your review to the first
step of the THP swap optimization!  Could you help me to review the
second step in this patchset?

Hi, Hugh, Shaohua, Minchan and Rik, could you help me to review the
swap part of the patchset?  Especially [01/12], [02/12], [03/12],
[04/12], [11/12], and [12/12].

Hi, Andrea and Kirill, could you help me to review the THP part of the
patchset?  Especially [01/12], [03/12], [07/12], [08/12], [09/12],
[11/12].

Hi, Johannes, Michal, could you help me to review the cgroup part of
the patchset?  Especially [08/12], [09/12], and [10/12].

And for all, Any comment is welcome!

Because the THP swap writing support patch [06/12] needs to be rebased
on multipage bvec patchset which hasn't been merged yet.  The [06/12]
in this patchset is just a test patch and will be rewritten later.
The patchset depends on multipage bvec patchset too.

This is the second step of THP (Transparent Huge Page) swap
optimization.  In the first step, the splitting huge page is delayed
from almost the first step of swapping out to after allocating the
swap space for the THP and adding the THP into the swap cache.  In the
second step, the splitting is delayed further to after the swapping
out finished.  The plan is to delay splitting THP step by step,
finally avoid splitting THP for the THP swapping out and swap out/in
the THP as a whole.

In the patchset, more operations for the anonymous THP reclaiming,
such as TLB flushing, writing the THP to the swap device, removing the
THP from the swap cache are batched.  So that the performance of
anonymous THP swapping out are improved.

This patchset is based on the 7/14 head of mmotm/master.

During the development, the following scenarios/code paths have been
checked,

- swap out/in
- swap off
- write protect page fault
- madvise_free
- process exit
- split huge page

Please let me know if I missed something.

With the patchset, the swap out throughput improves 42% (from about
5.81GB/s to about 8.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  At the same time, the IPI (reflect TLB flushing)
reduced about 78.9%.  The test is done on a Xeon E5 v3 system.  The
swap device used is a RAM simulated PMEM (persistent memory) device.
To test the sequential swapping out, the test case creates 8
processes, which sequentially allocate and write to the anonymous
pages until the RAM and part of the swap device is used up.

Below is the part of the cover letter for the first step patchset of
THP swap optimization which applies to all steps.

->

Recently, the performance of the storage devices improved so fast that
we cannot saturate the disk bandwidth with single logical CPU when do
page swap out even on a high-end server machine.  Because the
performance of the storage device improved faster than that of single
logical CPU.  And it seems that the trend will not change in the near
future.  On the other hand, the THP becomes more and more popular
because of increased memory size.  So it becomes necessary to optimize
THP swap performance.

The advantages of the THP swap support include:

- Batch the swap operations for the THP to reduce TLB flushing and
  lock acquiring/releasing, including allocating/freeing the swap
  space, adding/deleting to/from the swap cache, and writing/reading
  the swap space, etc.  This will help improve the performance of the
  THP swap.

- The THP swap space read/write will be 2M sequential IO.  It is
  particularly helpful for the swap read, which are usually 4k random
  IO.  This will improve the performance of the THP swap too.

- It will help the memory fragmentation, especially when the THP is
  heavily used by the applications.  The 2M continuous pages will be
  free up after THP swapping out.

- It will improve the THP utilization on the system with the swap
  turned on.  Because the speed for khugepaged to collapse the normal
  pages into the THP is quite slow.  After the THP is split during the
  swapping out, it will take quite long time for the normal pages to
  collapse back into the THP after being swapped in.  The high THP
  utilization helps the efficiency of the page based memory management
  too.

There are some concerns regarding THP swap in, mainly because possible
enlarged read/write IO size (for swap in/out) may put more overhead on
the storage device.  To deal with that, the THP swap in should be
turned on only when necessary.  For example, it can be selected via
"always/never/madvise" logic, to be turned on globally, turned off
globally, or turned on only for VMA with MADV_HUGEPAGE, etc.

Changelog:

v3:

- Rebased on latest -mm tree
- Some minor fixes

Best Regards,
Huang, Ying


[PATCH -mm -v3 00/12] mm, THP, swap: Delay splitting THP after swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

Hi, Andrew, could you help me to check whether the overall design is
reasonable?

Hi, Johannes and Minchan, Thanks a lot for your review to the first
step of the THP swap optimization!  Could you help me to review the
second step in this patchset?

Hi, Hugh, Shaohua, Minchan and Rik, could you help me to review the
swap part of the patchset?  Especially [01/12], [02/12], [03/12],
[04/12], [11/12], and [12/12].

Hi, Andrea and Kirill, could you help me to review the THP part of the
patchset?  Especially [01/12], [03/12], [07/12], [08/12], [09/12],
[11/12].

Hi, Johannes, Michal, could you help me to review the cgroup part of
the patchset?  Especially [08/12], [09/12], and [10/12].

And for all, Any comment is welcome!

Because the THP swap writing support patch [06/12] needs to be rebased
on multipage bvec patchset which hasn't been merged yet.  The [06/12]
in this patchset is just a test patch and will be rewritten later.
The patchset depends on multipage bvec patchset too.

This is the second step of THP (Transparent Huge Page) swap
optimization.  In the first step, the splitting huge page is delayed
from almost the first step of swapping out to after allocating the
swap space for the THP and adding the THP into the swap cache.  In the
second step, the splitting is delayed further to after the swapping
out finished.  The plan is to delay splitting THP step by step,
finally avoid splitting THP for the THP swapping out and swap out/in
the THP as a whole.

In the patchset, more operations for the anonymous THP reclaiming,
such as TLB flushing, writing the THP to the swap device, removing the
THP from the swap cache are batched.  So that the performance of
anonymous THP swapping out are improved.

This patchset is based on the 7/14 head of mmotm/master.

During the development, the following scenarios/code paths have been
checked,

- swap out/in
- swap off
- write protect page fault
- madvise_free
- process exit
- split huge page

Please let me know if I missed something.

With the patchset, the swap out throughput improves 42% (from about
5.81GB/s to about 8.25GB/s) in the vm-scalability swap-w-seq test case
with 16 processes.  At the same time, the IPI (reflect TLB flushing)
reduced about 78.9%.  The test is done on a Xeon E5 v3 system.  The
swap device used is a RAM simulated PMEM (persistent memory) device.
To test the sequential swapping out, the test case creates 8
processes, which sequentially allocate and write to the anonymous
pages until the RAM and part of the swap device is used up.

Below is the part of the cover letter for the first step patchset of
THP swap optimization which applies to all steps.

->

Recently, the performance of the storage devices improved so fast that
we cannot saturate the disk bandwidth with single logical CPU when do
page swap out even on a high-end server machine.  Because the
performance of the storage device improved faster than that of single
logical CPU.  And it seems that the trend will not change in the near
future.  On the other hand, the THP becomes more and more popular
because of increased memory size.  So it becomes necessary to optimize
THP swap performance.

The advantages of the THP swap support include:

- Batch the swap operations for the THP to reduce TLB flushing and
  lock acquiring/releasing, including allocating/freeing the swap
  space, adding/deleting to/from the swap cache, and writing/reading
  the swap space, etc.  This will help improve the performance of the
  THP swap.

- The THP swap space read/write will be 2M sequential IO.  It is
  particularly helpful for the swap read, which are usually 4k random
  IO.  This will improve the performance of the THP swap too.

- It will help the memory fragmentation, especially when the THP is
  heavily used by the applications.  The 2M continuous pages will be
  free up after THP swapping out.

- It will improve the THP utilization on the system with the swap
  turned on.  Because the speed for khugepaged to collapse the normal
  pages into the THP is quite slow.  After the THP is split during the
  swapping out, it will take quite long time for the normal pages to
  collapse back into the THP after being swapped in.  The high THP
  utilization helps the efficiency of the page based memory management
  too.

There are some concerns regarding THP swap in, mainly because possible
enlarged read/write IO size (for swap in/out) may put more overhead on
the storage device.  To deal with that, the THP swap in should be
turned on only when necessary.  For example, it can be selected via
"always/never/madvise" logic, to be turned on globally, turned off
globally, or turned on only for VMA with MADV_HUGEPAGE, etc.

Changelog:

v3:

- Rebased on latest -mm tree
- Some minor fixes

Best Regards,
Huang, Ying


[PATCH -mm -v3 02/12] mm, THP, swap: Support to reclaim swap space for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

The normal swap slot reclaiming can be done when the swap count
reaches SWAP_HAS_CACHE.  But for the swap slot which is backing a THP,
all swap slots backing one THP must be reclaimed together, because the
swap slot may be used again when the THP is swapped out again later.
So the swap slots backing one THP can be reclaimed together when the
swap count for all swap slots for the THP reached SWAP_HAS_CACHE.  In
the patch, the functions to check whether the swap count for all swap
slots backing one THP reached SWAP_HAS_CACHE are implemented and used
when checking whether a swap slot can be reclaimed.

To make it easier to determine whether a swap slot is backing a THP, a
new swap cluster flag named CLUSTER_FLAG_HUGE is added to mark a swap
cluster which is backing a THP (Transparent Huge Page).  Because THP
swap in as a whole isn't supported now.  After deleting the THP from
the swap cache (for example, swapping out finished), the
CLUSTER_FLAG_HUGE flag will be cleared.  So that, the normal pages
inside THP can be swapped in individually.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 include/linux/swap.h |  1 +
 mm/swapfile.c| 78 +++-
 2 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index d83d28e53e62..964b4f1fba4a 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -188,6 +188,7 @@ struct swap_cluster_info {
 };
 #define CLUSTER_FLAG_FREE 1 /* This cluster is free */
 #define CLUSTER_FLAG_NEXT_NULL 2 /* This cluster has no next cluster */
+#define CLUSTER_FLAG_HUGE 4 /* This cluster is backing a transparent huge page 
*/
 
 /*
  * We assign a cluster to each CPU, so each CPU can allocate swap entry from
diff --git a/mm/swapfile.c b/mm/swapfile.c
index c32e9b23d642..7db19846f8c7 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -265,6 +265,16 @@ static inline void cluster_set_null(struct 
swap_cluster_info *info)
info->data = 0;
 }
 
+static inline bool cluster_is_huge(struct swap_cluster_info *info)
+{
+   return info->flags & CLUSTER_FLAG_HUGE;
+}
+
+static inline void cluster_clear_huge(struct swap_cluster_info *info)
+{
+   info->flags &= ~CLUSTER_FLAG_HUGE;
+}
+
 static inline struct swap_cluster_info *lock_cluster(struct swap_info_struct 
*si,
 unsigned long offset)
 {
@@ -846,7 +856,7 @@ static int swap_alloc_cluster(struct swap_info_struct *si, 
swp_entry_t *slot)
offset = idx * SWAPFILE_CLUSTER;
ci = lock_cluster(si, offset);
alloc_cluster(si, idx);
-   cluster_set_count_flag(ci, SWAPFILE_CLUSTER, 0);
+   cluster_set_count_flag(ci, SWAPFILE_CLUSTER, CLUSTER_FLAG_HUGE);
 
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++)
@@ -1176,6 +1186,7 @@ static void swapcache_free_cluster(swp_entry_t entry)
return;
 
ci = lock_cluster(si, offset);
+   VM_BUG_ON(!cluster_is_huge(ci));
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++) {
val = map[i];
@@ -1187,6 +1198,7 @@ static void swapcache_free_cluster(swp_entry_t entry)
for (i = 0; i < SWAPFILE_CLUSTER; i++)
map[i] &= ~SWAP_HAS_CACHE;
}
+   cluster_clear_huge(ci);
unlock_cluster(ci);
if (free_entries == SWAPFILE_CLUSTER) {
spin_lock(>lock);
@@ -1350,6 +1362,54 @@ int swp_swapcount(swp_entry_t entry)
return count;
 }
 
+#ifdef CONFIG_THP_SWAP
+static bool swap_page_trans_huge_swapped(struct swap_info_struct *si,
+swp_entry_t entry)
+{
+   struct swap_cluster_info *ci;
+   unsigned char *map = si->swap_map;
+   unsigned long roffset = swp_offset(entry);
+   unsigned long offset = round_down(roffset, SWAPFILE_CLUSTER);
+   int i;
+   bool ret = false;
+
+   ci = lock_cluster_or_swap_info(si, offset);
+   if (!cluster_is_huge(ci)) {
+   if (map[roffset] != SWAP_HAS_CACHE)
+   ret = true;
+   goto unlock_out;
+   }
+   for (i = 0; i < SWAPFILE_CLUSTER; i++) {
+   if (map[offset + i] != SWAP_HAS_CACHE) {
+   ret = true;
+   break;
+   }
+   }
+unlock_out:
+   unlock_cluster_or_swap_info(si, ci);
+   return ret;
+}
+
+static bool page_swapped(struct page *page)
+{
+   swp_entry_t entry;
+   struct swap_info_struct *si;
+
+   if (likely(!PageTransCompound(page)))
+   return page_swapcount(page) != 0;
+
+   page = compound_head(page);
+   entry.val = page_private(page);
+   si = 

[PATCH -mm -v3 01/12] mm, THP, swap: Support to clear swap cache flag for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

Previously, swapcache_free_cluster() is used only in the error path of
shrink_page_list() to free the swap cluster just allocated if the
THP (Transparent Huge Page) is failed to be split.  In this patch, it
is enhanced to clear the swap cache flag (SWAP_HAS_CACHE) for the swap
cluster that holds the contents of THP swapped out.

This will be used in delaying splitting THP after swapping out
support.  Because there is no THP swapping in as a whole support yet,
after clearing the swap cache flag, the swap cluster backing the THP
swapped out will be split.  So that the swap slots in the swap cluster
can be swapped in as normal pages later.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 mm/swapfile.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6ba4aab2db0b..c32e9b23d642 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1168,22 +1168,40 @@ static void swapcache_free_cluster(swp_entry_t entry)
struct swap_cluster_info *ci;
struct swap_info_struct *si;
unsigned char *map;
-   unsigned int i;
+   unsigned int i, free_entries = 0;
+   unsigned char val;
 
-   si = swap_info_get(entry);
+   si = _swap_info_get(entry);
if (!si)
return;
 
ci = lock_cluster(si, offset);
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++) {
-   VM_BUG_ON(map[i] != SWAP_HAS_CACHE);
-   map[i] = 0;
+   val = map[i];
+   VM_BUG_ON(!(val & SWAP_HAS_CACHE));
+   if (val == SWAP_HAS_CACHE)
+   free_entries++;
+   }
+   if (!free_entries) {
+   for (i = 0; i < SWAPFILE_CLUSTER; i++)
+   map[i] &= ~SWAP_HAS_CACHE;
}
unlock_cluster(ci);
-   mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
-   swap_free_cluster(si, idx);
-   spin_unlock(>lock);
+   if (free_entries == SWAPFILE_CLUSTER) {
+   spin_lock(>lock);
+   ci = lock_cluster(si, offset);
+   memset(map, 0, SWAPFILE_CLUSTER);
+   unlock_cluster(ci);
+   mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
+   swap_free_cluster(si, idx);
+   spin_unlock(>lock);
+   } else if (free_entries) {
+   for (i = 0; i < SWAPFILE_CLUSTER; i++, entry.val++) {
+   if (!__swap_entry_free(si, entry, SWAP_HAS_CACHE))
+   free_swap_slot(entry);
+   }
+   }
 }
 #else
 static inline void swapcache_free_cluster(swp_entry_t entry)
-- 
2.13.2



[PATCH -mm -v3 02/12] mm, THP, swap: Support to reclaim swap space for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

The normal swap slot reclaiming can be done when the swap count
reaches SWAP_HAS_CACHE.  But for the swap slot which is backing a THP,
all swap slots backing one THP must be reclaimed together, because the
swap slot may be used again when the THP is swapped out again later.
So the swap slots backing one THP can be reclaimed together when the
swap count for all swap slots for the THP reached SWAP_HAS_CACHE.  In
the patch, the functions to check whether the swap count for all swap
slots backing one THP reached SWAP_HAS_CACHE are implemented and used
when checking whether a swap slot can be reclaimed.

To make it easier to determine whether a swap slot is backing a THP, a
new swap cluster flag named CLUSTER_FLAG_HUGE is added to mark a swap
cluster which is backing a THP (Transparent Huge Page).  Because THP
swap in as a whole isn't supported now.  After deleting the THP from
the swap cache (for example, swapping out finished), the
CLUSTER_FLAG_HUGE flag will be cleared.  So that, the normal pages
inside THP can be swapped in individually.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 include/linux/swap.h |  1 +
 mm/swapfile.c| 78 +++-
 2 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index d83d28e53e62..964b4f1fba4a 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -188,6 +188,7 @@ struct swap_cluster_info {
 };
 #define CLUSTER_FLAG_FREE 1 /* This cluster is free */
 #define CLUSTER_FLAG_NEXT_NULL 2 /* This cluster has no next cluster */
+#define CLUSTER_FLAG_HUGE 4 /* This cluster is backing a transparent huge page 
*/
 
 /*
  * We assign a cluster to each CPU, so each CPU can allocate swap entry from
diff --git a/mm/swapfile.c b/mm/swapfile.c
index c32e9b23d642..7db19846f8c7 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -265,6 +265,16 @@ static inline void cluster_set_null(struct 
swap_cluster_info *info)
info->data = 0;
 }
 
+static inline bool cluster_is_huge(struct swap_cluster_info *info)
+{
+   return info->flags & CLUSTER_FLAG_HUGE;
+}
+
+static inline void cluster_clear_huge(struct swap_cluster_info *info)
+{
+   info->flags &= ~CLUSTER_FLAG_HUGE;
+}
+
 static inline struct swap_cluster_info *lock_cluster(struct swap_info_struct 
*si,
 unsigned long offset)
 {
@@ -846,7 +856,7 @@ static int swap_alloc_cluster(struct swap_info_struct *si, 
swp_entry_t *slot)
offset = idx * SWAPFILE_CLUSTER;
ci = lock_cluster(si, offset);
alloc_cluster(si, idx);
-   cluster_set_count_flag(ci, SWAPFILE_CLUSTER, 0);
+   cluster_set_count_flag(ci, SWAPFILE_CLUSTER, CLUSTER_FLAG_HUGE);
 
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++)
@@ -1176,6 +1186,7 @@ static void swapcache_free_cluster(swp_entry_t entry)
return;
 
ci = lock_cluster(si, offset);
+   VM_BUG_ON(!cluster_is_huge(ci));
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++) {
val = map[i];
@@ -1187,6 +1198,7 @@ static void swapcache_free_cluster(swp_entry_t entry)
for (i = 0; i < SWAPFILE_CLUSTER; i++)
map[i] &= ~SWAP_HAS_CACHE;
}
+   cluster_clear_huge(ci);
unlock_cluster(ci);
if (free_entries == SWAPFILE_CLUSTER) {
spin_lock(>lock);
@@ -1350,6 +1362,54 @@ int swp_swapcount(swp_entry_t entry)
return count;
 }
 
+#ifdef CONFIG_THP_SWAP
+static bool swap_page_trans_huge_swapped(struct swap_info_struct *si,
+swp_entry_t entry)
+{
+   struct swap_cluster_info *ci;
+   unsigned char *map = si->swap_map;
+   unsigned long roffset = swp_offset(entry);
+   unsigned long offset = round_down(roffset, SWAPFILE_CLUSTER);
+   int i;
+   bool ret = false;
+
+   ci = lock_cluster_or_swap_info(si, offset);
+   if (!cluster_is_huge(ci)) {
+   if (map[roffset] != SWAP_HAS_CACHE)
+   ret = true;
+   goto unlock_out;
+   }
+   for (i = 0; i < SWAPFILE_CLUSTER; i++) {
+   if (map[offset + i] != SWAP_HAS_CACHE) {
+   ret = true;
+   break;
+   }
+   }
+unlock_out:
+   unlock_cluster_or_swap_info(si, ci);
+   return ret;
+}
+
+static bool page_swapped(struct page *page)
+{
+   swp_entry_t entry;
+   struct swap_info_struct *si;
+
+   if (likely(!PageTransCompound(page)))
+   return page_swapcount(page) != 0;
+
+   page = compound_head(page);
+   entry.val = page_private(page);
+   si = _swap_info_get(entry);
+   if (si)
+   return swap_page_trans_huge_swapped(si, entry);
+   return false;
+}
+#else

[PATCH -mm -v3 01/12] mm, THP, swap: Support to clear swap cache flag for THP swapped out

2017-07-23 Thread Huang, Ying
From: Huang Ying 

Previously, swapcache_free_cluster() is used only in the error path of
shrink_page_list() to free the swap cluster just allocated if the
THP (Transparent Huge Page) is failed to be split.  In this patch, it
is enhanced to clear the swap cache flag (SWAP_HAS_CACHE) for the swap
cluster that holds the contents of THP swapped out.

This will be used in delaying splitting THP after swapping out
support.  Because there is no THP swapping in as a whole support yet,
after clearing the swap cache flag, the swap cluster backing the THP
swapped out will be split.  So that the swap slots in the swap cluster
can be swapped in as normal pages later.

Signed-off-by: "Huang, Ying" 
Cc: Johannes Weiner 
Cc: Minchan Kim 
Cc: Hugh Dickins 
Cc: Shaohua Li 
Cc: Rik van Riel 
---
 mm/swapfile.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6ba4aab2db0b..c32e9b23d642 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1168,22 +1168,40 @@ static void swapcache_free_cluster(swp_entry_t entry)
struct swap_cluster_info *ci;
struct swap_info_struct *si;
unsigned char *map;
-   unsigned int i;
+   unsigned int i, free_entries = 0;
+   unsigned char val;
 
-   si = swap_info_get(entry);
+   si = _swap_info_get(entry);
if (!si)
return;
 
ci = lock_cluster(si, offset);
map = si->swap_map + offset;
for (i = 0; i < SWAPFILE_CLUSTER; i++) {
-   VM_BUG_ON(map[i] != SWAP_HAS_CACHE);
-   map[i] = 0;
+   val = map[i];
+   VM_BUG_ON(!(val & SWAP_HAS_CACHE));
+   if (val == SWAP_HAS_CACHE)
+   free_entries++;
+   }
+   if (!free_entries) {
+   for (i = 0; i < SWAPFILE_CLUSTER; i++)
+   map[i] &= ~SWAP_HAS_CACHE;
}
unlock_cluster(ci);
-   mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
-   swap_free_cluster(si, idx);
-   spin_unlock(>lock);
+   if (free_entries == SWAPFILE_CLUSTER) {
+   spin_lock(>lock);
+   ci = lock_cluster(si, offset);
+   memset(map, 0, SWAPFILE_CLUSTER);
+   unlock_cluster(ci);
+   mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
+   swap_free_cluster(si, idx);
+   spin_unlock(>lock);
+   } else if (free_entries) {
+   for (i = 0; i < SWAPFILE_CLUSTER; i++, entry.val++) {
+   if (!__swap_entry_free(si, entry, SWAP_HAS_CACHE))
+   free_swap_slot(entry);
+   }
+   }
 }
 #else
 static inline void swapcache_free_cluster(swp_entry_t entry)
-- 
2.13.2



linux-next: Tree for Jul 24

2017-07-23 Thread Stephen Rothwell
Hi all,

Changes since 20170721:

The kbuild tree lost its large number of build warnings.

The reset tree gained a conflict against Linus' tree.

The clk tree gained a conflict against Linus' tree.

The btrfs-kdave tree gained a conflict against Linus' tree.

Non-merge commits (relative to Linus' tree): 2015
 2153 files changed, 77526 insertions(+), 40458 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And
finally, a simple boot test of the powerpc pseries_le_defconfig kernel
in qemu.

Below is a summary of the state of the merge.

I am currently merging 266 trees (counting Linus' and 41 trees of bug
fix patches pending for the current merge release).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (520eccdfe187 Linux 4.13-rc2)
Merging fixes/master (b4b8cbf679c4 Cavium CNN55XX: fix broken default Kconfig 
entry)
Merging kbuild-current/fixes (ad8181060788 kconfig: fix sparse warnings in 
nconfig)
Merging arc-current/for-curr (37f1db0e85ff ARC: [plat-axs10x]: prepare dts 
files for enabling PAE40 on axs103)
Merging arm-current/fixes (9e25ebfe56ec ARM: 8685/1: ensure memblock-limit is 
pmd-aligned)
Merging m68k-current/for-linus (204a2be30a7a m68k: Remove ptrace_signal_deliver)
Merging metag-fixes/fixes (b884a190afce metag/usercopy: Add missing fixups)
Merging powerpc-fixes/fixes (029d9252b116 powerpc/mm: Mark __init memory 
no-execute when STRICT_KERNEL_RWX=y)
Merging sparc/master (8cd3ec51c0c3 sbus: Convert to using %pOF instead of 
full_name)
Merging fscrypt-current/for-stable (42d97eb0ade3 fscrypt: fix renaming and 
linking special files)
Merging net/master (96080f697786 Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net)
Merging ipsec/master (e6194923237f esp: Fix memleaks on error paths.)
Merging netfilter/master (36ac344e16e0 netfilter: expect: fix crash when 
putting uninited expectation)
Merging ipvs/master (3c5ab3f395d6 ipvs: SNAT packet replies only for NATed 
connections)
Merging wireless-drivers/master (d755cbc26e82 Merge tag 
'iwlwifi-for-kalle-2017-07-21' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes)
Merging mac80211/master (d7f13f745036 cfg80211: Validate frequencies nested in 
NL80211_ATTR_SCAN_FREQUENCIES)
Merging sound-current/for-linus (e674ac9a4705 ALSA: hda/realtek - No loopback 
on ALC225/ALC295 codec)
Merging pci-current/for-linus (34d5ac2af644 PCI: rockchip: Check for 
pci_scan_root_bus_bridge() failure correctly)
Merging driver-core.current/driver-core-linus (5771a8c08880 Linux v4.13-rc1)
Merging tty.current/tty-linus (c6325179238f tty: Fix TIOCGPTPEER ioctl 
definition)
Merging usb.current/usb-linus (d6f5f071f1e1 xhci: fix memleak in xhci_run())
Merging usb-gadget-fixes/fixes (b8b9c974afee usb: renesas_usbhs: gadget: 
disable all eps when the driver stops)
Merging usb-serial-fixes/usb-linus (9585e340db9f USB: serial: cp210x: add 
support for Qivicon USB ZigBee dongle)
Merging usb-chipidea-fixes/ci-for-usb-stable (cbb22ebcfb99 usb: chipidea: core: 
check before accessing ci_role in ci_role_show)
Merging phy/fixes (5771a8c08880 Linux v4.13-rc1)
Merging staging.current/staging-linus (5a1d4c5dd4eb staging: rtl8188eu: add 
TL-WN722N v2 support)
Merging char-misc.current/char-misc-linus (c89876dda018 w1: omap-hdq: fix error 
return code in omap_hdq_probe())
Merging input-current/for-linus (293b915fd9be Input: trackpoint - assume 3 
buttons when buttons detection fails)
Merging crypto-current/master (41cdf7a45389 crypto: authencesn - Fix 
digest_null crash)
Merging 

linux-next: Tree for Jul 24

2017-07-23 Thread Stephen Rothwell
Hi all,

Changes since 20170721:

The kbuild tree lost its large number of build warnings.

The reset tree gained a conflict against Linus' tree.

The clk tree gained a conflict against Linus' tree.

The btrfs-kdave tree gained a conflict against Linus' tree.

Non-merge commits (relative to Linus' tree): 2015
 2153 files changed, 77526 insertions(+), 40458 deletions(-)



I have created today's linux-next tree at
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
(patches at http://www.kernel.org/pub/linux/kernel/next/ ).  If you
are tracking the linux-next tree using git, you should not use "git pull"
to do so as that will try to merge the new linux-next release with the
old one.  You should use "git fetch" and checkout or reset to the new
master.

You can see which trees have been included by looking in the Next/Trees
file in the source.  There are also quilt-import.log and merge.log
files in the Next directory.  Between each merge, the tree was built
with a ppc64_defconfig for powerpc and an allmodconfig (with
CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a
native build of tools/perf. After the final fixups (if any), I do an
x86_64 modules_install followed by builds for x86_64 allnoconfig,
powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig
and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And
finally, a simple boot test of the powerpc pseries_le_defconfig kernel
in qemu.

Below is a summary of the state of the merge.

I am currently merging 266 trees (counting Linus' and 41 trees of bug
fix patches pending for the current merge release).

Stats about the size of the tree over time can be seen at
http://neuling.org/linux-next-size.html .

Status of my local build tests will be at
http://kisskb.ellerman.id.au/linux-next .  If maintainers want to give
advice about cross compilers/configs that work, we are always open to add
more builds.

Thanks to Randy Dunlap for doing many randconfig builds.  And to Paul
Gortmaker for triage and bug fixes.

-- 
Cheers,
Stephen Rothwell

$ git checkout master
$ git reset --hard stable
Merging origin/master (520eccdfe187 Linux 4.13-rc2)
Merging fixes/master (b4b8cbf679c4 Cavium CNN55XX: fix broken default Kconfig 
entry)
Merging kbuild-current/fixes (ad8181060788 kconfig: fix sparse warnings in 
nconfig)
Merging arc-current/for-curr (37f1db0e85ff ARC: [plat-axs10x]: prepare dts 
files for enabling PAE40 on axs103)
Merging arm-current/fixes (9e25ebfe56ec ARM: 8685/1: ensure memblock-limit is 
pmd-aligned)
Merging m68k-current/for-linus (204a2be30a7a m68k: Remove ptrace_signal_deliver)
Merging metag-fixes/fixes (b884a190afce metag/usercopy: Add missing fixups)
Merging powerpc-fixes/fixes (029d9252b116 powerpc/mm: Mark __init memory 
no-execute when STRICT_KERNEL_RWX=y)
Merging sparc/master (8cd3ec51c0c3 sbus: Convert to using %pOF instead of 
full_name)
Merging fscrypt-current/for-stable (42d97eb0ade3 fscrypt: fix renaming and 
linking special files)
Merging net/master (96080f697786 Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net)
Merging ipsec/master (e6194923237f esp: Fix memleaks on error paths.)
Merging netfilter/master (36ac344e16e0 netfilter: expect: fix crash when 
putting uninited expectation)
Merging ipvs/master (3c5ab3f395d6 ipvs: SNAT packet replies only for NATed 
connections)
Merging wireless-drivers/master (d755cbc26e82 Merge tag 
'iwlwifi-for-kalle-2017-07-21' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes)
Merging mac80211/master (d7f13f745036 cfg80211: Validate frequencies nested in 
NL80211_ATTR_SCAN_FREQUENCIES)
Merging sound-current/for-linus (e674ac9a4705 ALSA: hda/realtek - No loopback 
on ALC225/ALC295 codec)
Merging pci-current/for-linus (34d5ac2af644 PCI: rockchip: Check for 
pci_scan_root_bus_bridge() failure correctly)
Merging driver-core.current/driver-core-linus (5771a8c08880 Linux v4.13-rc1)
Merging tty.current/tty-linus (c6325179238f tty: Fix TIOCGPTPEER ioctl 
definition)
Merging usb.current/usb-linus (d6f5f071f1e1 xhci: fix memleak in xhci_run())
Merging usb-gadget-fixes/fixes (b8b9c974afee usb: renesas_usbhs: gadget: 
disable all eps when the driver stops)
Merging usb-serial-fixes/usb-linus (9585e340db9f USB: serial: cp210x: add 
support for Qivicon USB ZigBee dongle)
Merging usb-chipidea-fixes/ci-for-usb-stable (cbb22ebcfb99 usb: chipidea: core: 
check before accessing ci_role in ci_role_show)
Merging phy/fixes (5771a8c08880 Linux v4.13-rc1)
Merging staging.current/staging-linus (5a1d4c5dd4eb staging: rtl8188eu: add 
TL-WN722N v2 support)
Merging char-misc.current/char-misc-linus (c89876dda018 w1: omap-hdq: fix error 
return code in omap_hdq_probe())
Merging input-current/for-linus (293b915fd9be Input: trackpoint - assume 3 
buttons when buttons detection fails)
Merging crypto-current/master (41cdf7a45389 crypto: authencesn - Fix 
digest_null crash)
Merging 

Re: [Patch v5 11/12] [media] s5p-mfc: Add support for HEVC encoder

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:32 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add HEVC encoder support and necessary registers, V4L2 CIDs,
> > and hevc encoder parameters
> > 
> > Signed-off-by: Smitha T Murthy 
> > ---
> >  drivers/media/platform/s5p-mfc/regs-mfc-v10.h   |  28 +-
> >  drivers/media/platform/s5p-mfc/s5p_mfc.c|   1 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c |   3 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_common.h |  53 ++-
> >  drivers/media/platform/s5p-mfc/s5p_mfc_enc.c| 521 
> > 
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr.h|   8 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 168 
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h |   8 +
> >  8 files changed, 788 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v10.h 
> > b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > index 6754477..7065b9d 100644
> > --- a/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > @@ -20,13 +20,35 @@
> >  #define S5P_FIMV_MFC_STATE_V10 0x7124
> >  #define S5P_FIMV_D_STATIC_BUFFER_ADDR_V10  0xF570
> >  #define S5P_FIMV_D_STATIC_BUFFER_SIZE_V10  0xF574
> > +#define S5P_FIMV_E_NUM_T_LAYER_V10 0xFBAC
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0_V10  0xFBB0
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1_V10  0xFBB4
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2_V10  0xFBB8
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER3_V10  0xFBBC
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER4_V10  0xFBC0
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER5_V10  0xFBC4
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6_V10  0xFBC8
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0_V100xFD18
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1_V100xFD1C
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2_V100xFD20
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3_V100xFD24
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4_V100xFD28
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5_V100xFD2C
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6_V100xFD30
> > +#define S5P_FIMV_E_HEVC_OPTIONS_V100xFDD4
> > +#define S5P_FIMV_E_HEVC_REFRESH_PERIOD_V10 0xFDD8
> > +#define S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET_V10   0xFDDC
> > +#define S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2_V100xFDE0
> > +#define S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2_V10  0xFDE4
> > +#define S5P_FIMV_E_HEVC_NAL_CONTROL_V100xFDE8
> >  
> >  /* MFCv10 Context buffer sizes */
> >  #define MFC_CTX_BUF_SIZE_V10   (30 * SZ_1K)
> >  #define MFC_H264_DEC_CTX_BUF_SIZE_V10  (2 * SZ_1M)
> >  #define MFC_OTHER_DEC_CTX_BUF_SIZE_V10 (20 * SZ_1K)
> >  #define MFC_H264_ENC_CTX_BUF_SIZE_V10  (100 * SZ_1K)
> > -#define MFC_OTHER_ENC_CTX_BUF_SIZE_V10 (15 * SZ_1K)
> > +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V10  (30 * SZ_1K)
> > +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V10  (15 * SZ_1K)
> >  
> >  /* MFCv10 variant defines */
> >  #define MAX_FW_SIZE_V10(SZ_1M)
> > @@ -58,5 +80,9 @@
> >  #define ENC_V100_VP8_ME_SIZE(x, y) \
> > ENC_V100_BASE_SIZE(x, y)
> >  
> > +#define ENC_V100_HEVC_ME_SIZE(x, y)\
> > +   (((x + 3) * (y + 3) * 32)   \
> > ++ ((y * 128) + 1280) * DIV_ROUND_UP(x, 4))
> > +
> >  #endif /*_REGS_MFC_V10_H*/
> >  
> > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
> > b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > index efc36b0..742c2b7 100644
> > --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > @@ -1621,6 +1621,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = {
> > .h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V10,
> > .other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V10,
> > .h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V10,
> > +   .hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V10,
> > .other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V10,
> >  };
> >  
> > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c 
> > b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > index 102b47e..7521fce 100644
> > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > @@ -122,6 +122,9 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx 
> > *ctx)
> > case S5P_MFC_CODEC_VP8_ENC:
> > codec_type = S5P_FIMV_CODEC_VP8_ENC_V7;
> > break;
> > +   case S5P_MFC_CODEC_HEVC_ENC:
> > +   codec_type = S5P_FIMV_CODEC_HEVC_ENC;
> > +   break;
> > default:
> > codec_type = S5P_FIMV_CODEC_NONE_V6;
> > }
> > diff --git 

Re: [Patch v5 11/12] [media] s5p-mfc: Add support for HEVC encoder

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:32 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add HEVC encoder support and necessary registers, V4L2 CIDs,
> > and hevc encoder parameters
> > 
> > Signed-off-by: Smitha T Murthy 
> > ---
> >  drivers/media/platform/s5p-mfc/regs-mfc-v10.h   |  28 +-
> >  drivers/media/platform/s5p-mfc/s5p_mfc.c|   1 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c |   3 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_common.h |  53 ++-
> >  drivers/media/platform/s5p-mfc/s5p_mfc_enc.c| 521 
> > 
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr.h|   8 +
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 168 
> >  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h |   8 +
> >  8 files changed, 788 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v10.h 
> > b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > index 6754477..7065b9d 100644
> > --- a/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h
> > @@ -20,13 +20,35 @@
> >  #define S5P_FIMV_MFC_STATE_V10 0x7124
> >  #define S5P_FIMV_D_STATIC_BUFFER_ADDR_V10  0xF570
> >  #define S5P_FIMV_D_STATIC_BUFFER_SIZE_V10  0xF574
> > +#define S5P_FIMV_E_NUM_T_LAYER_V10 0xFBAC
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0_V10  0xFBB0
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1_V10  0xFBB4
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2_V10  0xFBB8
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER3_V10  0xFBBC
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER4_V10  0xFBC0
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER5_V10  0xFBC4
> > +#define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6_V10  0xFBC8
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0_V100xFD18
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1_V100xFD1C
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2_V100xFD20
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3_V100xFD24
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4_V100xFD28
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5_V100xFD2C
> > +#define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6_V100xFD30
> > +#define S5P_FIMV_E_HEVC_OPTIONS_V100xFDD4
> > +#define S5P_FIMV_E_HEVC_REFRESH_PERIOD_V10 0xFDD8
> > +#define S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET_V10   0xFDDC
> > +#define S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2_V100xFDE0
> > +#define S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2_V10  0xFDE4
> > +#define S5P_FIMV_E_HEVC_NAL_CONTROL_V100xFDE8
> >  
> >  /* MFCv10 Context buffer sizes */
> >  #define MFC_CTX_BUF_SIZE_V10   (30 * SZ_1K)
> >  #define MFC_H264_DEC_CTX_BUF_SIZE_V10  (2 * SZ_1M)
> >  #define MFC_OTHER_DEC_CTX_BUF_SIZE_V10 (20 * SZ_1K)
> >  #define MFC_H264_ENC_CTX_BUF_SIZE_V10  (100 * SZ_1K)
> > -#define MFC_OTHER_ENC_CTX_BUF_SIZE_V10 (15 * SZ_1K)
> > +#define MFC_HEVC_ENC_CTX_BUF_SIZE_V10  (30 * SZ_1K)
> > +#define MFC_OTHER_ENC_CTX_BUF_SIZE_V10  (15 * SZ_1K)
> >  
> >  /* MFCv10 variant defines */
> >  #define MAX_FW_SIZE_V10(SZ_1M)
> > @@ -58,5 +80,9 @@
> >  #define ENC_V100_VP8_ME_SIZE(x, y) \
> > ENC_V100_BASE_SIZE(x, y)
> >  
> > +#define ENC_V100_HEVC_ME_SIZE(x, y)\
> > +   (((x + 3) * (y + 3) * 32)   \
> > ++ ((y * 128) + 1280) * DIV_ROUND_UP(x, 4))
> > +
> >  #endif /*_REGS_MFC_V10_H*/
> >  
> > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c 
> > b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > index efc36b0..742c2b7 100644
> > --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> > @@ -1621,6 +1621,7 @@ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = {
> > .h264_dec_ctx   = MFC_H264_DEC_CTX_BUF_SIZE_V10,
> > .other_dec_ctx  = MFC_OTHER_DEC_CTX_BUF_SIZE_V10,
> > .h264_enc_ctx   = MFC_H264_ENC_CTX_BUF_SIZE_V10,
> > +   .hevc_enc_ctx   = MFC_HEVC_ENC_CTX_BUF_SIZE_V10,
> > .other_enc_ctx  = MFC_OTHER_ENC_CTX_BUF_SIZE_V10,
> >  };
> >  
> > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c 
> > b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > index 102b47e..7521fce 100644
> > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c
> > @@ -122,6 +122,9 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx 
> > *ctx)
> > case S5P_MFC_CODEC_VP8_ENC:
> > codec_type = S5P_FIMV_CODEC_VP8_ENC_V7;
> > break;
> > +   case S5P_MFC_CODEC_HEVC_ENC:
> > +   codec_type = S5P_FIMV_CODEC_HEVC_ENC;
> > +   break;
> > default:
> > codec_type = S5P_FIMV_CODEC_NONE_V6;
> > }
> > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h 
> 

Re: [Patch v5 10/12] [media] v4l2: Add v4l2 control IDs for HEVC encoder

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:13 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add v4l2 controls for HEVC encoder
> > 
> > Signed-off-by: Smitha T Murthy 
> > Reviewed-by: Andrzej Hajda 
> > ---
> >  drivers/media/v4l2-core/v4l2-ctrls.c | 103 
> > +++
> >  include/uapi/linux/v4l2-controls.h   |  84 
> >  2 files changed, 187 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
> > b/drivers/media/v4l2-core/v4l2-ctrls.c
> > index ec42872..6a7e732 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> > @@ -479,6 +479,51 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> > NULL,
> > };
> >  
> > +   static const char * const hevc_profile[] = {
> > +   "Main",
> > +   "Main Still Picture",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_level[] = {
> > +   "1",
> > +   "2",
> > +   "2.1",
> > +   "3",
> > +   "3.1",
> > +   "4",
> > +   "4.1",
> > +   "5",
> > +   "5.1",
> > +   "5.2",
> > +   "6",
> > +   "6.1",
> > +   "6.2",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_hierarchial_coding_type[] = {
> > +   "B",
> > +   "P",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_refresh_type[] = {
> > +   "None",
> > +   "CRA",
> > +   "IDR",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_size_of_length_field[] = {
> > +   "0",
> > +   "1",
> > +   "2",
> > +   "4",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_tier_flag[] = {
> > +   "Main",
> > +   "High",
> > +   NULL,
> > +   };
> > +
> >  
> > switch (id) {
> > case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
> > @@ -574,6 +619,18 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> > return dv_it_content_type;
> > case V4L2_CID_DETECT_MD_MODE:
> > return detect_md_mode;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
> > +   return hevc_profile;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
> > +   return hevc_level;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
> > +   return hevc_hierarchial_coding_type;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:
> > +   return hevc_refresh_type;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
> > +   return hevc_size_of_length_field;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:
> > +   return hevc_tier_flag;
> >  
> > default:
> > return NULL;
> > @@ -775,6 +832,46 @@ const char *v4l2_ctrl_get_name(u32 id)
> > case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:return "VPX 
> > P-Frame QP Value";
> > case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:   return "VPX 
> > Profile";
> >  
> > +   /* HEVC controls */
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:   return "HEVC 
> > I-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:   return "HEVC 
> > P-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:   return "HEVC 
> > B-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:   return "HEVC 
> > Minimum QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:   return "HEVC 
> > Maximum QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:  return "HEVC 
> > Profile";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:return "HEVC 
> > Level";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:return "HEVC 
> > Tier_flag";
> 
> "HEVC Tier Flag"
> 
I will correct this.

> > +   case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION:return "HEVC 
> > Frame Rate Resolution";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH:  return "HEVC 
> > Maximum Coding Unit Depth";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC 
> > Refresh Type";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC 
> > Constant Intra Prediction";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:  return "HEVC 
> > Lossless Encoding";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:return "HEVC 
> > Wavefront";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LF:   return "HEVC 
> > Loop Filter";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LF_SLICE_BOUNDARY:return "HEVC LF 
> > Across Slice Boundary";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP:  return "HEVC QP 
> > Values";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC 
> > Hierarchical Coding Type";
> > +   

Re: [Patch v5 10/12] [media] v4l2: Add v4l2 control IDs for HEVC encoder

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:13 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add v4l2 controls for HEVC encoder
> > 
> > Signed-off-by: Smitha T Murthy 
> > Reviewed-by: Andrzej Hajda 
> > ---
> >  drivers/media/v4l2-core/v4l2-ctrls.c | 103 
> > +++
> >  include/uapi/linux/v4l2-controls.h   |  84 
> >  2 files changed, 187 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
> > b/drivers/media/v4l2-core/v4l2-ctrls.c
> > index ec42872..6a7e732 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> > @@ -479,6 +479,51 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> > NULL,
> > };
> >  
> > +   static const char * const hevc_profile[] = {
> > +   "Main",
> > +   "Main Still Picture",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_level[] = {
> > +   "1",
> > +   "2",
> > +   "2.1",
> > +   "3",
> > +   "3.1",
> > +   "4",
> > +   "4.1",
> > +   "5",
> > +   "5.1",
> > +   "5.2",
> > +   "6",
> > +   "6.1",
> > +   "6.2",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_hierarchial_coding_type[] = {
> > +   "B",
> > +   "P",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_refresh_type[] = {
> > +   "None",
> > +   "CRA",
> > +   "IDR",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_size_of_length_field[] = {
> > +   "0",
> > +   "1",
> > +   "2",
> > +   "4",
> > +   NULL,
> > +   };
> > +   static const char * const hevc_tier_flag[] = {
> > +   "Main",
> > +   "High",
> > +   NULL,
> > +   };
> > +
> >  
> > switch (id) {
> > case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
> > @@ -574,6 +619,18 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> > return dv_it_content_type;
> > case V4L2_CID_DETECT_MD_MODE:
> > return detect_md_mode;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
> > +   return hevc_profile;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
> > +   return hevc_level;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
> > +   return hevc_hierarchial_coding_type;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:
> > +   return hevc_refresh_type;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
> > +   return hevc_size_of_length_field;
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:
> > +   return hevc_tier_flag;
> >  
> > default:
> > return NULL;
> > @@ -775,6 +832,46 @@ const char *v4l2_ctrl_get_name(u32 id)
> > case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:return "VPX 
> > P-Frame QP Value";
> > case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:   return "VPX 
> > Profile";
> >  
> > +   /* HEVC controls */
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:   return "HEVC 
> > I-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:   return "HEVC 
> > P-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:   return "HEVC 
> > B-Frame QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:   return "HEVC 
> > Minimum QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:   return "HEVC 
> > Maximum QP Value";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:  return "HEVC 
> > Profile";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:return "HEVC 
> > Level";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:return "HEVC 
> > Tier_flag";
> 
> "HEVC Tier Flag"
> 
I will correct this.

> > +   case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION:return "HEVC 
> > Frame Rate Resolution";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH:  return "HEVC 
> > Maximum Coding Unit Depth";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC 
> > Refresh Type";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC 
> > Constant Intra Prediction";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:  return "HEVC 
> > Lossless Encoding";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:return "HEVC 
> > Wavefront";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LF:   return "HEVC 
> > Loop Filter";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_LF_SLICE_BOUNDARY:return "HEVC LF 
> > Across Slice Boundary";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP:  return "HEVC QP 
> > Values";
> > +   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC 
> > Hierarchical Coding Type";
> > +   case 

Re: [PATCH v3 2/8] MIPS: ranchu: Add Goldfish RTC driver (fwd)

2017-07-23 Thread Julia Lawall
Please check line 203; it seems that the tested value is unsigned.

julia

-- Forwarded message --
Date: Mon, 24 Jul 2017 11:40:38 +0800
From: kbuild test robot 
To: kbu...@01.org
Cc: Julia Lawall 
Subject: Re: [PATCH v3 2/8] MIPS: ranchu: Add Goldfish RTC driver

Hi Miodrag,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.13-rc2 next-20170721]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Aleksandar-Markovic/MIPS-Add-virtual-Ranchu-board-as-a-generic-based-board/20170724-062318
:: branch date: 5 hours ago
:: commit date: 5 hours ago

>> drivers/rtc/rtc-goldfish.c:203:5-16: WARNING: Unsigned expression compared 
>> with zero: rtcdrv -> irq < 0

git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 3b43c4b417a02749f734942456b41eb397e389ae
vim +203 drivers/rtc/rtc-goldfish.c

3b43c4b4 Miodrag Dinic 2017-07-21  181
3b43c4b4 Miodrag Dinic 2017-07-21  182  static int goldfish_rtc_probe(struct 
platform_device *pdev)
3b43c4b4 Miodrag Dinic 2017-07-21  183  {
3b43c4b4 Miodrag Dinic 2017-07-21  184  struct resource *r;
3b43c4b4 Miodrag Dinic 2017-07-21  185  struct goldfish_rtc *rtcdrv;
3b43c4b4 Miodrag Dinic 2017-07-21  186  int err;
3b43c4b4 Miodrag Dinic 2017-07-21  187
3b43c4b4 Miodrag Dinic 2017-07-21  188  rtcdrv = 
devm_kzalloc(>dev, sizeof(*rtcdrv), GFP_KERNEL);
3b43c4b4 Miodrag Dinic 2017-07-21  189  if (rtcdrv == NULL)
3b43c4b4 Miodrag Dinic 2017-07-21  190  return -ENOMEM;
3b43c4b4 Miodrag Dinic 2017-07-21  191
3b43c4b4 Miodrag Dinic 2017-07-21  192  platform_set_drvdata(pdev, 
rtcdrv);
3b43c4b4 Miodrag Dinic 2017-07-21  193
3b43c4b4 Miodrag Dinic 2017-07-21  194  r = platform_get_resource(pdev, 
IORESOURCE_MEM, 0);
3b43c4b4 Miodrag Dinic 2017-07-21  195  if (r == NULL)
3b43c4b4 Miodrag Dinic 2017-07-21  196  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  197
3b43c4b4 Miodrag Dinic 2017-07-21  198  rtcdrv->base = 
devm_ioremap_resource(>dev, r);
3b43c4b4 Miodrag Dinic 2017-07-21  199  if (IS_ERR(rtcdrv->base))
3b43c4b4 Miodrag Dinic 2017-07-21  200  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  201
3b43c4b4 Miodrag Dinic 2017-07-21  202  rtcdrv->irq = 
platform_get_irq(pdev, 0);
3b43c4b4 Miodrag Dinic 2017-07-21 @203  if (rtcdrv->irq < 0)
3b43c4b4 Miodrag Dinic 2017-07-21  204  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  205
3b43c4b4 Miodrag Dinic 2017-07-21  206  rtcdrv->rtc = 
devm_rtc_device_register(>dev, pdev->name,
3b43c4b4 Miodrag Dinic 2017-07-21  207  
_rtc_ops, THIS_MODULE);
3b43c4b4 Miodrag Dinic 2017-07-21  208  if (IS_ERR(rtcdrv->rtc))
3b43c4b4 Miodrag Dinic 2017-07-21  209  return 
PTR_ERR(rtcdrv->rtc);
3b43c4b4 Miodrag Dinic 2017-07-21  210
3b43c4b4 Miodrag Dinic 2017-07-21  211  err = 
devm_request_irq(>dev, rtcdrv->irq, goldfish_rtc_interrupt,
3b43c4b4 Miodrag Dinic 2017-07-21  212  0, pdev->name, rtcdrv);
3b43c4b4 Miodrag Dinic 2017-07-21  213  if (err)
3b43c4b4 Miodrag Dinic 2017-07-21  214  return err;
3b43c4b4 Miodrag Dinic 2017-07-21  215
3b43c4b4 Miodrag Dinic 2017-07-21  216  return 0;
3b43c4b4 Miodrag Dinic 2017-07-21  217  }
3b43c4b4 Miodrag Dinic 2017-07-21  218

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


Re: [PATCH v3 2/8] MIPS: ranchu: Add Goldfish RTC driver (fwd)

2017-07-23 Thread Julia Lawall
Please check line 203; it seems that the tested value is unsigned.

julia

-- Forwarded message --
Date: Mon, 24 Jul 2017 11:40:38 +0800
From: kbuild test robot 
To: kbu...@01.org
Cc: Julia Lawall 
Subject: Re: [PATCH v3 2/8] MIPS: ranchu: Add Goldfish RTC driver

Hi Miodrag,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.13-rc2 next-20170721]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Aleksandar-Markovic/MIPS-Add-virtual-Ranchu-board-as-a-generic-based-board/20170724-062318
:: branch date: 5 hours ago
:: commit date: 5 hours ago

>> drivers/rtc/rtc-goldfish.c:203:5-16: WARNING: Unsigned expression compared 
>> with zero: rtcdrv -> irq < 0

git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 3b43c4b417a02749f734942456b41eb397e389ae
vim +203 drivers/rtc/rtc-goldfish.c

3b43c4b4 Miodrag Dinic 2017-07-21  181
3b43c4b4 Miodrag Dinic 2017-07-21  182  static int goldfish_rtc_probe(struct 
platform_device *pdev)
3b43c4b4 Miodrag Dinic 2017-07-21  183  {
3b43c4b4 Miodrag Dinic 2017-07-21  184  struct resource *r;
3b43c4b4 Miodrag Dinic 2017-07-21  185  struct goldfish_rtc *rtcdrv;
3b43c4b4 Miodrag Dinic 2017-07-21  186  int err;
3b43c4b4 Miodrag Dinic 2017-07-21  187
3b43c4b4 Miodrag Dinic 2017-07-21  188  rtcdrv = 
devm_kzalloc(>dev, sizeof(*rtcdrv), GFP_KERNEL);
3b43c4b4 Miodrag Dinic 2017-07-21  189  if (rtcdrv == NULL)
3b43c4b4 Miodrag Dinic 2017-07-21  190  return -ENOMEM;
3b43c4b4 Miodrag Dinic 2017-07-21  191
3b43c4b4 Miodrag Dinic 2017-07-21  192  platform_set_drvdata(pdev, 
rtcdrv);
3b43c4b4 Miodrag Dinic 2017-07-21  193
3b43c4b4 Miodrag Dinic 2017-07-21  194  r = platform_get_resource(pdev, 
IORESOURCE_MEM, 0);
3b43c4b4 Miodrag Dinic 2017-07-21  195  if (r == NULL)
3b43c4b4 Miodrag Dinic 2017-07-21  196  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  197
3b43c4b4 Miodrag Dinic 2017-07-21  198  rtcdrv->base = 
devm_ioremap_resource(>dev, r);
3b43c4b4 Miodrag Dinic 2017-07-21  199  if (IS_ERR(rtcdrv->base))
3b43c4b4 Miodrag Dinic 2017-07-21  200  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  201
3b43c4b4 Miodrag Dinic 2017-07-21  202  rtcdrv->irq = 
platform_get_irq(pdev, 0);
3b43c4b4 Miodrag Dinic 2017-07-21 @203  if (rtcdrv->irq < 0)
3b43c4b4 Miodrag Dinic 2017-07-21  204  return -ENODEV;
3b43c4b4 Miodrag Dinic 2017-07-21  205
3b43c4b4 Miodrag Dinic 2017-07-21  206  rtcdrv->rtc = 
devm_rtc_device_register(>dev, pdev->name,
3b43c4b4 Miodrag Dinic 2017-07-21  207  
_rtc_ops, THIS_MODULE);
3b43c4b4 Miodrag Dinic 2017-07-21  208  if (IS_ERR(rtcdrv->rtc))
3b43c4b4 Miodrag Dinic 2017-07-21  209  return 
PTR_ERR(rtcdrv->rtc);
3b43c4b4 Miodrag Dinic 2017-07-21  210
3b43c4b4 Miodrag Dinic 2017-07-21  211  err = 
devm_request_irq(>dev, rtcdrv->irq, goldfish_rtc_interrupt,
3b43c4b4 Miodrag Dinic 2017-07-21  212  0, pdev->name, rtcdrv);
3b43c4b4 Miodrag Dinic 2017-07-21  213  if (err)
3b43c4b4 Miodrag Dinic 2017-07-21  214  return err;
3b43c4b4 Miodrag Dinic 2017-07-21  215
3b43c4b4 Miodrag Dinic 2017-07-21  216  return 0;
3b43c4b4 Miodrag Dinic 2017-07-21  217  }
3b43c4b4 Miodrag Dinic 2017-07-21  218

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


Re: [Patch v5 06/12] [media] v4l2-ioctl: add HEVC format description

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:07 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > HEVC is a video coding format
> > 
> > Signed-off-by: Smitha T Murthy 
> > ---
> >  drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
> > b/drivers/media/v4l2-core/v4l2-ioctl.c
> > index e5a2187..4f6f8d9 100644
> > --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> > @@ -1257,6 +1257,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> > case V4L2_PIX_FMT_VC1_ANNEX_L:  descr = "VC-1 (SMPTE 412M Annex 
> > L)"; break;
> > case V4L2_PIX_FMT_VP8:  descr = "VP8"; break;
> > case V4L2_PIX_FMT_VP9:  descr = "VP9"; break;
> > +   case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break;
> 
> Add a little comment at the end of the line: /* aka H.265 */
> 
> After that you can add my:
> 
> Acked-by: Hans Verkuil 
> 
> Regards,
> 
>   Hans
> 
Ok I will make the change. Thanks for the review.

Regards,
Smitha

> > case V4L2_PIX_FMT_CPIA1:descr = "GSPCA CPiA YUV"; break;
> > case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
> > case V4L2_PIX_FMT_SN9C10X:  descr = "GSPCA SN9C10X"; break;
> > 
> 
> 
> 




Re: [Patch v5 06/12] [media] v4l2-ioctl: add HEVC format description

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:07 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > HEVC is a video coding format
> > 
> > Signed-off-by: Smitha T Murthy 
> > ---
> >  drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
> > b/drivers/media/v4l2-core/v4l2-ioctl.c
> > index e5a2187..4f6f8d9 100644
> > --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> > @@ -1257,6 +1257,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> > case V4L2_PIX_FMT_VC1_ANNEX_L:  descr = "VC-1 (SMPTE 412M Annex 
> > L)"; break;
> > case V4L2_PIX_FMT_VP8:  descr = "VP8"; break;
> > case V4L2_PIX_FMT_VP9:  descr = "VP9"; break;
> > +   case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break;
> 
> Add a little comment at the end of the line: /* aka H.265 */
> 
> After that you can add my:
> 
> Acked-by: Hans Verkuil 
> 
> Regards,
> 
>   Hans
> 
Ok I will make the change. Thanks for the review.

Regards,
Smitha

> > case V4L2_PIX_FMT_CPIA1:descr = "GSPCA CPiA YUV"; break;
> > case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
> > case V4L2_PIX_FMT_SN9C10X:  descr = "GSPCA SN9C10X"; break;
> > 
> 
> 
> 




Re: [Patch v5 05/12] [media] videodev2.h: Add v4l2 definition for HEVC

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:07 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add V4L2 definition for HEVC compressed format
> > 
> > Signed-off-by: Smitha T Murthy 
> > Reviewed-by: Andrzej Hajda 
> > ---
> >  include/uapi/linux/videodev2.h | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index 2b8feb8..488de3d 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -629,6 +629,7 @@ struct v4l2_pix_format {
> >  #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 
> > 421M Annex L compliant stream */
> >  #define V4L2_PIX_FMT_VP8  v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
> >  #define V4L2_PIX_FMT_VP9  v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
> > +#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC */
> 
> Change the comment to: /* HEVC aka H.265 */
> 
> After that you can add my:
> 
> Acked-by: Hans Verkuil 
> 
> Regards,
> 
>   Hans
> 
I will make the change. Thanks for the review.

Regards,
Smitha
> >  
> >  /*  Vendor-specific formats   */
> >  #define V4L2_PIX_FMT_CPIA1v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV 
> > */
> > 
> 
> 
> 




Re: [Patch v5 05/12] [media] videodev2.h: Add v4l2 definition for HEVC

2017-07-23 Thread Smitha T Murthy
On Thu, 2017-07-20 at 15:07 +0200, Hans Verkuil wrote:
> On 19/06/17 07:10, Smitha T Murthy wrote:
> > Add V4L2 definition for HEVC compressed format
> > 
> > Signed-off-by: Smitha T Murthy 
> > Reviewed-by: Andrzej Hajda 
> > ---
> >  include/uapi/linux/videodev2.h | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index 2b8feb8..488de3d 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -629,6 +629,7 @@ struct v4l2_pix_format {
> >  #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 
> > 421M Annex L compliant stream */
> >  #define V4L2_PIX_FMT_VP8  v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
> >  #define V4L2_PIX_FMT_VP9  v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
> > +#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC */
> 
> Change the comment to: /* HEVC aka H.265 */
> 
> After that you can add my:
> 
> Acked-by: Hans Verkuil 
> 
> Regards,
> 
>   Hans
> 
I will make the change. Thanks for the review.

Regards,
Smitha
> >  
> >  /*  Vendor-specific formats   */
> >  #define V4L2_PIX_FMT_CPIA1v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV 
> > */
> > 
> 
> 
> 




Re: [PATCH] soc/samsung: use kbasename instead of open coding

2017-07-23 Thread Krzysztof Kozlowski
On Tue, Jul 18, 2017 at 04:43:30PM -0500, Rob Herring wrote:
> In preparation to not store the full path of nodes in full_name, use
> kbasename instead as it will work either with the full path or not.
> 
> Signed-off-by: Rob Herring 
> Cc: Kukjin Kim 
> Cc: Krzysztof Kozlowski 
> Cc: Javier Martinez Canillas 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-samsung-...@vger.kernel.org
> ---
>  drivers/soc/samsung/pm_domains.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Thanks, applied, with slightly changed title.

Best regards,
Krzysztof



Re: [PATCH] soc/samsung: use kbasename instead of open coding

2017-07-23 Thread Krzysztof Kozlowski
On Tue, Jul 18, 2017 at 04:43:30PM -0500, Rob Herring wrote:
> In preparation to not store the full path of nodes in full_name, use
> kbasename instead as it will work either with the full path or not.
> 
> Signed-off-by: Rob Herring 
> Cc: Kukjin Kim 
> Cc: Krzysztof Kozlowski 
> Cc: Javier Martinez Canillas 
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-samsung-...@vger.kernel.org
> ---
>  drivers/soc/samsung/pm_domains.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Thanks, applied, with slightly changed title.

Best regards,
Krzysztof



Re: [PATCH] documentation: Fix two-CPU control-dependency example

2017-07-23 Thread Paul E. McKenney
On Mon, Jul 24, 2017 at 09:04:57AM +0900, Akira Yokosawa wrote:
> On 2017/07/23 23:39:36 +0800, Boqun Feng wrote:
> > On Sat, Jul 22, 2017 at 09:43:00PM -0700, Paul E. McKenney wrote:
> > [...]
> >>> Your priority seemed to be in reducing the chance of the "if" statement
> >>> to be optimized away.  So I suggested to use "extern" as a compromise.
> >>
> > 
> > Hi Akira,
> > 
> 
> Hi Boqun,
> 
> > The problem is that, such a compromise doesn't help *developers* write
> > good concurrent code. The document should serve as a reference book for
> > the developers, and with the compromise you suggest, the developers will
> > possibly add "extern" to their shared variables. This is not only
> > unrealistic but also wrong, because "extern" means external for
> > translation units(compiling units), not external for execution
> > units(CPUs).
> 
> Yes, I suggested it regarding the situation when the tiny litmus test
> is compiled in a translation unit. Also it might not be effective once
> link time optimization becomes "smart" enough.
> 
> And I agree it was not appropriate for memory-barriers.txt.
> 
> > 
> > And as I said, the proper semantics of READ_ONCE() should work well
> > without using "extern", if we find a 'volatile' load doesn't work, we
> > can find another way (writing in asm or use asm volatile("" : "+m"(var));
> > to indicate @var changed). And the compromise just changes the
> > semantics... To me, it's not worth changing the semantics because the
> > implementation might be broken in the feature ;-)
> 
> I agree.
> 
> > 
> > 
> >> If the various tools accept the "extern", this might not be a bad thing
> >> to do.
> >>
> >> But what this really means is that I need to take another tilt at
> >> the "volatile" windmill in the committee.
> >>
> >>> Another way would be to express the ">=" version in a pseudo-asm form.
> >>>
> >>>   CPU 0 CPU 1
> >>>   ===   ===
> >>>   r1 = LOAD x   r2 = LOAD y
> >>>   if (r1 >= 0)  if (r2 >= 0)
> >>> STORE y = 1   STORE x = 1
> >>>
> >>>   assert(!(r1 == 1 && r2 == 1));
> >>>
> >>> This should eliminate any concern of compiler optimization.
> >>> In this final part of CONTROL DEPENDENCIES section, separating the
> >>> problem of optimization and transitivity would clarify the point
> >>> (at least for me).
> >>
> >> The problem is that people really do use C-language control dependencies
> >> in the Linux kernel, so we need to describe them.  Maybe someday it
> >> will be necessary to convert them to asm, but I am hoping that we can
> >> avoid that.
> >>
> >>> Thoughts?
> >>
> >> My hope is that the memory model can help here, but that will in any
> >> case take time.
> > 
> > Hi Paul,
> > 
> > I add some comments for READ_ONCE() to emphasize compilers should honor
> > the return value, in the future, we may need a separate document for the
> > use/definition of volatile in kernel, but I think the comment of
> > READ_ONCE() is good enough now?
> > 
> > Regards,
> > Boqun
> > 
> > ->8
> > Subject: [PATCH] kernel: Emphasize the return value of READ_ONCE() is 
> > honored
> > 
> > READ_ONCE() is used around in kernel to provide a control dependency,
> > and to make the control dependency valid, we must 1) make the load of
> > READ_ONCE() actually happen and 2) make sure compilers take the return
> > value of READ_ONCE() serious. 1) is already done and commented,
> > and in current implementation, 2) is also considered done in the
> > same way as 1): a 'volatile' load.
> > 
> > Whereas, Akira Yokosawa recently reported a problem that would be
> > triggered if 2) is not achieved. 
> 
> To clarity the timeline, it was Paul who pointed out it would become
> easier for compilers to optimize away the "if" statements in response
> to my suggestion of partial revert (">" -> ">=").

Indeed I did.

And if nothing else, this discussion convinced me that I should push
harder on volatile.  It would be nice if we had more of a guarantee!

Thanx, Paul

> >  Moreover, according to Paul Mckenney,
> > using volatile might not actually give us what we want for 2) depending
> > on compiler writers' definition of 'volatile'. Therefore it's necessary
> > to emphasize 2) as a part of the semantics of READ_ONCE(), this not only
> > fits the conceptual semantics we have been using, but also makes the
> > implementation requirement more accurate.
> > 
> > In the future, we can either make compiler writers accept our use of
> > 'volatile', or(if that fails) find another way to provide this
> > guarantee.
> > 
> > Cc: Akira Yokosawa 
> > Cc: Paul E. McKenney 
> > Signed-off-by: Boqun Feng 
> > ---
> >  include/linux/compiler.h | 25 +
> >  1 file changed, 25 insertions(+)
> > 
> > diff --git 

Re: [PATCH] documentation: Fix two-CPU control-dependency example

2017-07-23 Thread Paul E. McKenney
On Mon, Jul 24, 2017 at 09:04:57AM +0900, Akira Yokosawa wrote:
> On 2017/07/23 23:39:36 +0800, Boqun Feng wrote:
> > On Sat, Jul 22, 2017 at 09:43:00PM -0700, Paul E. McKenney wrote:
> > [...]
> >>> Your priority seemed to be in reducing the chance of the "if" statement
> >>> to be optimized away.  So I suggested to use "extern" as a compromise.
> >>
> > 
> > Hi Akira,
> > 
> 
> Hi Boqun,
> 
> > The problem is that, such a compromise doesn't help *developers* write
> > good concurrent code. The document should serve as a reference book for
> > the developers, and with the compromise you suggest, the developers will
> > possibly add "extern" to their shared variables. This is not only
> > unrealistic but also wrong, because "extern" means external for
> > translation units(compiling units), not external for execution
> > units(CPUs).
> 
> Yes, I suggested it regarding the situation when the tiny litmus test
> is compiled in a translation unit. Also it might not be effective once
> link time optimization becomes "smart" enough.
> 
> And I agree it was not appropriate for memory-barriers.txt.
> 
> > 
> > And as I said, the proper semantics of READ_ONCE() should work well
> > without using "extern", if we find a 'volatile' load doesn't work, we
> > can find another way (writing in asm or use asm volatile("" : "+m"(var));
> > to indicate @var changed). And the compromise just changes the
> > semantics... To me, it's not worth changing the semantics because the
> > implementation might be broken in the feature ;-)
> 
> I agree.
> 
> > 
> > 
> >> If the various tools accept the "extern", this might not be a bad thing
> >> to do.
> >>
> >> But what this really means is that I need to take another tilt at
> >> the "volatile" windmill in the committee.
> >>
> >>> Another way would be to express the ">=" version in a pseudo-asm form.
> >>>
> >>>   CPU 0 CPU 1
> >>>   ===   ===
> >>>   r1 = LOAD x   r2 = LOAD y
> >>>   if (r1 >= 0)  if (r2 >= 0)
> >>> STORE y = 1   STORE x = 1
> >>>
> >>>   assert(!(r1 == 1 && r2 == 1));
> >>>
> >>> This should eliminate any concern of compiler optimization.
> >>> In this final part of CONTROL DEPENDENCIES section, separating the
> >>> problem of optimization and transitivity would clarify the point
> >>> (at least for me).
> >>
> >> The problem is that people really do use C-language control dependencies
> >> in the Linux kernel, so we need to describe them.  Maybe someday it
> >> will be necessary to convert them to asm, but I am hoping that we can
> >> avoid that.
> >>
> >>> Thoughts?
> >>
> >> My hope is that the memory model can help here, but that will in any
> >> case take time.
> > 
> > Hi Paul,
> > 
> > I add some comments for READ_ONCE() to emphasize compilers should honor
> > the return value, in the future, we may need a separate document for the
> > use/definition of volatile in kernel, but I think the comment of
> > READ_ONCE() is good enough now?
> > 
> > Regards,
> > Boqun
> > 
> > ->8
> > Subject: [PATCH] kernel: Emphasize the return value of READ_ONCE() is 
> > honored
> > 
> > READ_ONCE() is used around in kernel to provide a control dependency,
> > and to make the control dependency valid, we must 1) make the load of
> > READ_ONCE() actually happen and 2) make sure compilers take the return
> > value of READ_ONCE() serious. 1) is already done and commented,
> > and in current implementation, 2) is also considered done in the
> > same way as 1): a 'volatile' load.
> > 
> > Whereas, Akira Yokosawa recently reported a problem that would be
> > triggered if 2) is not achieved. 
> 
> To clarity the timeline, it was Paul who pointed out it would become
> easier for compilers to optimize away the "if" statements in response
> to my suggestion of partial revert (">" -> ">=").

Indeed I did.

And if nothing else, this discussion convinced me that I should push
harder on volatile.  It would be nice if we had more of a guarantee!

Thanx, Paul

> >  Moreover, according to Paul Mckenney,
> > using volatile might not actually give us what we want for 2) depending
> > on compiler writers' definition of 'volatile'. Therefore it's necessary
> > to emphasize 2) as a part of the semantics of READ_ONCE(), this not only
> > fits the conceptual semantics we have been using, but also makes the
> > implementation requirement more accurate.
> > 
> > In the future, we can either make compiler writers accept our use of
> > 'volatile', or(if that fails) find another way to provide this
> > guarantee.
> > 
> > Cc: Akira Yokosawa 
> > Cc: Paul E. McKenney 
> > Signed-off-by: Boqun Feng 
> > ---
> >  include/linux/compiler.h | 25 +
> >  1 file changed, 25 insertions(+)
> > 
> > diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> > index 

[PATCH v3 1/2] x86/amd: Refactor topology extension related code

2017-07-23 Thread Suravee Suthikulpanit
Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 77 ++-
 1 file changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..b481df4e 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -296,55 +296,64 @@ static int nearby_node(int apicid)
 }
 #endif
 
+#ifdef CONFIG_SMP
 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );
 
-   cpuid(0x801e, , , , );
+   node_id = ecx & 0xff;
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   node_id  = ecx & 0xff;
-   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+   if (c->x86 == 0x15)
+   c->cu_id = ebx & 0xff;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
+   if (c->x86 >= 0x17) {
+   c->cpu_core_id = ebx & 0xff;
 
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
+   if (smp_num_siblings > 1)
+   c->x86_max_cores /= smp_num_siblings;
+   }
 
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (cpuid_edx(0x8006)) {
+   if (c->x86 == 0x17) {
+   /*
+* LLC is at the core complex level.
+* Core complex id is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   } else {
+   /* LLC is at the node level. */
+   per_cpu(cpu_llc_id, cpu) = node_id;
}
+   }
+}
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
-   /*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
-*/
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
-   } else {
-   /* LLC is at the node level. */
-   per_cpu(cpu_llc_id, cpu) = node_id;
-   }
-   }
+/*
+ * Fixup core topology information for
+ * (1) AMD multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) AMD processors supporting compute units
+ */
+static void amd_get_topology(struct cpuinfo_x86 *c)
+{
+   /* get information required for multi-node processors */
+   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+   __get_topoext(c);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+   u8 node_id;
u64 value;
+   int cpu = smp_processor_id();
 
rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7;
-- 
2.7.4



[PATCH v3 2/2] x86/amd: Fixup cpu_core_id for family17h downcore configuration

2017-07-23 Thread Suravee Suthikulpanit
For family17h, current cpu_core_id is directly taken from the value
CPUID_Fn801E_EBX[7:0] (CoreId), which is the physical ID of the
core within a die. However, on system with downcore configuration
(where not all physical cores within a die are available), this could
result in the case where cpu_core_id > (cores_per_node - 1).

Fix up the cpu_core_id by breaking down the bitfields of CoreId,
and calculate relative ID using available topology information.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 77 ++-
 1 file changed, 56 insertions(+), 21 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index b481df4e..62a4814 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -302,38 +302,73 @@ static int nearby_node(int apicid)
  */
 static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u16 l3_nshared = 0;
u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
+   if (cpuid_edx(0x8006)) {
+   cpuid_count(0x801d, 3, , , , );
+   l3_nshared = ((eax >> 14) & 0xfff) + 1;
+   }
+
cpuid(0x801e, , , , );
 
-   node_id = ecx & 0xff;
smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
-
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
-
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   switch (c->x86) {
+   case 0x17: {
+   u32 tmp, ccx_offset, cpu_offset;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
+   /*
+* In family 17h, the CPUID_Fn801E_EBX[7:0] (CoreId)
+* is non-contiguous in downcore and non-SMT cases.
+* Fixup the cpu_core_id to be contiguous for cores within
+* the die.
+*/
+   tmp = ebx & 0xff;
+   if (smp_num_siblings == 1) {
/*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
+* CoreId bit-encoding for SMT-disabled
+* [7:4] : die
+* [3]   : ccx
+* [2:0] : core
 */
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   ccx_offset = ((tmp >> 3) & 1) * l3_nshared;
+   cpu_offset = tmp & 7;
} else {
-   /* LLC is at the node level. */
+   /*
+* CoreId bit-encoding for SMT-enabled
+* [7:3] : die
+* [2]   : ccx
+* [1:0] : core
+*/
+   ccx_offset = ((tmp >> 2) & 1) * l3_nshared /
+  smp_num_siblings;
+   cpu_offset = tmp & 3;
+   c->x86_max_cores /= smp_num_siblings;
+
+   }
+   c->cpu_core_id = ccx_offset + cpu_offset;
+
+   /*
+* Family17h L3 cache (LLC) is at Core Complex (CCX).
+* There could be multiple CCXs in a node.
+* CCX ID is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+
+   pr_debug("Fixup coreid:%#x to cpu_core_id:%#x\n",
+tmp, c->cpu_core_id);
+   break;
+   }
+   case 0x15:
+   c->cu_id = ebx & 0xff;
+   /* Follow through */
+   default:
+   /* LLC is default to L3, which generally per-node */
+   if (l3_nshared > 0) {
+   u8 node_id = ecx & 0xff;
+
per_cpu(cpu_llc_id, cpu) = node_id;
}
}
-- 
2.7.4



[PATCH v3 1/2] x86/amd: Refactor topology extension related code

2017-07-23 Thread Suravee Suthikulpanit
Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 77 ++-
 1 file changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..b481df4e 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -296,55 +296,64 @@ static int nearby_node(int apicid)
 }
 #endif
 
+#ifdef CONFIG_SMP
 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );
 
-   cpuid(0x801e, , , , );
+   node_id = ecx & 0xff;
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   node_id  = ecx & 0xff;
-   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+   if (c->x86 == 0x15)
+   c->cu_id = ebx & 0xff;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
+   if (c->x86 >= 0x17) {
+   c->cpu_core_id = ebx & 0xff;
 
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
+   if (smp_num_siblings > 1)
+   c->x86_max_cores /= smp_num_siblings;
+   }
 
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
+   /*
+* We may have multiple LLCs if L3 caches exist, so check if we
+* have an L3 cache by looking at the L3 cache CPUID leaf.
+*/
+   if (cpuid_edx(0x8006)) {
+   if (c->x86 == 0x17) {
+   /*
+* LLC is at the core complex level.
+* Core complex id is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   } else {
+   /* LLC is at the node level. */
+   per_cpu(cpu_llc_id, cpu) = node_id;
}
+   }
+}
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
-   /*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
-*/
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
-   } else {
-   /* LLC is at the node level. */
-   per_cpu(cpu_llc_id, cpu) = node_id;
-   }
-   }
+/*
+ * Fixup core topology information for
+ * (1) AMD multi-node processors
+ * Assumption: Number of cores in each internal node is the same.
+ * (2) AMD processors supporting compute units
+ */
+static void amd_get_topology(struct cpuinfo_x86 *c)
+{
+   /* get information required for multi-node processors */
+   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+   __get_topoext(c);
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+   u8 node_id;
u64 value;
+   int cpu = smp_processor_id();
 
rdmsrl(MSR_FAM10H_NODE_ID, value);
node_id = value & 7;
-- 
2.7.4



[PATCH v3 2/2] x86/amd: Fixup cpu_core_id for family17h downcore configuration

2017-07-23 Thread Suravee Suthikulpanit
For family17h, current cpu_core_id is directly taken from the value
CPUID_Fn801E_EBX[7:0] (CoreId), which is the physical ID of the
core within a die. However, on system with downcore configuration
(where not all physical cores within a die are available), this could
result in the case where cpu_core_id > (cores_per_node - 1).

Fix up the cpu_core_id by breaking down the bitfields of CoreId,
and calculate relative ID using available topology information.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 77 ++-
 1 file changed, 56 insertions(+), 21 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index b481df4e..62a4814 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -302,38 +302,73 @@ static int nearby_node(int apicid)
  */
 static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u16 l3_nshared = 0;
u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();
 
+   if (cpuid_edx(0x8006)) {
+   cpuid_count(0x801d, 3, , , , );
+   l3_nshared = ((eax >> 14) & 0xfff) + 1;
+   }
+
cpuid(0x801e, , , , );
 
-   node_id = ecx & 0xff;
smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
 
-   if (c->x86 == 0x15)
-   c->cu_id = ebx & 0xff;
-
-   if (c->x86 >= 0x17) {
-   c->cpu_core_id = ebx & 0xff;
-
-   if (smp_num_siblings > 1)
-   c->x86_max_cores /= smp_num_siblings;
-   }
+   switch (c->x86) {
+   case 0x17: {
+   u32 tmp, ccx_offset, cpu_offset;
 
-   /*
-* We may have multiple LLCs if L3 caches exist, so check if we
-* have an L3 cache by looking at the L3 cache CPUID leaf.
-*/
-   if (cpuid_edx(0x8006)) {
-   if (c->x86 == 0x17) {
+   /*
+* In family 17h, the CPUID_Fn801E_EBX[7:0] (CoreId)
+* is non-contiguous in downcore and non-SMT cases.
+* Fixup the cpu_core_id to be contiguous for cores within
+* the die.
+*/
+   tmp = ebx & 0xff;
+   if (smp_num_siblings == 1) {
/*
-* LLC is at the core complex level.
-* Core complex id is ApicId[3].
+* CoreId bit-encoding for SMT-disabled
+* [7:4] : die
+* [3]   : ccx
+* [2:0] : core
 */
-   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+   ccx_offset = ((tmp >> 3) & 1) * l3_nshared;
+   cpu_offset = tmp & 7;
} else {
-   /* LLC is at the node level. */
+   /*
+* CoreId bit-encoding for SMT-enabled
+* [7:3] : die
+* [2]   : ccx
+* [1:0] : core
+*/
+   ccx_offset = ((tmp >> 2) & 1) * l3_nshared /
+  smp_num_siblings;
+   cpu_offset = tmp & 3;
+   c->x86_max_cores /= smp_num_siblings;
+
+   }
+   c->cpu_core_id = ccx_offset + cpu_offset;
+
+   /*
+* Family17h L3 cache (LLC) is at Core Complex (CCX).
+* There could be multiple CCXs in a node.
+* CCX ID is ApicId[3].
+*/
+   per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+
+   pr_debug("Fixup coreid:%#x to cpu_core_id:%#x\n",
+tmp, c->cpu_core_id);
+   break;
+   }
+   case 0x15:
+   c->cu_id = ebx & 0xff;
+   /* Follow through */
+   default:
+   /* LLC is default to L3, which generally per-node */
+   if (l3_nshared > 0) {
+   u8 node_id = ecx & 0xff;
+
per_cpu(cpu_llc_id, cpu) = node_id;
}
}
-- 
2.7.4



[PATCH v3 0/2] x86/amd: Refactor and fixup family17h cpu_core_id

2017-07-23 Thread Suravee Suthikulpanit
Changes from V2 (https://lkml.org/lkml/2017/7/21/730)
  * In patch 1/2
* Fix kbuild error for the __get_topoext() due to #ifdef CONFIG_SMP.
* Do not move node_id declaration in the refactored function.

Changes from V1 (https://lkml.org/lkml/2017/7/20/180)
  * Refactor topology extension logic into __get_topoext() (per Boris)

Suravee Suthikulpanit (2):
  x86/amd: Refactor topology extension related code
  x86/amd: Fixup cpu_core_id for family17h downcore configuration

 arch/x86/kernel/cpu/amd.c | 108 --
 1 file changed, 76 insertions(+), 32 deletions(-)

-- 
2.7.4



[PATCH v3 0/2] x86/amd: Refactor and fixup family17h cpu_core_id

2017-07-23 Thread Suravee Suthikulpanit
Changes from V2 (https://lkml.org/lkml/2017/7/21/730)
  * In patch 1/2
* Fix kbuild error for the __get_topoext() due to #ifdef CONFIG_SMP.
* Do not move node_id declaration in the refactored function.

Changes from V1 (https://lkml.org/lkml/2017/7/20/180)
  * Refactor topology extension logic into __get_topoext() (per Boris)

Suravee Suthikulpanit (2):
  x86/amd: Refactor topology extension related code
  x86/amd: Fixup cpu_core_id for family17h downcore configuration

 arch/x86/kernel/cpu/amd.c | 108 --
 1 file changed, 76 insertions(+), 32 deletions(-)

-- 
2.7.4



Re: [linux-sunxi] [PATCH 09/10] ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> Orange Pi Zero board has a SY8113B regulator, which is controlled via
> GPIO and capable of outputing 1.1V when the PL6 GPIO is set to output 0
> or 1.3V when the PL6 GPIO is set to input or output 1, and the output is
> the power supply of the ARM cores in H2+ SoC.
>
> Add the device tree node of this regulator and set the cpu's cpu-supply
> property to it.
>
> Signed-off-by: Icenowy Zheng 
> ---
>  arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 21 +
>  1 file changed, 21 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts 
> b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> index 6713d0f2b3f4..28b4433bd7f7 100644
> --- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> +++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> @@ -94,6 +94,27 @@
> reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>;
> post-power-on-delay-ms = <200>;
> };
> +
> +   reg_sy8113b: gpio-regulator {
> +   compatible = "regulator-gpio";
> +

No need for the newline.

> +   regulator-name = "vdd-cpux";
> +   regulator-type = "voltage";
> +   regulator-boot-on;
> +   regulator-always-on;
> +   regulator-min-microvolt = <110>;
> +   regulator-max-microvolt = <130>;
> +   regulator-ramp-delay = <50>; /* 4ms */

You should also add "enable-active-high". The driver might not
honor the GPIO_ACTIVE_HIGH flag. AFAIK this was a problem with
the old GPIO API.

ChenYu

> +
> +   gpios = <_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
> +   gpios-states = <0x1>;
> +   states = <110 0x0
> + 130 0x1>;
> +   };
> +};
> +
> + {
> +   cpu-supply = <_sy8113b>;
>  };
>
>   {
> --
> 2.13.0
>
> --
> You received this message because you are subscribed to the Google Groups 
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to linux-sunxi+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] [PATCH 09/10] ARM: sun8i: h2+: add SY8113B regulator used by Orange Pi Zero board

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> Orange Pi Zero board has a SY8113B regulator, which is controlled via
> GPIO and capable of outputing 1.1V when the PL6 GPIO is set to output 0
> or 1.3V when the PL6 GPIO is set to input or output 1, and the output is
> the power supply of the ARM cores in H2+ SoC.
>
> Add the device tree node of this regulator and set the cpu's cpu-supply
> property to it.
>
> Signed-off-by: Icenowy Zheng 
> ---
>  arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 21 +
>  1 file changed, 21 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts 
> b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> index 6713d0f2b3f4..28b4433bd7f7 100644
> --- a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> +++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
> @@ -94,6 +94,27 @@
> reset-gpios = <_pio 0 7 GPIO_ACTIVE_LOW>;
> post-power-on-delay-ms = <200>;
> };
> +
> +   reg_sy8113b: gpio-regulator {
> +   compatible = "regulator-gpio";
> +

No need for the newline.

> +   regulator-name = "vdd-cpux";
> +   regulator-type = "voltage";
> +   regulator-boot-on;
> +   regulator-always-on;
> +   regulator-min-microvolt = <110>;
> +   regulator-max-microvolt = <130>;
> +   regulator-ramp-delay = <50>; /* 4ms */

You should also add "enable-active-high". The driver might not
honor the GPIO_ACTIVE_HIGH flag. AFAIK this was a problem with
the old GPIO API.

ChenYu

> +
> +   gpios = <_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
> +   gpios-states = <0x1>;
> +   states = <110 0x0
> + 130 0x1>;
> +   };
> +};
> +
> + {
> +   cpu-supply = <_sy8113b>;
>  };
>
>   {
> --
> 2.13.0
>
> --
> You received this message because you are subscribed to the Google Groups 
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to linux-sunxi+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver

2017-07-23 Thread Lu Baolu
Hi Felipe,

On 07/21/2017 06:31 PM, Felipe Balbi wrote:
> Hi,
>
> Lu Baolu  writes:
>> +static void xhci_dbc_stop(struct xhci_hcd *xhci)
>> +{
>> +struct xhci_dbc *dbc = xhci->dbc;
>> +
>> +WARN_ON(!dbc);
>> +
>> +cancel_delayed_work_sync(>event_work);
>> +
>> +if (dbc->gs_port_num != GSPORT_INVAL) {
>> +gserial_disconnect(>gs_port);
>> +gserial_free_line(dbc->gs_port_num);
> why are you tying host stack to the gadget framework?

XHCI debug capability is actually a debug device gadget.
The hardware and firmware do everything of gadget work
and leave the interface to xHCI for enabling/disabling and
queuing transfer requests.

u_serial.c provides a generic layer between a USB gadget
and the TTY layer. I used it to avoid duplicating code.

>
> With this, you're forcing every single PC in the world to compile the
> gadget framework, that's a bit much don't you think?
>

Yes, you are right. Is it acceptable if I move u_serial.c from
the current place to drivers/usb/common?

Best regards,
Lu Baolu


Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver

2017-07-23 Thread Lu Baolu
Hi Felipe,

On 07/21/2017 06:31 PM, Felipe Balbi wrote:
> Hi,
>
> Lu Baolu  writes:
>> +static void xhci_dbc_stop(struct xhci_hcd *xhci)
>> +{
>> +struct xhci_dbc *dbc = xhci->dbc;
>> +
>> +WARN_ON(!dbc);
>> +
>> +cancel_delayed_work_sync(>event_work);
>> +
>> +if (dbc->gs_port_num != GSPORT_INVAL) {
>> +gserial_disconnect(>gs_port);
>> +gserial_free_line(dbc->gs_port_num);
> why are you tying host stack to the gadget framework?

XHCI debug capability is actually a debug device gadget.
The hardware and firmware do everything of gadget work
and leave the interface to xHCI for enabling/disabling and
queuing transfer requests.

u_serial.c provides a generic layer between a USB gadget
and the TTY layer. I used it to avoid duplicating code.

>
> With this, you're forcing every single PC in the world to compile the
> gadget framework, that's a bit much don't you think?
>

Yes, you are right. Is it acceptable if I move u_serial.c from
the current place to drivers/usb/common?

Best regards,
Lu Baolu


Re: [PATCH v2 6/7] mailbox: bcm-flexrm-mailbox: Set msg_queue_len for each channel

2017-07-23 Thread Anup Patel
Hi Jassi,

Sorry for the delayed response...

On Fri, Jul 21, 2017 at 9:16 PM, Jassi Brar  wrote:
> Hi Anup,
>
> On Fri, Jul 21, 2017 at 12:25 PM, Anup Patel  wrote:
>> The Broadcom FlexRM ring (i.e. mailbox channel) can handle
>> larger number of messages queued in one FlexRM ring hence
>> this patch sets msg_queue_len for each mailbox channel to
>> be same as RING_MAX_REQ_COUNT.
>>
>> Signed-off-by: Anup Patel 
>> Reviewed-by: Scott Branden 
>> ---
>>  drivers/mailbox/bcm-flexrm-mailbox.c | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c 
>> b/drivers/mailbox/bcm-flexrm-mailbox.c
>> index 9873818..20055a0 100644
>> --- a/drivers/mailbox/bcm-flexrm-mailbox.c
>> +++ b/drivers/mailbox/bcm-flexrm-mailbox.c
>> @@ -1683,8 +1683,11 @@ static int flexrm_mbox_probe(struct platform_device 
>> *pdev)
>> ret = -ENOMEM;
>> goto fail_free_debugfs_root;
>> }
>> -   for (index = 0; index < mbox->num_rings; index++)
>> +   for (index = 0; index < mbox->num_rings; index++) {
>> +   mbox->controller.chans[index].msg_queue_len =
>> +   RING_MAX_REQ_COUNT;
>> mbox->controller.chans[index].con_priv = >rings[index];
>> +   }
>>
> While writing mailbox.c I wasn't unaware that there is the option to
> choose the queue length at runtime.
> The idea was to keep the code as simple as possible. I am open to
> making it a runtime thing, but first, please help me understand how
> that is useful here.
>
> I understand FlexRm has a ring buffer of RING_MAX_REQ_COUNT(1024)
> elements. Any message submitted to mailbox api can be immediately
> written onto the ringbuffer if there is some space.
> Is there any mechanism to report back to a client driver, if its
> message in ringbuffer failed "to be sent"?
> If there isn't any, then I think, in flexrm_last_tx_done() you should
> simply return true if there is some space left in the rung-buffer,
> false otherwise.

Yes, we have error code in "struct brcm_message" to report back
errors from send_message. In our mailbox clients, we check
return value of mbox_send_message() and also the error code
in "struct brcm_message".

The flexrm_last_tx_done() will mostly return true when it is able to
write message in the FlexRM ring. It will return false only when
there was no room in FlexRM ring or number of in-flight messages
in FlexRM ring are 1024 (max enteries in completion queue of
FlexRM ring).

We started seeing issues with fixed queue length in mailbox framework
when we stressed one FlexRM ring from multiple CPUs. Instead of simply
increasing MBOX_TX_QUEUE_LEN, it is better to let mailbox controller
driver to choose the queue length because there also Ring Manager
hardware who support variable sized rings.

Regards,
Anup


Re: [PATCH v2 6/7] mailbox: bcm-flexrm-mailbox: Set msg_queue_len for each channel

2017-07-23 Thread Anup Patel
Hi Jassi,

Sorry for the delayed response...

On Fri, Jul 21, 2017 at 9:16 PM, Jassi Brar  wrote:
> Hi Anup,
>
> On Fri, Jul 21, 2017 at 12:25 PM, Anup Patel  wrote:
>> The Broadcom FlexRM ring (i.e. mailbox channel) can handle
>> larger number of messages queued in one FlexRM ring hence
>> this patch sets msg_queue_len for each mailbox channel to
>> be same as RING_MAX_REQ_COUNT.
>>
>> Signed-off-by: Anup Patel 
>> Reviewed-by: Scott Branden 
>> ---
>>  drivers/mailbox/bcm-flexrm-mailbox.c | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c 
>> b/drivers/mailbox/bcm-flexrm-mailbox.c
>> index 9873818..20055a0 100644
>> --- a/drivers/mailbox/bcm-flexrm-mailbox.c
>> +++ b/drivers/mailbox/bcm-flexrm-mailbox.c
>> @@ -1683,8 +1683,11 @@ static int flexrm_mbox_probe(struct platform_device 
>> *pdev)
>> ret = -ENOMEM;
>> goto fail_free_debugfs_root;
>> }
>> -   for (index = 0; index < mbox->num_rings; index++)
>> +   for (index = 0; index < mbox->num_rings; index++) {
>> +   mbox->controller.chans[index].msg_queue_len =
>> +   RING_MAX_REQ_COUNT;
>> mbox->controller.chans[index].con_priv = >rings[index];
>> +   }
>>
> While writing mailbox.c I wasn't unaware that there is the option to
> choose the queue length at runtime.
> The idea was to keep the code as simple as possible. I am open to
> making it a runtime thing, but first, please help me understand how
> that is useful here.
>
> I understand FlexRm has a ring buffer of RING_MAX_REQ_COUNT(1024)
> elements. Any message submitted to mailbox api can be immediately
> written onto the ringbuffer if there is some space.
> Is there any mechanism to report back to a client driver, if its
> message in ringbuffer failed "to be sent"?
> If there isn't any, then I think, in flexrm_last_tx_done() you should
> simply return true if there is some space left in the rung-buffer,
> false otherwise.

Yes, we have error code in "struct brcm_message" to report back
errors from send_message. In our mailbox clients, we check
return value of mbox_send_message() and also the error code
in "struct brcm_message".

The flexrm_last_tx_done() will mostly return true when it is able to
write message in the FlexRM ring. It will return false only when
there was no room in FlexRM ring or number of in-flight messages
in FlexRM ring are 1024 (max enteries in completion queue of
FlexRM ring).

We started seeing issues with fixed queue length in mailbox framework
when we stressed one FlexRM ring from multiple CPUs. Instead of simply
increasing MBOX_TX_QUEUE_LEN, it is better to let mailbox controller
driver to choose the queue length because there also Ring Manager
hardware who support variable sized rings.

Regards,
Anup


[PATCH v2] qe: fix compile issue for arm64

2017-07-23 Thread Zhao Qiang
Signed-off-by: Zhao Qiang 
---
Changes for v2:
- include all Errata QE_General4 in #ifdef

 drivers/soc/fsl/qe/qe.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 2ef6fc6..4ac9ce8 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -229,9 +229,11 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, 
unsigned int multiplier)
/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
   that the BRG divisor must be even if you're not using divide-by-16
   mode. */
+#ifdef CONFIG_PPC
if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x))
if (!div16 && (divisor & 1) && (divisor > 3))
divisor++;
+#endif
 
tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
QE_BRGC_ENABLE | div16;
-- 
2.1.0.27.g96db324



[PATCH v2] qe: fix compile issue for arm64

2017-07-23 Thread Zhao Qiang
Signed-off-by: Zhao Qiang 
---
Changes for v2:
- include all Errata QE_General4 in #ifdef

 drivers/soc/fsl/qe/qe.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 2ef6fc6..4ac9ce8 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -229,9 +229,11 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, 
unsigned int multiplier)
/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
   that the BRG divisor must be even if you're not using divide-by-16
   mode. */
+#ifdef CONFIG_PPC
if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x))
if (!div16 && (divisor & 1) && (divisor > 3))
divisor++;
+#endif
 
tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
QE_BRGC_ENABLE | div16;
-- 
2.1.0.27.g96db324



[PATCH] usb: dwc2: skip L2 state of hcd if work in device mode

2017-07-23 Thread Meng Dongyang
The gadget may fail to enqueue request if the controller has enter L2
state. This patch prevent enter L2 state in hcd driver if the controller
works in device mode.

Meng Dongyang (1):
  usb: dwc2: skip L2 state of hcd if controller work in device mode

 drivers/usb/dwc2/hcd.c | 6 ++
 1 file changed, 6 insertions(+)

-- 
1.9.1




[PATCH] usb: dwc2: skip L2 state of hcd if controller work in device mode

2017-07-23 Thread Meng Dongyang
In the case hcd autosuspend is enabled, the hcd will enter L2 state
if no device connected. But if the controller works in otg mode, the
gadget driver still works in L0 state if connected with host. This
may result in transfer fail when gadget enqueue new request but the
hcd driver has set the global state into L2. This patch prevent the
hcd enter L2 state if the controller work in device mode.

Signed-off-by: Meng Dongyang 
---
 drivers/usb/dwc2/hcd.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 740c7e8..c263114 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 
spin_lock_irqsave(>lock, flags);
 
+   if (dwc2_is_device_mode(hsotg))
+   goto unlock;
+
if (hsotg->lx_state != DWC2_L0)
goto unlock;
 
@@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 
spin_lock_irqsave(>lock, flags);
 
+   if (dwc2_is_device_mode(hsotg))
+   goto unlock;
+
if (hsotg->lx_state != DWC2_L2)
goto unlock;
 
-- 
1.9.1




[PATCH] usb: dwc2: skip L2 state of hcd if work in device mode

2017-07-23 Thread Meng Dongyang
The gadget may fail to enqueue request if the controller has enter L2
state. This patch prevent enter L2 state in hcd driver if the controller
works in device mode.

Meng Dongyang (1):
  usb: dwc2: skip L2 state of hcd if controller work in device mode

 drivers/usb/dwc2/hcd.c | 6 ++
 1 file changed, 6 insertions(+)

-- 
1.9.1




[PATCH] usb: dwc2: skip L2 state of hcd if controller work in device mode

2017-07-23 Thread Meng Dongyang
In the case hcd autosuspend is enabled, the hcd will enter L2 state
if no device connected. But if the controller works in otg mode, the
gadget driver still works in L0 state if connected with host. This
may result in transfer fail when gadget enqueue new request but the
hcd driver has set the global state into L2. This patch prevent the
hcd enter L2 state if the controller work in device mode.

Signed-off-by: Meng Dongyang 
---
 drivers/usb/dwc2/hcd.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 740c7e8..c263114 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 
spin_lock_irqsave(>lock, flags);
 
+   if (dwc2_is_device_mode(hsotg))
+   goto unlock;
+
if (hsotg->lx_state != DWC2_L0)
goto unlock;
 
@@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 
spin_lock_irqsave(>lock, flags);
 
+   if (dwc2_is_device_mode(hsotg))
+   goto unlock;
+
if (hsotg->lx_state != DWC2_L2)
goto unlock;
 
-- 
1.9.1




Re: [PATCH RFC] mm: allow isolation for pages not inserted into lru lists yet

2017-07-23 Thread Minchan Kim
Hi,

On Tue, Jul 18, 2017 at 07:00:23PM +0300, Konstantin Khlebnikov wrote:
> Pages are added into lru lists via per-cpu page vectors in order
> to combine these insertions and reduce lru lock contention.
> 
> These pending pages cannot be isolated and moved into another lru.
> This breaks in some cases page activation and makes mlock-munlock
> much more complicated.
> 
> Also this breaks newly added swapless MADV_FREE: if it cannot move
> anon page into file lru then page could never be freed lazily.

Yes, it's really unforunate.

> 
> This patch rearranges lru list handling to allow lru isolation for
> such pages. It set PageLRU earlier and initialize page->lru to mark
> pages still pending for lru insert.

At a first glance, it seems to work but it's rather hacky to me.

Could you make mark_page_lazyfree be aware of it?
IOW, mark_page_lazyfree can clear PG_active|referenced|swapbacked under
lru_lock if it was not in the LRU. With it, pagevec handler for LRU
can move pages into proper list when drain happens.

> 
> Signed-off-by: Konstantin Khlebnikov 
> ---
>  include/linux/mm_inline.h |   10 --
>  mm/swap.c |   26 --
>  2 files changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
> index e030a68ead7e..6618c588ee40 100644
> --- a/include/linux/mm_inline.h
> +++ b/include/linux/mm_inline.h
> @@ -60,8 +60,14 @@ static __always_inline void 
> add_page_to_lru_list_tail(struct page *page,
>  static __always_inline void del_page_from_lru_list(struct page *page,
>   struct lruvec *lruvec, enum lru_list lru)
>  {
> - list_del(>lru);
> - update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
> + /*
> +  * Empty list head means page is not drained to lru list yet.
> +  */
> + if (likely(!list_empty(>lru))) {
> + list_del(>lru);
> + update_lru_size(lruvec, lru, page_zonenum(page),
> + -hpage_nr_pages(page));
> + }
>  }
>  
>  /**
> diff --git a/mm/swap.c b/mm/swap.c
> index 23fc6e049cda..ba4c98074a09 100644
> --- a/mm/swap.c
> +++ b/mm/swap.c
> @@ -400,13 +400,35 @@ void mark_page_accessed(struct page *page)
>  }
>  EXPORT_SYMBOL(mark_page_accessed);
>  
> +static void __pagevec_lru_add_drain_fn(struct page *page, struct lruvec 
> *lruvec,
> +void *arg)
> +{
> + /* Check for isolated or already added pages */
> + if (likely(PageLRU(page) && list_empty(>lru))) {
> + int file = page_is_file_cache(page);
> + int active = PageActive(page);
> + enum lru_list lru = page_lru(page);
> +
> + add_page_to_lru_list(page, lruvec, lru);
> + update_page_reclaim_stat(lruvec, file, active);
> + trace_mm_lru_insertion(page, lru);
> + }
> +}
> +
>  static void __lru_cache_add(struct page *page)
>  {
>   struct pagevec *pvec = _cpu_var(lru_add_pvec);
>  
> + /*
> +  * Set PageLRU right here and initialize list head to
> +  * allow page isolation while it on the way to the LRU list.
> +  */
> + VM_BUG_ON_PAGE(PageLRU(page), page);
> + INIT_LIST_HEAD(>lru);
>   get_page(page);
> + SetPageLRU(page);
>   if (!pagevec_add(pvec, page) || PageCompound(page))
> - __pagevec_lru_add(pvec);
> + pagevec_lru_move_fn(pvec, __pagevec_lru_add_drain_fn, NULL);
>   put_cpu_var(lru_add_pvec);
>  }
>  
> @@ -611,7 +633,7 @@ void lru_add_drain_cpu(int cpu)
>   struct pagevec *pvec = _cpu(lru_add_pvec, cpu);
>  
>   if (pagevec_count(pvec))
> - __pagevec_lru_add(pvec);
> + pagevec_lru_move_fn(pvec, __pagevec_lru_add_drain_fn, NULL);
>  
>   pvec = _cpu(lru_rotate_pvecs, cpu);
>   if (pagevec_count(pvec)) {
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [PATCH RFC] mm: allow isolation for pages not inserted into lru lists yet

2017-07-23 Thread Minchan Kim
Hi,

On Tue, Jul 18, 2017 at 07:00:23PM +0300, Konstantin Khlebnikov wrote:
> Pages are added into lru lists via per-cpu page vectors in order
> to combine these insertions and reduce lru lock contention.
> 
> These pending pages cannot be isolated and moved into another lru.
> This breaks in some cases page activation and makes mlock-munlock
> much more complicated.
> 
> Also this breaks newly added swapless MADV_FREE: if it cannot move
> anon page into file lru then page could never be freed lazily.

Yes, it's really unforunate.

> 
> This patch rearranges lru list handling to allow lru isolation for
> such pages. It set PageLRU earlier and initialize page->lru to mark
> pages still pending for lru insert.

At a first glance, it seems to work but it's rather hacky to me.

Could you make mark_page_lazyfree be aware of it?
IOW, mark_page_lazyfree can clear PG_active|referenced|swapbacked under
lru_lock if it was not in the LRU. With it, pagevec handler for LRU
can move pages into proper list when drain happens.

> 
> Signed-off-by: Konstantin Khlebnikov 
> ---
>  include/linux/mm_inline.h |   10 --
>  mm/swap.c |   26 --
>  2 files changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
> index e030a68ead7e..6618c588ee40 100644
> --- a/include/linux/mm_inline.h
> +++ b/include/linux/mm_inline.h
> @@ -60,8 +60,14 @@ static __always_inline void 
> add_page_to_lru_list_tail(struct page *page,
>  static __always_inline void del_page_from_lru_list(struct page *page,
>   struct lruvec *lruvec, enum lru_list lru)
>  {
> - list_del(>lru);
> - update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
> + /*
> +  * Empty list head means page is not drained to lru list yet.
> +  */
> + if (likely(!list_empty(>lru))) {
> + list_del(>lru);
> + update_lru_size(lruvec, lru, page_zonenum(page),
> + -hpage_nr_pages(page));
> + }
>  }
>  
>  /**
> diff --git a/mm/swap.c b/mm/swap.c
> index 23fc6e049cda..ba4c98074a09 100644
> --- a/mm/swap.c
> +++ b/mm/swap.c
> @@ -400,13 +400,35 @@ void mark_page_accessed(struct page *page)
>  }
>  EXPORT_SYMBOL(mark_page_accessed);
>  
> +static void __pagevec_lru_add_drain_fn(struct page *page, struct lruvec 
> *lruvec,
> +void *arg)
> +{
> + /* Check for isolated or already added pages */
> + if (likely(PageLRU(page) && list_empty(>lru))) {
> + int file = page_is_file_cache(page);
> + int active = PageActive(page);
> + enum lru_list lru = page_lru(page);
> +
> + add_page_to_lru_list(page, lruvec, lru);
> + update_page_reclaim_stat(lruvec, file, active);
> + trace_mm_lru_insertion(page, lru);
> + }
> +}
> +
>  static void __lru_cache_add(struct page *page)
>  {
>   struct pagevec *pvec = _cpu_var(lru_add_pvec);
>  
> + /*
> +  * Set PageLRU right here and initialize list head to
> +  * allow page isolation while it on the way to the LRU list.
> +  */
> + VM_BUG_ON_PAGE(PageLRU(page), page);
> + INIT_LIST_HEAD(>lru);
>   get_page(page);
> + SetPageLRU(page);
>   if (!pagevec_add(pvec, page) || PageCompound(page))
> - __pagevec_lru_add(pvec);
> + pagevec_lru_move_fn(pvec, __pagevec_lru_add_drain_fn, NULL);
>   put_cpu_var(lru_add_pvec);
>  }
>  
> @@ -611,7 +633,7 @@ void lru_add_drain_cpu(int cpu)
>   struct pagevec *pvec = _cpu(lru_add_pvec, cpu);
>  
>   if (pagevec_count(pvec))
> - __pagevec_lru_add(pvec);
> + pagevec_lru_move_fn(pvec, __pagevec_lru_add_drain_fn, NULL);
>  
>   pvec = _cpu(lru_rotate_pvecs, cpu);
>   if (pagevec_count(pvec)) {
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org;> em...@kvack.org 


Re: [lkp-robot] [x86/refcount] b631e535c6: WARNING:at_net/netlink/af_netlink.c:#netlink_sock_destruct

2017-07-23 Thread Kees Cook
Is 14afee4b6092f ("net: convert sock.sk_wmem_alloc from atomic_t to
refcount_t") correct? That looks like a statistics counter, not a
refcounter? I can't quite tell, though...

I think this WARN is from:

WARN_ON(refcount_read(>sk_wmem_alloc));

-Kees

On Sun, Jul 23, 2017 at 7:13 PM, kernel test robot
 wrote:
>
> FYI, we noticed the following commit:
>
> commit: b631e535c61d7ddbb7ebac545f729ca9b3b6d70e ("x86/refcount: Implement 
> fast refcount overflow protection")
> https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git 
> kspp/fast-refcount/ud/v6
>
> in testcase: boot
>
> on test machine: qemu-system-x86_64 -enable-kvm -smp 2 -m 512M
>
> caused below changes (please refer to attached dmesg/kmsg for entire 
> log/backtrace):
>
>
> ++++
> || 561ee9566e | 
> b631e535c6 |
> ++++
> | boot_successes | 37 | 0 
>  |
> | boot_failures  | 0  | 4 
>  |
> | WARNING:at_net/netlink/af_netlink.c:#netlink_sock_destruct | 0  | 4 
>  |
> ++++
>
>
>
> [   36.991339] WARNING: CPU: 0 PID: 280 at net/netlink/af_netlink.c:374 
> netlink_sock_destruct+0x1ea/0x200
> [   36.994035] Modules linked in:
> [   36.994815] CPU: 0 PID: 280 Comm: sh Not tainted 4.13.0-rc1-3-gb631e53 
> #1
> [   36.996546] task: 88001448c180 task.stack: c94e
> [   36.998006] RIP: 0010:netlink_sock_destruct+0x1ea/0x200
> [   36.999290] RSP: 0018:82433de0 EFLAGS: 00010206
> [   37.000591] RAX: 88001448c180 RBX: 880016a3d000 RCX: 
> 
> [   37.002319] RDX: 0100 RSI: 0001 RDI: 
> 82796f48
> [   37.004061] RBP: 82433df0 R08:  R09: 
> 
> [   37.005780] R10: 0001 R11: 0001 R12: 
> 0001
> [   37.007528] R13: 81cd4a00 R14: 96e49674e09954cf R15: 
> 001f
> [   37.009261] FS:  () GS:8243() 
> knlGS:
> [   37.011233] CS:  0010 DS:  ES:  CR0: 80050033
> [   37.012629] CR2: 7f268a96e688 CR3: 159ff000 CR4: 
> 06b0
> [   37.014212] Call Trace:
> [   37.014745]  
> [   37.015201]  __sk_destruct+0x3a2/0x4c0
> [   37.015994]  sk_destruct+0x3f/0x70
> [   37.016747]  __sk_free+0x10d/0x160
> [   37.017479]  sk_free+0x4a/0x60
> [   37.018127]  deferred_put_nlk_sk+0xd9/0xf0
> [   37.018998]  rcu_process_callbacks+0x766/0x1cb0
> [   37.019944]  ? rcu_process_callbacks+0x643/0x1cb0
> [   37.020960]  __do_softirq+0x10c/0x6b2
> [   37.021749]  irq_exit+0x135/0x140
> [   37.022458]  smp_apic_timer_interrupt+0x3b/0x50
> [   37.023429]  apic_timer_interrupt+0x8e/0xa0
> [   37.024303] RIP: 0010:__sanitizer_cov_trace_pc+0x0/0x60
> [   37.025141] RSP: 0018:c94e3c10 EFLAGS: 0246 ORIG_RAX: 
> ff10
> [   37.026605] RAX: 88001448c180 RBX: 82727288 RCX: 
> 
> [   37.028340] RDX:  RSI:  RDI: 
> 82727288
> [   37.030077] RBP: c94e3c60 R08:  R09: 
> 
> [   37.031796] R10:  R11: 0001 R12: 
> 
> [   37.033546] R13:  R14:  R15: 
> 7f2689f93000
> [   37.035262]  
> [   37.035814]  ? ftrace_likely_update+0x39/0x200
> [   37.036925]  ? vm_normal_page+0xd7/0x1a0
> [   37.037886]  unmap_page_range+0x775/0x14d0
> [   37.038658]  unmap_single_vma+0x158/0x180
> [   37.039403]  unmap_vmas+0x5b/0x80
> [   37.040202]  exit_mmap+0x118/0x220
> [   37.040900]  mmput+0xd5/0x240
> [   37.041479]  do_exit+0xdb6/0x16d0
> [   37.042183]  ? entry_SYSCALL_64_fastpath+0x5/0xbd
> [   37.043365]  do_group_exit+0x8a/0x160
> [   37.044282]  SyS_exit_group+0x1d/0x20
> [   37.045192]  entry_SYSCALL_64_fastpath+0x1f/0xbd
> [   37.046321] RIP: 0033:0x7f268a676408
> [   37.047221] RSP: 002b:7ffcba052ea8 EFLAGS: 0246 ORIG_RAX: 
> 00e7
> [   37.049042] RAX: ffda RBX: 007f RCX: 
> 7f268a676408
> [   37.050784] RDX: 007f RSI: 003c RDI: 
> 007f
> [   37.052512] RBP: 7f268a96e688 R08: 00e7 R09: 
> ffa0
> [   37.054281] R10:  R11: 0246 R12: 
> 7f268a96ff40
> [   37.056004] R13: 0001 R14:  R15: 
> 
> [   37.057765] Code: e8 56 14 48 ff eb ca e8 b5 42 4f ff 0f ff 0f 1f 00 eb a7 
> e8 a9 42 4f ff 0f ff 0f 1f 80 00 00 00 00 e9 48 ff ff ff e8 96 42 4f ff <0f> 
> ff 0f 1f 40 00 e9 e5 fe ff ff 90 66 2e 0f 1f 84 00 00 

Re: [lkp-robot] [x86/refcount] b631e535c6: WARNING:at_net/netlink/af_netlink.c:#netlink_sock_destruct

2017-07-23 Thread Kees Cook
Is 14afee4b6092f ("net: convert sock.sk_wmem_alloc from atomic_t to
refcount_t") correct? That looks like a statistics counter, not a
refcounter? I can't quite tell, though...

I think this WARN is from:

WARN_ON(refcount_read(>sk_wmem_alloc));

-Kees

On Sun, Jul 23, 2017 at 7:13 PM, kernel test robot
 wrote:
>
> FYI, we noticed the following commit:
>
> commit: b631e535c61d7ddbb7ebac545f729ca9b3b6d70e ("x86/refcount: Implement 
> fast refcount overflow protection")
> https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git 
> kspp/fast-refcount/ud/v6
>
> in testcase: boot
>
> on test machine: qemu-system-x86_64 -enable-kvm -smp 2 -m 512M
>
> caused below changes (please refer to attached dmesg/kmsg for entire 
> log/backtrace):
>
>
> ++++
> || 561ee9566e | 
> b631e535c6 |
> ++++
> | boot_successes | 37 | 0 
>  |
> | boot_failures  | 0  | 4 
>  |
> | WARNING:at_net/netlink/af_netlink.c:#netlink_sock_destruct | 0  | 4 
>  |
> ++++
>
>
>
> [   36.991339] WARNING: CPU: 0 PID: 280 at net/netlink/af_netlink.c:374 
> netlink_sock_destruct+0x1ea/0x200
> [   36.994035] Modules linked in:
> [   36.994815] CPU: 0 PID: 280 Comm: sh Not tainted 4.13.0-rc1-3-gb631e53 
> #1
> [   36.996546] task: 88001448c180 task.stack: c94e
> [   36.998006] RIP: 0010:netlink_sock_destruct+0x1ea/0x200
> [   36.999290] RSP: 0018:82433de0 EFLAGS: 00010206
> [   37.000591] RAX: 88001448c180 RBX: 880016a3d000 RCX: 
> 
> [   37.002319] RDX: 0100 RSI: 0001 RDI: 
> 82796f48
> [   37.004061] RBP: 82433df0 R08:  R09: 
> 
> [   37.005780] R10: 0001 R11: 0001 R12: 
> 0001
> [   37.007528] R13: 81cd4a00 R14: 96e49674e09954cf R15: 
> 001f
> [   37.009261] FS:  () GS:8243() 
> knlGS:
> [   37.011233] CS:  0010 DS:  ES:  CR0: 80050033
> [   37.012629] CR2: 7f268a96e688 CR3: 159ff000 CR4: 
> 06b0
> [   37.014212] Call Trace:
> [   37.014745]  
> [   37.015201]  __sk_destruct+0x3a2/0x4c0
> [   37.015994]  sk_destruct+0x3f/0x70
> [   37.016747]  __sk_free+0x10d/0x160
> [   37.017479]  sk_free+0x4a/0x60
> [   37.018127]  deferred_put_nlk_sk+0xd9/0xf0
> [   37.018998]  rcu_process_callbacks+0x766/0x1cb0
> [   37.019944]  ? rcu_process_callbacks+0x643/0x1cb0
> [   37.020960]  __do_softirq+0x10c/0x6b2
> [   37.021749]  irq_exit+0x135/0x140
> [   37.022458]  smp_apic_timer_interrupt+0x3b/0x50
> [   37.023429]  apic_timer_interrupt+0x8e/0xa0
> [   37.024303] RIP: 0010:__sanitizer_cov_trace_pc+0x0/0x60
> [   37.025141] RSP: 0018:c94e3c10 EFLAGS: 0246 ORIG_RAX: 
> ff10
> [   37.026605] RAX: 88001448c180 RBX: 82727288 RCX: 
> 
> [   37.028340] RDX:  RSI:  RDI: 
> 82727288
> [   37.030077] RBP: c94e3c60 R08:  R09: 
> 
> [   37.031796] R10:  R11: 0001 R12: 
> 
> [   37.033546] R13:  R14:  R15: 
> 7f2689f93000
> [   37.035262]  
> [   37.035814]  ? ftrace_likely_update+0x39/0x200
> [   37.036925]  ? vm_normal_page+0xd7/0x1a0
> [   37.037886]  unmap_page_range+0x775/0x14d0
> [   37.038658]  unmap_single_vma+0x158/0x180
> [   37.039403]  unmap_vmas+0x5b/0x80
> [   37.040202]  exit_mmap+0x118/0x220
> [   37.040900]  mmput+0xd5/0x240
> [   37.041479]  do_exit+0xdb6/0x16d0
> [   37.042183]  ? entry_SYSCALL_64_fastpath+0x5/0xbd
> [   37.043365]  do_group_exit+0x8a/0x160
> [   37.044282]  SyS_exit_group+0x1d/0x20
> [   37.045192]  entry_SYSCALL_64_fastpath+0x1f/0xbd
> [   37.046321] RIP: 0033:0x7f268a676408
> [   37.047221] RSP: 002b:7ffcba052ea8 EFLAGS: 0246 ORIG_RAX: 
> 00e7
> [   37.049042] RAX: ffda RBX: 007f RCX: 
> 7f268a676408
> [   37.050784] RDX: 007f RSI: 003c RDI: 
> 007f
> [   37.052512] RBP: 7f268a96e688 R08: 00e7 R09: 
> ffa0
> [   37.054281] R10:  R11: 0246 R12: 
> 7f268a96ff40
> [   37.056004] R13: 0001 R14:  R15: 
> 
> [   37.057765] Code: e8 56 14 48 ff eb ca e8 b5 42 4f ff 0f ff 0f 1f 00 eb a7 
> e8 a9 42 4f ff 0f ff 0f 1f 80 00 00 00 00 e9 48 ff ff ff e8 96 42 4f ff <0f> 
> ff 0f 1f 40 00 e9 e5 fe ff ff 90 66 2e 0f 1f 84 00 00 00 00
> [   37.062621] 

Re: [PATCH v2] perf report: Make --branch-history work without callgraphs(-g) option in perf record

2017-07-23 Thread Jin, Yao

Hi Arnaldo,

Is this patch OK for merging? It's more than 2 months no more comments.

Thanks
Jin Yao


On 5/8/2017 6:43 PM, Jin Yao wrote:

perf record -b -g 
perf report --branch-history

This merges the LBRs with the callgraphs.

However it would be nice if it also works without callgraphs (-g)
set in perf record, so that only the LBRs are displayed.
But currently perf report errors in this case. For example,

perf record -b 
perf report --branch-history

Error:
Selected -g or --branch-history but no callchain data. Did
you call 'perf record' without -g?

This patch displays the LBRs only even if callgraphs(-g) is not
enabled in perf record.

Change log:
--
v2: According to Milian Wolff's comment, change the obsolete error
message. Now the error message is:

  ┌─Error:─┐
  │Selected -g or --branch-history.│
  │But no callchain or branch data.│
  │Did you call 'perf record' without -g or -b?│
  ││
  ││
  │Press any key...│
  └┘

When passing the last parameter to hists__fprintf,
changes "|" to "||".

hsts__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
   symbol_conf.use_callchain ||
   symbol_conf.show_branchflag_count);

Signed-off-by: Jin Yao 
---
  tools/perf/builtin-report.c | 12 +++-
  tools/perf/util/callchain.c |  7 ---
  tools/perf/util/hist.c  |  2 ++
  tools/perf/util/machine.c   | 13 -
  4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 22478ff..4ceb2d2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -259,10 +259,11 @@ static int report__setup_sample_type(struct report *rep)
"'perf record' without -g?\n");
return -EINVAL;
}
-   if (symbol_conf.use_callchain) {
-   ui__error("Selected -g or --branch-history but no "
- "callchain data. Did\n"
- "you call 'perf record' without -g?\n");
+   if (symbol_conf.use_callchain &&
+   !symbol_conf.show_branchflag_count) {
+   ui__error("Selected -g or --branch-history.\n"
+ "But no callchain or branch data.\n"
+ "Did you call 'perf record' without -g or 
-b?\n");
return -1;
}
} else if (!callchain_param.enabled &&
@@ -397,7 +398,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist 
*evlist,
  
  		hists__fprintf_nr_sample_events(hists, rep, evname, stdout);

hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
-  symbol_conf.use_callchain);
+  symbol_conf.use_callchain ||
+  symbol_conf.show_branchflag_count);
fprintf(stdout, "\n\n");
}
  
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c

index 81fc29a..08d3abf 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -993,11 +993,11 @@ int sample__resolve_callchain(struct perf_sample *sample,
  struct perf_evsel *evsel, struct addr_location 
*al,
  int max_stack)
  {
-   if (sample->callchain == NULL)
+   if (sample->callchain == NULL && !symbol_conf.show_branchflag_count)
return 0;
  
  	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||

-   perf_hpp_list.parent) {
+   perf_hpp_list.parent || symbol_conf.show_branchflag_count) {
return thread__resolve_callchain(al->thread, cursor, evsel, 
sample,
 parent, al, max_stack);
}
@@ -1006,7 +1006,8 @@ int sample__resolve_callchain(struct perf_sample *sample,
  
  int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)

  {
-   if (!symbol_conf.use_callchain || sample->callchain == NULL)
+   if ((!symbol_conf.use_callchain || sample->callchain == NULL) &&
+   !symbol_conf.show_branchflag_count)
return 0;
return callchain_append(he->callchain, _cursor, 
sample->period);
  }
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cf0186a..8b045a5 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1762,6 +1762,8 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, 
struct ui_progress *pro
else

Re: [PATCH v2] perf report: Make --branch-history work without callgraphs(-g) option in perf record

2017-07-23 Thread Jin, Yao

Hi Arnaldo,

Is this patch OK for merging? It's more than 2 months no more comments.

Thanks
Jin Yao


On 5/8/2017 6:43 PM, Jin Yao wrote:

perf record -b -g 
perf report --branch-history

This merges the LBRs with the callgraphs.

However it would be nice if it also works without callgraphs (-g)
set in perf record, so that only the LBRs are displayed.
But currently perf report errors in this case. For example,

perf record -b 
perf report --branch-history

Error:
Selected -g or --branch-history but no callchain data. Did
you call 'perf record' without -g?

This patch displays the LBRs only even if callgraphs(-g) is not
enabled in perf record.

Change log:
--
v2: According to Milian Wolff's comment, change the obsolete error
message. Now the error message is:

  ┌─Error:─┐
  │Selected -g or --branch-history.│
  │But no callchain or branch data.│
  │Did you call 'perf record' without -g or -b?│
  ││
  ││
  │Press any key...│
  └┘

When passing the last parameter to hists__fprintf,
changes "|" to "||".

hsts__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
   symbol_conf.use_callchain ||
   symbol_conf.show_branchflag_count);

Signed-off-by: Jin Yao 
---
  tools/perf/builtin-report.c | 12 +++-
  tools/perf/util/callchain.c |  7 ---
  tools/perf/util/hist.c  |  2 ++
  tools/perf/util/machine.c   | 13 -
  4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 22478ff..4ceb2d2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -259,10 +259,11 @@ static int report__setup_sample_type(struct report *rep)
"'perf record' without -g?\n");
return -EINVAL;
}
-   if (symbol_conf.use_callchain) {
-   ui__error("Selected -g or --branch-history but no "
- "callchain data. Did\n"
- "you call 'perf record' without -g?\n");
+   if (symbol_conf.use_callchain &&
+   !symbol_conf.show_branchflag_count) {
+   ui__error("Selected -g or --branch-history.\n"
+ "But no callchain or branch data.\n"
+ "Did you call 'perf record' without -g or 
-b?\n");
return -1;
}
} else if (!callchain_param.enabled &&
@@ -397,7 +398,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist 
*evlist,
  
  		hists__fprintf_nr_sample_events(hists, rep, evname, stdout);

hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
-  symbol_conf.use_callchain);
+  symbol_conf.use_callchain ||
+  symbol_conf.show_branchflag_count);
fprintf(stdout, "\n\n");
}
  
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c

index 81fc29a..08d3abf 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -993,11 +993,11 @@ int sample__resolve_callchain(struct perf_sample *sample,
  struct perf_evsel *evsel, struct addr_location 
*al,
  int max_stack)
  {
-   if (sample->callchain == NULL)
+   if (sample->callchain == NULL && !symbol_conf.show_branchflag_count)
return 0;
  
  	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||

-   perf_hpp_list.parent) {
+   perf_hpp_list.parent || symbol_conf.show_branchflag_count) {
return thread__resolve_callchain(al->thread, cursor, evsel, 
sample,
 parent, al, max_stack);
}
@@ -1006,7 +1006,8 @@ int sample__resolve_callchain(struct perf_sample *sample,
  
  int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample)

  {
-   if (!symbol_conf.use_callchain || sample->callchain == NULL)
+   if ((!symbol_conf.use_callchain || sample->callchain == NULL) &&
+   !symbol_conf.show_branchflag_count)
return 0;
return callchain_append(he->callchain, _cursor, 
sample->period);
  }
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cf0186a..8b045a5 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1762,6 +1762,8 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, 
struct ui_progress *pro
else
use_callchain = 

Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread icenowy

在 2017-07-24 11:33,Chen-Yu Tsai 写道:

On Mon, Jul 24, 2017 at 11:18 AM,   wrote:

在 2017-07-24 11:03,Chen-Yu Tsai 写道:


On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  
wrote:


From: Ondrej Jirman 

SY8106A is an I2C attached single output regulator made by Silergy 
Corp,

which is used on several Allwinner H3/H5 SBCs to control the power
supply of the ARM cores.

Add a driver for it.

Signed-off-by: Ondrej Jirman 
[Icenowy: Change commit message]
Signed-off-by: Icenowy Zheng 
---
 drivers/regulator/Kconfig |   8 +-
 drivers/regulator/Makefile|   2 +-
 drivers/regulator/sy8106a-regulator.c | 163
++
 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 drivers/regulator/sy8106a-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 99b9362331b5..1efa73e18d07 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
  This driver supports the internal VMMC regulator in the 
STw481x

  PMIC chips.

+config REGULATOR_SY8106A
+   tristate "Silergy SY8106A regulator"
+   depends on I2C && (OF || COMPILE_TEST)
+   select REGMAP_I2C
+   help
+ This driver supports SY8106A single output regulator.
+
 config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C
@@ -938,4 +945,3 @@ config REGULATOR_WM8994
  WM8994 CODEC.

 endif
-
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 95b1e86ae692..f5120252f86a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
+obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
@@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += 
wm8350-regulator.o

 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o

-
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/sy8106a-regulator.c
b/drivers/regulator/sy8106a-regulator.c
new file mode 100644
index ..1df889f68b3d
--- /dev/null
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -0,0 +1,163 @@
+/*
+ * sy8106a-regulator.c - Regulator device driver for SY8106A
+ *
+ * Copyright (C) 2016 Ondřej Jirman 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU

+ * Library General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SY8106A_REG_VOUT1_SEL  0x01
+#define SY8106A_REG_VOUT_COM   0x02
+#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
+#define SY8106A_DISABLE_REGBIT(0)
+#define SY8106A_GO_BIT BIT(7)
+
+struct sy8106a {
+   struct regulator_dev *rdev;
+   struct regmap *regmap;
+};
+
+static const struct regmap_config sy8106a_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, 
unsigned

int sel)
+{
+   /* We use our set_voltage_sel in order to avoid unnecessary 
I2C
+* chatter, because the regulator_get_voltage_sel_regmap 
using
+* apply_bit would perform 4 unnecessary transfers instead 
of

one,
+* increasing the chance of error.
+*/
+   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
+   sel | SY8106A_GO_BIT);



There should also be an explanation of what the "go bit" does.
In this case it enables control of the voltage over I2C.


+}
+
+static const struct regulator_ops sy8106a_ops = {
+   .is_enabled = regulator_is_enabled_regmap,
+   .set_voltage_sel = sy8106a_set_voltage_sel,
+   .set_voltage_time_sel = regulator_set_voltage_time_sel,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .list_voltage = regulator_list_voltage_linear,



No enable/disable ops?


+};
+
+/* Default limits measured in millivolts and milliamps */
+#define SY8106A_MIN_MV 680
+#define SY8106A_MAX_MV 1950
+#define SY8106A_STEP_MV10
+
+static const 

Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread icenowy

在 2017-07-24 11:33,Chen-Yu Tsai 写道:

On Mon, Jul 24, 2017 at 11:18 AM,   wrote:

在 2017-07-24 11:03,Chen-Yu Tsai 写道:


On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  
wrote:


From: Ondrej Jirman 

SY8106A is an I2C attached single output regulator made by Silergy 
Corp,

which is used on several Allwinner H3/H5 SBCs to control the power
supply of the ARM cores.

Add a driver for it.

Signed-off-by: Ondrej Jirman 
[Icenowy: Change commit message]
Signed-off-by: Icenowy Zheng 
---
 drivers/regulator/Kconfig |   8 +-
 drivers/regulator/Makefile|   2 +-
 drivers/regulator/sy8106a-regulator.c | 163
++
 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 drivers/regulator/sy8106a-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 99b9362331b5..1efa73e18d07 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
  This driver supports the internal VMMC regulator in the 
STw481x

  PMIC chips.

+config REGULATOR_SY8106A
+   tristate "Silergy SY8106A regulator"
+   depends on I2C && (OF || COMPILE_TEST)
+   select REGMAP_I2C
+   help
+ This driver supports SY8106A single output regulator.
+
 config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C
@@ -938,4 +945,3 @@ config REGULATOR_WM8994
  WM8994 CODEC.

 endif
-
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 95b1e86ae692..f5120252f86a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
+obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
@@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += 
wm8350-regulator.o

 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o

-
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/sy8106a-regulator.c
b/drivers/regulator/sy8106a-regulator.c
new file mode 100644
index ..1df889f68b3d
--- /dev/null
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -0,0 +1,163 @@
+/*
+ * sy8106a-regulator.c - Regulator device driver for SY8106A
+ *
+ * Copyright (C) 2016 Ondřej Jirman 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
GNU

+ * Library General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SY8106A_REG_VOUT1_SEL  0x01
+#define SY8106A_REG_VOUT_COM   0x02
+#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
+#define SY8106A_DISABLE_REGBIT(0)
+#define SY8106A_GO_BIT BIT(7)
+
+struct sy8106a {
+   struct regulator_dev *rdev;
+   struct regmap *regmap;
+};
+
+static const struct regmap_config sy8106a_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, 
unsigned

int sel)
+{
+   /* We use our set_voltage_sel in order to avoid unnecessary 
I2C
+* chatter, because the regulator_get_voltage_sel_regmap 
using
+* apply_bit would perform 4 unnecessary transfers instead 
of

one,
+* increasing the chance of error.
+*/
+   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
+   sel | SY8106A_GO_BIT);



There should also be an explanation of what the "go bit" does.
In this case it enables control of the voltage over I2C.


+}
+
+static const struct regulator_ops sy8106a_ops = {
+   .is_enabled = regulator_is_enabled_regmap,
+   .set_voltage_sel = sy8106a_set_voltage_sel,
+   .set_voltage_time_sel = regulator_set_voltage_time_sel,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .list_voltage = regulator_list_voltage_linear,



No enable/disable ops?


+};
+
+/* Default limits measured in millivolts and milliamps */
+#define SY8106A_MIN_MV 680
+#define SY8106A_MAX_MV 1950
+#define SY8106A_STEP_MV10
+
+static const struct regulator_desc sy8106a_reg = {
+   .name = "SY8106A",
+   .id = 0,
+   .ops = _ops,
+   

Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread Chen-Yu Tsai
On Mon, Jul 24, 2017 at 11:18 AM,   wrote:
> 在 2017-07-24 11:03,Chen-Yu Tsai 写道:
>>
>> On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
>>>
>>> From: Ondrej Jirman 
>>>
>>> SY8106A is an I2C attached single output regulator made by Silergy Corp,
>>> which is used on several Allwinner H3/H5 SBCs to control the power
>>> supply of the ARM cores.
>>>
>>> Add a driver for it.
>>>
>>> Signed-off-by: Ondrej Jirman 
>>> [Icenowy: Change commit message]
>>> Signed-off-by: Icenowy Zheng 
>>> ---
>>>  drivers/regulator/Kconfig |   8 +-
>>>  drivers/regulator/Makefile|   2 +-
>>>  drivers/regulator/sy8106a-regulator.c | 163
>>> ++
>>>  3 files changed, 171 insertions(+), 2 deletions(-)
>>>  create mode 100644 drivers/regulator/sy8106a-regulator.c
>>>
>>> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
>>> index 99b9362331b5..1efa73e18d07 100644
>>> --- a/drivers/regulator/Kconfig
>>> +++ b/drivers/regulator/Kconfig
>>> @@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
>>>   This driver supports the internal VMMC regulator in the STw481x
>>>   PMIC chips.
>>>
>>> +config REGULATOR_SY8106A
>>> +   tristate "Silergy SY8106A regulator"
>>> +   depends on I2C && (OF || COMPILE_TEST)
>>> +   select REGMAP_I2C
>>> +   help
>>> + This driver supports SY8106A single output regulator.
>>> +
>>>  config REGULATOR_TPS51632
>>> tristate "TI TPS51632 Power Regulator"
>>> depends on I2C
>>> @@ -938,4 +945,3 @@ config REGULATOR_WM8994
>>>   WM8994 CODEC.
>>>
>>>  endif
>>> -
>>> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
>>> index 95b1e86ae692..f5120252f86a 100644
>>> --- a/drivers/regulator/Makefile
>>> +++ b/drivers/regulator/Makefile
>>> @@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
>>>  obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
>>>  obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
>>>  obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
>>> +obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
>>> @@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
>>>  obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
>>>  obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
>>>
>>> -
>>>  ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
>>> diff --git a/drivers/regulator/sy8106a-regulator.c
>>> b/drivers/regulator/sy8106a-regulator.c
>>> new file mode 100644
>>> index ..1df889f68b3d
>>> --- /dev/null
>>> +++ b/drivers/regulator/sy8106a-regulator.c
>>> @@ -0,0 +1,163 @@
>>> +/*
>>> + * sy8106a-regulator.c - Regulator device driver for SY8106A
>>> + *
>>> + * Copyright (C) 2016 Ondřej Jirman 
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU Library General Public
>>> + * License as published by the Free Software Foundation; either
>>> + * version 2 of the License, or (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> + * Library General Public License for more details.
>>> + */
>>> +
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +
>>> +#define SY8106A_REG_VOUT1_SEL  0x01
>>> +#define SY8106A_REG_VOUT_COM   0x02
>>> +#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
>>> +#define SY8106A_DISABLE_REGBIT(0)
>>> +#define SY8106A_GO_BIT BIT(7)
>>> +
>>> +struct sy8106a {
>>> +   struct regulator_dev *rdev;
>>> +   struct regmap *regmap;
>>> +};
>>> +
>>> +static const struct regmap_config sy8106a_regmap_config = {
>>> +   .reg_bits = 8,
>>> +   .val_bits = 8,
>>> +};
>>> +
>>> +static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, unsigned
>>> int sel)
>>> +{
>>> +   /* We use our set_voltage_sel in order to avoid unnecessary I2C
>>> +* chatter, because the regulator_get_voltage_sel_regmap using
>>> +* apply_bit would perform 4 unnecessary transfers instead of
>>> one,
>>> +* increasing the chance of error.
>>> +*/
>>> +   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
>>> +   sel | SY8106A_GO_BIT);
>>
>>
>> There should also be an explanation of what the "go bit" does.
>> In this case it enables control of the voltage over I2C.
>>
>>> +}
>>> +
>>> +static const struct regulator_ops sy8106a_ops = {
>>> +   .is_enabled = regulator_is_enabled_regmap,
>>> +   

Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread Chen-Yu Tsai
On Mon, Jul 24, 2017 at 11:18 AM,   wrote:
> 在 2017-07-24 11:03,Chen-Yu Tsai 写道:
>>
>> On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
>>>
>>> From: Ondrej Jirman 
>>>
>>> SY8106A is an I2C attached single output regulator made by Silergy Corp,
>>> which is used on several Allwinner H3/H5 SBCs to control the power
>>> supply of the ARM cores.
>>>
>>> Add a driver for it.
>>>
>>> Signed-off-by: Ondrej Jirman 
>>> [Icenowy: Change commit message]
>>> Signed-off-by: Icenowy Zheng 
>>> ---
>>>  drivers/regulator/Kconfig |   8 +-
>>>  drivers/regulator/Makefile|   2 +-
>>>  drivers/regulator/sy8106a-regulator.c | 163
>>> ++
>>>  3 files changed, 171 insertions(+), 2 deletions(-)
>>>  create mode 100644 drivers/regulator/sy8106a-regulator.c
>>>
>>> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
>>> index 99b9362331b5..1efa73e18d07 100644
>>> --- a/drivers/regulator/Kconfig
>>> +++ b/drivers/regulator/Kconfig
>>> @@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
>>>   This driver supports the internal VMMC regulator in the STw481x
>>>   PMIC chips.
>>>
>>> +config REGULATOR_SY8106A
>>> +   tristate "Silergy SY8106A regulator"
>>> +   depends on I2C && (OF || COMPILE_TEST)
>>> +   select REGMAP_I2C
>>> +   help
>>> + This driver supports SY8106A single output regulator.
>>> +
>>>  config REGULATOR_TPS51632
>>> tristate "TI TPS51632 Power Regulator"
>>> depends on I2C
>>> @@ -938,4 +945,3 @@ config REGULATOR_WM8994
>>>   WM8994 CODEC.
>>>
>>>  endif
>>> -
>>> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
>>> index 95b1e86ae692..f5120252f86a 100644
>>> --- a/drivers/regulator/Makefile
>>> +++ b/drivers/regulator/Makefile
>>> @@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
>>>  obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
>>>  obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
>>>  obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
>>> +obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
>>>  obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
>>> @@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
>>>  obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
>>>  obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
>>>
>>> -
>>>  ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
>>> diff --git a/drivers/regulator/sy8106a-regulator.c
>>> b/drivers/regulator/sy8106a-regulator.c
>>> new file mode 100644
>>> index ..1df889f68b3d
>>> --- /dev/null
>>> +++ b/drivers/regulator/sy8106a-regulator.c
>>> @@ -0,0 +1,163 @@
>>> +/*
>>> + * sy8106a-regulator.c - Regulator device driver for SY8106A
>>> + *
>>> + * Copyright (C) 2016 Ondřej Jirman 
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU Library General Public
>>> + * License as published by the Free Software Foundation; either
>>> + * version 2 of the License, or (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> + * Library General Public License for more details.
>>> + */
>>> +
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +
>>> +#define SY8106A_REG_VOUT1_SEL  0x01
>>> +#define SY8106A_REG_VOUT_COM   0x02
>>> +#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
>>> +#define SY8106A_DISABLE_REGBIT(0)
>>> +#define SY8106A_GO_BIT BIT(7)
>>> +
>>> +struct sy8106a {
>>> +   struct regulator_dev *rdev;
>>> +   struct regmap *regmap;
>>> +};
>>> +
>>> +static const struct regmap_config sy8106a_regmap_config = {
>>> +   .reg_bits = 8,
>>> +   .val_bits = 8,
>>> +};
>>> +
>>> +static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, unsigned
>>> int sel)
>>> +{
>>> +   /* We use our set_voltage_sel in order to avoid unnecessary I2C
>>> +* chatter, because the regulator_get_voltage_sel_regmap using
>>> +* apply_bit would perform 4 unnecessary transfers instead of
>>> one,
>>> +* increasing the chance of error.
>>> +*/
>>> +   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
>>> +   sel | SY8106A_GO_BIT);
>>
>>
>> There should also be an explanation of what the "go bit" does.
>> In this case it enables control of the voltage over I2C.
>>
>>> +}
>>> +
>>> +static const struct regulator_ops sy8106a_ops = {
>>> +   .is_enabled = regulator_is_enabled_regmap,
>>> +   .set_voltage_sel = sy8106a_set_voltage_sel,
>>> +   .set_voltage_time_sel = regulator_set_voltage_time_sel,

Re: [PATCH] qe: fix compile issue for arm64

2017-07-23 Thread Scott Wood
On Mon, 2017-07-24 at 02:09 +, Qiang Zhao wrote:
> On Fri, 2017-07-21 at 02:34PM, Michael Ellerman  wrote:
> 
> > -Original Message-
> > From: Michael Ellerman [mailto:m...@ellerman.id.au]
> > Sent: Friday, July 21, 2017 2:34 PM
> > To: Qiang Zhao ; o...@buserror.net
> > Cc: valentin.longch...@keymile.com; linuxppc-...@lists.ozlabs.org; linux-
> > ker...@vger.kernel.org; Qiang Zhao 
> > Subject: Re: [PATCH] qe: fix compile issue for arm64
> > 
> > Zhao Qiang  writes:
> > 
> > > Signed-off-by: Zhao Qiang 
> > > ---
> > >  drivers/soc/fsl/qe/qe.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index
> > > 2ef6fc6..d48fa4a 100644
> > > --- a/drivers/soc/fsl/qe/qe.c
> > > +++ b/drivers/soc/fsl/qe/qe.c
> > > @@ -229,7 +229,9 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate,
> > 
> > unsigned int multiplier)
> > >   /* Errata QE_General4, which affects some MPC832x and MPC836x
> > 
> > SOCs, says
> > >      that the BRG divisor must be even if you're not using
> > > divide-by-16
> > >      mode. */
> > > +#ifdef CONFIG_PPC
> > >   if (pvr_version_is(PVR_VER_836x) ||
> > > pvr_version_is(PVR_VER_832x)
> > > +#endif
> > >   if (!div16 && (divisor & 1) && (divisor > 3))
> > >   divisor++;
> > 
> > Are you sure that's what you want to do on arm64 ?
> 
> Is there any problem?
> 
> Best Regards
> Qiang Zhao

The comment says the workaround applies to MPC832x and MPC836x, but you're
applying the workaround on arm64 as well.

-Scott



Re: [PATCH] qe: fix compile issue for arm64

2017-07-23 Thread Scott Wood
On Mon, 2017-07-24 at 02:09 +, Qiang Zhao wrote:
> On Fri, 2017-07-21 at 02:34PM, Michael Ellerman  wrote:
> 
> > -Original Message-
> > From: Michael Ellerman [mailto:m...@ellerman.id.au]
> > Sent: Friday, July 21, 2017 2:34 PM
> > To: Qiang Zhao ; o...@buserror.net
> > Cc: valentin.longch...@keymile.com; linuxppc-...@lists.ozlabs.org; linux-
> > ker...@vger.kernel.org; Qiang Zhao 
> > Subject: Re: [PATCH] qe: fix compile issue for arm64
> > 
> > Zhao Qiang  writes:
> > 
> > > Signed-off-by: Zhao Qiang 
> > > ---
> > >  drivers/soc/fsl/qe/qe.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index
> > > 2ef6fc6..d48fa4a 100644
> > > --- a/drivers/soc/fsl/qe/qe.c
> > > +++ b/drivers/soc/fsl/qe/qe.c
> > > @@ -229,7 +229,9 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate,
> > 
> > unsigned int multiplier)
> > >   /* Errata QE_General4, which affects some MPC832x and MPC836x
> > 
> > SOCs, says
> > >      that the BRG divisor must be even if you're not using
> > > divide-by-16
> > >      mode. */
> > > +#ifdef CONFIG_PPC
> > >   if (pvr_version_is(PVR_VER_836x) ||
> > > pvr_version_is(PVR_VER_832x)
> > > +#endif
> > >   if (!div16 && (divisor & 1) && (divisor > 3))
> > >   divisor++;
> > 
> > Are you sure that's what you want to do on arm64 ?
> 
> Is there any problem?
> 
> Best Regards
> Qiang Zhao

The comment says the workaround applies to MPC832x and MPC836x, but you're
applying the workaround on arm64 as well.

-Scott



Re: [PATCH v2 1/2] x86/amd: Refactor topology extension related code

2017-07-23 Thread Suravee Suthikulpanit

Boris,

On 7/22/17 23:12, Borislav Petkov wrote:

On Fri, Jul 21, 2017 at 09:00:38PM -0500, Suravee Suthikulpanit wrote:

Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 79 ++-
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..74d8d7c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -297,54 +297,63 @@ static int nearby_node(int apicid)
 #endif

 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();

-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );

-   cpuid(0x801e, , , , );
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;

-   node_id  = ecx & 0xff;


When reviewers ask you about a preparatory cleanup patch, you don't
sneak in changes in it - you *only* *move* the code so that the change
is *absolutely* comprehensible. Ontop you do changes. Don't tell me you
didn't know that!


I know that we should not sneak in change. I might have missed something here.

Are you referring to the part that I moved the "node_id = ecx & 0xff" from the 
top level of the function to inside the "if/else" logic where it is the only 
place that used within this new refactored __get_topoext() and there is nothing 
changed functionally? If that's really the case, I'll fix it.


Thanks,
Suravee





Re: [PATCH v2 1/2] x86/amd: Refactor topology extension related code

2017-07-23 Thread Suravee Suthikulpanit

Boris,

On 7/22/17 23:12, Borislav Petkov wrote:

On Fri, Jul 21, 2017 at 09:00:38PM -0500, Suravee Suthikulpanit wrote:

Refactoring in preparation for subsequent changes.
There is no functional change.

Signed-off-by: Suravee Suthikulpanit 
---
 arch/x86/kernel/cpu/amd.c | 79 ++-
 1 file changed, 44 insertions(+), 35 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8..74d8d7c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -297,54 +297,63 @@ static int nearby_node(int apicid)
 #endif

 /*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
+ * Get topology information via X86_FEATURE_TOPOEXT
  */
-#ifdef CONFIG_SMP
-static void amd_get_topology(struct cpuinfo_x86 *c)
+static void __get_topoext(struct cpuinfo_x86 *c)
 {
-   u8 node_id;
+   u32 eax, ebx, ecx, edx;
int cpu = smp_processor_id();

-   /* get information required for multi-node processors */
-   if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-   u32 eax, ebx, ecx, edx;
+   cpuid(0x801e, , , , );

-   cpuid(0x801e, , , , );
+   smp_num_siblings = ((ebx >> 8) & 0xff) + 1;

-   node_id  = ecx & 0xff;


When reviewers ask you about a preparatory cleanup patch, you don't
sneak in changes in it - you *only* *move* the code so that the change
is *absolutely* comprehensible. Ontop you do changes. Don't tell me you
didn't know that!


I know that we should not sneak in change. I might have missed something here.

Are you referring to the part that I moved the "node_id = ecx & 0xff" from the 
top level of the function to inside the "if/else" logic where it is the only 
place that used within this new refactored __get_topoext() and there is nothing 
changed functionally? If that's really the case, I'll fix it.


Thanks,
Suravee





Re: [PATCH] staging: pi433: fix sparse warning: missing static

2017-07-23 Thread Marcus Wolf
reviewed-by: Marcus Wolf 

The fixes of this patch are fine, but there are already patches out there,
containing these fixes.

Thanks,
Marcus

> David Wittman  hat am 24. Juli 2017 um 00:46 geschrieben:
>
>
> A few local functions in the pi433 module were getting flagged by Sparse
> for missing declarations, so I added static qualifiers to clean up the
> warnings.
>
> Signed-off-by: David Wittman 
> ---
> drivers/staging/pi433/pi433_if.c | 4 ++--
> drivers/staging/pi433/rf69.c | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/pi433/pi433_if.c
> b/drivers/staging/pi433/pi433_if.c
> index 1bc478a..46461b4 100644
> --- a/drivers/staging/pi433/pi433_if.c
> +++ b/drivers/staging/pi433/pi433_if.c
> @@ -313,7 +313,7 @@ struct pi433_instance {
>
> /*-*/
>
> -int
> +static int
> pi433_receive(void *data)
> {
> struct pi433_device *dev = data;
> @@ -463,7 +463,7 @@ struct pi433_instance {
> return bytes_total;
> }
>
> -int
> +static int
> pi433_tx_thread(void *data)
> {
> struct pi433_device *device = data;
> diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
> index e391ce7..e5eee84 100644
> --- a/drivers/staging/pi433/rf69.c
> +++ b/drivers/staging/pi433/rf69.c
> @@ -433,7 +433,7 @@ int rf69_set_dc_cut_off_frequency_during_afc(struct
> spi_device *spi, enum dccPer
> return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent);
> }
>
> -int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum mantisse
> mantisse, u8 exponent)
> +static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum
> mantisse mantisse, u8 exponent)
> {
> u8 newValue;
>
> --
> 1.9.1
>
>


Re: [PATCH 1/3] rtc: sun6i: Remove double init of spinlock in sun6i_rtc_clk_init()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:

A bit more description would be nice. Maybe a kernel message that
prompted this fix?

> Fixes: 847b8bf62eb4 ("rtc: sun6i: Expose the 32kHz oscillator")
> Cc: Maxime Ripard 
> Cc: Rob Herring 
> Signed-off-by: Alexey Klimov 

Otherwise,

Reviewed-by: Chen-Yu Tsai 


Re: [PATCH] staging: pi433: fix sparse warning: missing static

2017-07-23 Thread Marcus Wolf
reviewed-by: Marcus Wolf 

The fixes of this patch are fine, but there are already patches out there,
containing these fixes.

Thanks,
Marcus

> David Wittman  hat am 24. Juli 2017 um 00:46 geschrieben:
>
>
> A few local functions in the pi433 module were getting flagged by Sparse
> for missing declarations, so I added static qualifiers to clean up the
> warnings.
>
> Signed-off-by: David Wittman 
> ---
> drivers/staging/pi433/pi433_if.c | 4 ++--
> drivers/staging/pi433/rf69.c | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/pi433/pi433_if.c
> b/drivers/staging/pi433/pi433_if.c
> index 1bc478a..46461b4 100644
> --- a/drivers/staging/pi433/pi433_if.c
> +++ b/drivers/staging/pi433/pi433_if.c
> @@ -313,7 +313,7 @@ struct pi433_instance {
>
> /*-*/
>
> -int
> +static int
> pi433_receive(void *data)
> {
> struct pi433_device *dev = data;
> @@ -463,7 +463,7 @@ struct pi433_instance {
> return bytes_total;
> }
>
> -int
> +static int
> pi433_tx_thread(void *data)
> {
> struct pi433_device *device = data;
> diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c
> index e391ce7..e5eee84 100644
> --- a/drivers/staging/pi433/rf69.c
> +++ b/drivers/staging/pi433/rf69.c
> @@ -433,7 +433,7 @@ int rf69_set_dc_cut_off_frequency_during_afc(struct
> spi_device *spi, enum dccPer
> return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent);
> }
>
> -int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum mantisse
> mantisse, u8 exponent)
> +static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum
> mantisse mantisse, u8 exponent)
> {
> u8 newValue;
>
> --
> 1.9.1
>
>


Re: [PATCH 1/3] rtc: sun6i: Remove double init of spinlock in sun6i_rtc_clk_init()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:

A bit more description would be nice. Maybe a kernel message that
prompted this fix?

> Fixes: 847b8bf62eb4 ("rtc: sun6i: Expose the 32kHz oscillator")
> Cc: Maxime Ripard 
> Cc: Rob Herring 
> Signed-off-by: Alexey Klimov 

Otherwise,

Reviewed-by: Chen-Yu Tsai 


Re: [PATCH 3/3] rtc: sun6i: Remove unneeded initalization of ret in sun6i_rtc_setalarm()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:

A bit more description would be nice.

> Signed-off-by: Alexey Klimov 

Otherwise,

Reviewed-by: Chen-Yu Tsai 


Re: [PATCH 3/3] rtc: sun6i: Remove unneeded initalization of ret in sun6i_rtc_setalarm()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:

A bit more description would be nice.

> Signed-off-by: Alexey Klimov 

Otherwise,

Reviewed-by: Chen-Yu Tsai 


Re: [PATCH 2/3] rtc: sun6i: fix memleaks and add error-path in sun6i_rtc_clk_init()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:
> The memory allocated for rtc and clk_data will never be freed in
> sun6i_rtc_clk_init() in case of error and return. This patch adds
> required error path with memory freeing.
>
> Fixes: 847b8bf62eb4 ("rtc: sun6i: Expose the 32kHz oscillator")
> Cc: Maxime Ripard 
> Cc: Rob Herring 
> Signed-off-by: Alexey Klimov 
> ---
>  drivers/rtc/rtc-sun6i.c | 17 -
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> index 7e7da60..77bc4d3 100644
> --- a/drivers/rtc/rtc-sun6i.c
> +++ b/drivers/rtc/rtc-sun6i.c
> @@ -197,14 +197,14 @@ static void __init sun6i_rtc_clk_init(struct 
> device_node *node)
> clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws),
>GFP_KERNEL);
> if (!clk_data)
> -   return;
> +   goto out_rtc_free;
>
> spin_lock_init(>lock);
>
> rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node));
> if (IS_ERR(rtc->base)) {
> pr_crit("Can't map RTC registers");
> -   return;
> +   goto out_clk_data_free;
> }
>
> /* Switch to the external, more precise, oscillator */
> @@ -216,7 +216,7 @@ static void __init sun6i_rtc_clk_init(struct device_node 
> *node)
>
> /* Deal with old DTs */
> if (!of_get_property(node, "clocks", NULL))
> -   return;
> +   goto out_clk_data_free;
>
> rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
> "rtc-int-osc",
> @@ -225,7 +225,7 @@ static void __init sun6i_rtc_clk_init(struct device_node 
> *node)
> 3);
> if (IS_ERR(rtc->int_osc)) {
> pr_crit("Couldn't register the internal oscillator\n");
> -   return;
> +   goto out_clk_data_free;
> }
>
> parents[0] = clk_hw_get_name(rtc->int_osc);
> @@ -240,12 +240,19 @@ static void __init sun6i_rtc_clk_init(struct 
> device_node *node)
> rtc->losc = clk_register(NULL, >hw);
> if (IS_ERR(rtc->losc)) {
> pr_crit("Couldn't register the LOSC clock\n");
> -   return;
> +   goto out_clk_data_free;

You should also unregister the fixed rate clk above.

> }
>
> clk_data->num = 1;
> clk_data->hws[0] = >hw;
> of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
> +
> +   return;
> +
> +out_clk_data_free:
> +   kfree(clk_data);
> +out_rtc_free:
> +   kfree(rtc);

rtc can not be freed. It has already been assigned to sun6i_rtc, a static
variable within this module. It then gets used by the actual RTC driver
later in this file to get the register base pointer. This was done to
avoid issues with trying to map the same I/O addresses twice.


Regards
ChenYu

>  }
>  CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
>   sun6i_rtc_clk_init);
> --
> 1.9.1
>


Re: [PATCH 2/3] rtc: sun6i: fix memleaks and add error-path in sun6i_rtc_clk_init()

2017-07-23 Thread Chen-Yu Tsai
On Wed, Jul 12, 2017 at 6:59 PM, Alexey Klimov  wrote:
> The memory allocated for rtc and clk_data will never be freed in
> sun6i_rtc_clk_init() in case of error and return. This patch adds
> required error path with memory freeing.
>
> Fixes: 847b8bf62eb4 ("rtc: sun6i: Expose the 32kHz oscillator")
> Cc: Maxime Ripard 
> Cc: Rob Herring 
> Signed-off-by: Alexey Klimov 
> ---
>  drivers/rtc/rtc-sun6i.c | 17 -
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> index 7e7da60..77bc4d3 100644
> --- a/drivers/rtc/rtc-sun6i.c
> +++ b/drivers/rtc/rtc-sun6i.c
> @@ -197,14 +197,14 @@ static void __init sun6i_rtc_clk_init(struct 
> device_node *node)
> clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws),
>GFP_KERNEL);
> if (!clk_data)
> -   return;
> +   goto out_rtc_free;
>
> spin_lock_init(>lock);
>
> rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node));
> if (IS_ERR(rtc->base)) {
> pr_crit("Can't map RTC registers");
> -   return;
> +   goto out_clk_data_free;
> }
>
> /* Switch to the external, more precise, oscillator */
> @@ -216,7 +216,7 @@ static void __init sun6i_rtc_clk_init(struct device_node 
> *node)
>
> /* Deal with old DTs */
> if (!of_get_property(node, "clocks", NULL))
> -   return;
> +   goto out_clk_data_free;
>
> rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
> "rtc-int-osc",
> @@ -225,7 +225,7 @@ static void __init sun6i_rtc_clk_init(struct device_node 
> *node)
> 3);
> if (IS_ERR(rtc->int_osc)) {
> pr_crit("Couldn't register the internal oscillator\n");
> -   return;
> +   goto out_clk_data_free;
> }
>
> parents[0] = clk_hw_get_name(rtc->int_osc);
> @@ -240,12 +240,19 @@ static void __init sun6i_rtc_clk_init(struct 
> device_node *node)
> rtc->losc = clk_register(NULL, >hw);
> if (IS_ERR(rtc->losc)) {
> pr_crit("Couldn't register the LOSC clock\n");
> -   return;
> +   goto out_clk_data_free;

You should also unregister the fixed rate clk above.

> }
>
> clk_data->num = 1;
> clk_data->hws[0] = >hw;
> of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
> +
> +   return;
> +
> +out_clk_data_free:
> +   kfree(clk_data);
> +out_rtc_free:
> +   kfree(rtc);

rtc can not be freed. It has already been assigned to sun6i_rtc, a static
variable within this module. It then gets used by the actual RTC driver
later in this file to get the register base pointer. This was done to
avoid issues with trying to map the same I/O addresses twice.


Regards
ChenYu

>  }
>  CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
>   sun6i_rtc_clk_init);
> --
> 1.9.1
>


Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread icenowy

在 2017-07-24 11:03,Chen-Yu Tsai 写道:

On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:

From: Ondrej Jirman 

SY8106A is an I2C attached single output regulator made by Silergy 
Corp,

which is used on several Allwinner H3/H5 SBCs to control the power
supply of the ARM cores.

Add a driver for it.

Signed-off-by: Ondrej Jirman 
[Icenowy: Change commit message]
Signed-off-by: Icenowy Zheng 
---
 drivers/regulator/Kconfig |   8 +-
 drivers/regulator/Makefile|   2 +-
 drivers/regulator/sy8106a-regulator.c | 163 
++

 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 drivers/regulator/sy8106a-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 99b9362331b5..1efa73e18d07 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
  This driver supports the internal VMMC regulator in the 
STw481x

  PMIC chips.

+config REGULATOR_SY8106A
+   tristate "Silergy SY8106A regulator"
+   depends on I2C && (OF || COMPILE_TEST)
+   select REGMAP_I2C
+   help
+ This driver supports SY8106A single output regulator.
+
 config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C
@@ -938,4 +945,3 @@ config REGULATOR_WM8994
  WM8994 CODEC.

 endif
-
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 95b1e86ae692..f5120252f86a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
+obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
@@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += 
wm8350-regulator.o

 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o

-
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/sy8106a-regulator.c 
b/drivers/regulator/sy8106a-regulator.c

new file mode 100644
index ..1df889f68b3d
--- /dev/null
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -0,0 +1,163 @@
+/*
+ * sy8106a-regulator.c - Regulator device driver for SY8106A
+ *
+ * Copyright (C) 2016 Ondřej Jirman 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SY8106A_REG_VOUT1_SEL  0x01
+#define SY8106A_REG_VOUT_COM   0x02
+#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
+#define SY8106A_DISABLE_REGBIT(0)
+#define SY8106A_GO_BIT BIT(7)
+
+struct sy8106a {
+   struct regulator_dev *rdev;
+   struct regmap *regmap;
+};
+
+static const struct regmap_config sy8106a_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, 
unsigned int sel)

+{
+   /* We use our set_voltage_sel in order to avoid unnecessary 
I2C

+* chatter, because the regulator_get_voltage_sel_regmap using
+* apply_bit would perform 4 unnecessary transfers instead of 
one,

+* increasing the chance of error.
+*/
+   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
+   sel | SY8106A_GO_BIT);


There should also be an explanation of what the "go bit" does.
In this case it enables control of the voltage over I2C.


+}
+
+static const struct regulator_ops sy8106a_ops = {
+   .is_enabled = regulator_is_enabled_regmap,
+   .set_voltage_sel = sy8106a_set_voltage_sel,
+   .set_voltage_time_sel = regulator_set_voltage_time_sel,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .list_voltage = regulator_list_voltage_linear,


No enable/disable ops?


+};
+
+/* Default limits measured in millivolts and milliamps */
+#define SY8106A_MIN_MV 680
+#define SY8106A_MAX_MV 1950
+#define SY8106A_STEP_MV10
+
+static const struct regulator_desc sy8106a_reg = {
+   .name = "SY8106A",
+   .id = 0,
+   .ops = _ops,

Re: [linux-sunxi] [PATCH 02/10] regulator: add support for SY8106A regulator

2017-07-23 Thread icenowy

在 2017-07-24 11:03,Chen-Yu Tsai 写道:

On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:

From: Ondrej Jirman 

SY8106A is an I2C attached single output regulator made by Silergy 
Corp,

which is used on several Allwinner H3/H5 SBCs to control the power
supply of the ARM cores.

Add a driver for it.

Signed-off-by: Ondrej Jirman 
[Icenowy: Change commit message]
Signed-off-by: Icenowy Zheng 
---
 drivers/regulator/Kconfig |   8 +-
 drivers/regulator/Makefile|   2 +-
 drivers/regulator/sy8106a-regulator.c | 163 
++

 3 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 drivers/regulator/sy8106a-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 99b9362331b5..1efa73e18d07 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -764,6 +764,13 @@ config REGULATOR_STW481X_VMMC
  This driver supports the internal VMMC regulator in the 
STw481x

  PMIC chips.

+config REGULATOR_SY8106A
+   tristate "Silergy SY8106A regulator"
+   depends on I2C && (OF || COMPILE_TEST)
+   select REGMAP_I2C
+   help
+ This driver supports SY8106A single output regulator.
+
 config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C
@@ -938,4 +945,3 @@ config REGULATOR_WM8994
  WM8994 CODEC.

 endif
-
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 95b1e86ae692..f5120252f86a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
+obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
@@ -120,5 +121,4 @@ obj-$(CONFIG_REGULATOR_WM8350) += 
wm8350-regulator.o

 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o

-
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/sy8106a-regulator.c 
b/drivers/regulator/sy8106a-regulator.c

new file mode 100644
index ..1df889f68b3d
--- /dev/null
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -0,0 +1,163 @@
+/*
+ * sy8106a-regulator.c - Regulator device driver for SY8106A
+ *
+ * Copyright (C) 2016 Ondřej Jirman 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SY8106A_REG_VOUT1_SEL  0x01
+#define SY8106A_REG_VOUT_COM   0x02
+#define SY8106A_REG_VOUT1_SEL_MASK 0x7f
+#define SY8106A_DISABLE_REGBIT(0)
+#define SY8106A_GO_BIT BIT(7)
+
+struct sy8106a {
+   struct regulator_dev *rdev;
+   struct regmap *regmap;
+};
+
+static const struct regmap_config sy8106a_regmap_config = {
+   .reg_bits = 8,
+   .val_bits = 8,
+};
+
+static int sy8106a_set_voltage_sel(struct regulator_dev *rdev, 
unsigned int sel)

+{
+   /* We use our set_voltage_sel in order to avoid unnecessary 
I2C

+* chatter, because the regulator_get_voltage_sel_regmap using
+* apply_bit would perform 4 unnecessary transfers instead of 
one,

+* increasing the chance of error.
+*/
+   return regmap_write(rdev->regmap, rdev->desc->vsel_reg,
+   sel | SY8106A_GO_BIT);


There should also be an explanation of what the "go bit" does.
In this case it enables control of the voltage over I2C.


+}
+
+static const struct regulator_ops sy8106a_ops = {
+   .is_enabled = regulator_is_enabled_regmap,
+   .set_voltage_sel = sy8106a_set_voltage_sel,
+   .set_voltage_time_sel = regulator_set_voltage_time_sel,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .list_voltage = regulator_list_voltage_linear,


No enable/disable ops?


+};
+
+/* Default limits measured in millivolts and milliamps */
+#define SY8106A_MIN_MV 680
+#define SY8106A_MAX_MV 1950
+#define SY8106A_STEP_MV10
+
+static const struct regulator_desc sy8106a_reg = {
+   .name = "SY8106A",
+   .id = 0,
+   .ops = _ops,
+   .type = REGULATOR_VOLTAGE,
+   .n_voltages = ((SY8106A_MAX_MV - SY8106A_MIN_MV) 

[PATCH] perf report: Tag branch type/flag on "to" and tag cycles on "from"

2017-07-23 Thread Jin Yao
Current --branch-history LBR annotation displays confused
data. For example, each cycles report is duplicated on both
"from" and "to" entries.

For example:
perf report --branch-history --no-children --stdio

--2.32%--main div.c:39 (COND_BWD CROSS_2M predicted:49.7% cycles:1)
  main div.c:44 (predicted:49.7% cycles:1)
  main div.c:42 (RET CROSS_2M cycles:2)
  compute_flag div.c:28 (cycles:2)
  compute_flag div.c:27 (RET CROSS_2M cycles:1)
  rand rand.c:28 (cycles:1)
  rand rand.c:28 (RET CROSS_2M cycles:1)
  __random random.c:298 (cycles:1)
  __random random.c:297 (COND_BWD CROSS_2M cycles:1)
  __random random.c:295 (cycles:1)
  __random random.c:295 (COND_BWD CROSS_2M cycles:1)
  __random random.c:295 (cycles:1)
  __random random.c:295 (RET CROSS_2M cycles:9)

The cycles should be tagged only on the "from". It's for
the code block that ends with "from", not for "to".

Another issue is the "predicted:49.7%" is duplicated too
(tag on both "from" and "to").

This patch tags the branch type/flag on "to" and tag the
cycles on "from".

For example:

--2.32%--main div.c:39 (COND_BWD CROSS_2M predicted:49.7%)
  main div.c:44 (cycles:1)
  main div.c:42 (RET CROSS_2M)
  compute_flag div.c:28 (cycles:2)
  compute_flag div.c:27 (RET CROSS_2M)
  rand rand.c:28 (cycles:1)
  rand rand.c:28 (RET CROSS_2M)
  __random random.c:298 (cycles:1)
  __random random.c:297 (COND_BWD CROSS_2M)
  __random random.c:295 (cycles:1)
  __random random.c:295 (COND_BWD CROSS_2M)
  __random random.c:295 (cycles:1)
  __random random.c:295 (RET CROSS_2M)
  |
   --2.23%--__random_r random_r.c:392 (cycles:9)

In this example, The "main div.c:39 (COND_BWD CROSS_2M predicted:49.7%)"
is "to" of branch and "main div.c:44 (cycles:1)" is "from" of branch.
It should be easier for understanding than before.

Signed-off-by: Jin Yao 
---
 tools/perf/util/branch.h|  11 ++--
 tools/perf/util/callchain.c | 148 +++-
 2 files changed, 111 insertions(+), 48 deletions(-)

diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 686f2b6..1e3c7c5 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -5,11 +5,12 @@
 #include "../perf.h"
 
 struct branch_type_stat {
-   u64 counts[PERF_BR_MAX];
-   u64 cond_fwd;
-   u64 cond_bwd;
-   u64 cross_4k;
-   u64 cross_2m;
+   boolbranch_to;
+   u64 counts[PERF_BR_MAX];
+   u64 cond_fwd;
+   u64 cond_bwd;
+   u64 cross_4k;
+   u64 cross_2m;
 };
 
 struct branch_flags;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 22d413a..8c17ea6 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -563,20 +563,33 @@ fill_node(struct callchain_node *node, struct 
callchain_cursor *cursor)
if (cursor_node->branch) {
call->branch_count = 1;
 
-   if (cursor_node->branch_flags.predicted)
-   call->predicted_count = 1;
-
-   if (cursor_node->branch_flags.abort)
-   call->abort_count = 1;
-
-   call->cycles_count = cursor_node->branch_flags.cycles;
-   call->iter_count = cursor_node->nr_loop_iter;
-   call->samples_count = cursor_node->samples;
-
-   branch_type_count(>brtype_stat,
- _node->branch_flags,
- cursor_node->branch_from,
- cursor_node->ip);
+   if (cursor_node->branch_from) {
+   /*
+* branch_from is set with value somewhere else
+* to imply it's "to" of a branch.
+*/
+   call->brtype_stat.branch_to = true;
+
+   if (cursor_node->branch_flags.predicted)
+   call->predicted_count = 1;
+
+   if (cursor_node->branch_flags.abort)
+   call->abort_count = 1;
+
+   branch_type_count(>brtype_stat,
+ _node->branch_flags,
+ cursor_node->branch_from,
+ cursor_node->ip);
+   } else {
+   /*
+* It's "from" of a branch
+*/
+   call->brtype_stat.branch_to = false;
+ 

[PATCH] perf report: Tag branch type/flag on "to" and tag cycles on "from"

2017-07-23 Thread Jin Yao
Current --branch-history LBR annotation displays confused
data. For example, each cycles report is duplicated on both
"from" and "to" entries.

For example:
perf report --branch-history --no-children --stdio

--2.32%--main div.c:39 (COND_BWD CROSS_2M predicted:49.7% cycles:1)
  main div.c:44 (predicted:49.7% cycles:1)
  main div.c:42 (RET CROSS_2M cycles:2)
  compute_flag div.c:28 (cycles:2)
  compute_flag div.c:27 (RET CROSS_2M cycles:1)
  rand rand.c:28 (cycles:1)
  rand rand.c:28 (RET CROSS_2M cycles:1)
  __random random.c:298 (cycles:1)
  __random random.c:297 (COND_BWD CROSS_2M cycles:1)
  __random random.c:295 (cycles:1)
  __random random.c:295 (COND_BWD CROSS_2M cycles:1)
  __random random.c:295 (cycles:1)
  __random random.c:295 (RET CROSS_2M cycles:9)

The cycles should be tagged only on the "from". It's for
the code block that ends with "from", not for "to".

Another issue is the "predicted:49.7%" is duplicated too
(tag on both "from" and "to").

This patch tags the branch type/flag on "to" and tag the
cycles on "from".

For example:

--2.32%--main div.c:39 (COND_BWD CROSS_2M predicted:49.7%)
  main div.c:44 (cycles:1)
  main div.c:42 (RET CROSS_2M)
  compute_flag div.c:28 (cycles:2)
  compute_flag div.c:27 (RET CROSS_2M)
  rand rand.c:28 (cycles:1)
  rand rand.c:28 (RET CROSS_2M)
  __random random.c:298 (cycles:1)
  __random random.c:297 (COND_BWD CROSS_2M)
  __random random.c:295 (cycles:1)
  __random random.c:295 (COND_BWD CROSS_2M)
  __random random.c:295 (cycles:1)
  __random random.c:295 (RET CROSS_2M)
  |
   --2.23%--__random_r random_r.c:392 (cycles:9)

In this example, The "main div.c:39 (COND_BWD CROSS_2M predicted:49.7%)"
is "to" of branch and "main div.c:44 (cycles:1)" is "from" of branch.
It should be easier for understanding than before.

Signed-off-by: Jin Yao 
---
 tools/perf/util/branch.h|  11 ++--
 tools/perf/util/callchain.c | 148 +++-
 2 files changed, 111 insertions(+), 48 deletions(-)

diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 686f2b6..1e3c7c5 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -5,11 +5,12 @@
 #include "../perf.h"
 
 struct branch_type_stat {
-   u64 counts[PERF_BR_MAX];
-   u64 cond_fwd;
-   u64 cond_bwd;
-   u64 cross_4k;
-   u64 cross_2m;
+   boolbranch_to;
+   u64 counts[PERF_BR_MAX];
+   u64 cond_fwd;
+   u64 cond_bwd;
+   u64 cross_4k;
+   u64 cross_2m;
 };
 
 struct branch_flags;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 22d413a..8c17ea6 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -563,20 +563,33 @@ fill_node(struct callchain_node *node, struct 
callchain_cursor *cursor)
if (cursor_node->branch) {
call->branch_count = 1;
 
-   if (cursor_node->branch_flags.predicted)
-   call->predicted_count = 1;
-
-   if (cursor_node->branch_flags.abort)
-   call->abort_count = 1;
-
-   call->cycles_count = cursor_node->branch_flags.cycles;
-   call->iter_count = cursor_node->nr_loop_iter;
-   call->samples_count = cursor_node->samples;
-
-   branch_type_count(>brtype_stat,
- _node->branch_flags,
- cursor_node->branch_from,
- cursor_node->ip);
+   if (cursor_node->branch_from) {
+   /*
+* branch_from is set with value somewhere else
+* to imply it's "to" of a branch.
+*/
+   call->brtype_stat.branch_to = true;
+
+   if (cursor_node->branch_flags.predicted)
+   call->predicted_count = 1;
+
+   if (cursor_node->branch_flags.abort)
+   call->abort_count = 1;
+
+   branch_type_count(>brtype_stat,
+ _node->branch_flags,
+ cursor_node->branch_from,
+ cursor_node->ip);
+   } else {
+   /*
+* It's "from" of a branch
+*/
+   call->brtype_stat.branch_to = false;
+   call->cycles_count =
+ 

Re: [linux-sunxi] [PATCH 06/10] clk: sunxi-ng: allow set parent clock (PLL_CPUX) for CPUX clock on H3

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> The CPUX clock, which is the main clock of the ARM core on Allwinner H3,
> can be adjusted by changing the frequency of the PLL_CPUX clock.
>
> Allowing setting parent clock for the CPUX clock, thus the PLL_CPUX
> clock can be adjusted when adjusting the CPUX clock.
>
> Signed-off-by: Icenowy Zheng 

Fixes: 0577e4853bfb ("clk: sunxi-ng: Add H3 clocks")
Reviewed-by: Chen-Yu Tsai 


Re: [linux-sunxi] [PATCH 06/10] clk: sunxi-ng: allow set parent clock (PLL_CPUX) for CPUX clock on H3

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> The CPUX clock, which is the main clock of the ARM core on Allwinner H3,
> can be adjusted by changing the frequency of the PLL_CPUX clock.
>
> Allowing setting parent clock for the CPUX clock, thus the PLL_CPUX
> clock can be adjusted when adjusting the CPUX clock.
>
> Signed-off-by: Icenowy Zheng 

Fixes: 0577e4853bfb ("clk: sunxi-ng: Add H3 clocks")
Reviewed-by: Chen-Yu Tsai 


Re: [linux-sunxi] [PATCH 04/10] ARM: sunxi: h3/h5: Add r_i2c I2C controller

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> From: Ondrej Jirman 
>
> Allwinner H3/H5 SoCs have an I2C controller at PL GPIO bank.
>
> Add support for it in the device tree.
>
> Signed-off-by: Ondrej Jirman 
> [Icenowy: Change to use r_ccu and change pinmux node name]
> Signed-off-by: Icenowy Zheng 

Reviewed-by: Chen-Yu Tsai 


Re: [linux-sunxi] [PATCH 04/10] ARM: sunxi: h3/h5: Add r_i2c I2C controller

2017-07-23 Thread Chen-Yu Tsai
On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:
> From: Ondrej Jirman 
>
> Allwinner H3/H5 SoCs have an I2C controller at PL GPIO bank.
>
> Add support for it in the device tree.
>
> Signed-off-by: Ondrej Jirman 
> [Icenowy: Change to use r_ccu and change pinmux node name]
> Signed-off-by: Icenowy Zheng 

Reviewed-by: Chen-Yu Tsai 


Re: [linux-sunxi] [PATCH 03/10] ARM: sunxi: h3/h5: Add r_i2c pinmux node

2017-07-23 Thread icenowy

在 2017-07-24 11:07,Chen-Yu Tsai 写道:

On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:

From: Ondrej Jirman 

H3/H5 SoCs contain an I2C controller optionally available
on the PL0 and PL1 pins. This patch adds pinmux configuration
for this controller.

Signed-off-by: Ondrej Jirman 
[Icenowy: change commit message and node name]
Signed-off-by: Icenowy Zheng 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi

index 6f2162608006..b240099bc865 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -639,6 +639,11 @@
pins = "PL11";
function = "s_cir_rx";
};
+
+   r_i2c_pins: r-i2c {
+   pins = "PL0", "PL1";
+   function = "s_twi";


Can we fix the pinctrl driver to use standard names first? :(


Oh good problem.

Let me fix it.



ChenYu


+   };
};
};
 };
--
2.13.0

--
You received this message because you are subscribed to the Google 
Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to linux-sunxi+unsubscr...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] [PATCH 03/10] ARM: sunxi: h3/h5: Add r_i2c pinmux node

2017-07-23 Thread icenowy

在 2017-07-24 11:07,Chen-Yu Tsai 写道:

On Sun, Jul 23, 2017 at 6:27 PM, Icenowy Zheng  wrote:

From: Ondrej Jirman 

H3/H5 SoCs contain an I2C controller optionally available
on the PL0 and PL1 pins. This patch adds pinmux configuration
for this controller.

Signed-off-by: Ondrej Jirman 
[Icenowy: change commit message and node name]
Signed-off-by: Icenowy Zheng 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi

index 6f2162608006..b240099bc865 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -639,6 +639,11 @@
pins = "PL11";
function = "s_cir_rx";
};
+
+   r_i2c_pins: r-i2c {
+   pins = "PL0", "PL1";
+   function = "s_twi";


Can we fix the pinctrl driver to use standard names first? :(


Oh good problem.

Let me fix it.



ChenYu


+   };
};
};
 };
--
2.13.0

--
You received this message because you are subscribed to the Google 
Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to linux-sunxi+unsubscr...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


  1   2   3   4   5   >