Re: [PATCH] zram: fix null dereference of handle

2017-09-19 Thread Minchan Kim
On Tue, Sep 19, 2017 at 07:21:25PM +0900, Sergey Senozhatsky wrote:
> Minchan,
> 
> I just ran across it [because I had a bug to analize where this
> part was involved]. I'd really prefer the kernel to BUG_ON immediately
> instead of dying in agony.
> 
> can we, please, return BUG_ON() back?
> 
> there is no point in trying to save the kernel once it did that type
> of violation.

I agree. If it happens, it would corrupt other user's buffer which ends
up leaking some private data from others so there is pointless to keep
system alive to debug it.

Do you mind sending a formal patch?
Thanks!

> 
> ---
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 7c38e850a8fc..685049a9048d 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1349,7 +1349,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long 
> handle,
>  * pools/users, we can't allow mapping in interrupt context
>  * because it can corrupt another users mappings.
>  */
> -   WARN_ON_ONCE(in_interrupt());
> +   BUG_ON(in_interrupt());
>  
> /* From now on, migration cannot move the object */
> pin_tag(handle);
> 


Re: [PATCH] zram: fix null dereference of handle

2017-09-19 Thread Minchan Kim
On Tue, Sep 19, 2017 at 07:21:25PM +0900, Sergey Senozhatsky wrote:
> Minchan,
> 
> I just ran across it [because I had a bug to analize where this
> part was involved]. I'd really prefer the kernel to BUG_ON immediately
> instead of dying in agony.
> 
> can we, please, return BUG_ON() back?
> 
> there is no point in trying to save the kernel once it did that type
> of violation.

I agree. If it happens, it would corrupt other user's buffer which ends
up leaking some private data from others so there is pointless to keep
system alive to debug it.

Do you mind sending a formal patch?
Thanks!

> 
> ---
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 7c38e850a8fc..685049a9048d 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1349,7 +1349,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long 
> handle,
>  * pools/users, we can't allow mapping in interrupt context
>  * because it can corrupt another users mappings.
>  */
> -   WARN_ON_ONCE(in_interrupt());
> +   BUG_ON(in_interrupt());
>  
> /* From now on, migration cannot move the object */
> pin_tag(handle);
> 


Re: Error when building the kernel on top of 4.14-rc1 for target firmware_install?

2017-09-19 Thread Yu Chen
On Wed, Sep 20, 2017 at 1:37 PM, Greg Kroah-Hartman
 wrote:
> On Wed, Sep 20, 2017 at 11:20:19AM +0800, Yu Chen wrote:
>> Hi,
>> kernel compile failed after running # make rpm
>>
>> + 
>> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
>> + make 
>> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
>> firmware_install
>> make[2]: warning: jobserver unavailable: using -j1.  Add '+' to parent
>> make rule.
>> make[2]: *** No rule to make target 'firmware_install'.  Stop.
>>
>> I have to hack the script to compile through:
>> diff --git a/scripts/package/mkspec b/scripts/package/mkspec
>> index bb43f15..cb9c1b3 100755
>> --- a/scripts/package/mkspec
>> +++ b/scripts/package/mkspec
>> @@ -92,7 +92,7 @@ echo 'mkdir -p 
>> $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
>>
>>  echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags}
>> KBUILD_SRC= mod-fw= modules_install'
>>  echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
>> -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
>> +echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH'
>>  echo "%ifarch ia64"
>>
>> Not sure if this is a regression but several version ago it works well.
>
> See the maling list for fixes for this already :)
>
> thanks,
>
> greg k-h
Got it! thanks.


Re: [PATCH v2 3/5] dmaengine: zynqmp_ps_pcie: Adding PS PCIe DMA driver

2017-09-19 Thread Michal Simek
On 8.9.2017 14:23, Ravi Shankar Jonnalagadda wrote:
> Adding support for ZynqmMP PS PCIe EP driver.
> Adding support for ZynqmMP PS PCIe Root DMA driver.
> Modifying Kconfig and Makefile to add the support.
> 
> Signed-off-by: Ravi Shankar Jonnalagadda 
> Signed-off-by: RaviKiran Gummaluri 
> ---
>  drivers/dma/Kconfig   |  12 +++
>  drivers/dma/xilinx/Makefile   |   2 +
>  drivers/dma/xilinx/ps_pcie.h  |  44 +
>  drivers/dma/xilinx/ps_pcie_main.c | 200 
> ++
>  include/linux/dma/ps_pcie_dma.h   |  69 +
>  5 files changed, 327 insertions(+)
>  create mode 100644 drivers/dma/xilinx/ps_pcie.h
>  create mode 100644 drivers/dma/xilinx/ps_pcie_main.c
>  create mode 100644 include/linux/dma/ps_pcie_dma.h
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index fa8f9c0..e2fe4e5 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -586,6 +586,18 @@ config XILINX_ZYNQMP_DMA
>   help
> Enable support for Xilinx ZynqMP DMA controller.
>  
> +config XILINX_PS_PCIE_DMA
> + tristate "Xilinx PS PCIe DMA support"
> + depends on (PCI && X86_64 || ARM64)
> + select DMA_ENGINE
> + help
> +   Enable support for the Xilinx PS PCIe DMA engine present
> +   in recent Xilinx ZynqMP chipsets.
> +
> +   Say Y here if you have such a chipset.
> +
> +   If unsure, say N.
> +
>  config ZX_DMA
>   tristate "ZTE ZX DMA support"
>   depends on ARCH_ZX || COMPILE_TEST
> diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> index 9e91f8f..04f6f99 100644
> --- a/drivers/dma/xilinx/Makefile
> +++ b/drivers/dma/xilinx/Makefile
> @@ -1,2 +1,4 @@
>  obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
>  obj-$(CONFIG_XILINX_ZYNQMP_DMA) += zynqmp_dma.o
> +ps_pcie_dma-objs := ps_pcie_main.o ps_pcie_platform.o
> +obj-$(CONFIG_XILINX_PS_PCIE_DMA) += ps_pcie_dma.o
> diff --git a/drivers/dma/xilinx/ps_pcie.h b/drivers/dma/xilinx/ps_pcie.h
> new file mode 100644
> index 000..351f051
> --- /dev/null
> +++ b/drivers/dma/xilinx/ps_pcie.h
> @@ -0,0 +1,44 @@
> +/*
> + * Xilinx PS PCIe DMA Engine platform header file
> + *
> + * Copyright (C) 2010-2017 Xilinx, Inc. All rights reserved.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation
> + */
> +
> +#ifndef __XILINX_PS_PCIE_H
> +#define __XILINX_PS_PCIE_H
> +
> +#include 
> +#include 

this is included via dma-mapping.h below.

> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

this is already include via of.h

> +#include 
> +#include 
> +#include 

Don't we have any script for checking this?

> +
> +/**
> + * dma_platform_driver_register - This will be invoked by module init
> + *
> + * Return: returns status of platform_driver_register
> + */
> +int dma_platform_driver_register(void);


put empty line here.

> +/**
> + * dma_platform_driver_unregister - This will be invoked by module exit
> + *
> + * Return: returns void after unregustering platform driver
> + */
> +void dma_platform_driver_unregister(void);
> +
> +#endif
> diff --git a/drivers/dma/xilinx/ps_pcie_main.c 
> b/drivers/dma/xilinx/ps_pcie_main.c
> new file mode 100644
> index 000..4ccd8ef
> --- /dev/null
> +++ b/drivers/dma/xilinx/ps_pcie_main.c
> @@ -0,0 +1,200 @@
> +/*
> + * XILINX PS PCIe driver
> + *
> + * Copyright (C) 2017 Xilinx, Inc. All rights reserved.
> + *
> + * Description
> + * PS PCIe DMA is memory mapped DMA used to execute PS to PL transfers
> + * on ZynqMP UltraScale+ Devices.
> + * This PCIe driver creates a platform device with specific platform
> + * info enabling creation of DMA device corresponding to the channel
> + * information provided in the properties
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation
> + */
> +
> +#include "ps_pcie.h"
> +#include "../dmaengine.h"
> +
> +#define DRV_MODULE_NAME"ps_pcie_dma"
> +
> +static int ps_pcie_dma_probe(struct pci_dev *pdev,
> +  const struct pci_device_id *ent);
> +static void ps_pcie_dma_remove(struct pci_dev *pdev);
> +
> +static u32 channel_properties_pcie_axi[] = {
> + (u32)(PCIE_AXI_DIRECTION), (u32)(NUMBER_OF_BUFFER_DESCRIPTORS),
> + (u32)(DEFAULT_DMA_QUEUES), (u32)(CHANNEL_COAELSE_COUNT),
> + (u32)(CHANNEL_POLL_TIMER_FREQUENCY) };
> +
> +static u32 channel_properties_axi_pcie[] = {
> + (u32)(AXI_PCIE_DIRECTION), (u32)(NUMBER_OF_BUFFER_DESCRIPTORS),
> + (u32)(DEFAULT_DMA_QUEUES), (u32)(CHANNEL_COAELSE_COUNT),
> + (u32)(CHANNEL_POLL_TIMER_FREQUENCY) };
> +
> +static struct property_entry generic_pcie_ep_property[] 

Re: Error when building the kernel on top of 4.14-rc1 for target firmware_install?

2017-09-19 Thread Yu Chen
On Wed, Sep 20, 2017 at 1:37 PM, Greg Kroah-Hartman
 wrote:
> On Wed, Sep 20, 2017 at 11:20:19AM +0800, Yu Chen wrote:
>> Hi,
>> kernel compile failed after running # make rpm
>>
>> + 
>> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
>> + make 
>> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
>> firmware_install
>> make[2]: warning: jobserver unavailable: using -j1.  Add '+' to parent
>> make rule.
>> make[2]: *** No rule to make target 'firmware_install'.  Stop.
>>
>> I have to hack the script to compile through:
>> diff --git a/scripts/package/mkspec b/scripts/package/mkspec
>> index bb43f15..cb9c1b3 100755
>> --- a/scripts/package/mkspec
>> +++ b/scripts/package/mkspec
>> @@ -92,7 +92,7 @@ echo 'mkdir -p 
>> $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
>>
>>  echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags}
>> KBUILD_SRC= mod-fw= modules_install'
>>  echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
>> -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
>> +echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH'
>>  echo "%ifarch ia64"
>>
>> Not sure if this is a regression but several version ago it works well.
>
> See the maling list for fixes for this already :)
>
> thanks,
>
> greg k-h
Got it! thanks.


Re: [PATCH v2 3/5] dmaengine: zynqmp_ps_pcie: Adding PS PCIe DMA driver

2017-09-19 Thread Michal Simek
On 8.9.2017 14:23, Ravi Shankar Jonnalagadda wrote:
> Adding support for ZynqmMP PS PCIe EP driver.
> Adding support for ZynqmMP PS PCIe Root DMA driver.
> Modifying Kconfig and Makefile to add the support.
> 
> Signed-off-by: Ravi Shankar Jonnalagadda 
> Signed-off-by: RaviKiran Gummaluri 
> ---
>  drivers/dma/Kconfig   |  12 +++
>  drivers/dma/xilinx/Makefile   |   2 +
>  drivers/dma/xilinx/ps_pcie.h  |  44 +
>  drivers/dma/xilinx/ps_pcie_main.c | 200 
> ++
>  include/linux/dma/ps_pcie_dma.h   |  69 +
>  5 files changed, 327 insertions(+)
>  create mode 100644 drivers/dma/xilinx/ps_pcie.h
>  create mode 100644 drivers/dma/xilinx/ps_pcie_main.c
>  create mode 100644 include/linux/dma/ps_pcie_dma.h
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index fa8f9c0..e2fe4e5 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -586,6 +586,18 @@ config XILINX_ZYNQMP_DMA
>   help
> Enable support for Xilinx ZynqMP DMA controller.
>  
> +config XILINX_PS_PCIE_DMA
> + tristate "Xilinx PS PCIe DMA support"
> + depends on (PCI && X86_64 || ARM64)
> + select DMA_ENGINE
> + help
> +   Enable support for the Xilinx PS PCIe DMA engine present
> +   in recent Xilinx ZynqMP chipsets.
> +
> +   Say Y here if you have such a chipset.
> +
> +   If unsure, say N.
> +
>  config ZX_DMA
>   tristate "ZTE ZX DMA support"
>   depends on ARCH_ZX || COMPILE_TEST
> diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> index 9e91f8f..04f6f99 100644
> --- a/drivers/dma/xilinx/Makefile
> +++ b/drivers/dma/xilinx/Makefile
> @@ -1,2 +1,4 @@
>  obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
>  obj-$(CONFIG_XILINX_ZYNQMP_DMA) += zynqmp_dma.o
> +ps_pcie_dma-objs := ps_pcie_main.o ps_pcie_platform.o
> +obj-$(CONFIG_XILINX_PS_PCIE_DMA) += ps_pcie_dma.o
> diff --git a/drivers/dma/xilinx/ps_pcie.h b/drivers/dma/xilinx/ps_pcie.h
> new file mode 100644
> index 000..351f051
> --- /dev/null
> +++ b/drivers/dma/xilinx/ps_pcie.h
> @@ -0,0 +1,44 @@
> +/*
> + * Xilinx PS PCIe DMA Engine platform header file
> + *
> + * Copyright (C) 2010-2017 Xilinx, Inc. All rights reserved.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation
> + */
> +
> +#ifndef __XILINX_PS_PCIE_H
> +#define __XILINX_PS_PCIE_H
> +
> +#include 
> +#include 

this is included via dma-mapping.h below.

> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 

this is already include via of.h

> +#include 
> +#include 
> +#include 

Don't we have any script for checking this?

> +
> +/**
> + * dma_platform_driver_register - This will be invoked by module init
> + *
> + * Return: returns status of platform_driver_register
> + */
> +int dma_platform_driver_register(void);


put empty line here.

> +/**
> + * dma_platform_driver_unregister - This will be invoked by module exit
> + *
> + * Return: returns void after unregustering platform driver
> + */
> +void dma_platform_driver_unregister(void);
> +
> +#endif
> diff --git a/drivers/dma/xilinx/ps_pcie_main.c 
> b/drivers/dma/xilinx/ps_pcie_main.c
> new file mode 100644
> index 000..4ccd8ef
> --- /dev/null
> +++ b/drivers/dma/xilinx/ps_pcie_main.c
> @@ -0,0 +1,200 @@
> +/*
> + * XILINX PS PCIe driver
> + *
> + * Copyright (C) 2017 Xilinx, Inc. All rights reserved.
> + *
> + * Description
> + * PS PCIe DMA is memory mapped DMA used to execute PS to PL transfers
> + * on ZynqMP UltraScale+ Devices.
> + * This PCIe driver creates a platform device with specific platform
> + * info enabling creation of DMA device corresponding to the channel
> + * information provided in the properties
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation
> + */
> +
> +#include "ps_pcie.h"
> +#include "../dmaengine.h"
> +
> +#define DRV_MODULE_NAME"ps_pcie_dma"
> +
> +static int ps_pcie_dma_probe(struct pci_dev *pdev,
> +  const struct pci_device_id *ent);
> +static void ps_pcie_dma_remove(struct pci_dev *pdev);
> +
> +static u32 channel_properties_pcie_axi[] = {
> + (u32)(PCIE_AXI_DIRECTION), (u32)(NUMBER_OF_BUFFER_DESCRIPTORS),
> + (u32)(DEFAULT_DMA_QUEUES), (u32)(CHANNEL_COAELSE_COUNT),
> + (u32)(CHANNEL_POLL_TIMER_FREQUENCY) };
> +
> +static u32 channel_properties_axi_pcie[] = {
> + (u32)(AXI_PCIE_DIRECTION), (u32)(NUMBER_OF_BUFFER_DESCRIPTORS),
> + (u32)(DEFAULT_DMA_QUEUES), (u32)(CHANNEL_COAELSE_COUNT),
> + (u32)(CHANNEL_POLL_TIMER_FREQUENCY) };
> +
> +static struct property_entry generic_pcie_ep_property[] = {
> + 

[PATCH v2 4/4] mm:swap: skip swapcache for swapin of synchronous device

2017-09-19 Thread Minchan Kim
With fast swap storage, platform want to use swap more aggressively
and swap-in is crucial to application latency.

The rw_page based synchronous devices like zram, pmem and btt are such
fast storage. When I profile swapin performance with zram lz4 decompress
test, S/W overhead is more than 70%. Maybe, it would be bigger in nvdimm.

This patch aims for reducing swap-in latency via skipping swapcache
if swap device is synchronous device like rw_page based device.
It enhances 45% my swapin test(5G sequential swapin, no readahead,
from 2.41sec to 1.64sec).

Cc: Dan Williams 
Cc: Ross Zwisler 
Cc: Hugh Dickins 
Signed-off-by: Minchan Kim 
---
 include/linux/swap.h | 11 +++
 mm/memory.c  | 52 
 mm/page_io.c |  6 +++---
 mm/swapfile.c| 11 +++
 4 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index fbb33919d1c6..cd2f66fdfc2d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -461,6 +461,7 @@ extern int page_swapcount(struct page *);
 extern int __swp_swapcount(swp_entry_t entry);
 extern int swp_swapcount(swp_entry_t entry);
 extern struct swap_info_struct *page_swap_info(struct page *);
+extern struct swap_info_struct *swp_swap_info(swp_entry_t entry);
 extern bool reuse_swap_page(struct page *, int *);
 extern int try_to_free_swap(struct page *);
 struct backing_dev_info;
@@ -469,6 +470,16 @@ extern void exit_swap_address_space(unsigned int type);
 
 #else /* CONFIG_SWAP */
 
+static inline int swap_readpage(struct page *page, bool do_poll)
+{
+   return 0;
+}
+
+static inline struct swap_info_struct *swp_swap_info(swp_entry_t entry)
+{
+   return NULL;
+}
+
 #define swap_address_space(entry)  (NULL)
 #define get_nr_swap_pages()0L
 #define total_swap_pages   0L
diff --git a/mm/memory.c b/mm/memory.c
index ec4e15494901..163ab2062385 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2842,7 +2842,7 @@ EXPORT_SYMBOL(unmap_mapping_range);
 int do_swap_page(struct vm_fault *vmf)
 {
struct vm_area_struct *vma = vmf->vma;
-   struct page *page = NULL, *swapcache;
+   struct page *page = NULL, *swapcache = NULL;
struct mem_cgroup *memcg;
struct vma_swap_readahead swap_ra;
swp_entry_t entry;
@@ -2881,17 +2881,35 @@ int do_swap_page(struct vm_fault *vmf)
}
goto out;
}
+
+
delayacct_set_flag(DELAYACCT_PF_SWAPIN);
if (!page)
page = lookup_swap_cache(entry, vma_readahead ? vma : NULL,
 vmf->address);
if (!page) {
-   if (vma_readahead)
-   page = do_swap_page_readahead(entry,
-   GFP_HIGHUSER_MOVABLE, vmf, _ra);
-   else
-   page = swapin_readahead(entry,
-   GFP_HIGHUSER_MOVABLE, vma, vmf->address);
+   struct swap_info_struct *si = swp_swap_info(entry);
+
+   if (!(si->flags & SWP_SYNCHRONOUS_IO)) {
+   if (vma_readahead)
+   page = do_swap_page_readahead(entry,
+   GFP_HIGHUSER_MOVABLE, vmf, _ra);
+   else
+   page = swapin_readahead(entry,
+   GFP_HIGHUSER_MOVABLE, vma, 
vmf->address);
+   swapcache = page;
+   } else {
+   /* skip swapcache */
+   page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, 
vmf->address);
+   if (page) {
+   __SetPageLocked(page);
+   __SetPageSwapBacked(page);
+   set_page_private(page, entry.val);
+   lru_cache_add_anon(page);
+   swap_readpage(page, true);
+   }
+   }
+
if (!page) {
/*
 * Back out if somebody else faulted in this pte
@@ -2920,7 +2938,6 @@ int do_swap_page(struct vm_fault *vmf)
goto out_release;
}
 
-   swapcache = page;
locked = lock_page_or_retry(page, vma->vm_mm, vmf->flags);
 
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
@@ -2935,7 +2952,8 @@ int do_swap_page(struct vm_fault *vmf)
 * test below, are not enough to exclude that.  Even if it is still
 * swapcache, we need to check that the page's swap has not changed.
 */
-   if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val))
+   if (unlikely((!PageSwapCache(page) ||
+   page_private(page) != entry.val)) && swapcache)
   

[PATCH v2 4/4] mm:swap: skip swapcache for swapin of synchronous device

2017-09-19 Thread Minchan Kim
With fast swap storage, platform want to use swap more aggressively
and swap-in is crucial to application latency.

The rw_page based synchronous devices like zram, pmem and btt are such
fast storage. When I profile swapin performance with zram lz4 decompress
test, S/W overhead is more than 70%. Maybe, it would be bigger in nvdimm.

This patch aims for reducing swap-in latency via skipping swapcache
if swap device is synchronous device like rw_page based device.
It enhances 45% my swapin test(5G sequential swapin, no readahead,
from 2.41sec to 1.64sec).

Cc: Dan Williams 
Cc: Ross Zwisler 
Cc: Hugh Dickins 
Signed-off-by: Minchan Kim 
---
 include/linux/swap.h | 11 +++
 mm/memory.c  | 52 
 mm/page_io.c |  6 +++---
 mm/swapfile.c| 11 +++
 4 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index fbb33919d1c6..cd2f66fdfc2d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -461,6 +461,7 @@ extern int page_swapcount(struct page *);
 extern int __swp_swapcount(swp_entry_t entry);
 extern int swp_swapcount(swp_entry_t entry);
 extern struct swap_info_struct *page_swap_info(struct page *);
+extern struct swap_info_struct *swp_swap_info(swp_entry_t entry);
 extern bool reuse_swap_page(struct page *, int *);
 extern int try_to_free_swap(struct page *);
 struct backing_dev_info;
@@ -469,6 +470,16 @@ extern void exit_swap_address_space(unsigned int type);
 
 #else /* CONFIG_SWAP */
 
+static inline int swap_readpage(struct page *page, bool do_poll)
+{
+   return 0;
+}
+
+static inline struct swap_info_struct *swp_swap_info(swp_entry_t entry)
+{
+   return NULL;
+}
+
 #define swap_address_space(entry)  (NULL)
 #define get_nr_swap_pages()0L
 #define total_swap_pages   0L
diff --git a/mm/memory.c b/mm/memory.c
index ec4e15494901..163ab2062385 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2842,7 +2842,7 @@ EXPORT_SYMBOL(unmap_mapping_range);
 int do_swap_page(struct vm_fault *vmf)
 {
struct vm_area_struct *vma = vmf->vma;
-   struct page *page = NULL, *swapcache;
+   struct page *page = NULL, *swapcache = NULL;
struct mem_cgroup *memcg;
struct vma_swap_readahead swap_ra;
swp_entry_t entry;
@@ -2881,17 +2881,35 @@ int do_swap_page(struct vm_fault *vmf)
}
goto out;
}
+
+
delayacct_set_flag(DELAYACCT_PF_SWAPIN);
if (!page)
page = lookup_swap_cache(entry, vma_readahead ? vma : NULL,
 vmf->address);
if (!page) {
-   if (vma_readahead)
-   page = do_swap_page_readahead(entry,
-   GFP_HIGHUSER_MOVABLE, vmf, _ra);
-   else
-   page = swapin_readahead(entry,
-   GFP_HIGHUSER_MOVABLE, vma, vmf->address);
+   struct swap_info_struct *si = swp_swap_info(entry);
+
+   if (!(si->flags & SWP_SYNCHRONOUS_IO)) {
+   if (vma_readahead)
+   page = do_swap_page_readahead(entry,
+   GFP_HIGHUSER_MOVABLE, vmf, _ra);
+   else
+   page = swapin_readahead(entry,
+   GFP_HIGHUSER_MOVABLE, vma, 
vmf->address);
+   swapcache = page;
+   } else {
+   /* skip swapcache */
+   page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, 
vmf->address);
+   if (page) {
+   __SetPageLocked(page);
+   __SetPageSwapBacked(page);
+   set_page_private(page, entry.val);
+   lru_cache_add_anon(page);
+   swap_readpage(page, true);
+   }
+   }
+
if (!page) {
/*
 * Back out if somebody else faulted in this pte
@@ -2920,7 +2938,6 @@ int do_swap_page(struct vm_fault *vmf)
goto out_release;
}
 
-   swapcache = page;
locked = lock_page_or_retry(page, vma->vm_mm, vmf->flags);
 
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
@@ -2935,7 +2952,8 @@ int do_swap_page(struct vm_fault *vmf)
 * test below, are not enough to exclude that.  Even if it is still
 * swapcache, we need to check that the page's swap has not changed.
 */
-   if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val))
+   if (unlikely((!PageSwapCache(page) ||
+   page_private(page) != entry.val)) && swapcache)
goto out_page;
 
page = ksm_might_need_to_copy(page, vma, vmf->address);

[PATCH v2 1/4] zram: set BDI_CAP_STABLE_WRITES once

2017-09-19 Thread Minchan Kim
[1] fixed weird thing(i.e., reset BDI_CAP_STABLE_WRITES flag
unconditionally whenever revalidat_disk is called) so zram doesn't
need to reset the flag any more whenever revalidating the bdev.
Instead, set the flag just once when the zram device is created.

It shouldn't change any behavior.

[1] 19b7ccf8651d, block: get rid of blk_integrity_revalidate()
Cc: Ilya Dryomov 
Reviewed-by: Sergey Senozhatsky 
Signed-off-by: Minchan Kim 
---
 drivers/block/zram/zram_drv.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index cc78f61e22d1..98ef1a8389b0 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -122,14 +122,6 @@ static inline bool is_partial_io(struct bio_vec *bvec)
 }
 #endif
 
-static void zram_revalidate_disk(struct zram *zram)
-{
-   revalidate_disk(zram->disk);
-   /* revalidate_disk reset the BDI_CAP_STABLE_WRITES so set again */
-   zram->disk->queue->backing_dev_info->capabilities |=
-   BDI_CAP_STABLE_WRITES;
-}
-
 /*
  * Check if request is within bounds and aligned on zram logical blocks.
  */
@@ -1371,7 +1363,8 @@ static ssize_t disksize_store(struct device *dev,
zram->comp = comp;
zram->disksize = disksize;
set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
-   zram_revalidate_disk(zram);
+
+   revalidate_disk(zram->disk);
up_write(>init_lock);
 
return len;
@@ -1418,7 +1411,7 @@ static ssize_t reset_store(struct device *dev,
/* Make sure all the pending I/O are finished */
fsync_bdev(bdev);
zram_reset_device(zram);
-   zram_revalidate_disk(zram);
+   revalidate_disk(zram->disk);
bdput(bdev);
 
mutex_lock(>bd_mutex);
@@ -1537,6 +1530,7 @@ static int zram_add(void)
/* zram devices sort of resembles non-rotational disks */
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, zram->disk->queue);
+
/*
 * To ensure that we always get PAGE_SIZE aligned
 * and n*PAGE_SIZED sized I/O requests.
@@ -1561,6 +1555,8 @@ static int zram_add(void)
if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE)
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
 
+   zram->disk->queue->backing_dev_info->capabilities |=
+   BDI_CAP_STABLE_WRITES;
add_disk(zram->disk);
 
ret = sysfs_create_group(_to_dev(zram->disk)->kobj,
-- 
2.7.4



[PATCH v2 1/4] zram: set BDI_CAP_STABLE_WRITES once

2017-09-19 Thread Minchan Kim
[1] fixed weird thing(i.e., reset BDI_CAP_STABLE_WRITES flag
unconditionally whenever revalidat_disk is called) so zram doesn't
need to reset the flag any more whenever revalidating the bdev.
Instead, set the flag just once when the zram device is created.

It shouldn't change any behavior.

[1] 19b7ccf8651d, block: get rid of blk_integrity_revalidate()
Cc: Ilya Dryomov 
Reviewed-by: Sergey Senozhatsky 
Signed-off-by: Minchan Kim 
---
 drivers/block/zram/zram_drv.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index cc78f61e22d1..98ef1a8389b0 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -122,14 +122,6 @@ static inline bool is_partial_io(struct bio_vec *bvec)
 }
 #endif
 
-static void zram_revalidate_disk(struct zram *zram)
-{
-   revalidate_disk(zram->disk);
-   /* revalidate_disk reset the BDI_CAP_STABLE_WRITES so set again */
-   zram->disk->queue->backing_dev_info->capabilities |=
-   BDI_CAP_STABLE_WRITES;
-}
-
 /*
  * Check if request is within bounds and aligned on zram logical blocks.
  */
@@ -1371,7 +1363,8 @@ static ssize_t disksize_store(struct device *dev,
zram->comp = comp;
zram->disksize = disksize;
set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
-   zram_revalidate_disk(zram);
+
+   revalidate_disk(zram->disk);
up_write(>init_lock);
 
return len;
@@ -1418,7 +1411,7 @@ static ssize_t reset_store(struct device *dev,
/* Make sure all the pending I/O are finished */
fsync_bdev(bdev);
zram_reset_device(zram);
-   zram_revalidate_disk(zram);
+   revalidate_disk(zram->disk);
bdput(bdev);
 
mutex_lock(>bd_mutex);
@@ -1537,6 +1530,7 @@ static int zram_add(void)
/* zram devices sort of resembles non-rotational disks */
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, zram->disk->queue);
+
/*
 * To ensure that we always get PAGE_SIZE aligned
 * and n*PAGE_SIZED sized I/O requests.
@@ -1561,6 +1555,8 @@ static int zram_add(void)
if (ZRAM_LOGICAL_BLOCK_SIZE == PAGE_SIZE)
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
 
+   zram->disk->queue->backing_dev_info->capabilities |=
+   BDI_CAP_STABLE_WRITES;
add_disk(zram->disk);
 
ret = sysfs_create_group(_to_dev(zram->disk)->kobj,
-- 
2.7.4



[PATCH v2 2/4] bdi: introduce BDI_CAP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
By discussion[1], someday we will remove rw_page function. If so, we need
something to detect such super-fast storage which synchronous IO operation
like current rw_page is always win.

This patch introduces BDI_CAP_SYNCHRONOUS_IO to indicate such devices.
With it, we could use various optimization techniques.

[1] lkml.kernel.org/r/<20170728165604.10455-1-ross.zwis...@linux.intel.com>

Cc: Christoph Hellwig 
Cc: Dan Williams 
Cc: Ross Zwisler 
Signed-off-by: Minchan Kim 
---
 drivers/block/brd.c   | 2 ++
 drivers/block/zram/zram_drv.c | 2 +-
 drivers/nvdimm/btt.c  | 3 +++
 drivers/nvdimm/pmem.c | 2 ++
 include/linux/backing-dev.h   | 8 
 5 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index bbd0d186cfc0..1fdb736aa882 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_BLK_DEV_RAM_DAX
 #include 
 #include 
@@ -449,6 +450,7 @@ static struct brd_device *brd_alloc(int i)
disk->flags = GENHD_FL_EXT_DEVT;
sprintf(disk->disk_name, "ram%d", i);
set_capacity(disk, rd_size * 2);
+   disk->queue->backing_dev_info->capabilities |= BDI_CAP_SYNCHRONOUS_IO;
 
 #ifdef CONFIG_BLK_DEV_RAM_DAX
queue_flag_set_unlocked(QUEUE_FLAG_DAX, brd->brd_queue);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 98ef1a8389b0..23172641fc01 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1556,7 +1556,7 @@ static int zram_add(void)
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
 
zram->disk->queue->backing_dev_info->capabilities |=
-   BDI_CAP_STABLE_WRITES;
+   (BDI_CAP_STABLE_WRITES | BDI_CAP_SYNCHRONOUS_IO);
add_disk(zram->disk);
 
ret = sysfs_create_group(_to_dev(zram->disk)->kobj,
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index d5612bd1cc81..e949e3302af4 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "btt.h"
 #include "nd.h"
 
@@ -1402,6 +1403,8 @@ static int btt_blk_init(struct btt *btt)
btt->btt_disk->private_data = btt;
btt->btt_disk->queue = btt->btt_queue;
btt->btt_disk->flags = GENHD_FL_EXT_DEVT;
+   btt->btt_disk->queue->backing_dev_info->capabilities |=
+   BDI_CAP_SYNCHRONOUS_IO;
 
blk_queue_make_request(btt->btt_queue, btt_make_request);
blk_queue_logical_block_size(btt->btt_queue, btt->sector_size);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 39dfd7affa31..7fbc5c5dc8e1 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pmem.h"
 #include "pfn.h"
 #include "nd.h"
@@ -394,6 +395,7 @@ static int pmem_attach_disk(struct device *dev,
disk->fops  = _fops;
disk->queue = q;
disk->flags = GENHD_FL_EXT_DEVT;
+   disk->queue->backing_dev_info->capabilities |= BDI_CAP_SYNCHRONOUS_IO;
nvdimm_namespace_disk_name(ndns, disk->disk_name);
set_capacity(disk, (pmem->size - pmem->pfn_pad - pmem->data_offset)
/ 512);
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 854e1bdd0b2a..cd41617c6594 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -123,6 +123,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, 
unsigned int max_ratio);
  * BDI_CAP_STRICTLIMIT:Keep number of dirty pages below bdi threshold.
  *
  * BDI_CAP_CGROUP_WRITEBACK: Supports cgroup-aware writeback.
+ * BDI_CAP_SYNCHRONOUS_IO: Device is so fast that asynchronous IO would be
+ *inefficient.
  */
 #define BDI_CAP_NO_ACCT_DIRTY  0x0001
 #define BDI_CAP_NO_WRITEBACK   0x0002
@@ -130,6 +132,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, 
unsigned int max_ratio);
 #define BDI_CAP_STABLE_WRITES  0x0008
 #define BDI_CAP_STRICTLIMIT0x0010
 #define BDI_CAP_CGROUP_WRITEBACK 0x0020
+#define BDI_CAP_SYNCHRONOUS_IO 0x0040
 
 #define BDI_CAP_NO_ACCT_AND_WRITEBACK \
(BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB)
@@ -177,6 +180,11 @@ long wait_iff_congested(struct pglist_data *pgdat, int 
sync, long timeout);
 int pdflush_proc_obsolete(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
 
+static inline bool bdi_cap_synchronous_io(struct backing_dev_info *bdi)
+{
+   return bdi->capabilities & BDI_CAP_SYNCHRONOUS_IO;
+}
+
 static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi)
 {
return bdi->capabilities & 

[PATCH v2 2/4] bdi: introduce BDI_CAP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
By discussion[1], someday we will remove rw_page function. If so, we need
something to detect such super-fast storage which synchronous IO operation
like current rw_page is always win.

This patch introduces BDI_CAP_SYNCHRONOUS_IO to indicate such devices.
With it, we could use various optimization techniques.

[1] lkml.kernel.org/r/<20170728165604.10455-1-ross.zwis...@linux.intel.com>

Cc: Christoph Hellwig 
Cc: Dan Williams 
Cc: Ross Zwisler 
Signed-off-by: Minchan Kim 
---
 drivers/block/brd.c   | 2 ++
 drivers/block/zram/zram_drv.c | 2 +-
 drivers/nvdimm/btt.c  | 3 +++
 drivers/nvdimm/pmem.c | 2 ++
 include/linux/backing-dev.h   | 8 
 5 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index bbd0d186cfc0..1fdb736aa882 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_BLK_DEV_RAM_DAX
 #include 
 #include 
@@ -449,6 +450,7 @@ static struct brd_device *brd_alloc(int i)
disk->flags = GENHD_FL_EXT_DEVT;
sprintf(disk->disk_name, "ram%d", i);
set_capacity(disk, rd_size * 2);
+   disk->queue->backing_dev_info->capabilities |= BDI_CAP_SYNCHRONOUS_IO;
 
 #ifdef CONFIG_BLK_DEV_RAM_DAX
queue_flag_set_unlocked(QUEUE_FLAG_DAX, brd->brd_queue);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 98ef1a8389b0..23172641fc01 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1556,7 +1556,7 @@ static int zram_add(void)
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
 
zram->disk->queue->backing_dev_info->capabilities |=
-   BDI_CAP_STABLE_WRITES;
+   (BDI_CAP_STABLE_WRITES | BDI_CAP_SYNCHRONOUS_IO);
add_disk(zram->disk);
 
ret = sysfs_create_group(_to_dev(zram->disk)->kobj,
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index d5612bd1cc81..e949e3302af4 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "btt.h"
 #include "nd.h"
 
@@ -1402,6 +1403,8 @@ static int btt_blk_init(struct btt *btt)
btt->btt_disk->private_data = btt;
btt->btt_disk->queue = btt->btt_queue;
btt->btt_disk->flags = GENHD_FL_EXT_DEVT;
+   btt->btt_disk->queue->backing_dev_info->capabilities |=
+   BDI_CAP_SYNCHRONOUS_IO;
 
blk_queue_make_request(btt->btt_queue, btt_make_request);
blk_queue_logical_block_size(btt->btt_queue, btt->sector_size);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 39dfd7affa31..7fbc5c5dc8e1 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "pmem.h"
 #include "pfn.h"
 #include "nd.h"
@@ -394,6 +395,7 @@ static int pmem_attach_disk(struct device *dev,
disk->fops  = _fops;
disk->queue = q;
disk->flags = GENHD_FL_EXT_DEVT;
+   disk->queue->backing_dev_info->capabilities |= BDI_CAP_SYNCHRONOUS_IO;
nvdimm_namespace_disk_name(ndns, disk->disk_name);
set_capacity(disk, (pmem->size - pmem->pfn_pad - pmem->data_offset)
/ 512);
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 854e1bdd0b2a..cd41617c6594 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -123,6 +123,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, 
unsigned int max_ratio);
  * BDI_CAP_STRICTLIMIT:Keep number of dirty pages below bdi threshold.
  *
  * BDI_CAP_CGROUP_WRITEBACK: Supports cgroup-aware writeback.
+ * BDI_CAP_SYNCHRONOUS_IO: Device is so fast that asynchronous IO would be
+ *inefficient.
  */
 #define BDI_CAP_NO_ACCT_DIRTY  0x0001
 #define BDI_CAP_NO_WRITEBACK   0x0002
@@ -130,6 +132,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, 
unsigned int max_ratio);
 #define BDI_CAP_STABLE_WRITES  0x0008
 #define BDI_CAP_STRICTLIMIT0x0010
 #define BDI_CAP_CGROUP_WRITEBACK 0x0020
+#define BDI_CAP_SYNCHRONOUS_IO 0x0040
 
 #define BDI_CAP_NO_ACCT_AND_WRITEBACK \
(BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB)
@@ -177,6 +180,11 @@ long wait_iff_congested(struct pglist_data *pgdat, int 
sync, long timeout);
 int pdflush_proc_obsolete(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
 
+static inline bool bdi_cap_synchronous_io(struct backing_dev_info *bdi)
+{
+   return bdi->capabilities & BDI_CAP_SYNCHRONOUS_IO;
+}
+
 static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi)
 {
return bdi->capabilities & BDI_CAP_STABLE_WRITES;
-- 
2.7.4



[PATCH v2 3/4] mm:swap: introduce SWP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
If rw-page based fast storage is used for swap devices, we need to
detect it to enhance swap IO operations.
This patch is preparation for optimizing of swap-in operation with
next patch.

Cc: Hugh Dickins 
Signed-off-by: Minchan Kim 
---
 include/linux/swap.h | 3 ++-
 mm/swapfile.c| 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 8a807292037f..fbb33919d1c6 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -170,8 +170,9 @@ enum {
SWP_AREA_DISCARD = (1 << 8),/* single-time swap area discards */
SWP_PAGE_DISCARD = (1 << 9),/* freed swap page-cluster discards */
SWP_STABLE_WRITES = (1 << 10),  /* no overwrite PG_writeback pages */
+   SWP_SYNCHRONOUS_IO = (1 << 11), /* synchronous IO is efficient */
/* add others here before... */
-   SWP_SCANNING= (1 << 11),/* refcount in scan_swap_map */
+   SWP_SCANNING= (1 << 12),/* refcount in scan_swap_map */
 };
 
 #define SWAP_CLUSTER_MAX 32UL
diff --git a/mm/swapfile.c b/mm/swapfile.c
index bf91dc9e7a79..1305591cde4d 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -3168,6 +3168,9 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, 
int, swap_flags)
if (bdi_cap_stable_pages_required(inode_to_bdi(inode)))
p->flags |= SWP_STABLE_WRITES;
 
+   if (bdi_cap_synchronous_io(inode_to_bdi(inode)))
+   p->flags |= SWP_SYNCHRONOUS_IO;
+
if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) {
int cpu;
unsigned long ci, nr_cluster;
-- 
2.7.4



[PATCH v2 0/4] skip swapcache for super fast device

2017-09-19 Thread Minchan Kim
With fast swap storage, platform want to use swap more aggressively
and swap-in is crucial to application latency.

The rw_page based synchronous devices like zram, pmem and btt are such
fast storage. When I profile swapin performance with zram lz4 decompress
test, S/W overhead is more than 70%. Maybe, it would be bigger in nvdimm.

This patch aims for reducing swap-in latency via skipping swapcache
if swap device is synchronous device like rw_page based device.

It enhances 45% my swapin test(5G sequential swapin, no readahead,
from 2.41sec to 1.64sec).

Andrew, [1] is zram specific patch so could be applied separately
but this patch is based on that so I include it in this series.

* From v1
  * style fix
  * a bug fix
  * drop page-cluster based readahead off
* This regression could be solved by other patch from Huang.
  http://lkml.kernel.org/r/87tw04in60@yhuang-dev.intel.com
  
Minchan Kim (4):
  [1] zram: set BDI_CAP_STABLE_WRITES once
  [2] bdi: introduce BDI_CAP_SYNCHRONOUS_IO
  [3] mm:swap: introduce SWP_SYNCHRONOUS_IO
  [4] mm:swap: skip swapcache for swapin of synchronous device

 drivers/block/brd.c   |  2 ++
 drivers/block/zram/zram_drv.c | 16 +
 drivers/nvdimm/btt.c  |  3 +++
 drivers/nvdimm/pmem.c |  2 ++
 include/linux/backing-dev.h   |  8 +++
 include/linux/swap.h  | 14 +++-
 mm/memory.c   | 52 ++-
 mm/page_io.c  |  6 ++---
 mm/swapfile.c | 14 
 9 files changed, 83 insertions(+), 34 deletions(-)

-- 
2.7.4



[PATCH v2 3/4] mm:swap: introduce SWP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
If rw-page based fast storage is used for swap devices, we need to
detect it to enhance swap IO operations.
This patch is preparation for optimizing of swap-in operation with
next patch.

Cc: Hugh Dickins 
Signed-off-by: Minchan Kim 
---
 include/linux/swap.h | 3 ++-
 mm/swapfile.c| 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 8a807292037f..fbb33919d1c6 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -170,8 +170,9 @@ enum {
SWP_AREA_DISCARD = (1 << 8),/* single-time swap area discards */
SWP_PAGE_DISCARD = (1 << 9),/* freed swap page-cluster discards */
SWP_STABLE_WRITES = (1 << 10),  /* no overwrite PG_writeback pages */
+   SWP_SYNCHRONOUS_IO = (1 << 11), /* synchronous IO is efficient */
/* add others here before... */
-   SWP_SCANNING= (1 << 11),/* refcount in scan_swap_map */
+   SWP_SCANNING= (1 << 12),/* refcount in scan_swap_map */
 };
 
 #define SWAP_CLUSTER_MAX 32UL
diff --git a/mm/swapfile.c b/mm/swapfile.c
index bf91dc9e7a79..1305591cde4d 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -3168,6 +3168,9 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, 
int, swap_flags)
if (bdi_cap_stable_pages_required(inode_to_bdi(inode)))
p->flags |= SWP_STABLE_WRITES;
 
+   if (bdi_cap_synchronous_io(inode_to_bdi(inode)))
+   p->flags |= SWP_SYNCHRONOUS_IO;
+
if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) {
int cpu;
unsigned long ci, nr_cluster;
-- 
2.7.4



[PATCH v2 0/4] skip swapcache for super fast device

2017-09-19 Thread Minchan Kim
With fast swap storage, platform want to use swap more aggressively
and swap-in is crucial to application latency.

The rw_page based synchronous devices like zram, pmem and btt are such
fast storage. When I profile swapin performance with zram lz4 decompress
test, S/W overhead is more than 70%. Maybe, it would be bigger in nvdimm.

This patch aims for reducing swap-in latency via skipping swapcache
if swap device is synchronous device like rw_page based device.

It enhances 45% my swapin test(5G sequential swapin, no readahead,
from 2.41sec to 1.64sec).

Andrew, [1] is zram specific patch so could be applied separately
but this patch is based on that so I include it in this series.

* From v1
  * style fix
  * a bug fix
  * drop page-cluster based readahead off
* This regression could be solved by other patch from Huang.
  http://lkml.kernel.org/r/87tw04in60@yhuang-dev.intel.com
  
Minchan Kim (4):
  [1] zram: set BDI_CAP_STABLE_WRITES once
  [2] bdi: introduce BDI_CAP_SYNCHRONOUS_IO
  [3] mm:swap: introduce SWP_SYNCHRONOUS_IO
  [4] mm:swap: skip swapcache for swapin of synchronous device

 drivers/block/brd.c   |  2 ++
 drivers/block/zram/zram_drv.c | 16 +
 drivers/nvdimm/btt.c  |  3 +++
 drivers/nvdimm/pmem.c |  2 ++
 include/linux/backing-dev.h   |  8 +++
 include/linux/swap.h  | 14 +++-
 mm/memory.c   | 52 ++-
 mm/page_io.c  |  6 ++---
 mm/swapfile.c | 14 
 9 files changed, 83 insertions(+), 34 deletions(-)

-- 
2.7.4



Re: [PATCH v2 2/4] bdi: introduce BDI_CAP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
On Tue, Sep 19, 2017 at 04:25:03PM +0200, Christoph Hellwig wrote:
> I'm only seeing patch 2 of 4 - please resend the whole series so
> that it can properly be reviewed.

Yub, I will resend.
Thanks for the review in advance.



Re: [PATCH v2 2/4] bdi: introduce BDI_CAP_SYNCHRONOUS_IO

2017-09-19 Thread Minchan Kim
On Tue, Sep 19, 2017 at 04:25:03PM +0200, Christoph Hellwig wrote:
> I'm only seeing patch 2 of 4 - please resend the whole series so
> that it can properly be reviewed.

Yub, I will resend.
Thanks for the review in advance.



Re: Error when building the kernel on top of 4.14-rc1 for target firmware_install?

2017-09-19 Thread Greg Kroah-Hartman
On Wed, Sep 20, 2017 at 11:20:19AM +0800, Yu Chen wrote:
> Hi,
> kernel compile failed after running # make rpm
> 
> + 
> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
> + make 
> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
> firmware_install
> make[2]: warning: jobserver unavailable: using -j1.  Add '+' to parent
> make rule.
> make[2]: *** No rule to make target 'firmware_install'.  Stop.
> 
> I have to hack the script to compile through:
> diff --git a/scripts/package/mkspec b/scripts/package/mkspec
> index bb43f15..cb9c1b3 100755
> --- a/scripts/package/mkspec
> +++ b/scripts/package/mkspec
> @@ -92,7 +92,7 @@ echo 'mkdir -p 
> $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
> 
>  echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags}
> KBUILD_SRC= mod-fw= modules_install'
>  echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
> -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
> +echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH'
>  echo "%ifarch ia64"
> 
> Not sure if this is a regression but several version ago it works well.

See the maling list for fixes for this already :)

thanks,

greg k-h


Re: Error when building the kernel on top of 4.14-rc1 for target firmware_install?

2017-09-19 Thread Greg Kroah-Hartman
On Wed, Sep 20, 2017 at 11:20:19AM +0800, Yu Chen wrote:
> Hi,
> kernel compile failed after running # make rpm
> 
> + 
> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
> + make 
> INSTALL_FW_PATH=/root/rpmbuild/BUILDROOT/kernel-4.14.0_rc1+-22.x86_64/lib/firmware/4.14.0-rc1+
> firmware_install
> make[2]: warning: jobserver unavailable: using -j1.  Add '+' to parent
> make rule.
> make[2]: *** No rule to make target 'firmware_install'.  Stop.
> 
> I have to hack the script to compile through:
> diff --git a/scripts/package/mkspec b/scripts/package/mkspec
> index bb43f15..cb9c1b3 100755
> --- a/scripts/package/mkspec
> +++ b/scripts/package/mkspec
> @@ -92,7 +92,7 @@ echo 'mkdir -p 
> $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
> 
>  echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags}
> KBUILD_SRC= mod-fw= modules_install'
>  echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
> -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
> +echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH'
>  echo "%ifarch ia64"
> 
> Not sure if this is a regression but several version ago it works well.

See the maling list for fixes for this already :)

thanks,

greg k-h


Re: linux-next: error while fetching the microblaze tree

2017-09-19 Thread Michal Simek
Hi Stephen,

On 20.9.2017 01:26, Stephen Rothwell wrote:
> Hi Michal,
> 
> On Thu, 7 Jan 2016 09:38:56 +1100 Stephen Rothwell  
> wrote:
>>
>> Fetching the microblaze tree
>> (git://git.monstr.eu/linux-2.6-microblaze.git#next) produces this error.
>>
>> fatal: read error: Connection reset by peer
>>
>> I will use the previously fetched version for today.
> 
> I have been unable to fetch the microblaze tree again for the past few
> days.  This time it is is getting:
> 
> git.monstr.eu[0: 195.88.143.27]: errno=Connection refused
> 

Thanks for letting me know. I have contacted admin to look at it.
Will let you know when it is recover.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs




signature.asc
Description: OpenPGP digital signature


Re: linux-next: error while fetching the microblaze tree

2017-09-19 Thread Michal Simek
Hi Stephen,

On 20.9.2017 01:26, Stephen Rothwell wrote:
> Hi Michal,
> 
> On Thu, 7 Jan 2016 09:38:56 +1100 Stephen Rothwell  
> wrote:
>>
>> Fetching the microblaze tree
>> (git://git.monstr.eu/linux-2.6-microblaze.git#next) produces this error.
>>
>> fatal: read error: Connection reset by peer
>>
>> I will use the previously fetched version for today.
> 
> I have been unable to fetch the microblaze tree again for the past few
> days.  This time it is is getting:
> 
> git.monstr.eu[0: 195.88.143.27]: errno=Connection refused
> 

Thanks for letting me know. I have contacted admin to look at it.
Will let you know when it is recover.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP SoCs




signature.asc
Description: OpenPGP digital signature


Re: [PATCH v6] security/keys: rewrite all of big_key crypto

2017-09-19 Thread Stephan Mueller
Am Sonntag, 17. September 2017, 13:52:17 CEST schrieb Jason A. Donenfeld:

Hi Jason,

>   * Use of ECB mode, allowing an attacker to trivially swap blocks or
> compare identical plaintext blocks.

The use of GCM with the implementtion here is just as challenging. The 
implementation uses a NULL IV. GCM is a very brittle cipher where the 
construction of the IV is of special importance. SP800-38D section 8.2.1 and 
8.2.2 outlines the generation methods of the IV. A collision of keys/IVs is 
fatal. I understand that keys are generated anew each time which makes that 
issue less critical here. However, as user space may see the ciphertext, GCM 
should simply not be used.

A fix could be as easy as to use CCM or one of the authenc() ciphers. Yet, for 
both I am not sure how a zero IV affects the cipher.

The cipher where you do not need to handle the IV at all would be the RFC3394/
SP800-38F keywrapping cipher which is meant for the encryption of key material 
which includes authentication as well. It is available as an skcipher under 
the name of kw(aes). If you want to use it, please be careful that you obtain 
the generated IV to be stored with the plaintext as documented in the comments 
in crypto/keywrap.c


Ciao
Stephan


Re: [PATCH v6] security/keys: rewrite all of big_key crypto

2017-09-19 Thread Stephan Mueller
Am Sonntag, 17. September 2017, 13:52:17 CEST schrieb Jason A. Donenfeld:

Hi Jason,

>   * Use of ECB mode, allowing an attacker to trivially swap blocks or
> compare identical plaintext blocks.

The use of GCM with the implementtion here is just as challenging. The 
implementation uses a NULL IV. GCM is a very brittle cipher where the 
construction of the IV is of special importance. SP800-38D section 8.2.1 and 
8.2.2 outlines the generation methods of the IV. A collision of keys/IVs is 
fatal. I understand that keys are generated anew each time which makes that 
issue less critical here. However, as user space may see the ciphertext, GCM 
should simply not be used.

A fix could be as easy as to use CCM or one of the authenc() ciphers. Yet, for 
both I am not sure how a zero IV affects the cipher.

The cipher where you do not need to handle the IV at all would be the RFC3394/
SP800-38F keywrapping cipher which is meant for the encryption of key material 
which includes authentication as well. It is available as an skcipher under 
the name of kw(aes). If you want to use it, please be careful that you obtain 
the generated IV to be stored with the plaintext as documented in the comments 
in crypto/keywrap.c


Ciao
Stephan


[PATCH v2 1/4] watchdog: aspeed: Retain watchdog enabled state

2017-09-19 Thread Andrew Jeffery
An unintended post-condition of probe() is that the watchdog is
disabled. This behaviour was introduced by an unnecessary write to the
control register to configure the hardware based on the devicetree. The
write is unnecessary because the cached control value that is
manipulated by the code parsing the devicetree is eventually written by
aspeed_wdt_enable(), which is when we care how the control register
should be configured.

Remove the write to restore expected behaviour.

Fixes: b7f0b8ad25f3 ("drivers/watchdog: ASPEED reference dev tree properties 
for config")
Signed-off-by: Andrew Jeffery 
---
 drivers/watchdog/aspeed_wdt.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 79cc766cd30f..6c6dd3f4c48d 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -243,9 +243,13 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (of_property_read_bool(np, "aspeed,external-signal"))
wdt->ctrl |= WDT_CTRL_WDT_EXT;
 
-   writel(wdt->ctrl, wdt->base + WDT_CTRL);
-
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
+   /*
+* The watchdog is running, but invoke aspeed_wdt_start() to
+* write wdt->ctrl to WDT_CTRL to ensure the watchdog's
+* configuration conforms to the driver's expectations.
+* Primarily, ensure we're using the 1MHz clock source.
+*/
aspeed_wdt_start(>wdd);
set_bit(WDOG_HW_RUNNING, >wdd.status);
}
-- 
2.11.0



[PATCH v2 3/4] watchdog: aspeed: Remove specific reference to AST2400 in Kconfig

2017-09-19 Thread Andrew Jeffery
The driver also supports the watchdog in the AST25xx series, and
may work on earlier SoCs as well.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Guenter Roeck 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b562d2e03eb9..a1b92ebe74b6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -741,7 +741,7 @@ config RENESAS_RZAWDT
  Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
 
 config ASPEED_WATCHDOG
-   tristate "Aspeed 2400 watchdog support"
+   tristate "Aspeed BMC watchdog support"
depends on ARCH_ASPEED || COMPILE_TEST
select WATCHDOG_CORE
help
-- 
2.11.0



[PATCH v2 1/4] watchdog: aspeed: Retain watchdog enabled state

2017-09-19 Thread Andrew Jeffery
An unintended post-condition of probe() is that the watchdog is
disabled. This behaviour was introduced by an unnecessary write to the
control register to configure the hardware based on the devicetree. The
write is unnecessary because the cached control value that is
manipulated by the code parsing the devicetree is eventually written by
aspeed_wdt_enable(), which is when we care how the control register
should be configured.

Remove the write to restore expected behaviour.

Fixes: b7f0b8ad25f3 ("drivers/watchdog: ASPEED reference dev tree properties 
for config")
Signed-off-by: Andrew Jeffery 
---
 drivers/watchdog/aspeed_wdt.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 79cc766cd30f..6c6dd3f4c48d 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -243,9 +243,13 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (of_property_read_bool(np, "aspeed,external-signal"))
wdt->ctrl |= WDT_CTRL_WDT_EXT;
 
-   writel(wdt->ctrl, wdt->base + WDT_CTRL);
-
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
+   /*
+* The watchdog is running, but invoke aspeed_wdt_start() to
+* write wdt->ctrl to WDT_CTRL to ensure the watchdog's
+* configuration conforms to the driver's expectations.
+* Primarily, ensure we're using the 1MHz clock source.
+*/
aspeed_wdt_start(>wdd);
set_bit(WDOG_HW_RUNNING, >wdd.status);
}
-- 
2.11.0



[PATCH v2 3/4] watchdog: aspeed: Remove specific reference to AST2400 in Kconfig

2017-09-19 Thread Andrew Jeffery
The driver also supports the watchdog in the AST25xx series, and
may work on earlier SoCs as well.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Guenter Roeck 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b562d2e03eb9..a1b92ebe74b6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -741,7 +741,7 @@ config RENESAS_RZAWDT
  Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
 
 config ASPEED_WATCHDOG
-   tristate "Aspeed 2400 watchdog support"
+   tristate "Aspeed BMC watchdog support"
depends on ARCH_ASPEED || COMPILE_TEST
select WATCHDOG_CORE
help
-- 
2.11.0



[PATCH v2 2/4] watchdog: aspeed: Fix 'Apseed' typo in Kconfig

2017-09-19 Thread Andrew Jeffery
Apseed sounds like a good name for a web/mobile start-up incubator, but
isn't a reflection of Aspeed themselves.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Guenter Roeck 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index c722cbfdc7e6..b562d2e03eb9 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -746,7 +746,7 @@ config ASPEED_WATCHDOG
select WATCHDOG_CORE
help
  Say Y here to include support for the watchdog timer
- in Apseed BMC SoCs.
+ in Aspeed BMC SoCs.
 
  This driver is required to reboot the SoC.
 
-- 
2.11.0



[PATCH v2 2/4] watchdog: aspeed: Fix 'Apseed' typo in Kconfig

2017-09-19 Thread Andrew Jeffery
Apseed sounds like a good name for a web/mobile start-up incubator, but
isn't a reflection of Aspeed themselves.

Signed-off-by: Andrew Jeffery 
Reviewed-by: Guenter Roeck 
---
 drivers/watchdog/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index c722cbfdc7e6..b562d2e03eb9 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -746,7 +746,7 @@ config ASPEED_WATCHDOG
select WATCHDOG_CORE
help
  Say Y here to include support for the watchdog timer
- in Apseed BMC SoCs.
+ in Aspeed BMC SoCs.
 
  This driver is required to reboot the SoC.
 
-- 
2.11.0



[PATCH v2 0/4] watchdog: aspeed: Retain enabled state and move to arch_initcall

2017-09-19 Thread Andrew Jeffery
Hello,

This series fixes some issues with the Aspeed watchdog, as outlined in the
v1[1] cover letter.

I've added a bit of an explanation as to why we call aspeed_wdt_start() in
probe() if the watchdog is already enabled, but the essence of it is to ensure
the watchdog is configured to the expectations of the kernel driver (rather
than however the bootloader configured it).

Please review!

Andrew

Since v1:

* Rework patch 1/4 to simply remove the writel() call to restore the original
  behaviour.
* Rework patch 4/4 to remove the Kconfig changes to retain the ability to build
  the watchdog as a module, and add the exit handler.

[1] https://lkml.org/lkml/2017/9/18/14

Andrew Jeffery (4):
  watchdog: aspeed: Retain watchdog enabled state
  watchdog: aspeed: Fix 'Apseed' typo in Kconfig
  watchdog: aspeed: Remove specific reference to AST2400 in Kconfig
  watchdog: aspeed: Move init to arch_initcall

 drivers/watchdog/Kconfig  |  4 ++--
 drivers/watchdog/aspeed_wdt.c | 21 ++---
 2 files changed, 20 insertions(+), 5 deletions(-)

-- 
2.11.0



[PATCH v2 0/4] watchdog: aspeed: Retain enabled state and move to arch_initcall

2017-09-19 Thread Andrew Jeffery
Hello,

This series fixes some issues with the Aspeed watchdog, as outlined in the
v1[1] cover letter.

I've added a bit of an explanation as to why we call aspeed_wdt_start() in
probe() if the watchdog is already enabled, but the essence of it is to ensure
the watchdog is configured to the expectations of the kernel driver (rather
than however the bootloader configured it).

Please review!

Andrew

Since v1:

* Rework patch 1/4 to simply remove the writel() call to restore the original
  behaviour.
* Rework patch 4/4 to remove the Kconfig changes to retain the ability to build
  the watchdog as a module, and add the exit handler.

[1] https://lkml.org/lkml/2017/9/18/14

Andrew Jeffery (4):
  watchdog: aspeed: Retain watchdog enabled state
  watchdog: aspeed: Fix 'Apseed' typo in Kconfig
  watchdog: aspeed: Remove specific reference to AST2400 in Kconfig
  watchdog: aspeed: Move init to arch_initcall

 drivers/watchdog/Kconfig  |  4 ++--
 drivers/watchdog/aspeed_wdt.c | 21 ++---
 2 files changed, 20 insertions(+), 5 deletions(-)

-- 
2.11.0



[PATCH v2 4/4] watchdog: aspeed: Move init to arch_initcall

2017-09-19 Thread Andrew Jeffery
Probing at device_initcall time lead to perverse cases where the
watchdog was probed after, say, I2C devices, which then leaves a
potentially running watchdog at the mercy of I2C device behaviour and
bus conditions.

Load the watchdog driver early to ensure that the kernel is patting it
well before initialising peripherals.

Signed-off-by: Andrew Jeffery 
---
 drivers/watchdog/aspeed_wdt.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 6c6dd3f4c48d..ca5b91e2eb92 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -316,7 +316,18 @@ static struct platform_driver aspeed_watchdog_driver = {
.of_match_table = of_match_ptr(aspeed_wdt_of_table),
},
 };
-module_platform_driver(aspeed_watchdog_driver);
+
+static int __init aspeed_wdt_init(void)
+{
+   return platform_driver_register(_watchdog_driver);
+}
+arch_initcall(aspeed_wdt_init);
+
+static void __exit aspeed_wdt_exit(void)
+{
+   platform_driver_unregister(_watchdog_driver);
+}
+module_exit(aspeed_wdt_exit);
 
 MODULE_DESCRIPTION("Aspeed Watchdog Driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0



[PATCH v2 4/4] watchdog: aspeed: Move init to arch_initcall

2017-09-19 Thread Andrew Jeffery
Probing at device_initcall time lead to perverse cases where the
watchdog was probed after, say, I2C devices, which then leaves a
potentially running watchdog at the mercy of I2C device behaviour and
bus conditions.

Load the watchdog driver early to ensure that the kernel is patting it
well before initialising peripherals.

Signed-off-by: Andrew Jeffery 
---
 drivers/watchdog/aspeed_wdt.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 6c6dd3f4c48d..ca5b91e2eb92 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -316,7 +316,18 @@ static struct platform_driver aspeed_watchdog_driver = {
.of_match_table = of_match_ptr(aspeed_wdt_of_table),
},
 };
-module_platform_driver(aspeed_watchdog_driver);
+
+static int __init aspeed_wdt_init(void)
+{
+   return platform_driver_register(_watchdog_driver);
+}
+arch_initcall(aspeed_wdt_init);
+
+static void __exit aspeed_wdt_exit(void)
+{
+   platform_driver_unregister(_watchdog_driver);
+}
+module_exit(aspeed_wdt_exit);
 
 MODULE_DESCRIPTION("Aspeed Watchdog Driver");
 MODULE_LICENSE("GPL");
-- 
2.11.0



Re: [PATCH v3] pci: dwc: dra7xx: Add shutdown handler to cleanly turn off clocks

2017-09-19 Thread Keerthy


On Wednesday 20 September 2017 01:00 AM, Bjorn Helgaas wrote:
> On Fri, Sep 08, 2017 at 10:44:54AM +0530, Keerthy wrote:
>> Add shutdown handler to cleanly turn off clocks. This will help
>> in cases of kexec where in a new kernel can boot abruptly.
>>
>> Signed-off-by: Keerthy 
>> Acked-by: Kishon Vijay Abraham I 
>> ---
>>
>> Changes in v3:
>>
>>   * Pushed the function outside #ifdef CONFIG_PM_SLEEP.
>>   * Added more details to commit log.
>>
>> Changes in v2:
>>
>>   * used a local dev pointer instead of dereferencing dev at multiple places.
>>   * dra7xx_pcie_stop_link before disabling clks in the shutdown path.
> 
> You lost both these changes in v3.  I assume you'll post a v4.

Thanks Bjorn for catching this!

Sent v4 with the corrections.

https://patchwork.ozlabs.org/patch/816010/

Regards,
Keerthy

> 
>>  drivers/pci/dwc/pci-dra7xx.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>> index 0f9adf2..ec8f842 100644
>> --- a/drivers/pci/dwc/pci-dra7xx.c
>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>> @@ -794,6 +794,19 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
>>  }
>>  #endif
>>  
>> +void dra7xx_pcie_shutdown(struct platform_device *pdev)
>> +{
>> +struct dra7xx_pcie *dra7xx = dev_get_drvdata(>dev);
>> +int ret;
>> +
>> +ret = pm_runtime_put_sync(>dev);
>> +if (ret < 0)
>> +dev_dbg(>dev, "pm_runtime_put_sync failed\n");
>> +
>> +pm_runtime_disable(>dev);
>> +dra7xx_pcie_disable_phy(dra7xx);
>> +}
>> +
>>  static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
>>  SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
>>  SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
>> @@ -807,5 +820,6 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
>>  .suppress_bind_attrs = true,
>>  .pm = _pcie_pm_ops,
>>  },
>> +.shutdown = dra7xx_pcie_shutdown,
>>  };
>>  builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
>> -- 
>> 1.9.1
>>


Re: [PATCH v3] pci: dwc: dra7xx: Add shutdown handler to cleanly turn off clocks

2017-09-19 Thread Keerthy


On Wednesday 20 September 2017 01:00 AM, Bjorn Helgaas wrote:
> On Fri, Sep 08, 2017 at 10:44:54AM +0530, Keerthy wrote:
>> Add shutdown handler to cleanly turn off clocks. This will help
>> in cases of kexec where in a new kernel can boot abruptly.
>>
>> Signed-off-by: Keerthy 
>> Acked-by: Kishon Vijay Abraham I 
>> ---
>>
>> Changes in v3:
>>
>>   * Pushed the function outside #ifdef CONFIG_PM_SLEEP.
>>   * Added more details to commit log.
>>
>> Changes in v2:
>>
>>   * used a local dev pointer instead of dereferencing dev at multiple places.
>>   * dra7xx_pcie_stop_link before disabling clks in the shutdown path.
> 
> You lost both these changes in v3.  I assume you'll post a v4.

Thanks Bjorn for catching this!

Sent v4 with the corrections.

https://patchwork.ozlabs.org/patch/816010/

Regards,
Keerthy

> 
>>  drivers/pci/dwc/pci-dra7xx.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>> index 0f9adf2..ec8f842 100644
>> --- a/drivers/pci/dwc/pci-dra7xx.c
>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>> @@ -794,6 +794,19 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
>>  }
>>  #endif
>>  
>> +void dra7xx_pcie_shutdown(struct platform_device *pdev)
>> +{
>> +struct dra7xx_pcie *dra7xx = dev_get_drvdata(>dev);
>> +int ret;
>> +
>> +ret = pm_runtime_put_sync(>dev);
>> +if (ret < 0)
>> +dev_dbg(>dev, "pm_runtime_put_sync failed\n");
>> +
>> +pm_runtime_disable(>dev);
>> +dra7xx_pcie_disable_phy(dra7xx);
>> +}
>> +
>>  static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
>>  SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
>>  SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
>> @@ -807,5 +820,6 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
>>  .suppress_bind_attrs = true,
>>  .pm = _pcie_pm_ops,
>>  },
>> +.shutdown = dra7xx_pcie_shutdown,
>>  };
>>  builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
>> -- 
>> 1.9.1
>>


[PATCH v4 2/2] ACPI / CPPC: Make cppc acpi driver aware of pcc subspace ids

2017-09-19 Thread George Cherian
Based on ACPI 6.2 Section 8.4.7.1.9 If the PCC register space is used,
all PCC registers, for all processors in the same performance
domain (as defined by _PSD), must be defined to be in the same subspace.
Based on Section 14.1 of ACPI specification, it is possible to have a
maximum of 256 PCC subspace ids. Add support of multiple PCC subspace id
instead of using a single global pcc_data structure.

While at that fix the time_delta check in send_pcc_cmd() so that last_mpar_reset
and mpar_count is initialized properly.

Signed-off-by: George Cherian 
---
 drivers/acpi/cppc_acpi.c | 243 +--
 1 file changed, 153 insertions(+), 90 deletions(-)

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index e5b47f0..3ae79ef 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -75,13 +75,16 @@ struct cppc_pcc_data {
 
/* Wait queue for CPUs whose requests were batched */
wait_queue_head_t pcc_write_wait_q;
+   ktime_t last_cmd_cmpl_time;
+   ktime_t last_mpar_reset;
+   int mpar_count;
+   int refcount;
 };
 
-/* Structure to represent the single PCC channel */
-static struct cppc_pcc_data pcc_data = {
-   .pcc_subspace_idx = -1,
-   .platform_owns_pcc = true,
-};
+/* Array  to represent the PCC channel per subspace id */
+static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
+/* The cpu_pcc_subspace_idx containsper CPU subspace id */
+static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
 
 /*
  * The cpc_desc structure contains the ACPI register details
@@ -93,7 +96,8 @@ static struct cppc_pcc_data pcc_data = {
 static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
 
 /* pcc mapped address + header size + offset within PCC subspace */
-#define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs))
+#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \
+   0x8 + (offs))
 
 /* Check if a CPC register is in PCC */
 #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER &&\
@@ -188,13 +192,16 @@ static struct kobj_type cppc_ktype = {
.default_attrs = cppc_attrs,
 };
 
-static int check_pcc_chan(bool chk_err_bit)
+static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
 {
int ret = -EIO, status = 0;
-   struct acpi_pcct_shared_memory __iomem *generic_comm_base = 
pcc_data.pcc_comm_addr;
-   ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline);
+   struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
+   struct acpi_pcct_shared_memory __iomem *generic_comm_base =
+   pcc_ss_data->pcc_comm_addr;
+   ktime_t next_deadline = ktime_add(ktime_get(),
+ pcc_ss_data->deadline);
 
-   if (!pcc_data.platform_owns_pcc)
+   if (!pcc_ss_data->platform_owns_pcc)
return 0;
 
/* Retry in case the remote processor was too slow to catch up. */
@@ -219,7 +226,7 @@ static int check_pcc_chan(bool chk_err_bit)
}
 
if (likely(!ret))
-   pcc_data.platform_owns_pcc = false;
+   pcc_ss_data->platform_owns_pcc = false;
else
pr_err("PCC check channel failed. Status=%x\n", status);
 
@@ -230,13 +237,12 @@ static int check_pcc_chan(bool chk_err_bit)
  * This function transfers the ownership of the PCC to the platform
  * So it must be called while holding write_lock(pcc_lock)
  */
-static int send_pcc_cmd(u16 cmd)
+static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
 {
int ret = -EIO, i;
+   struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
struct acpi_pcct_shared_memory *generic_comm_base =
-   (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr;
-   static ktime_t last_cmd_cmpl_time, last_mpar_reset;
-   static int mpar_count;
+   (struct acpi_pcct_shared_memory *)pcc_ss_data->pcc_comm_addr;
unsigned int time_delta;
 
/*
@@ -249,24 +255,25 @@ static int send_pcc_cmd(u16 cmd)
 * before write completion, so first send a WRITE command to
 * platform
 */
-   if (pcc_data.pending_pcc_write_cmd)
-   send_pcc_cmd(CMD_WRITE);
+   if (pcc_ss_data->pending_pcc_write_cmd)
+   send_pcc_cmd(pcc_ss_id, CMD_WRITE);
 
-   ret = check_pcc_chan(false);
+   ret = check_pcc_chan(pcc_ss_id, false);
if (ret)
goto end;
} else /* CMD_WRITE */
-   pcc_data.pending_pcc_write_cmd = FALSE;
+   pcc_ss_data->pending_pcc_write_cmd = FALSE;
 
/*
 * Handle the Minimum Request Turnaround Time(MRTT)
 * "The minimum amount of time that OSPM must wait after the completion
 * of a command before issuing the next command, in microseconds"

[PATCH v4 2/2] ACPI / CPPC: Make cppc acpi driver aware of pcc subspace ids

2017-09-19 Thread George Cherian
Based on ACPI 6.2 Section 8.4.7.1.9 If the PCC register space is used,
all PCC registers, for all processors in the same performance
domain (as defined by _PSD), must be defined to be in the same subspace.
Based on Section 14.1 of ACPI specification, it is possible to have a
maximum of 256 PCC subspace ids. Add support of multiple PCC subspace id
instead of using a single global pcc_data structure.

While at that fix the time_delta check in send_pcc_cmd() so that last_mpar_reset
and mpar_count is initialized properly.

Signed-off-by: George Cherian 
---
 drivers/acpi/cppc_acpi.c | 243 +--
 1 file changed, 153 insertions(+), 90 deletions(-)

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index e5b47f0..3ae79ef 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -75,13 +75,16 @@ struct cppc_pcc_data {
 
/* Wait queue for CPUs whose requests were batched */
wait_queue_head_t pcc_write_wait_q;
+   ktime_t last_cmd_cmpl_time;
+   ktime_t last_mpar_reset;
+   int mpar_count;
+   int refcount;
 };
 
-/* Structure to represent the single PCC channel */
-static struct cppc_pcc_data pcc_data = {
-   .pcc_subspace_idx = -1,
-   .platform_owns_pcc = true,
-};
+/* Array  to represent the PCC channel per subspace id */
+static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
+/* The cpu_pcc_subspace_idx containsper CPU subspace id */
+static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
 
 /*
  * The cpc_desc structure contains the ACPI register details
@@ -93,7 +96,8 @@ static struct cppc_pcc_data pcc_data = {
 static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
 
 /* pcc mapped address + header size + offset within PCC subspace */
-#define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs))
+#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \
+   0x8 + (offs))
 
 /* Check if a CPC register is in PCC */
 #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER &&\
@@ -188,13 +192,16 @@ static struct kobj_type cppc_ktype = {
.default_attrs = cppc_attrs,
 };
 
-static int check_pcc_chan(bool chk_err_bit)
+static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit)
 {
int ret = -EIO, status = 0;
-   struct acpi_pcct_shared_memory __iomem *generic_comm_base = 
pcc_data.pcc_comm_addr;
-   ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline);
+   struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
+   struct acpi_pcct_shared_memory __iomem *generic_comm_base =
+   pcc_ss_data->pcc_comm_addr;
+   ktime_t next_deadline = ktime_add(ktime_get(),
+ pcc_ss_data->deadline);
 
-   if (!pcc_data.platform_owns_pcc)
+   if (!pcc_ss_data->platform_owns_pcc)
return 0;
 
/* Retry in case the remote processor was too slow to catch up. */
@@ -219,7 +226,7 @@ static int check_pcc_chan(bool chk_err_bit)
}
 
if (likely(!ret))
-   pcc_data.platform_owns_pcc = false;
+   pcc_ss_data->platform_owns_pcc = false;
else
pr_err("PCC check channel failed. Status=%x\n", status);
 
@@ -230,13 +237,12 @@ static int check_pcc_chan(bool chk_err_bit)
  * This function transfers the ownership of the PCC to the platform
  * So it must be called while holding write_lock(pcc_lock)
  */
-static int send_pcc_cmd(u16 cmd)
+static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
 {
int ret = -EIO, i;
+   struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id];
struct acpi_pcct_shared_memory *generic_comm_base =
-   (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr;
-   static ktime_t last_cmd_cmpl_time, last_mpar_reset;
-   static int mpar_count;
+   (struct acpi_pcct_shared_memory *)pcc_ss_data->pcc_comm_addr;
unsigned int time_delta;
 
/*
@@ -249,24 +255,25 @@ static int send_pcc_cmd(u16 cmd)
 * before write completion, so first send a WRITE command to
 * platform
 */
-   if (pcc_data.pending_pcc_write_cmd)
-   send_pcc_cmd(CMD_WRITE);
+   if (pcc_ss_data->pending_pcc_write_cmd)
+   send_pcc_cmd(pcc_ss_id, CMD_WRITE);
 
-   ret = check_pcc_chan(false);
+   ret = check_pcc_chan(pcc_ss_id, false);
if (ret)
goto end;
} else /* CMD_WRITE */
-   pcc_data.pending_pcc_write_cmd = FALSE;
+   pcc_ss_data->pending_pcc_write_cmd = FALSE;
 
/*
 * Handle the Minimum Request Turnaround Time(MRTT)
 * "The minimum amount of time that OSPM must wait after the completion
 * of a command before issuing the next command, in microseconds"
 */
-   if 

[PATCH v4 1/2] mailbox: PCC: Move the MAX_PCC_SUBSPACES definition to header file

2017-09-19 Thread George Cherian
Move the MAX_PCC_SUBSPACES definition to acpi/pcc.h file. In preparation to add
subspace id support for cppc_acpi driver.

Signed-off-by: George Cherian 
---
 drivers/mailbox/pcc.c | 1 -
 include/acpi/pcc.h| 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 9b7005e..e5a6967 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -69,7 +69,6 @@
 
 #include "mailbox.h"
 
-#define MAX_PCC_SUBSPACES  256
 #define MBOX_IRQ_NAME  "pcc-mbox"
 
 static struct mbox_chan *pcc_mbox_channels;
diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
index 8caa79c..cd6ef45 100644
--- a/include/acpi/pcc.h
+++ b/include/acpi/pcc.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 
+#define MAX_PCC_SUBSPACES  256
 #ifdef CONFIG_PCC
 extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
  int subspace_id);
-- 
2.1.4



[PATCH v4] pci: dwc: dra7xx: Add shutdown handler to cleanly turn off clocks

2017-09-19 Thread Keerthy
Add shutdown handler to cleanly turn off clocks. This will help
in cases of kexec where in a new kernel can boot abruptly.

Signed-off-by: Keerthy 
Acked-by: Kishon Vijay Abraham I 
---

Changes in v4:

  * Added the missing changes from v2!

Changes in v3:

  * Pushed the function outside #ifdef CONFIG_PM_SLEEP.
  * Added more details to commit log.

Changes in v2:

  * used a local dev pointer instead of dereferencing dev at multiple places.
  * dra7xx_pcie_stop_link before disabling clks in the shutdown path.

 drivers/pci/dwc/pci-dra7xx.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 34427a6..d084800 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -794,6 +794,22 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
 }
 #endif
 
+void dra7xx_pcie_shutdown(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
+   int ret;
+
+   dra7xx_pcie_stop_link(dra7xx->pci);
+
+   ret = pm_runtime_put_sync(dev);
+   if (ret < 0)
+   dev_dbg(dev, "pm_runtime_put_sync failed\n");
+
+   pm_runtime_disable(dev);
+   dra7xx_pcie_disable_phy(dra7xx);
+}
+
 static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
@@ -807,5 +823,6 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
.suppress_bind_attrs = true,
.pm = _pcie_pm_ops,
},
+   .shutdown = dra7xx_pcie_shutdown,
 };
 builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
-- 
1.9.1



[PATCH v4 1/2] mailbox: PCC: Move the MAX_PCC_SUBSPACES definition to header file

2017-09-19 Thread George Cherian
Move the MAX_PCC_SUBSPACES definition to acpi/pcc.h file. In preparation to add
subspace id support for cppc_acpi driver.

Signed-off-by: George Cherian 
---
 drivers/mailbox/pcc.c | 1 -
 include/acpi/pcc.h| 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 9b7005e..e5a6967 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -69,7 +69,6 @@
 
 #include "mailbox.h"
 
-#define MAX_PCC_SUBSPACES  256
 #define MBOX_IRQ_NAME  "pcc-mbox"
 
 static struct mbox_chan *pcc_mbox_channels;
diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
index 8caa79c..cd6ef45 100644
--- a/include/acpi/pcc.h
+++ b/include/acpi/pcc.h
@@ -13,6 +13,7 @@
 #include 
 #include 
 
+#define MAX_PCC_SUBSPACES  256
 #ifdef CONFIG_PCC
 extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
  int subspace_id);
-- 
2.1.4



[PATCH v4] pci: dwc: dra7xx: Add shutdown handler to cleanly turn off clocks

2017-09-19 Thread Keerthy
Add shutdown handler to cleanly turn off clocks. This will help
in cases of kexec where in a new kernel can boot abruptly.

Signed-off-by: Keerthy 
Acked-by: Kishon Vijay Abraham I 
---

Changes in v4:

  * Added the missing changes from v2!

Changes in v3:

  * Pushed the function outside #ifdef CONFIG_PM_SLEEP.
  * Added more details to commit log.

Changes in v2:

  * used a local dev pointer instead of dereferencing dev at multiple places.
  * dra7xx_pcie_stop_link before disabling clks in the shutdown path.

 drivers/pci/dwc/pci-dra7xx.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 34427a6..d084800 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -794,6 +794,22 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
 }
 #endif
 
+void dra7xx_pcie_shutdown(struct platform_device *pdev)
+{
+   struct device *dev = >dev;
+   struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
+   int ret;
+
+   dra7xx_pcie_stop_link(dra7xx->pci);
+
+   ret = pm_runtime_put_sync(dev);
+   if (ret < 0)
+   dev_dbg(dev, "pm_runtime_put_sync failed\n");
+
+   pm_runtime_disable(dev);
+   dra7xx_pcie_disable_phy(dra7xx);
+}
+
 static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
@@ -807,5 +823,6 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
.suppress_bind_attrs = true,
.pm = _pcie_pm_ops,
},
+   .shutdown = dra7xx_pcie_shutdown,
 };
 builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
-- 
1.9.1



[PATCH v4 0/2] Make cppc acpi driver aware of pcc subspace ids

2017-09-19 Thread George Cherian
The current cppc acpi driver works with only one pcc subspace id.
It maintains and registers only one pcc channel even if the acpi table has 
different pcc subspace ids. 

As per ACPI 6.2 spec  all PCC registers, for all processors in the same 
performance domain (as defined by _PSD), must be defined to be in the same
subspace. The series tries to address the same by making cppc acpi driver 
aware of multiple possible pcc subspace ids.

Patch 1 : In preparation to share the MAX_PCC_SUBSPACE definition with cppc acpi
  driver
Patch 2 : Make the cppc acpi driver aware of multiple pcc subspace ids.

Changes from v3:
  - Address Issue reported by kbuild-robot.

Changes from v2:
  - Addressed Prashanth's comments on
* Not to use local variables to update mpar_count, last_mpar_reset and 
  last_cmd_cmpl_time
* Add check for kzalloc failure in pcc_data_alloc()
* Initialize pcc_subspace_id to -1 in acpi_cppc_processor_probe()
* Check for pcc_subspace_id validity before registering pcc_channel

Changes from v1:
  - Add last_cmd_cmpl_time, last_mpar_reset, mpar_count to the cppc_pcc_data to
make it per subspace.
  - PCC per subspace dynamic allocation support added instead of static
allocation
  - Added a new function pcc_data_alloc, In instances where CPU's with SMT
support same PCC subspace would be used for all CPU's belonging to same 
physical core. This function adds the pcc_subspace refcounting and allocates
the cppc_pcc_data per unique subspace idx.
  - Added cleanup in acpi_cppc_processor_exit. Free the mbox channel and free
the cppc_pcc_data in case refcount is zero.

George Cherian (2):
  mailbox: PCC: Move the MAX_PCC_SUBSPACES definition to header file
  ACPI / CPPC: Make cppc acpi driver aware of pcc subspace ids

 drivers/acpi/cppc_acpi.c | 243 +--
 drivers/mailbox/pcc.c|   1 -
 include/acpi/pcc.h   |   1 +
 3 files changed, 154 insertions(+), 91 deletions(-)

-- 
2.1.4



[PATCH v4 0/2] Make cppc acpi driver aware of pcc subspace ids

2017-09-19 Thread George Cherian
The current cppc acpi driver works with only one pcc subspace id.
It maintains and registers only one pcc channel even if the acpi table has 
different pcc subspace ids. 

As per ACPI 6.2 spec  all PCC registers, for all processors in the same 
performance domain (as defined by _PSD), must be defined to be in the same
subspace. The series tries to address the same by making cppc acpi driver 
aware of multiple possible pcc subspace ids.

Patch 1 : In preparation to share the MAX_PCC_SUBSPACE definition with cppc acpi
  driver
Patch 2 : Make the cppc acpi driver aware of multiple pcc subspace ids.

Changes from v3:
  - Address Issue reported by kbuild-robot.

Changes from v2:
  - Addressed Prashanth's comments on
* Not to use local variables to update mpar_count, last_mpar_reset and 
  last_cmd_cmpl_time
* Add check for kzalloc failure in pcc_data_alloc()
* Initialize pcc_subspace_id to -1 in acpi_cppc_processor_probe()
* Check for pcc_subspace_id validity before registering pcc_channel

Changes from v1:
  - Add last_cmd_cmpl_time, last_mpar_reset, mpar_count to the cppc_pcc_data to
make it per subspace.
  - PCC per subspace dynamic allocation support added instead of static
allocation
  - Added a new function pcc_data_alloc, In instances where CPU's with SMT
support same PCC subspace would be used for all CPU's belonging to same 
physical core. This function adds the pcc_subspace refcounting and allocates
the cppc_pcc_data per unique subspace idx.
  - Added cleanup in acpi_cppc_processor_exit. Free the mbox channel and free
the cppc_pcc_data in case refcount is zero.

George Cherian (2):
  mailbox: PCC: Move the MAX_PCC_SUBSPACES definition to header file
  ACPI / CPPC: Make cppc acpi driver aware of pcc subspace ids

 drivers/acpi/cppc_acpi.c | 243 +--
 drivers/mailbox/pcc.c|   1 -
 include/acpi/pcc.h   |   1 +
 3 files changed, 154 insertions(+), 91 deletions(-)

-- 
2.1.4



[PATCH v5] [DVB][FRONTEND] Modified the code related to FE_SET_PROPERTY ioctl

2017-09-19 Thread Satendra Singh Thakur
-Since all the properties in the func dtv_property_process_set
 are 4 bytes, We have added 2 new arguments u32 cmd and u32 data;
 in place of older argument struct dtv_property *tvp.
-We have removed property validation in function
 dtv_property_process_set because most of the frontend drivers in
 linux source are not using the method ops.set_property.
-In place of dtv_property_dump, we have added own logic
 to dump cmd and data of the incoming property
-We have also re-named dtv_property_dump to dtv_get_property_dump.
-We have modified logs in this func to be suitable only for getting
 properties.
Signed-off-by: Satendra Singh Thakur 
---
 drivers/media/dvb-core/dvb_frontend.c | 135 ++
 1 file changed, 73 insertions(+), 62 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c 
b/drivers/media/dvb-core/dvb_frontend.c
index 2fcba16..013476e 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -1092,22 +1092,19 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] 
= {
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
 };
 
-static void dtv_property_dump(struct dvb_frontend *fe,
- bool is_set,
+static void dtv_get_property_dump(struct dvb_frontend *fe,
  struct dtv_property *tvp)
 {
int i;
 
if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
-   dev_warn(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x undefined\n",
-   __func__,
-   is_set ? "SET" : "GET",
+   dev_warn(fe->dvb->device, "%s: GET tvp.cmd = 0x%08x undefined\n"
+   , __func__,
tvp->cmd);
return;
}
 
-   dev_dbg(fe->dvb->device, "%s: %s tvp.cmd= 0x%08x (%s)\n", __func__,
-   is_set ? "SET" : "GET",
+   dev_dbg(fe->dvb->device, "%s: GET tvp.cmd= 0x%08x (%s)\n", __func__,
tvp->cmd,
dtv_cmds[tvp->cmd].name);
 
@@ -1526,7 +1523,7 @@ static int dtv_property_process_get(struct dvb_frontend 
*fe,
return r;
}
 
-   dtv_property_dump(fe, false, tvp);
+   dtv_get_property_dump(fe, tvp);
 
return 0;
 }
@@ -1749,23 +1746,35 @@ static int dvbv3_set_delivery_system(struct 
dvb_frontend *fe)
return emulate_delivery_system(fe, delsys);
 }
 
+/**
+ * dtv_property_process_set -  Sets a single DTV property
+ * @fe:Pointer to  dvb_frontend
+ * @file:  Pointer to  file
+ * @cmd:   Digital TV command
+ * @data:  An unsigned 32-bits number
+ *
+ * This routine assigns the property
+ * value to the corresponding member of
+ *  dtv_frontend_properties
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
 static int dtv_property_process_set(struct dvb_frontend *fe,
-   struct dtv_property *tvp,
-   struct file *file)
+   struct file *file,
+   u32 cmd, u32 data)
 {
int r = 0;
struct dtv_frontend_properties *c = >dtv_property_cache;
-
-   /* Allow the frontend to validate incoming properties */
-   if (fe->ops.set_property) {
-   r = fe->ops.set_property(fe, tvp);
-   if (r < 0)
-   return r;
-   }
-
-   dtv_property_dump(fe, true, tvp);
-
-   switch(tvp->cmd) {
+   /** Dump DTV command name and value*/
+   if (!cmd || cmd > DTV_MAX_COMMAND)
+   dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n",
+__func__, cmd);
+   else
+   dev_dbg(fe->dvb->device,
+   "%s: SET cmd 0x%08x (%s) to 0x%08x\n",
+   __func__, cmd, dtv_cmds[cmd].name, data);
+   switch (cmd) {
case DTV_CLEAR:
/*
 * Reset a cache of data specific to the frontend here. This 
does
@@ -1778,140 +1787,140 @@ static int dtv_property_process_set(struct 
dvb_frontend *fe,
 * tunerequest so we can pass validation in the FE_SET_FRONTEND
 * ioctl.
 */
-   c->state = tvp->cmd;
+   c->state = cmd;
dev_dbg(fe->dvb->device, "%s: Finalised property cache\n",
__func__);
 
r = dtv_set_frontend(fe);
break;
case DTV_FREQUENCY:
-   c->frequency = tvp->u.data;
+   c->frequency = data;
break;
case DTV_MODULATION:
-   c->modulation = tvp->u.data;
+   c->modulation = data;
break;
case DTV_BANDWIDTH_HZ:
-   c->bandwidth_hz = tvp->u.data;
+   c->bandwidth_hz = data;

[PATCH v5] [DVB][FRONTEND] Modified the code related to FE_SET_PROPERTY ioctl

2017-09-19 Thread Satendra Singh Thakur
-Since all the properties in the func dtv_property_process_set
 are 4 bytes, We have added 2 new arguments u32 cmd and u32 data;
 in place of older argument struct dtv_property *tvp.
-We have removed property validation in function
 dtv_property_process_set because most of the frontend drivers in
 linux source are not using the method ops.set_property.
-In place of dtv_property_dump, we have added own logic
 to dump cmd and data of the incoming property
-We have also re-named dtv_property_dump to dtv_get_property_dump.
-We have modified logs in this func to be suitable only for getting
 properties.
Signed-off-by: Satendra Singh Thakur 
---
 drivers/media/dvb-core/dvb_frontend.c | 135 ++
 1 file changed, 73 insertions(+), 62 deletions(-)

diff --git a/drivers/media/dvb-core/dvb_frontend.c 
b/drivers/media/dvb-core/dvb_frontend.c
index 2fcba16..013476e 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -1092,22 +1092,19 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] 
= {
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
 };
 
-static void dtv_property_dump(struct dvb_frontend *fe,
- bool is_set,
+static void dtv_get_property_dump(struct dvb_frontend *fe,
  struct dtv_property *tvp)
 {
int i;
 
if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
-   dev_warn(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x undefined\n",
-   __func__,
-   is_set ? "SET" : "GET",
+   dev_warn(fe->dvb->device, "%s: GET tvp.cmd = 0x%08x undefined\n"
+   , __func__,
tvp->cmd);
return;
}
 
-   dev_dbg(fe->dvb->device, "%s: %s tvp.cmd= 0x%08x (%s)\n", __func__,
-   is_set ? "SET" : "GET",
+   dev_dbg(fe->dvb->device, "%s: GET tvp.cmd= 0x%08x (%s)\n", __func__,
tvp->cmd,
dtv_cmds[tvp->cmd].name);
 
@@ -1526,7 +1523,7 @@ static int dtv_property_process_get(struct dvb_frontend 
*fe,
return r;
}
 
-   dtv_property_dump(fe, false, tvp);
+   dtv_get_property_dump(fe, tvp);
 
return 0;
 }
@@ -1749,23 +1746,35 @@ static int dvbv3_set_delivery_system(struct 
dvb_frontend *fe)
return emulate_delivery_system(fe, delsys);
 }
 
+/**
+ * dtv_property_process_set -  Sets a single DTV property
+ * @fe:Pointer to  dvb_frontend
+ * @file:  Pointer to  file
+ * @cmd:   Digital TV command
+ * @data:  An unsigned 32-bits number
+ *
+ * This routine assigns the property
+ * value to the corresponding member of
+ *  dtv_frontend_properties
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
 static int dtv_property_process_set(struct dvb_frontend *fe,
-   struct dtv_property *tvp,
-   struct file *file)
+   struct file *file,
+   u32 cmd, u32 data)
 {
int r = 0;
struct dtv_frontend_properties *c = >dtv_property_cache;
-
-   /* Allow the frontend to validate incoming properties */
-   if (fe->ops.set_property) {
-   r = fe->ops.set_property(fe, tvp);
-   if (r < 0)
-   return r;
-   }
-
-   dtv_property_dump(fe, true, tvp);
-
-   switch(tvp->cmd) {
+   /** Dump DTV command name and value*/
+   if (!cmd || cmd > DTV_MAX_COMMAND)
+   dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n",
+__func__, cmd);
+   else
+   dev_dbg(fe->dvb->device,
+   "%s: SET cmd 0x%08x (%s) to 0x%08x\n",
+   __func__, cmd, dtv_cmds[cmd].name, data);
+   switch (cmd) {
case DTV_CLEAR:
/*
 * Reset a cache of data specific to the frontend here. This 
does
@@ -1778,140 +1787,140 @@ static int dtv_property_process_set(struct 
dvb_frontend *fe,
 * tunerequest so we can pass validation in the FE_SET_FRONTEND
 * ioctl.
 */
-   c->state = tvp->cmd;
+   c->state = cmd;
dev_dbg(fe->dvb->device, "%s: Finalised property cache\n",
__func__);
 
r = dtv_set_frontend(fe);
break;
case DTV_FREQUENCY:
-   c->frequency = tvp->u.data;
+   c->frequency = data;
break;
case DTV_MODULATION:
-   c->modulation = tvp->u.data;
+   c->modulation = data;
break;
case DTV_BANDWIDTH_HZ:
-   c->bandwidth_hz = tvp->u.data;
+   c->bandwidth_hz = data;
break;
case 

Re: [RFC] sched/fair: Use wake_q length as a hint for wake_wide

2017-09-19 Thread Joel Fernandes
> On Tue, Sep 19, 2017 at 3:05 AM, Brendan Jackman
>  wrote:
>> On Mon, Sep 18 2017 at 22:15, Joel Fernandes wrote:
[..]
 IIUC, if wake_affine() behaves correctly this trick wouldn't be
 necessary on SMP systems, so it might be best guarded by the presence
>>>
>>> Actually wake_affine doesn't check for balance if previous/next cpu
>>> are within the same shared cache domain. The difference is some time
>>> ago it would return true for shared cache but now it returns false as
>>> of 4.14-rc1:
>>> http://elixir.free-electrons.com/linux/v4.14-rc1/source/kernel/sched/fair.c#L5466
>>>
>>> Since it would return false in the above wake up cases for task 1 and
>>> 2, it would then run select_idle_sibling on the previous CPU which is
>>> also within the big cluster, so I don't think it will make a
>>> difference in this case... Infact what it returns probably doesn't
>>> matter.
>>
>> So my paragraph here was making a leap in reasoning, let me try to fill
>> the gap: On SMP these tasks never need to move around. If by some chance
>> they did get coscheduled, the first load balance would spread them out and
>> then every time they wake up from then on, prev_cpu is the sensible
>> choice. So it will look something like:
>>
>> v CPU v   ->time->
>>
>> -
>>  {  0  (SAME)   111
>>   cache  {  -
>>  {  1  (SAME)   |
>> -
>>  {  2  (SAME)   333
>>   cache  {  -
>>  {  3  (SAME)   444
>> -
>>
>> So here, task 2 wakes up the other guys and when it's doing tasks 3 and
>> 4, prev_cpu and smp_processor_id() don't share a cache, so IIUC its'
>> basically wake_affine's job to decide between prev_cpu and
>> smp_processor_id(). So "if wake_affine is behaving correctly" the
>> problem that this patch aims to solve (i.e. the fact that we overload
>> the waker's LLC domain because of bias towards prev_cpu) does not arise
>> on SMP.
>>
>
> Yes SMP, but your patch is for solving a problem for non-SMP. So your
> original statement about wake_affine solving any problem for SMP is
> not relevant I feel :-P. I guess you can just kill this para from the
> commit message to prevent confusion.

Ok I take that back, you were talking about guarding this feature by
the SD_ASYM_CPUCAPACITY flag.

I don't think that protection would be helpful because you can have
the same issue if the tasks do different amount of work on SMP. So in
that case some threads might still complete before the others and you
run into the same thing.

thanks,

- Joel


Re: [RFC] sched/fair: Use wake_q length as a hint for wake_wide

2017-09-19 Thread Joel Fernandes
> On Tue, Sep 19, 2017 at 3:05 AM, Brendan Jackman
>  wrote:
>> On Mon, Sep 18 2017 at 22:15, Joel Fernandes wrote:
[..]
 IIUC, if wake_affine() behaves correctly this trick wouldn't be
 necessary on SMP systems, so it might be best guarded by the presence
>>>
>>> Actually wake_affine doesn't check for balance if previous/next cpu
>>> are within the same shared cache domain. The difference is some time
>>> ago it would return true for shared cache but now it returns false as
>>> of 4.14-rc1:
>>> http://elixir.free-electrons.com/linux/v4.14-rc1/source/kernel/sched/fair.c#L5466
>>>
>>> Since it would return false in the above wake up cases for task 1 and
>>> 2, it would then run select_idle_sibling on the previous CPU which is
>>> also within the big cluster, so I don't think it will make a
>>> difference in this case... Infact what it returns probably doesn't
>>> matter.
>>
>> So my paragraph here was making a leap in reasoning, let me try to fill
>> the gap: On SMP these tasks never need to move around. If by some chance
>> they did get coscheduled, the first load balance would spread them out and
>> then every time they wake up from then on, prev_cpu is the sensible
>> choice. So it will look something like:
>>
>> v CPU v   ->time->
>>
>> -
>>  {  0  (SAME)   111
>>   cache  {  -
>>  {  1  (SAME)   |
>> -
>>  {  2  (SAME)   333
>>   cache  {  -
>>  {  3  (SAME)   444
>> -
>>
>> So here, task 2 wakes up the other guys and when it's doing tasks 3 and
>> 4, prev_cpu and smp_processor_id() don't share a cache, so IIUC its'
>> basically wake_affine's job to decide between prev_cpu and
>> smp_processor_id(). So "if wake_affine is behaving correctly" the
>> problem that this patch aims to solve (i.e. the fact that we overload
>> the waker's LLC domain because of bias towards prev_cpu) does not arise
>> on SMP.
>>
>
> Yes SMP, but your patch is for solving a problem for non-SMP. So your
> original statement about wake_affine solving any problem for SMP is
> not relevant I feel :-P. I guess you can just kill this para from the
> commit message to prevent confusion.

Ok I take that back, you were talking about guarding this feature by
the SD_ASYM_CPUCAPACITY flag.

I don't think that protection would be helpful because you can have
the same issue if the tasks do different amount of work on SMP. So in
that case some threads might still complete before the others and you
run into the same thing.

thanks,

- Joel


[PATCH review for 4.4 14/47] iio: adc: axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Hans de Goede 

[ Upstream commit fa2849e9649b5180ffc4cb3c3b005261c403093a ]

For some reason the axp288_adc driver was modifying the
AXP288_ADC_TS_PIN_CTRL register, changing bits 0-1 depending on
whether the GP_ADC channel or another channel was written.

These bits control when a bias current is send to the TS_PIN, the
GP_ADC has its own pin and a separate bit in another register to
control the bias current.

Not only does changing when to enable the TS_PIN bias current
(always or only when sampling) when reading the GP_ADC make no sense
at all, the code is modifying these bits is writing the entire register,
assuming that all the other bits have their default value.

So if the firmware has configured a different bias-current for either
pin, then that change gets clobbered by the write, likewise if the
firmware has set bit 2 to indicate that the battery has no thermal sensor,
this will get clobbered by the write.

This commit fixes all this, by simply removing all writes to the
AXP288_ADC_TS_PIN_CTRL register, they are not needed to read the
GP_ADC pin, and can actually be harmful.

Signed-off-by: Hans de Goede 
Acked-by: Chen-Yu Tsai 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Sasha Levin 
---
 drivers/iio/adc/axp288_adc.c | 32 +---
 1 file changed, 1 insertion(+), 31 deletions(-)

diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c
index 0c904edd6c00..f684fe31f832 100644
--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -28,8 +28,6 @@
 #include 
 
 #define AXP288_ADC_EN_MASK 0xF1
-#define AXP288_ADC_TS_PIN_GPADC0xF2
-#define AXP288_ADC_TS_PIN_ON   0xF3
 
 enum axp288_adc_id {
AXP288_ADC_TS,
@@ -123,16 +121,6 @@ static int axp288_adc_read_channel(int *val, unsigned long 
address,
return IIO_VAL_INT;
 }
 
-static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
-   unsigned long address)
-{
-   /* channels other than GPADC do not need to switch TS pin */
-   if (address != AXP288_GP_ADC_H)
-   return 0;
-
-   return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
-}
-
 static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -143,16 +131,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
-   chan->address)) {
-   dev_err(_dev->dev, "GPADC mode\n");
-   ret = -EINVAL;
-   break;
-   }
ret = axp288_adc_read_channel(val, chan->address, info->regmap);
-   if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
-   chan->address))
-   dev_err(_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
@@ -162,15 +141,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
 }
 
-static int axp288_adc_set_state(struct regmap *regmap)
-{
-   /* ADC should be always enabled for internal FG to function */
-   if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
-   return -EIO;
-
-   return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
-}
-
 static const struct iio_info axp288_adc_iio_info = {
.read_raw = _adc_read_raw,
.driver_module = THIS_MODULE,
@@ -199,7 +169,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
 * Set ADC to enabled state at all time, including system suspend.
 * otherwise internal fuel gauge functionality may be affected.
 */
-   ret = axp288_adc_set_state(axp20x->regmap);
+   ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
if (ret) {
dev_err(>dev, "unable to enable ADC device\n");
return ret;
-- 
2.11.0


[PATCH review for 4.4 14/47] iio: adc: axp288: Drop bogus AXP288_ADC_TS_PIN_CTRL register modifications

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Hans de Goede 

[ Upstream commit fa2849e9649b5180ffc4cb3c3b005261c403093a ]

For some reason the axp288_adc driver was modifying the
AXP288_ADC_TS_PIN_CTRL register, changing bits 0-1 depending on
whether the GP_ADC channel or another channel was written.

These bits control when a bias current is send to the TS_PIN, the
GP_ADC has its own pin and a separate bit in another register to
control the bias current.

Not only does changing when to enable the TS_PIN bias current
(always or only when sampling) when reading the GP_ADC make no sense
at all, the code is modifying these bits is writing the entire register,
assuming that all the other bits have their default value.

So if the firmware has configured a different bias-current for either
pin, then that change gets clobbered by the write, likewise if the
firmware has set bit 2 to indicate that the battery has no thermal sensor,
this will get clobbered by the write.

This commit fixes all this, by simply removing all writes to the
AXP288_ADC_TS_PIN_CTRL register, they are not needed to read the
GP_ADC pin, and can actually be harmful.

Signed-off-by: Hans de Goede 
Acked-by: Chen-Yu Tsai 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Sasha Levin 
---
 drivers/iio/adc/axp288_adc.c | 32 +---
 1 file changed, 1 insertion(+), 31 deletions(-)

diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c
index 0c904edd6c00..f684fe31f832 100644
--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -28,8 +28,6 @@
 #include 
 
 #define AXP288_ADC_EN_MASK 0xF1
-#define AXP288_ADC_TS_PIN_GPADC0xF2
-#define AXP288_ADC_TS_PIN_ON   0xF3
 
 enum axp288_adc_id {
AXP288_ADC_TS,
@@ -123,16 +121,6 @@ static int axp288_adc_read_channel(int *val, unsigned long 
address,
return IIO_VAL_INT;
 }
 
-static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
-   unsigned long address)
-{
-   /* channels other than GPADC do not need to switch TS pin */
-   if (address != AXP288_GP_ADC_H)
-   return 0;
-
-   return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
-}
-
 static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -143,16 +131,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
-   if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
-   chan->address)) {
-   dev_err(_dev->dev, "GPADC mode\n");
-   ret = -EINVAL;
-   break;
-   }
ret = axp288_adc_read_channel(val, chan->address, info->regmap);
-   if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
-   chan->address))
-   dev_err(_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
@@ -162,15 +141,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
 }
 
-static int axp288_adc_set_state(struct regmap *regmap)
-{
-   /* ADC should be always enabled for internal FG to function */
-   if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
-   return -EIO;
-
-   return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
-}
-
 static const struct iio_info axp288_adc_iio_info = {
.read_raw = _adc_read_raw,
.driver_module = THIS_MODULE,
@@ -199,7 +169,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
 * Set ADC to enabled state at all time, including system suspend.
 * otherwise internal fuel gauge functionality may be affected.
 */
-   ret = axp288_adc_set_state(axp20x->regmap);
+   ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
if (ret) {
dev_err(>dev, "unable to enable ADC device\n");
return ret;
-- 
2.11.0


[PATCH review for 4.4 25/47] partitions/efi: Fix integer overflow in GPT size calculation

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Alden Tondettar 

[ Upstream commit c5082b70adfe8e1ea1cf4a8eff92c9f260e364d2 ]

If a GUID Partition Table claims to have more than 2**25 entries, the
calculation of the partition table size in alloc_read_gpt_entries() will
overflow a 32-bit integer and not enough space will be allocated for the
table.

Nothing seems to get written out of bounds, but later efi_partition() will
read up to 32768 bytes from a 128 byte buffer, possibly OOPSing or exposing
information to /proc/partitions and uevents.

The problem exists on both 64-bit and 32-bit platforms.

Fix the overflow and also print a meaningful debug message if the table
size is too large.

Signed-off-by: Alden Tondettar 
Acked-by: Ard Biesheuvel 
Signed-off-by: Jens Axboe 
Signed-off-by: Sasha Levin 
---
 block/partitions/efi.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 26cb624ace05..d26d0d27f5fd 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries(struct 
parsed_partitions *state,
if (!gpt)
return NULL;
 
-   count = le32_to_cpu(gpt->num_partition_entries) *
+   count = (size_t)le32_to_cpu(gpt->num_partition_entries) *
 le32_to_cpu(gpt->sizeof_partition_entry);
if (!count)
return NULL;
@@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_partitions *state, 
u64 lba,
gpt_header **gpt, gpt_entry **ptes)
 {
u32 crc, origcrc;
-   u64 lastlba;
+   u64 lastlba, pt_size;
 
if (!ptes)
return 0;
@@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_partitions *state, 
u64 lba,
goto fail;
}
 
+   /* Sanity check partition table size */
+   pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) *
+   le32_to_cpu((*gpt)->sizeof_partition_entry);
+   if (pt_size > KMALLOC_MAX_SIZE) {
+   pr_debug("GUID Partition Table is too large: %llu > %lu 
bytes\n",
+(unsigned long long)pt_size, KMALLOC_MAX_SIZE);
+   goto fail;
+   }
+
if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
goto fail;
 
/* Check the GUID Partition Entry Array CRC */
-   crc = efi_crc32((const unsigned char *) (*ptes),
-   le32_to_cpu((*gpt)->num_partition_entries) *
-   le32_to_cpu((*gpt)->sizeof_partition_entry));
+   crc = efi_crc32((const unsigned char *) (*ptes), pt_size);
 
if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
pr_debug("GUID Partitition Entry Array CRC check failed.\n");
-- 
2.11.0


[PATCH review for 4.4 25/47] partitions/efi: Fix integer overflow in GPT size calculation

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Alden Tondettar 

[ Upstream commit c5082b70adfe8e1ea1cf4a8eff92c9f260e364d2 ]

If a GUID Partition Table claims to have more than 2**25 entries, the
calculation of the partition table size in alloc_read_gpt_entries() will
overflow a 32-bit integer and not enough space will be allocated for the
table.

Nothing seems to get written out of bounds, but later efi_partition() will
read up to 32768 bytes from a 128 byte buffer, possibly OOPSing or exposing
information to /proc/partitions and uevents.

The problem exists on both 64-bit and 32-bit platforms.

Fix the overflow and also print a meaningful debug message if the table
size is too large.

Signed-off-by: Alden Tondettar 
Acked-by: Ard Biesheuvel 
Signed-off-by: Jens Axboe 
Signed-off-by: Sasha Levin 
---
 block/partitions/efi.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index 26cb624ace05..d26d0d27f5fd 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -293,7 +293,7 @@ static gpt_entry *alloc_read_gpt_entries(struct 
parsed_partitions *state,
if (!gpt)
return NULL;
 
-   count = le32_to_cpu(gpt->num_partition_entries) *
+   count = (size_t)le32_to_cpu(gpt->num_partition_entries) *
 le32_to_cpu(gpt->sizeof_partition_entry);
if (!count)
return NULL;
@@ -352,7 +352,7 @@ static int is_gpt_valid(struct parsed_partitions *state, 
u64 lba,
gpt_header **gpt, gpt_entry **ptes)
 {
u32 crc, origcrc;
-   u64 lastlba;
+   u64 lastlba, pt_size;
 
if (!ptes)
return 0;
@@ -434,13 +434,20 @@ static int is_gpt_valid(struct parsed_partitions *state, 
u64 lba,
goto fail;
}
 
+   /* Sanity check partition table size */
+   pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) *
+   le32_to_cpu((*gpt)->sizeof_partition_entry);
+   if (pt_size > KMALLOC_MAX_SIZE) {
+   pr_debug("GUID Partition Table is too large: %llu > %lu 
bytes\n",
+(unsigned long long)pt_size, KMALLOC_MAX_SIZE);
+   goto fail;
+   }
+
if (!(*ptes = alloc_read_gpt_entries(state, *gpt)))
goto fail;
 
/* Check the GUID Partition Entry Array CRC */
-   crc = efi_crc32((const unsigned char *) (*ptes),
-   le32_to_cpu((*gpt)->num_partition_entries) *
-   le32_to_cpu((*gpt)->sizeof_partition_entry));
+   crc = efi_crc32((const unsigned char *) (*ptes), pt_size);
 
if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
pr_debug("GUID Partitition Entry Array CRC check failed.\n");
-- 
2.11.0


[PATCH review for 4.4 01/47] drm_fourcc: Fix DRM_FORMAT_MOD_LINEAR #define

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: "Kristian H. Kristensen" 

[ Upstream commit af913418261d6d3e7a29f06cf35f04610ead667c ]

We need to define DRM_FORMAT_MOD_VENDOR_NONE for the fourcc_mod_code()
macro to work correctly.

Signed-off-by: Kristian H. Kristensen 
Signed-off-by: Daniel Vetter 
Link: 
http://patchwork.freedesktop.org/patch/msgid/1481657272-25975-1-git-send-email-hoegsb...@google.com
Signed-off-by: Sasha Levin 
---
 include/uapi/drm/drm_fourcc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 0b69a7753558..f28f79966e9e 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -150,6 +150,7 @@
 
 /* Vendor Ids: */
 #define DRM_FORMAT_MOD_NONE   0
+#define DRM_FORMAT_MOD_VENDOR_NONE0
 #define DRM_FORMAT_MOD_VENDOR_INTEL   0x01
 #define DRM_FORMAT_MOD_VENDOR_AMD 0x02
 #define DRM_FORMAT_MOD_VENDOR_NV  0x03
-- 
2.11.0


[PATCH review for 4.4 01/47] drm_fourcc: Fix DRM_FORMAT_MOD_LINEAR #define

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: "Kristian H. Kristensen" 

[ Upstream commit af913418261d6d3e7a29f06cf35f04610ead667c ]

We need to define DRM_FORMAT_MOD_VENDOR_NONE for the fourcc_mod_code()
macro to work correctly.

Signed-off-by: Kristian H. Kristensen 
Signed-off-by: Daniel Vetter 
Link: 
http://patchwork.freedesktop.org/patch/msgid/1481657272-25975-1-git-send-email-hoegsb...@google.com
Signed-off-by: Sasha Levin 
---
 include/uapi/drm/drm_fourcc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 0b69a7753558..f28f79966e9e 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -150,6 +150,7 @@
 
 /* Vendor Ids: */
 #define DRM_FORMAT_MOD_NONE   0
+#define DRM_FORMAT_MOD_VENDOR_NONE0
 #define DRM_FORMAT_MOD_VENDOR_INTEL   0x01
 #define DRM_FORMAT_MOD_VENDOR_AMD 0x02
 #define DRM_FORMAT_MOD_VENDOR_NV  0x03
-- 
2.11.0


[PATCH review for 4.4 02/47] drm: bridge: add DT bindings for TI ths8135

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Bartosz Golaszewski 

[ Upstream commit 2e644be30fcc08c736f66b60f4898d274d4873ab ]

THS8135 is a configurable video DAC. Add DT bindings for this chip.

Signed-off-by: Bartosz Golaszewski 
Reviewed-by: Laurent Pinchart 
Acked-by: Rob Herring 
Signed-off-by: Archit Taneja 
Link: 
http://patchwork.freedesktop.org/patch/msgid/1481623759-12786-3-git-send-email-bgolaszew...@baylibre.com
Signed-off-by: Sasha Levin 
---
 .../bindings/display/bridge/ti,ths8135.txt | 46 ++
 1 file changed, 46 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt 
b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
new file mode 100644
index ..6ec1a880ac18
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
@@ -0,0 +1,46 @@
+THS8135 Video DAC
+-
+
+This is the binding for Texas Instruments THS8135 Video DAC bridge.
+
+Required properties:
+
+- compatible: Must be "ti,ths8135"
+
+Required nodes:
+
+This device has two video ports. Their connections are modelled using the OF
+graph bindings specified in Documentation/devicetree/bindings/graph.txt.
+
+- Video port 0 for RGB input
+- Video port 1 for VGA output
+
+Example
+---
+
+vga-bridge {
+   compatible = "ti,ths8135";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   vga_bridge_in: endpoint {
+   remote-endpoint = <_out_vga>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   vga_bridge_out: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+   };
+   };
+};
-- 
2.11.0


[PATCH review for 4.4 02/47] drm: bridge: add DT bindings for TI ths8135

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Bartosz Golaszewski 

[ Upstream commit 2e644be30fcc08c736f66b60f4898d274d4873ab ]

THS8135 is a configurable video DAC. Add DT bindings for this chip.

Signed-off-by: Bartosz Golaszewski 
Reviewed-by: Laurent Pinchart 
Acked-by: Rob Herring 
Signed-off-by: Archit Taneja 
Link: 
http://patchwork.freedesktop.org/patch/msgid/1481623759-12786-3-git-send-email-bgolaszew...@baylibre.com
Signed-off-by: Sasha Levin 
---
 .../bindings/display/bridge/ti,ths8135.txt | 46 ++
 1 file changed, 46 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt 
b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
new file mode 100644
index ..6ec1a880ac18
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
@@ -0,0 +1,46 @@
+THS8135 Video DAC
+-
+
+This is the binding for Texas Instruments THS8135 Video DAC bridge.
+
+Required properties:
+
+- compatible: Must be "ti,ths8135"
+
+Required nodes:
+
+This device has two video ports. Their connections are modelled using the OF
+graph bindings specified in Documentation/devicetree/bindings/graph.txt.
+
+- Video port 0 for RGB input
+- Video port 1 for VGA output
+
+Example
+---
+
+vga-bridge {
+   compatible = "ti,ths8135";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   vga_bridge_in: endpoint {
+   remote-endpoint = <_out_vga>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   vga_bridge_out: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+   };
+   };
+};
-- 
2.11.0


[PATCH review for 4.4 28/47] usb: chipidea: vbus event may exist before starting gadget

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Peter Chen 

[ Upstream commit c3b674a04b8ab62a1d35e86714d466af0a0ecc18 ]

At some situations, the vbus may already be there before starting
gadget. So we need to check vbus event after switching to gadget in
order to handle missing vbus event. The typical use cases are plugging
vbus cable before driver load or the vbus has already been there
after stopping host but before starting gadget.

Signed-off-by: Peter Chen 
Tested-by: Stephen Boyd 
Reported-by: Stephen Boyd 
Signed-off-by: Sasha Levin 
---
 drivers/usb/chipidea/otg.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 0cf149e8..f36a1ac3bfbd 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -134,9 +134,9 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
if (!ci->is_otg)
return;
 
-   if (hw_read_otgsc(ci, OTGSC_BSV))
+   if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
usb_gadget_vbus_connect(>gadget);
-   else
+   else if (!hw_read_otgsc(ci, OTGSC_BSV) && ci->vbus_active)
usb_gadget_vbus_disconnect(>gadget);
 }
 
@@ -175,14 +175,21 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 
ci_role_stop(ci);
 
-   if (role == CI_ROLE_GADGET)
+   if (role == CI_ROLE_GADGET &&
+   IS_ERR(ci->platdata->vbus_extcon.edev))
/*
-* wait vbus lower than OTGSC_BSV before connecting
-* to host
+* Wait vbus lower than OTGSC_BSV before connecting
+* to host. If connecting status is from an external
+* connector instead of register, we don't need to
+* care vbus on the board, since it will not affect
+* external connector status.
 */
hw_wait_vbus_lower_bsv(ci);
 
ci_role_start(ci, role);
+   /* vbus change may have already occurred */
+   if (role == CI_ROLE_GADGET)
+   ci_handle_vbus_change(ci);
}
 }
 /**
-- 
2.11.0


[PATCH review for 4.4 28/47] usb: chipidea: vbus event may exist before starting gadget

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Peter Chen 

[ Upstream commit c3b674a04b8ab62a1d35e86714d466af0a0ecc18 ]

At some situations, the vbus may already be there before starting
gadget. So we need to check vbus event after switching to gadget in
order to handle missing vbus event. The typical use cases are plugging
vbus cable before driver load or the vbus has already been there
after stopping host but before starting gadget.

Signed-off-by: Peter Chen 
Tested-by: Stephen Boyd 
Reported-by: Stephen Boyd 
Signed-off-by: Sasha Levin 
---
 drivers/usb/chipidea/otg.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 0cf149e8..f36a1ac3bfbd 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -134,9 +134,9 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
if (!ci->is_otg)
return;
 
-   if (hw_read_otgsc(ci, OTGSC_BSV))
+   if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
usb_gadget_vbus_connect(>gadget);
-   else
+   else if (!hw_read_otgsc(ci, OTGSC_BSV) && ci->vbus_active)
usb_gadget_vbus_disconnect(>gadget);
 }
 
@@ -175,14 +175,21 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 
ci_role_stop(ci);
 
-   if (role == CI_ROLE_GADGET)
+   if (role == CI_ROLE_GADGET &&
+   IS_ERR(ci->platdata->vbus_extcon.edev))
/*
-* wait vbus lower than OTGSC_BSV before connecting
-* to host
+* Wait vbus lower than OTGSC_BSV before connecting
+* to host. If connecting status is from an external
+* connector instead of register, we don't need to
+* care vbus on the board, since it will not affect
+* external connector status.
 */
hw_wait_vbus_lower_bsv(ci);
 
ci_role_start(ci, role);
+   /* vbus change may have already occurred */
+   if (role == CI_ROLE_GADGET)
+   ci_handle_vbus_change(ci);
}
 }
 /**
-- 
2.11.0


[PATCH review for 4.4 13/47] hwmon: (gl520sm) Fix overflows and crash seen when writing into limit attributes

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Guenter Roeck 

[ Upstream commit 87cdfa9d60f4f40e6d71b04b10b36d9df3c89282 ]

Writes into limit attributes can overflow due to multplications and
additions with unbound input values. Writing into fan limit attributes
can result in a crash with a division by zero if very large values are
written and the fan divider is larger than 1.

Signed-off-by: Guenter Roeck 
Signed-off-by: Sasha Levin 
---
 drivers/hwmon/gl520sm.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index dee93ec87d02..84e0994aafdd 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -208,11 +208,13 @@ static ssize_t get_cpu_vid(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
 
-#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
-#define VDD_TO_REG(val) clamp_valval) * 4 + 47) / 95), 0, 255)
+#define VDD_FROM_REG(val)  DIV_ROUND_CLOSEST((val) * 95, 4)
+#define VDD_CLAMP(val) clamp_val(val, 0, 255 * 95 / 4)
+#define VDD_TO_REG(val)DIV_ROUND_CLOSEST(VDD_CLAMP(val) * 4, 
95)
 
-#define IN_FROM_REG(val) ((val) * 19)
-#define IN_TO_REG(val) clamp_valval) + 9) / 19), 0, 255)
+#define IN_FROM_REG(val)   ((val) * 19)
+#define IN_CLAMP(val)  clamp_val(val, 0, 255 * 19)
+#define IN_TO_REG(val) DIV_ROUND_CLOSEST(IN_CLAMP(val), 19)
 
 static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -349,8 +351,13 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
 
 #define DIV_FROM_REG(val) (1 << (val))
 #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (48 / ((val) << (div
-#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \
-   clamp_val((48 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255))
+
+#define FAN_BASE(div)  (48 >> (div))
+#define FAN_CLAMP(val, div)clamp_val(val, FAN_BASE(div) / 255, \
+ FAN_BASE(div))
+#define FAN_TO_REG(val, div)   ((val) == 0 ? 0 : \
+DIV_ROUND_CLOSEST(48, \
+   FAN_CLAMP(val, div) << (div)))
 
 static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
 char *buf)
@@ -513,9 +520,9 @@ static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
get_fan_off, set_fan_off);
 
-#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
-#define TEMP_TO_REG(val) clamp_val(val) < 0 ? \
-   (val) - 500 : (val) + 500) / 1000) + 130), 0, 255)
+#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
+#define TEMP_CLAMP(val)clamp_val(val, -13, 125000)
+#define TEMP_TO_REG(val)   (DIV_ROUND_CLOSEST(TEMP_CLAMP(val), 1000) + 130)
 
 static ssize_t get_temp_input(struct device *dev, struct device_attribute 
*attr,
  char *buf)
-- 
2.11.0


[PATCH review for 4.4 13/47] hwmon: (gl520sm) Fix overflows and crash seen when writing into limit attributes

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Guenter Roeck 

[ Upstream commit 87cdfa9d60f4f40e6d71b04b10b36d9df3c89282 ]

Writes into limit attributes can overflow due to multplications and
additions with unbound input values. Writing into fan limit attributes
can result in a crash with a division by zero if very large values are
written and the fan divider is larger than 1.

Signed-off-by: Guenter Roeck 
Signed-off-by: Sasha Levin 
---
 drivers/hwmon/gl520sm.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index dee93ec87d02..84e0994aafdd 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -208,11 +208,13 @@ static ssize_t get_cpu_vid(struct device *dev, struct 
device_attribute *attr,
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
 
-#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
-#define VDD_TO_REG(val) clamp_valval) * 4 + 47) / 95), 0, 255)
+#define VDD_FROM_REG(val)  DIV_ROUND_CLOSEST((val) * 95, 4)
+#define VDD_CLAMP(val) clamp_val(val, 0, 255 * 95 / 4)
+#define VDD_TO_REG(val)DIV_ROUND_CLOSEST(VDD_CLAMP(val) * 4, 
95)
 
-#define IN_FROM_REG(val) ((val) * 19)
-#define IN_TO_REG(val) clamp_valval) + 9) / 19), 0, 255)
+#define IN_FROM_REG(val)   ((val) * 19)
+#define IN_CLAMP(val)  clamp_val(val, 0, 255 * 19)
+#define IN_TO_REG(val) DIV_ROUND_CLOSEST(IN_CLAMP(val), 19)
 
 static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -349,8 +351,13 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
 
 #define DIV_FROM_REG(val) (1 << (val))
 #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (48 / ((val) << (div
-#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \
-   clamp_val((48 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255))
+
+#define FAN_BASE(div)  (48 >> (div))
+#define FAN_CLAMP(val, div)clamp_val(val, FAN_BASE(div) / 255, \
+ FAN_BASE(div))
+#define FAN_TO_REG(val, div)   ((val) == 0 ? 0 : \
+DIV_ROUND_CLOSEST(48, \
+   FAN_CLAMP(val, div) << (div)))
 
 static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
 char *buf)
@@ -513,9 +520,9 @@ static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
get_fan_off, set_fan_off);
 
-#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
-#define TEMP_TO_REG(val) clamp_val(val) < 0 ? \
-   (val) - 500 : (val) + 500) / 1000) + 130), 0, 255)
+#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
+#define TEMP_CLAMP(val)clamp_val(val, -13, 125000)
+#define TEMP_TO_REG(val)   (DIV_ROUND_CLOSEST(TEMP_CLAMP(val), 1000) + 130)
 
 static ssize_t get_temp_input(struct device *dev, struct device_attribute 
*attr,
  char *buf)
-- 
2.11.0


[PATCH review for 4.4 12/47] clk: wm831x: fix usleep_range with bad range

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Nicholas Mc Guire 

[ Upstream commit ed784c532a3d0959db488f40a96c5127f63d42dc ]

The delay here is not in atomic context and does not seem critical with
respect to precision, but usleep_range(min,max) with min==max results in
giving the timer subsystem no room to optimize uncritical delays. Fix
this by setting the range to 2000,3000 us.

Fixes: commit f05259a6ffa4 ("clk: wm831x: Add initial WM831x clock driver")
Signed-off-by: Nicholas Mc Guire 
Acked-by: Charles Keepax 
Signed-off-by: Stephen Boyd 
Signed-off-by: Sasha Levin 
---
 drivers/clk/clk-wm831x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 763aed2de893..dfedcf5bc429 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -101,7 +101,8 @@ static int wm831x_fll_prepare(struct clk_hw *hw)
if (ret != 0)
dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
 
-   usleep_range(2000, 2000);
+   /* wait 2-3 ms for new frequency taking effect */
+   usleep_range(2000, 3000);
 
return ret;
 }
-- 
2.11.0


[PATCH review for 4.4 12/47] clk: wm831x: fix usleep_range with bad range

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Nicholas Mc Guire 

[ Upstream commit ed784c532a3d0959db488f40a96c5127f63d42dc ]

The delay here is not in atomic context and does not seem critical with
respect to precision, but usleep_range(min,max) with min==max results in
giving the timer subsystem no room to optimize uncritical delays. Fix
this by setting the range to 2000,3000 us.

Fixes: commit f05259a6ffa4 ("clk: wm831x: Add initial WM831x clock driver")
Signed-off-by: Nicholas Mc Guire 
Acked-by: Charles Keepax 
Signed-off-by: Stephen Boyd 
Signed-off-by: Sasha Levin 
---
 drivers/clk/clk-wm831x.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 763aed2de893..dfedcf5bc429 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -101,7 +101,8 @@ static int wm831x_fll_prepare(struct clk_hw *hw)
if (ret != 0)
dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
 
-   usleep_range(2000, 2000);
+   /* wait 2-3 ms for new frequency taking effect */
+   usleep_range(2000, 3000);
 
return ret;
 }
-- 
2.11.0


[PATCH review for 4.4 08/47] MIPS: ralink: Fix incorrect assignment on ralink_soc

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Colin Ian King 

[ Upstream commit 08d90c81b714482dceb5323d14f6617bcf55ee61 ]

ralink_soc sould be assigned to RT3883_SOC, replace incorrect
comparision with assignment.

Signed-off-by: Colin Ian King 
Fixes: 418d29c87061 ("MIPS: ralink: Unify SoC id handling")
Cc: John Crispin 
Cc: linux-m...@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/14903/
Signed-off-by: Ralf Baechle 
Signed-off-by: Sasha Levin 
---
 arch/mips/ralink/rt3883.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
index 3c575093f8f1..f2a6e1b8cce0 100644
--- a/arch/mips/ralink/rt3883.c
+++ b/arch/mips/ralink/rt3883.c
@@ -144,5 +144,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
rt2880_pinmux_data = rt3883_pinmux_data;
 
-   ralink_soc == RT3883_SOC;
+   ralink_soc = RT3883_SOC;
 }
-- 
2.11.0


[PATCH review for 4.4 08/47] MIPS: ralink: Fix incorrect assignment on ralink_soc

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Colin Ian King 

[ Upstream commit 08d90c81b714482dceb5323d14f6617bcf55ee61 ]

ralink_soc sould be assigned to RT3883_SOC, replace incorrect
comparision with assignment.

Signed-off-by: Colin Ian King 
Fixes: 418d29c87061 ("MIPS: ralink: Unify SoC id handling")
Cc: John Crispin 
Cc: linux-m...@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/14903/
Signed-off-by: Ralf Baechle 
Signed-off-by: Sasha Levin 
---
 arch/mips/ralink/rt3883.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
index 3c575093f8f1..f2a6e1b8cce0 100644
--- a/arch/mips/ralink/rt3883.c
+++ b/arch/mips/ralink/rt3883.c
@@ -144,5 +144,5 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 
rt2880_pinmux_data = rt3883_pinmux_data;
 
-   ralink_soc == RT3883_SOC;
+   ralink_soc = RT3883_SOC;
 }
-- 
2.11.0


[PATCH review for 4.4 11/47] sh_eth: use correct name for ECMR_MPDE bit

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Niklas Söderlund 

[ Upstream commit 6dcf45e514974a1ff10755015b5e06746a033e5f ]

This bit was wrongly named due to a typo, Sergei checked the SH7734/63
manuals and this bit should be named MPDE.

Suggested-by: Sergei Shtylyov 
Signed-off-by: Niklas Söderlund 
Signed-off-by: David S. Miller 
Signed-off-by: Sasha Levin 
---
 drivers/net/ethernet/renesas/sh_eth.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/sh_eth.h 
b/drivers/net/ethernet/renesas/sh_eth.h
index 72fcfc924589..0d18be0fed8e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -339,7 +339,7 @@ enum FELIC_MODE_BIT {
ECMR_DPAD = 0x0020, ECMR_RZPF = 0x0010,
ECMR_ZPF = 0x0008, ECMR_PFR = 0x0004, ECMR_RXF = 0x0002,
ECMR_TXF = 0x0001, ECMR_MCT = 0x2000, ECMR_PRCEF = 0x1000,
-   ECMR_PMDE = 0x0200, ECMR_RE = 0x0040, ECMR_TE = 0x0020,
+   ECMR_MPDE = 0x0200, ECMR_RE = 0x0040, ECMR_TE = 0x0020,
ECMR_RTM = 0x0010, ECMR_ILB = 0x0008, ECMR_ELB = 0x0004,
ECMR_DM = 0x0002, ECMR_PRM = 0x0001,
 };
-- 
2.11.0


[PATCH review for 4.4 11/47] sh_eth: use correct name for ECMR_MPDE bit

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Niklas Söderlund 

[ Upstream commit 6dcf45e514974a1ff10755015b5e06746a033e5f ]

This bit was wrongly named due to a typo, Sergei checked the SH7734/63
manuals and this bit should be named MPDE.

Suggested-by: Sergei Shtylyov 
Signed-off-by: Niklas Söderlund 
Signed-off-by: David S. Miller 
Signed-off-by: Sasha Levin 
---
 drivers/net/ethernet/renesas/sh_eth.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/sh_eth.h 
b/drivers/net/ethernet/renesas/sh_eth.h
index 72fcfc924589..0d18be0fed8e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -339,7 +339,7 @@ enum FELIC_MODE_BIT {
ECMR_DPAD = 0x0020, ECMR_RZPF = 0x0010,
ECMR_ZPF = 0x0008, ECMR_PFR = 0x0004, ECMR_RXF = 0x0002,
ECMR_TXF = 0x0001, ECMR_MCT = 0x2000, ECMR_PRCEF = 0x1000,
-   ECMR_PMDE = 0x0200, ECMR_RE = 0x0040, ECMR_TE = 0x0020,
+   ECMR_MPDE = 0x0200, ECMR_RE = 0x0040, ECMR_TE = 0x0020,
ECMR_RTM = 0x0010, ECMR_ILB = 0x0008, ECMR_ELB = 0x0004,
ECMR_DM = 0x0002, ECMR_PRM = 0x0001,
 };
-- 
2.11.0


[PATCH review for 4.4 19/47] IB/ipoib: rtnl_unlock can not come after free_netdev

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Feras Daoud 

[ Upstream commit 89a3987ab7a923c047c6dec008e60ad6f41fac22 ]

The ipoib_vlan_add function calls rtnl_unlock after free_netdev,
rtnl_unlock not only releases the lock, but also calls netdev_run_todo.
The latter function browses the net_todo_list array and completes the
unregistration of all its net_device instances. If we call free_netdev
before rtnl_unlock, then netdev_run_todo call over the freed device causes
panic.
To fix, move rtnl_unlock call before free_netdev call.

Fixes: 9baa0b036410 ("IB/ipoib: Add rtnl_link_ops support")
Cc: Or Gerlitz 
Signed-off-by: Feras Daoud 
Signed-off-by: Erez Shitrit 
Reviewed-by: Yuval Shaia 
Signed-off-by: Leon Romanovsky 
Signed-off-by: Doug Ledford 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 
b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 3a647fd50f09..9b47a437d6c9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -160,11 +160,11 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned 
short pkey)
 out:
up_write(>vlan_rwsem);
 
+   rtnl_unlock();
+
if (result)
free_netdev(priv->dev);
 
-   rtnl_unlock();
-
return result;
 }
 
-- 
2.11.0


[PATCH review for 4.4 15/47] iio: adc: hx711: Add DT binding for avia,hx711

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Andreas Klinger 

[ Upstream commit ff1293f67734da68e23fecb6ecdae7112b8c43f9 ]

Add DT bindings for avia,hx711
Add vendor avia to vendor list

Signed-off-by: Andreas Klinger 
Acked-by: Rob Herring 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Sasha Levin 
---
 .../devicetree/bindings/iio/adc/avia-hx711.txt | 18 ++
 Documentation/devicetree/bindings/vendor-prefixes.txt  |  1 +
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/avia-hx711.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt 
b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
new file mode 100644
index ..b3629405f568
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
@@ -0,0 +1,18 @@
+* AVIA HX711 ADC chip for weight cells
+  Bit-banging driver
+
+Required properties:
+ - compatible: Should be "avia,hx711"
+ - sck-gpios:  Definition of the GPIO for the clock
+ - dout-gpios: Definition of the GPIO for data-out
+   See Documentation/devicetree/bindings/gpio/gpio.txt
+ - avdd-supply:Definition of the regulator used as analog supply
+
+Example:
+weight@0 {
+   compatible = "avia,hx711";
+   sck-gpios = < 10 GPIO_ACTIVE_HIGH>;
+   dout-gpios = < 7 GPIO_ACTIVE_HIGH>;
+   avdd-suppy = <>;
+};
+
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d444e9f..98dc17507a84 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -31,6 +31,7 @@ asahi-kasei   Asahi Kasei Corp.
 atmel  Atmel Corporation
 auoAU Optronics Corporation
 avago  Avago Technologies
+avia   avia semiconductor
 avic   Shanghai AVIC Optoelectronics Co., Ltd.
 axis   Axis Communications AB
 bosch  Bosch Sensortec GmbH
-- 
2.11.0


[PATCH review for 4.4 19/47] IB/ipoib: rtnl_unlock can not come after free_netdev

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Feras Daoud 

[ Upstream commit 89a3987ab7a923c047c6dec008e60ad6f41fac22 ]

The ipoib_vlan_add function calls rtnl_unlock after free_netdev,
rtnl_unlock not only releases the lock, but also calls netdev_run_todo.
The latter function browses the net_todo_list array and completes the
unregistration of all its net_device instances. If we call free_netdev
before rtnl_unlock, then netdev_run_todo call over the freed device causes
panic.
To fix, move rtnl_unlock call before free_netdev call.

Fixes: 9baa0b036410 ("IB/ipoib: Add rtnl_link_ops support")
Cc: Or Gerlitz 
Signed-off-by: Feras Daoud 
Signed-off-by: Erez Shitrit 
Reviewed-by: Yuval Shaia 
Signed-off-by: Leon Romanovsky 
Signed-off-by: Doug Ledford 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 
b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 3a647fd50f09..9b47a437d6c9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -160,11 +160,11 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned 
short pkey)
 out:
up_write(>vlan_rwsem);
 
+   rtnl_unlock();
+
if (result)
free_netdev(priv->dev);
 
-   rtnl_unlock();
-
return result;
 }
 
-- 
2.11.0


[PATCH review for 4.4 15/47] iio: adc: hx711: Add DT binding for avia,hx711

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Andreas Klinger 

[ Upstream commit ff1293f67734da68e23fecb6ecdae7112b8c43f9 ]

Add DT bindings for avia,hx711
Add vendor avia to vendor list

Signed-off-by: Andreas Klinger 
Acked-by: Rob Herring 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Sasha Levin 
---
 .../devicetree/bindings/iio/adc/avia-hx711.txt | 18 ++
 Documentation/devicetree/bindings/vendor-prefixes.txt  |  1 +
 2 files changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/avia-hx711.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt 
b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
new file mode 100644
index ..b3629405f568
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
@@ -0,0 +1,18 @@
+* AVIA HX711 ADC chip for weight cells
+  Bit-banging driver
+
+Required properties:
+ - compatible: Should be "avia,hx711"
+ - sck-gpios:  Definition of the GPIO for the clock
+ - dout-gpios: Definition of the GPIO for data-out
+   See Documentation/devicetree/bindings/gpio/gpio.txt
+ - avdd-supply:Definition of the regulator used as analog supply
+
+Example:
+weight@0 {
+   compatible = "avia,hx711";
+   sck-gpios = < 10 GPIO_ACTIVE_HIGH>;
+   dout-gpios = < 7 GPIO_ACTIVE_HIGH>;
+   avdd-suppy = <>;
+};
+
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt 
b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d444e9f..98dc17507a84 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -31,6 +31,7 @@ asahi-kasei   Asahi Kasei Corp.
 atmel  Atmel Corporation
 auoAU Optronics Corporation
 avago  Avago Technologies
+avia   avia semiconductor
 avic   Shanghai AVIC Optoelectronics Co., Ltd.
 axis   Axis Communications AB
 bosch  Bosch Sensortec GmbH
-- 
2.11.0


[PATCH review for 4.4 05/47] ARM: dts: r8a7790: Use R-Car Gen 2 fallback binding for msiof nodes

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Simon Horman 

[ Upstream commit 654450baf2afba86cf328e1849ccac61ec4630af ]

Use recently added R-Car Gen 2 fallback binding for msiof nodes in
DT for r8a7790 SoC.

This has no run-time effect for the current driver as the initialisation
sequence is the same for the SoC-specific binding for r8a7790 and the
fallback binding for R-Car Gen 2.

Signed-off-by: Simon Horman 
Reviewed-by: Geert Uytterhoeven 
Signed-off-by: Sasha Levin 
---
 arch/arm/boot/dts/r8a7790.dtsi | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index e07ae5d45e19..7b39d8fae61e 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -1409,7 +1409,8 @@
};
 
msiof0: spi@e6e2 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e2 0 0x0064>;
interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF0>;
@@ -1422,7 +1423,8 @@
};
 
msiof1: spi@e6e1 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e1 0 0x0064>;
interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF1>;
@@ -1435,7 +1437,8 @@
};
 
msiof2: spi@e6e0 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e0 0 0x0064>;
interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF2>;
@@ -1448,7 +1451,8 @@
};
 
msiof3: spi@e6c9 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6c9 0 0x0064>;
interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF3>;
-- 
2.11.0


[PATCH review for 4.4 05/47] ARM: dts: r8a7790: Use R-Car Gen 2 fallback binding for msiof nodes

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Simon Horman 

[ Upstream commit 654450baf2afba86cf328e1849ccac61ec4630af ]

Use recently added R-Car Gen 2 fallback binding for msiof nodes in
DT for r8a7790 SoC.

This has no run-time effect for the current driver as the initialisation
sequence is the same for the SoC-specific binding for r8a7790 and the
fallback binding for R-Car Gen 2.

Signed-off-by: Simon Horman 
Reviewed-by: Geert Uytterhoeven 
Signed-off-by: Sasha Levin 
---
 arch/arm/boot/dts/r8a7790.dtsi | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index e07ae5d45e19..7b39d8fae61e 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -1409,7 +1409,8 @@
};
 
msiof0: spi@e6e2 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e2 0 0x0064>;
interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF0>;
@@ -1422,7 +1423,8 @@
};
 
msiof1: spi@e6e1 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e1 0 0x0064>;
interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF1>;
@@ -1435,7 +1437,8 @@
};
 
msiof2: spi@e6e0 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6e0 0 0x0064>;
interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF2>;
@@ -1448,7 +1451,8 @@
};
 
msiof3: spi@e6c9 {
-   compatible = "renesas,msiof-r8a7790";
+   compatible = "renesas,msiof-r8a7790",
+"renesas,rcar-gen2-msiof";
reg = <0 0xe6c9 0 0x0064>;
interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>;
clocks = <_clks R8A7790_CLK_MSIOF3>;
-- 
2.11.0


[PATCH review for 4.4 35/47] mmc: sdio: fix alignment issue in struct sdio_func

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Heiner Kallweit 

[ Upstream commit 5ef1ecf060f28ecef313b5723f1fd39bf5a35f56 ]

Certain 64-bit systems (e.g. Amlogic Meson GX) require buffers to be
used for DMA to be 8-byte-aligned. struct sdio_func has an embedded
small DMA buffer not meeting this requirement.
When testing switching to descriptor chain mode in meson-gx driver
SDIO is broken therefore. Fix this by allocating the small DMA buffer
separately as kmalloc ensures that the returned memory area is
properly aligned for every basic data type.

Signed-off-by: Heiner Kallweit 
Tested-by: Helmut Klein 
Signed-off-by: Ulf Hansson 
Signed-off-by: Sasha Levin 
---
 drivers/mmc/core/sdio_bus.c   | 12 +++-
 include/linux/mmc/sdio_func.h |  2 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 7e327a6dd53d..c23bc4f331bd 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -266,7 +266,7 @@ static void sdio_release_func(struct device *dev)
sdio_free_func_cis(func);
 
kfree(func->info);
-
+   kfree(func->tmpbuf);
kfree(func);
 }
 
@@ -281,6 +281,16 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card)
if (!func)
return ERR_PTR(-ENOMEM);
 
+   /*
+* allocate buffer separately to make sure it's properly aligned for
+* DMA usage (incl. 64 bit DMA)
+*/
+   func->tmpbuf = kmalloc(4, GFP_KERNEL);
+   if (!func->tmpbuf) {
+   kfree(func);
+   return ERR_PTR(-ENOMEM);
+   }
+
func->card = card;
 
device_initialize(>dev);
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index aab032a6ae61..97ca105347a6 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -53,7 +53,7 @@ struct sdio_func {
unsigned intstate;  /* function state */
 #define SDIO_STATE_PRESENT (1<<0)  /* present in sysfs */
 
-   u8  tmpbuf[4];  /* DMA:able scratch buffer */
+   u8  *tmpbuf;/* DMA:able scratch buffer */
 
unsignednum_info;   /* number of info strings */
const char  **info; /* info strings */
-- 
2.11.0


[PATCH review for 4.4 35/47] mmc: sdio: fix alignment issue in struct sdio_func

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Heiner Kallweit 

[ Upstream commit 5ef1ecf060f28ecef313b5723f1fd39bf5a35f56 ]

Certain 64-bit systems (e.g. Amlogic Meson GX) require buffers to be
used for DMA to be 8-byte-aligned. struct sdio_func has an embedded
small DMA buffer not meeting this requirement.
When testing switching to descriptor chain mode in meson-gx driver
SDIO is broken therefore. Fix this by allocating the small DMA buffer
separately as kmalloc ensures that the returned memory area is
properly aligned for every basic data type.

Signed-off-by: Heiner Kallweit 
Tested-by: Helmut Klein 
Signed-off-by: Ulf Hansson 
Signed-off-by: Sasha Levin 
---
 drivers/mmc/core/sdio_bus.c   | 12 +++-
 include/linux/mmc/sdio_func.h |  2 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 7e327a6dd53d..c23bc4f331bd 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -266,7 +266,7 @@ static void sdio_release_func(struct device *dev)
sdio_free_func_cis(func);
 
kfree(func->info);
-
+   kfree(func->tmpbuf);
kfree(func);
 }
 
@@ -281,6 +281,16 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card)
if (!func)
return ERR_PTR(-ENOMEM);
 
+   /*
+* allocate buffer separately to make sure it's properly aligned for
+* DMA usage (incl. 64 bit DMA)
+*/
+   func->tmpbuf = kmalloc(4, GFP_KERNEL);
+   if (!func->tmpbuf) {
+   kfree(func);
+   return ERR_PTR(-ENOMEM);
+   }
+
func->card = card;
 
device_initialize(>dev);
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index aab032a6ae61..97ca105347a6 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -53,7 +53,7 @@ struct sdio_func {
unsigned intstate;  /* function state */
 #define SDIO_STATE_PRESENT (1<<0)  /* present in sysfs */
 
-   u8  tmpbuf[4];  /* DMA:able scratch buffer */
+   u8  *tmpbuf;/* DMA:able scratch buffer */
 
unsignednum_info;   /* number of info strings */
const char  **info; /* info strings */
-- 
2.11.0


[PATCH review for 4.4 18/47] IB/ipoib: Fix deadlock over vlan_mutex

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Feras Daoud 

[ Upstream commit 1c3098cdb05207e740715857df7b0998e372f527 ]

This patch fixes Deadlock while executing ipoib_vlan_delete.

The function takes the vlan_rwsem semaphore and calls
unregister_netdevice. The later function calls
ipoib_mcast_stop_thread that cause workqueue flush.

When the queue has one of the ipoib_ib_dev_flush_xxx events,
a deadlock occur because these events also tries to catch the
same vlan_rwsem semaphore.

To fix, unregister_netdevice should be called after releasing
the semaphore.

Fixes: cbbe1efa4972 ("IPoIB: Fix deadlock between ipoib_open() and child 
interface create")
Signed-off-by: Feras Daoud 
Signed-off-by: Erez Shitrit 
Reviewed-by: Alex Vesker 
Signed-off-by: Leon Romanovsky 
Signed-off-by: Doug Ledford 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 
b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 57a34f87dedf..3a647fd50f09 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -185,7 +185,6 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned 
short pkey)
list_for_each_entry_safe(priv, tpriv, >child_intfs, list) {
if (priv->pkey == pkey &&
priv->child_type == IPOIB_LEGACY_CHILD) {
-   unregister_netdevice(priv->dev);
list_del(>list);
dev = priv->dev;
break;
@@ -193,6 +192,11 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned 
short pkey)
}
up_write(>vlan_rwsem);
 
+   if (dev) {
+   ipoib_dbg(ppriv, "delete child vlan %s\n", dev->name);
+   unregister_netdevice(dev);
+   }
+
rtnl_unlock();
 
if (dev) {
-- 
2.11.0


[PATCH review for 4.4 18/47] IB/ipoib: Fix deadlock over vlan_mutex

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Feras Daoud 

[ Upstream commit 1c3098cdb05207e740715857df7b0998e372f527 ]

This patch fixes Deadlock while executing ipoib_vlan_delete.

The function takes the vlan_rwsem semaphore and calls
unregister_netdevice. The later function calls
ipoib_mcast_stop_thread that cause workqueue flush.

When the queue has one of the ipoib_ib_dev_flush_xxx events,
a deadlock occur because these events also tries to catch the
same vlan_rwsem semaphore.

To fix, unregister_netdevice should be called after releasing
the semaphore.

Fixes: cbbe1efa4972 ("IPoIB: Fix deadlock between ipoib_open() and child 
interface create")
Signed-off-by: Feras Daoud 
Signed-off-by: Erez Shitrit 
Reviewed-by: Alex Vesker 
Signed-off-by: Leon Romanovsky 
Signed-off-by: Doug Ledford 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c 
b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 57a34f87dedf..3a647fd50f09 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -185,7 +185,6 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned 
short pkey)
list_for_each_entry_safe(priv, tpriv, >child_intfs, list) {
if (priv->pkey == pkey &&
priv->child_type == IPOIB_LEGACY_CHILD) {
-   unregister_netdevice(priv->dev);
list_del(>list);
dev = priv->dev;
break;
@@ -193,6 +192,11 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned 
short pkey)
}
up_write(>vlan_rwsem);
 
+   if (dev) {
+   ipoib_dbg(ppriv, "delete child vlan %s\n", dev->name);
+   unregister_netdevice(dev);
+   }
+
rtnl_unlock();
 
if (dev) {
-- 
2.11.0


[PATCH review for 4.4 21/47] drm/amdkfd: fix improper return value on error

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Pan Bian 

[ Upstream commit 8bf793883da213864efc50c274d2b38ec0ca58b2 ]

In function kfd_wait_on_events(), when the call to copy_from_user()
fails, the value of return variable ret is 0. 0 indicates success, which
is inconsistent with the execution status. This patch fixes the bug by
assigning "-EFAULT" to ret when copy_from_user() returns an unexpected
value.

Signed-off-by: Pan Bian 
Signed-off-by: Oded Gabbay 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_events.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index b6e28dcaea1d..1fb1daa0b366 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -739,8 +739,10 @@ int kfd_wait_on_events(struct kfd_process *p,
struct kfd_event_data event_data;
 
if (copy_from_user(_data, [i],
-   sizeof(struct kfd_event_data)))
+   sizeof(struct kfd_event_data))) {
+   ret = -EFAULT;
goto fail;
+   }
 
ret = init_event_waiter(p, _waiters[i],
event_data.event_id, i);
-- 
2.11.0


[PATCH review for 4.4 21/47] drm/amdkfd: fix improper return value on error

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Pan Bian 

[ Upstream commit 8bf793883da213864efc50c274d2b38ec0ca58b2 ]

In function kfd_wait_on_events(), when the call to copy_from_user()
fails, the value of return variable ret is 0. 0 indicates success, which
is inconsistent with the execution status. This patch fixes the bug by
assigning "-EFAULT" to ret when copy_from_user() returns an unexpected
value.

Signed-off-by: Pan Bian 
Signed-off-by: Oded Gabbay 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_events.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index b6e28dcaea1d..1fb1daa0b366 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -739,8 +739,10 @@ int kfd_wait_on_events(struct kfd_process *p,
struct kfd_event_data event_data;
 
if (copy_from_user(_data, [i],
-   sizeof(struct kfd_event_data)))
+   sizeof(struct kfd_event_data))) {
+   ret = -EFAULT;
goto fail;
+   }
 
ret = init_event_waiter(p, _waiters[i],
event_data.event_id, i);
-- 
2.11.0


[PATCH review for 4.4 04/47] RDS: RDMA: Fix the composite message user notification

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Santosh Shilimkar 

[ Upstream commit 941f8d55f6d613a460a5e080d25a38509f45eb75 ]

When application sends an RDS RDMA composite message consist of
RDMA transfer to be followed up by non RDMA payload, it expect to
be notified *only* when the full message gets delivered. RDS RDMA
notification doesn't behave this way though.

Thanks to Venkat for debug and root casuing the issue
where only first part of the message(RDMA) was
successfully delivered but remainder payload delivery failed.
In that case, application should not be notified with
a false positive of message delivery success.

Fix this case by making sure the user gets notified only after
the full message delivery.

Reviewed-by: Venkat Venkatsubra 
Signed-off-by: Santosh Shilimkar 
Signed-off-by: Sasha Levin 
---
 net/rds/ib_send.c | 25 +++--
 net/rds/rdma.c| 10 ++
 net/rds/rds.h |  1 +
 net/rds/send.c|  4 +++-
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index eac30bf486d7..094e2a12860a 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -68,16 +68,6 @@ static void rds_ib_send_complete(struct rds_message *rm,
complete(rm, notify_status);
 }
 
-static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
-  struct rm_data_op *op,
-  int wc_status)
-{
-   if (op->op_nents)
-   ib_dma_unmap_sg(ic->i_cm_id->device,
-   op->op_sg, op->op_nents,
-   DMA_TO_DEVICE);
-}
-
 static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic,
   struct rm_rdma_op *op,
   int wc_status)
@@ -138,6 +128,21 @@ static void rds_ib_send_unmap_atomic(struct 
rds_ib_connection *ic,
rds_ib_stats_inc(s_ib_atomic_fadd);
 }
 
+static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
+  struct rm_data_op *op,
+  int wc_status)
+{
+   struct rds_message *rm = container_of(op, struct rds_message, data);
+
+   if (op->op_nents)
+   ib_dma_unmap_sg(ic->i_cm_id->device,
+   op->op_sg, op->op_nents,
+   DMA_TO_DEVICE);
+
+   if (rm->rdma.op_active && rm->data.op_notify)
+   rds_ib_send_unmap_rdma(ic, >rdma, wc_status);
+}
+
 /*
  * Unmap the resources associated with a struct send_work.
  *
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 4c93badeabf2..8d3a851a3476 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -626,6 +626,16 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct 
rds_message *rm,
}
op->op_notifier->n_user_token = args->user_token;
op->op_notifier->n_status = RDS_RDMA_SUCCESS;
+
+   /* Enable rmda notification on data operation for composite
+* rds messages and make sure notification is enabled only
+* for the data operation which follows it so that application
+* gets notified only after full message gets delivered.
+*/
+   if (rm->data.op_sg) {
+   rm->rdma.op_notify = 0;
+   rm->data.op_notify = !!(args->flags & 
RDS_RDMA_NOTIFY_ME);
+   }
}
 
/* The cookie contains the R_Key of the remote memory region, and
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 0e2797bdc316..4588860f4c3b 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -378,6 +378,7 @@ struct rds_message {
} rdma;
struct rm_data_op {
unsigned intop_active:1;
+   unsigned intop_notify:1;
unsigned intop_nents;
unsigned intop_count;
unsigned intop_dmasg;
diff --git a/net/rds/send.c b/net/rds/send.c
index c9cdb358ea88..6815f03324d7 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -467,12 +467,14 @@ void rds_rdma_send_complete(struct rds_message *rm, int 
status)
struct rm_rdma_op *ro;
struct rds_notifier *notifier;
unsigned long flags;
+   unsigned int notify = 0;
 
spin_lock_irqsave(>m_rs_lock, flags);
 
+   notify =  rm->rdma.op_notify | rm->data.op_notify;
ro = >rdma;
if (test_bit(RDS_MSG_ON_SOCK, >m_flags) &&
-   ro->op_active && ro->op_notify && ro->op_notifier) {
+   ro->op_active && notify && ro->op_notifier) {
notifier = ro->op_notifier;
rs = rm->m_rs;
sock_hold(rds_rs_to_sk(rs));
-- 
2.11.0


[PATCH review for 4.4 22/47] USB: serial: mos7720: fix control-message error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Johan Hovold 

[ Upstream commit 0d130367abf582e7cbf60075c2a7ab53817b1d14 ]

Make sure to log an error on short transfers when reading a device
register.

Also clear the provided buffer (which if often an uninitialised
automatic variable) on errors as the driver currently does not bother to
check for errors.

Reviewed-by: Greg Kroah-Hartman 
Signed-off-by: Johan Hovold 
Signed-off-by: Sasha Levin 
---
 drivers/usb/serial/mos7720.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index e56cdb436de3..4581fa1dec98 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -234,11 +234,16 @@ static int read_mos_reg(struct usb_serial *serial, 
unsigned int serial_portnum,
 
status = usb_control_msg(usbdev, pipe, request, requesttype, value,
 index, buf, 1, MOS_WDR_TIMEOUT);
-   if (status == 1)
+   if (status == 1) {
*data = *buf;
-   else if (status < 0)
+   } else {
dev_err(>dev,
"mos7720: usb_control_msg() failed: %d\n", status);
+   if (status >= 0)
+   status = -EIO;
+   *data = 0;
+   }
+
kfree(buf);
 
return status;
-- 
2.11.0


[PATCH review for 4.4 04/47] RDS: RDMA: Fix the composite message user notification

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Santosh Shilimkar 

[ Upstream commit 941f8d55f6d613a460a5e080d25a38509f45eb75 ]

When application sends an RDS RDMA composite message consist of
RDMA transfer to be followed up by non RDMA payload, it expect to
be notified *only* when the full message gets delivered. RDS RDMA
notification doesn't behave this way though.

Thanks to Venkat for debug and root casuing the issue
where only first part of the message(RDMA) was
successfully delivered but remainder payload delivery failed.
In that case, application should not be notified with
a false positive of message delivery success.

Fix this case by making sure the user gets notified only after
the full message delivery.

Reviewed-by: Venkat Venkatsubra 
Signed-off-by: Santosh Shilimkar 
Signed-off-by: Sasha Levin 
---
 net/rds/ib_send.c | 25 +++--
 net/rds/rdma.c| 10 ++
 net/rds/rds.h |  1 +
 net/rds/send.c|  4 +++-
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index eac30bf486d7..094e2a12860a 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -68,16 +68,6 @@ static void rds_ib_send_complete(struct rds_message *rm,
complete(rm, notify_status);
 }
 
-static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
-  struct rm_data_op *op,
-  int wc_status)
-{
-   if (op->op_nents)
-   ib_dma_unmap_sg(ic->i_cm_id->device,
-   op->op_sg, op->op_nents,
-   DMA_TO_DEVICE);
-}
-
 static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic,
   struct rm_rdma_op *op,
   int wc_status)
@@ -138,6 +128,21 @@ static void rds_ib_send_unmap_atomic(struct 
rds_ib_connection *ic,
rds_ib_stats_inc(s_ib_atomic_fadd);
 }
 
+static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
+  struct rm_data_op *op,
+  int wc_status)
+{
+   struct rds_message *rm = container_of(op, struct rds_message, data);
+
+   if (op->op_nents)
+   ib_dma_unmap_sg(ic->i_cm_id->device,
+   op->op_sg, op->op_nents,
+   DMA_TO_DEVICE);
+
+   if (rm->rdma.op_active && rm->data.op_notify)
+   rds_ib_send_unmap_rdma(ic, >rdma, wc_status);
+}
+
 /*
  * Unmap the resources associated with a struct send_work.
  *
diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index 4c93badeabf2..8d3a851a3476 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -626,6 +626,16 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct 
rds_message *rm,
}
op->op_notifier->n_user_token = args->user_token;
op->op_notifier->n_status = RDS_RDMA_SUCCESS;
+
+   /* Enable rmda notification on data operation for composite
+* rds messages and make sure notification is enabled only
+* for the data operation which follows it so that application
+* gets notified only after full message gets delivered.
+*/
+   if (rm->data.op_sg) {
+   rm->rdma.op_notify = 0;
+   rm->data.op_notify = !!(args->flags & 
RDS_RDMA_NOTIFY_ME);
+   }
}
 
/* The cookie contains the R_Key of the remote memory region, and
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 0e2797bdc316..4588860f4c3b 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -378,6 +378,7 @@ struct rds_message {
} rdma;
struct rm_data_op {
unsigned intop_active:1;
+   unsigned intop_notify:1;
unsigned intop_nents;
unsigned intop_count;
unsigned intop_dmasg;
diff --git a/net/rds/send.c b/net/rds/send.c
index c9cdb358ea88..6815f03324d7 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -467,12 +467,14 @@ void rds_rdma_send_complete(struct rds_message *rm, int 
status)
struct rm_rdma_op *ro;
struct rds_notifier *notifier;
unsigned long flags;
+   unsigned int notify = 0;
 
spin_lock_irqsave(>m_rs_lock, flags);
 
+   notify =  rm->rdma.op_notify | rm->data.op_notify;
ro = >rdma;
if (test_bit(RDS_MSG_ON_SOCK, >m_flags) &&
-   ro->op_active && ro->op_notify && ro->op_notifier) {
+   ro->op_active && notify && ro->op_notifier) {
notifier = ro->op_notifier;
rs = rm->m_rs;
sock_hold(rds_rs_to_sk(rs));
-- 
2.11.0


[PATCH review for 4.4 22/47] USB: serial: mos7720: fix control-message error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Johan Hovold 

[ Upstream commit 0d130367abf582e7cbf60075c2a7ab53817b1d14 ]

Make sure to log an error on short transfers when reading a device
register.

Also clear the provided buffer (which if often an uninitialised
automatic variable) on errors as the driver currently does not bother to
check for errors.

Reviewed-by: Greg Kroah-Hartman 
Signed-off-by: Johan Hovold 
Signed-off-by: Sasha Levin 
---
 drivers/usb/serial/mos7720.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index e56cdb436de3..4581fa1dec98 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -234,11 +234,16 @@ static int read_mos_reg(struct usb_serial *serial, 
unsigned int serial_portnum,
 
status = usb_control_msg(usbdev, pipe, request, requesttype, value,
 index, buf, 1, MOS_WDR_TIMEOUT);
-   if (status == 1)
+   if (status == 1) {
*data = *buf;
-   else if (status < 0)
+   } else {
dev_err(>dev,
"mos7720: usb_control_msg() failed: %d\n", status);
+   if (status >= 0)
+   status = -EIO;
+   *data = 0;
+   }
+
kfree(buf);
 
return status;
-- 
2.11.0


[PATCH review for 4.4 37/47] netfilter: invoke synchronize_rcu after set the _hook_ to NULL

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Liping Zhang 

[ Upstream commit 3b7dabf029478bb80507a6c4500ca94132a2bc0b ]

Otherwise, another CPU may access the invalid pointer. For example:
CPU0CPU1
 -  rcu_read_lock();
 -  pfunc = _hook_;
  _hook_ = NULL;  -
  mod unload  -
 - pfunc(); // invalid, panic
 - rcu_read_unlock();

So we must call synchronize_rcu() to wait the rcu reader to finish.

Also note, in nf_nat_snmp_basic_fini, synchronize_rcu() will be invoked
by later nf_conntrack_helper_unregister, but I'm inclined to add a
explicit synchronize_rcu after set the nf_nat_snmp_hook to NULL. Depend
on such obscure assumptions is not a good idea.

Last, in nfnetlink_cttimeout, we use kfree_rcu to free the time object,
so in cttimeout_exit, invoking rcu_barrier() is not necessary at all,
remove it too.

Signed-off-by: Liping Zhang 
Signed-off-by: Pablo Neira Ayuso 
Signed-off-by: Sasha Levin 
---
 net/ipv4/netfilter/nf_nat_snmp_basic.c | 1 +
 net/netfilter/nf_conntrack_ecache.c| 2 ++
 net/netfilter/nf_conntrack_netlink.c   | 1 +
 net/netfilter/nf_nat_core.c| 2 ++
 net/netfilter/nfnetlink_cttimeout.c| 2 +-
 5 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c 
b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index ddb894ac1458..2689c9c4f1a0 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1304,6 +1304,7 @@ static int __init nf_nat_snmp_basic_init(void)
 static void __exit nf_nat_snmp_basic_fini(void)
 {
RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
+   synchronize_rcu();
nf_conntrack_helper_unregister(_trap_helper);
 }
 
diff --git a/net/netfilter/nf_conntrack_ecache.c 
b/net/netfilter/nf_conntrack_ecache.c
index 4e78c57b818f..f3b92ce463b0 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -200,6 +200,7 @@ void nf_conntrack_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
mutex_unlock(_ct_ecache_mutex);
+   /* synchronize_rcu() is called from ctnetlink_exit. */
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
@@ -236,6 +237,7 @@ void nf_ct_expect_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
mutex_unlock(_ct_ecache_mutex);
+   /* synchronize_rcu() is called from ctnetlink_exit. */
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
 
diff --git a/net/netfilter/nf_conntrack_netlink.c 
b/net/netfilter/nf_conntrack_netlink.c
index e565b2becb14..660939df7c94 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3415,6 +3415,7 @@ static void __exit ctnetlink_exit(void)
 #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
RCU_INIT_POINTER(nfnl_ct_hook, NULL);
 #endif
+   synchronize_rcu();
 }
 
 module_init(ctnetlink_init);
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 06a9f45771ab..44516c90118a 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -892,6 +892,8 @@ static void __exit nf_nat_cleanup(void)
 #ifdef CONFIG_XFRM
RCU_INIT_POINTER(nf_nat_decode_session_hook, NULL);
 #endif
+   synchronize_rcu();
+
for (i = 0; i < NFPROTO_NUMPROTO; i++)
kfree(nf_nat_l4protos[i]);
synchronize_net();
diff --git a/net/netfilter/nfnetlink_cttimeout.c 
b/net/netfilter/nfnetlink_cttimeout.c
index c7a2d0e1c462..ed9153bd7e73 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -611,8 +611,8 @@ static void __exit cttimeout_exit(void)
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
+   synchronize_rcu();
 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
-   rcu_barrier();
 }
 
 module_init(cttimeout_init);
-- 
2.11.0


[PATCH review for 4.4 37/47] netfilter: invoke synchronize_rcu after set the _hook_ to NULL

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Liping Zhang 

[ Upstream commit 3b7dabf029478bb80507a6c4500ca94132a2bc0b ]

Otherwise, another CPU may access the invalid pointer. For example:
CPU0CPU1
 -  rcu_read_lock();
 -  pfunc = _hook_;
  _hook_ = NULL;  -
  mod unload  -
 - pfunc(); // invalid, panic
 - rcu_read_unlock();

So we must call synchronize_rcu() to wait the rcu reader to finish.

Also note, in nf_nat_snmp_basic_fini, synchronize_rcu() will be invoked
by later nf_conntrack_helper_unregister, but I'm inclined to add a
explicit synchronize_rcu after set the nf_nat_snmp_hook to NULL. Depend
on such obscure assumptions is not a good idea.

Last, in nfnetlink_cttimeout, we use kfree_rcu to free the time object,
so in cttimeout_exit, invoking rcu_barrier() is not necessary at all,
remove it too.

Signed-off-by: Liping Zhang 
Signed-off-by: Pablo Neira Ayuso 
Signed-off-by: Sasha Levin 
---
 net/ipv4/netfilter/nf_nat_snmp_basic.c | 1 +
 net/netfilter/nf_conntrack_ecache.c| 2 ++
 net/netfilter/nf_conntrack_netlink.c   | 1 +
 net/netfilter/nf_nat_core.c| 2 ++
 net/netfilter/nfnetlink_cttimeout.c| 2 +-
 5 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c 
b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index ddb894ac1458..2689c9c4f1a0 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1304,6 +1304,7 @@ static int __init nf_nat_snmp_basic_init(void)
 static void __exit nf_nat_snmp_basic_fini(void)
 {
RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
+   synchronize_rcu();
nf_conntrack_helper_unregister(_trap_helper);
 }
 
diff --git a/net/netfilter/nf_conntrack_ecache.c 
b/net/netfilter/nf_conntrack_ecache.c
index 4e78c57b818f..f3b92ce463b0 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -200,6 +200,7 @@ void nf_conntrack_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
mutex_unlock(_ct_ecache_mutex);
+   /* synchronize_rcu() is called from ctnetlink_exit. */
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
@@ -236,6 +237,7 @@ void nf_ct_expect_unregister_notifier(struct net *net,
BUG_ON(notify != new);
RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
mutex_unlock(_ct_ecache_mutex);
+   /* synchronize_rcu() is called from ctnetlink_exit. */
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
 
diff --git a/net/netfilter/nf_conntrack_netlink.c 
b/net/netfilter/nf_conntrack_netlink.c
index e565b2becb14..660939df7c94 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3415,6 +3415,7 @@ static void __exit ctnetlink_exit(void)
 #ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
RCU_INIT_POINTER(nfnl_ct_hook, NULL);
 #endif
+   synchronize_rcu();
 }
 
 module_init(ctnetlink_init);
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 06a9f45771ab..44516c90118a 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -892,6 +892,8 @@ static void __exit nf_nat_cleanup(void)
 #ifdef CONFIG_XFRM
RCU_INIT_POINTER(nf_nat_decode_session_hook, NULL);
 #endif
+   synchronize_rcu();
+
for (i = 0; i < NFPROTO_NUMPROTO; i++)
kfree(nf_nat_l4protos[i]);
synchronize_net();
diff --git a/net/netfilter/nfnetlink_cttimeout.c 
b/net/netfilter/nfnetlink_cttimeout.c
index c7a2d0e1c462..ed9153bd7e73 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -611,8 +611,8 @@ static void __exit cttimeout_exit(void)
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
+   synchronize_rcu();
 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
-   rcu_barrier();
 }
 
 module_init(cttimeout_init);
-- 
2.11.0


[PATCH review for 4.4 24/47] pinctrl: mvebu: Use seq_puts() in mvebu_pinconf_group_dbg_show()

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Markus Elfring 

[ Upstream commit 420dc61642920849d824a0de2aa853db59f5244f ]

Strings which did not contain data format specifications should be put
into a sequence. Thus use the corresponding function "seq_puts".

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 
Signed-off-by: Linus Walleij 
Signed-off-by: Sasha Levin 
---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c 
b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 77d2221d379d..076c2ee2ff70 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -195,11 +195,12 @@ static void mvebu_pinconf_group_dbg_show(struct 
pinctrl_dev *pctldev,
seq_printf(s, "o");
seq_printf(s, ")");
}
-   } else
-   seq_printf(s, "current: UNKNOWN");
+   } else {
+   seq_puts(s, "current: UNKNOWN");
+   }
 
if (grp->num_settings > 1) {
-   seq_printf(s, ", available = [");
+   seq_puts(s, ", available = [");
for (n = 0; n < grp->num_settings; n++) {
if (curr == >settings[n])
continue;
@@ -222,7 +223,7 @@ static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev 
*pctldev,
seq_printf(s, ")");
}
}
-   seq_printf(s, " ]");
+   seq_puts(s, " ]");
}
return;
 }
-- 
2.11.0


[PATCH review for 4.4 40/47] netfilter: nfnl_cthelper: fix incorrect helper->expect_class_max

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Liping Zhang 

[ Upstream commit ae5c682113f9f94cc5e76f92cf041ee624c173ee ]

The helper->expect_class_max must be set to the total number of
expect_policy minus 1, since we will use the statement "if (class >
helper->expect_class_max)" to validate the CTA_EXPECT_CLASS attr in
ctnetlink_alloc_expect.

So for compatibility, set the helper->expect_class_max to the
NFCTH_POLICY_SET_NUM attr's value minus 1.

Also: it's invalid when the NFCTH_POLICY_SET_NUM attr's value is zero.
1. this will result "expect_policy = kzalloc(0, GFP_KERNEL);";
2. we cannot set the helper->expect_class_max to a proper value.

So if nla_get_be32(tb[NFCTH_POLICY_SET_NUM]) is zero, report -EINVAL to
the userspace.

Signed-off-by: Liping Zhang 
Signed-off-by: Pablo Neira Ayuso 
Signed-off-by: Sasha Levin 
---
 net/netfilter/nfnetlink_cthelper.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/net/netfilter/nfnetlink_cthelper.c 
b/net/netfilter/nfnetlink_cthelper.c
index 54330fb5efaf..6d10002d23f8 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -161,6 +161,7 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
int i, ret;
struct nf_conntrack_expect_policy *expect_policy;
struct nlattr *tb[NFCTH_POLICY_SET_MAX+1];
+   unsigned int class_max;
 
ret = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
   nfnl_cthelper_expect_policy_set);
@@ -170,19 +171,18 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
if (!tb[NFCTH_POLICY_SET_NUM])
return -EINVAL;
 
-   helper->expect_class_max =
-   ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
-
-   if (helper->expect_class_max != 0 &&
-   helper->expect_class_max > NF_CT_MAX_EXPECT_CLASSES)
+   class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
+   if (class_max == 0)
+   return -EINVAL;
+   if (class_max > NF_CT_MAX_EXPECT_CLASSES)
return -EOVERFLOW;
 
expect_policy = kzalloc(sizeof(struct nf_conntrack_expect_policy) *
-   helper->expect_class_max, GFP_KERNEL);
+   class_max, GFP_KERNEL);
if (expect_policy == NULL)
return -ENOMEM;
 
-   for (i=0; iexpect_class_max; i++) {
+   for (i = 0; i < class_max; i++) {
if (!tb[NFCTH_POLICY_SET+i])
goto err;
 
@@ -191,6 +191,8 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
if (ret < 0)
goto err;
}
+
+   helper->expect_class_max = class_max - 1;
helper->expect_policy = expect_policy;
return 0;
 err:
@@ -377,10 +379,10 @@ nfnl_cthelper_dump_policy(struct sk_buff *skb,
goto nla_put_failure;
 
if (nla_put_be32(skb, NFCTH_POLICY_SET_NUM,
-htonl(helper->expect_class_max)))
+htonl(helper->expect_class_max + 1)))
goto nla_put_failure;
 
-   for (i=0; iexpect_class_max; i++) {
+   for (i = 0; i < helper->expect_class_max + 1; i++) {
nest_parms2 = nla_nest_start(skb,
(NFCTH_POLICY_SET+i) | NLA_F_NESTED);
if (nest_parms2 == NULL)
-- 
2.11.0


[PATCH review for 4.4 24/47] pinctrl: mvebu: Use seq_puts() in mvebu_pinconf_group_dbg_show()

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Markus Elfring 

[ Upstream commit 420dc61642920849d824a0de2aa853db59f5244f ]

Strings which did not contain data format specifications should be put
into a sequence. Thus use the corresponding function "seq_puts".

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring 
Signed-off-by: Linus Walleij 
Signed-off-by: Sasha Levin 
---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c 
b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
index 77d2221d379d..076c2ee2ff70 100644
--- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c
+++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c
@@ -195,11 +195,12 @@ static void mvebu_pinconf_group_dbg_show(struct 
pinctrl_dev *pctldev,
seq_printf(s, "o");
seq_printf(s, ")");
}
-   } else
-   seq_printf(s, "current: UNKNOWN");
+   } else {
+   seq_puts(s, "current: UNKNOWN");
+   }
 
if (grp->num_settings > 1) {
-   seq_printf(s, ", available = [");
+   seq_puts(s, ", available = [");
for (n = 0; n < grp->num_settings; n++) {
if (curr == >settings[n])
continue;
@@ -222,7 +223,7 @@ static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev 
*pctldev,
seq_printf(s, ")");
}
}
-   seq_printf(s, " ]");
+   seq_puts(s, " ]");
}
return;
 }
-- 
2.11.0


[PATCH review for 4.4 40/47] netfilter: nfnl_cthelper: fix incorrect helper->expect_class_max

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Liping Zhang 

[ Upstream commit ae5c682113f9f94cc5e76f92cf041ee624c173ee ]

The helper->expect_class_max must be set to the total number of
expect_policy minus 1, since we will use the statement "if (class >
helper->expect_class_max)" to validate the CTA_EXPECT_CLASS attr in
ctnetlink_alloc_expect.

So for compatibility, set the helper->expect_class_max to the
NFCTH_POLICY_SET_NUM attr's value minus 1.

Also: it's invalid when the NFCTH_POLICY_SET_NUM attr's value is zero.
1. this will result "expect_policy = kzalloc(0, GFP_KERNEL);";
2. we cannot set the helper->expect_class_max to a proper value.

So if nla_get_be32(tb[NFCTH_POLICY_SET_NUM]) is zero, report -EINVAL to
the userspace.

Signed-off-by: Liping Zhang 
Signed-off-by: Pablo Neira Ayuso 
Signed-off-by: Sasha Levin 
---
 net/netfilter/nfnetlink_cthelper.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/net/netfilter/nfnetlink_cthelper.c 
b/net/netfilter/nfnetlink_cthelper.c
index 54330fb5efaf..6d10002d23f8 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -161,6 +161,7 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
int i, ret;
struct nf_conntrack_expect_policy *expect_policy;
struct nlattr *tb[NFCTH_POLICY_SET_MAX+1];
+   unsigned int class_max;
 
ret = nla_parse_nested(tb, NFCTH_POLICY_SET_MAX, attr,
   nfnl_cthelper_expect_policy_set);
@@ -170,19 +171,18 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
if (!tb[NFCTH_POLICY_SET_NUM])
return -EINVAL;
 
-   helper->expect_class_max =
-   ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
-
-   if (helper->expect_class_max != 0 &&
-   helper->expect_class_max > NF_CT_MAX_EXPECT_CLASSES)
+   class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
+   if (class_max == 0)
+   return -EINVAL;
+   if (class_max > NF_CT_MAX_EXPECT_CLASSES)
return -EOVERFLOW;
 
expect_policy = kzalloc(sizeof(struct nf_conntrack_expect_policy) *
-   helper->expect_class_max, GFP_KERNEL);
+   class_max, GFP_KERNEL);
if (expect_policy == NULL)
return -ENOMEM;
 
-   for (i=0; iexpect_class_max; i++) {
+   for (i = 0; i < class_max; i++) {
if (!tb[NFCTH_POLICY_SET+i])
goto err;
 
@@ -191,6 +191,8 @@ nfnl_cthelper_parse_expect_policy(struct 
nf_conntrack_helper *helper,
if (ret < 0)
goto err;
}
+
+   helper->expect_class_max = class_max - 1;
helper->expect_policy = expect_policy;
return 0;
 err:
@@ -377,10 +379,10 @@ nfnl_cthelper_dump_policy(struct sk_buff *skb,
goto nla_put_failure;
 
if (nla_put_be32(skb, NFCTH_POLICY_SET_NUM,
-htonl(helper->expect_class_max)))
+htonl(helper->expect_class_max + 1)))
goto nla_put_failure;
 
-   for (i=0; iexpect_class_max; i++) {
+   for (i = 0; i < helper->expect_class_max + 1; i++) {
nest_parms2 = nla_nest_start(skb,
(NFCTH_POLICY_SET+i) | NLA_F_NESTED);
if (nest_parms2 == NULL)
-- 
2.11.0


[PATCH review for 4.4 23/47] USB: serial: mos7840: fix control-message error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Johan Hovold 

[ Upstream commit cd8db057e93ddaacbec025b567490555d2bca280 ]

Make sure to detect short transfers when reading a device register.

The modem-status handling had sufficient error checks in place, but move
handling of short transfers into the register accessor function itself
for consistency.

Reviewed-by: Greg Kroah-Hartman 
Signed-off-by: Johan Hovold 
Signed-off-by: Sasha Levin 
---
 drivers/usb/serial/mos7840.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index d17685cc00c9..ed883a7ad533 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -285,9 +285,15 @@ static int mos7840_get_reg_sync(struct usb_serial_port 
*port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
  MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
  MOS_WDR_TIMEOUT);
+   if (ret < VENDOR_READ_LENGTH) {
+   if (ret >= 0)
+   ret = -EIO;
+   goto out;
+   }
+
*val = buf[0];
dev_dbg(>dev, "%s offset is %x, return val %x\n", __func__, reg, 
*val);
-
+out:
kfree(buf);
return ret;
 }
@@ -353,8 +359,13 @@ static int mos7840_get_uart_reg(struct usb_serial_port 
*port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
  MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
  MOS_WDR_TIMEOUT);
+   if (ret < VENDOR_READ_LENGTH) {
+   if (ret >= 0)
+   ret = -EIO;
+   goto out;
+   }
*val = buf[0];
-
+out:
kfree(buf);
return ret;
 }
@@ -1490,10 +1501,10 @@ static int mos7840_tiocmget(struct tty_struct *tty)
return -ENODEV;
 
status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, );
-   if (status != 1)
+   if (status < 0)
return -EIO;
status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, );
-   if (status != 1)
+   if (status < 0)
return -EIO;
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
| ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
-- 
2.11.0


[PATCH review for 4.4 23/47] USB: serial: mos7840: fix control-message error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Johan Hovold 

[ Upstream commit cd8db057e93ddaacbec025b567490555d2bca280 ]

Make sure to detect short transfers when reading a device register.

The modem-status handling had sufficient error checks in place, but move
handling of short transfers into the register accessor function itself
for consistency.

Reviewed-by: Greg Kroah-Hartman 
Signed-off-by: Johan Hovold 
Signed-off-by: Sasha Levin 
---
 drivers/usb/serial/mos7840.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index d17685cc00c9..ed883a7ad533 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -285,9 +285,15 @@ static int mos7840_get_reg_sync(struct usb_serial_port 
*port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
  MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
  MOS_WDR_TIMEOUT);
+   if (ret < VENDOR_READ_LENGTH) {
+   if (ret >= 0)
+   ret = -EIO;
+   goto out;
+   }
+
*val = buf[0];
dev_dbg(>dev, "%s offset is %x, return val %x\n", __func__, reg, 
*val);
-
+out:
kfree(buf);
return ret;
 }
@@ -353,8 +359,13 @@ static int mos7840_get_uart_reg(struct usb_serial_port 
*port, __u16 reg,
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
  MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
  MOS_WDR_TIMEOUT);
+   if (ret < VENDOR_READ_LENGTH) {
+   if (ret >= 0)
+   ret = -EIO;
+   goto out;
+   }
*val = buf[0];
-
+out:
kfree(buf);
return ret;
 }
@@ -1490,10 +1501,10 @@ static int mos7840_tiocmget(struct tty_struct *tty)
return -ENODEV;
 
status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, );
-   if (status != 1)
+   if (status < 0)
return -EIO;
status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, );
-   if (status != 1)
+   if (status < 0)
return -EIO;
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
| ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
-- 
2.11.0


[PATCH review for 4.4 16/47] ARM: 8635/1: nommu: allow enabling REMAP_VECTORS_TO_RAM

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Afzal Mohammed 

[ Upstream commit 8a792e9afbce84a0fdaf213fe42bb97382487094 ]

REMAP_VECTORS_TO_RAM depends on DRAM_BASE, but since DRAM_BASE is a
hex, REMAP_VECTORS_TO_RAM could never get enabled. Also depending on
DRAM_BASE is redundant as whenever REMAP_VECTORS_TO_RAM makes itself
available to Kconfig, DRAM_BASE also is available as the Kconfig
gets sourced on !MMU.

Signed-off-by: Afzal Mohammed 
Reviewed-by: Vladimir Murzin 
Signed-off-by: Russell King 
Signed-off-by: Sasha Levin 
---
 arch/arm/Kconfig-nommu | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index aed66d5df7f1..b7576349528c 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -34,8 +34,7 @@ config PROCESSOR_ID
  used instead of the auto-probing which utilizes the register.
 
 config REMAP_VECTORS_TO_RAM
-   bool 'Install vectors to the beginning of RAM' if DRAM_BASE
-   depends on DRAM_BASE
+   bool 'Install vectors to the beginning of RAM'
help
  The kernel needs to change the hardware exception vectors.
  In nommu mode, the hardware exception vectors are normally
-- 
2.11.0


[PATCH review for 4.4 16/47] ARM: 8635/1: nommu: allow enabling REMAP_VECTORS_TO_RAM

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Afzal Mohammed 

[ Upstream commit 8a792e9afbce84a0fdaf213fe42bb97382487094 ]

REMAP_VECTORS_TO_RAM depends on DRAM_BASE, but since DRAM_BASE is a
hex, REMAP_VECTORS_TO_RAM could never get enabled. Also depending on
DRAM_BASE is redundant as whenever REMAP_VECTORS_TO_RAM makes itself
available to Kconfig, DRAM_BASE also is available as the Kconfig
gets sourced on !MMU.

Signed-off-by: Afzal Mohammed 
Reviewed-by: Vladimir Murzin 
Signed-off-by: Russell King 
Signed-off-by: Sasha Levin 
---
 arch/arm/Kconfig-nommu | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index aed66d5df7f1..b7576349528c 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -34,8 +34,7 @@ config PROCESSOR_ID
  used instead of the auto-probing which utilizes the register.
 
 config REMAP_VECTORS_TO_RAM
-   bool 'Install vectors to the beginning of RAM' if DRAM_BASE
-   depends on DRAM_BASE
+   bool 'Install vectors to the beginning of RAM'
help
  The kernel needs to change the hardware exception vectors.
  In nommu mode, the hardware exception vectors are normally
-- 
2.11.0


[PATCH review for 4.4 29/47] ASoC: dapm: fix some pointer error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Linus Walleij 

[ Upstream commit 639467c8f26d834c934215e8b59129ce442475fe ]

commit 66feeec9322132689d42723df2537d60f96f8e44
"RFC: ASoC: dapm: handle probe deferrals"
forgot a to update some two sites where the call
was used. The static codechecks quickly found them.

Reported-by: Dan Carpenter 
Fixes: 66feeec93221 ("RFC: ASoC: dapm: handle probe deferrals")
Signed-off-by: Linus Walleij 
Signed-off-by: Mark Brown 
Signed-off-by: Sasha Levin 
---
 sound/soc/soc-dapm.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index df036afb2197..6a438a361592 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3794,6 +3794,16 @@ int snd_soc_dapm_new_dai_widgets(struct 
snd_soc_dapm_context *dapm,
template.name);
 
w = snd_soc_dapm_new_control_unlocked(dapm, );
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   /* Do not nag about probe deferrals */
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create %s widget (%d)\n",
+   dai->driver->playback.stream_name, ret);
+   return ret;
+   }
if (!w) {
dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
dai->driver->playback.stream_name);
@@ -3813,6 +3823,16 @@ int snd_soc_dapm_new_dai_widgets(struct 
snd_soc_dapm_context *dapm,
template.name);
 
w = snd_soc_dapm_new_control_unlocked(dapm, );
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   /* Do not nag about probe deferrals */
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create %s widget (%d)\n",
+   dai->driver->playback.stream_name, ret);
+   return ret;
+   }
if (!w) {
dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
dai->driver->capture.stream_name);
-- 
2.11.0


[PATCH review for 4.4 26/47] ASoC: dapm: handle probe deferrals

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Linus Walleij 

[ Upstream commit 37e1df8c95e2c8a57c77eafc097648f6e40a60ff ]

This starts to handle probe deferrals on regulators and clocks
on the ASoC DAPM.

I came to this patch after audio stopped working on Ux500 ages
ago and I finally looked into it to see what is wrong. I had
messages like this in the console since a while back:

ab8500-codec.0: ASoC: Failed to request audioclk: -517
ab8500-codec.0: ASoC: Failed to create DAPM control audioclk
ab8500-codec.0: Failed to create new controls -12
snd-soc-mop500.0: ASoC: failed to instantiate card -12
snd-soc-mop500.0: Error: snd_soc_register_card failed (-12)!
snd-soc-mop500: probe of snd-soc-mop500.0 failed with error -12

Apparently because the widget table for the codec looks like
this (sound/soc/codecs/ab8500-codec.c):

static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {

/* Clocks */
SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),

/* Regulators */
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),

So when we call snd_soc_register_codec() and any of these widgets
get a deferred probe we do not get an -EPROBE_DEFER (-517) back as
we should and instead we just fail. Apparently the code assumes
that clocks and regulators must be available at this point and
not defer.

After this patch it rather looks like this:

ab8500-codec.0: Failed to create new controls -517
snd-soc-mop500.0: ASoC: failed to instantiate card -517
snd-soc-mop500.0: Error: snd_soc_register_card failed (-517)!
(...)
abx500-clk.0: registered clocks for ab850x
snd-soc-mop500.0: ab8500-codec-dai.0 <-> ux500-msp-i2s.1 mapping ok
snd-soc-mop500.0: ab8500-codec-dai.1 <-> ux500-msp-i2s.3 mapping ok

I'm pretty happy about the patch as it it, but I'm a bit
uncertain on how to proceed: there are a lot of users of the
external functions snd_soc_dapm_new_control() (111 sites)
and that will now return an occassional error pointer, which
is not handled in the calling sites.

I want an indication from the maintainers whether I should just
go in and augment all these call sites, or if deferred probe
is frowned upon when it leads to this much overhead.

Signed-off-by: Linus Walleij 
Signed-off-by: Mark Brown 
Signed-off-by: Sasha Levin 
---
 sound/soc/soc-dapm.c | 42 ++
 sound/soc/soc-topology.c |  9 +
 2 files changed, 51 insertions(+)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b8a256dfed7e..df036afb2197 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -358,6 +358,10 @@ static int dapm_kcontrol_data_alloc(struct 
snd_soc_dapm_widget *widget,
snd_soc_dapm_new_control_unlocked(widget->dapm,
);
kfree(name);
+   if (IS_ERR(data->widget)) {
+   ret = PTR_ERR(data->widget);
+   goto err_data;
+   }
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
@@ -392,6 +396,10 @@ static int dapm_kcontrol_data_alloc(struct 
snd_soc_dapm_widget *widget,
data->widget = snd_soc_dapm_new_control_unlocked(
widget->dapm, );
kfree(name);
+   if (IS_ERR(data->widget)) {
+   ret = PTR_ERR(data->widget);
+   goto err_data;
+   }
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
@@ -3278,11 +3286,22 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context 
*dapm,
 
mutex_lock_nested(>card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
w = snd_soc_dapm_new_control_unlocked(dapm, widget);
+   /* Do not nag about probe deferrals */
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create DAPM control %s (%d)\n",
+   widget->name, ret);
+   goto out_unlock;
+   }
if (!w)
dev_err(dapm->dev,
"ASoC: Failed to create DAPM control %s\n",
widget->name);
 
+out_unlock:
mutex_unlock(>card->dapm_mutex);
return w;
 }
@@ -3304,6 +3323,8 @@ snd_soc_dapm_new_control_unlocked(struct 
snd_soc_dapm_context *dapm,
w->regulator = devm_regulator_get(dapm->dev, w->name);
if (IS_ERR(w->regulator)) {
 

[PATCH review for 4.4 29/47] ASoC: dapm: fix some pointer error handling

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Linus Walleij 

[ Upstream commit 639467c8f26d834c934215e8b59129ce442475fe ]

commit 66feeec9322132689d42723df2537d60f96f8e44
"RFC: ASoC: dapm: handle probe deferrals"
forgot a to update some two sites where the call
was used. The static codechecks quickly found them.

Reported-by: Dan Carpenter 
Fixes: 66feeec93221 ("RFC: ASoC: dapm: handle probe deferrals")
Signed-off-by: Linus Walleij 
Signed-off-by: Mark Brown 
Signed-off-by: Sasha Levin 
---
 sound/soc/soc-dapm.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index df036afb2197..6a438a361592 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3794,6 +3794,16 @@ int snd_soc_dapm_new_dai_widgets(struct 
snd_soc_dapm_context *dapm,
template.name);
 
w = snd_soc_dapm_new_control_unlocked(dapm, );
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   /* Do not nag about probe deferrals */
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create %s widget (%d)\n",
+   dai->driver->playback.stream_name, ret);
+   return ret;
+   }
if (!w) {
dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
dai->driver->playback.stream_name);
@@ -3813,6 +3823,16 @@ int snd_soc_dapm_new_dai_widgets(struct 
snd_soc_dapm_context *dapm,
template.name);
 
w = snd_soc_dapm_new_control_unlocked(dapm, );
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   /* Do not nag about probe deferrals */
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create %s widget (%d)\n",
+   dai->driver->playback.stream_name, ret);
+   return ret;
+   }
if (!w) {
dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
dai->driver->capture.stream_name);
-- 
2.11.0


[PATCH review for 4.4 26/47] ASoC: dapm: handle probe deferrals

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Linus Walleij 

[ Upstream commit 37e1df8c95e2c8a57c77eafc097648f6e40a60ff ]

This starts to handle probe deferrals on regulators and clocks
on the ASoC DAPM.

I came to this patch after audio stopped working on Ux500 ages
ago and I finally looked into it to see what is wrong. I had
messages like this in the console since a while back:

ab8500-codec.0: ASoC: Failed to request audioclk: -517
ab8500-codec.0: ASoC: Failed to create DAPM control audioclk
ab8500-codec.0: Failed to create new controls -12
snd-soc-mop500.0: ASoC: failed to instantiate card -12
snd-soc-mop500.0: Error: snd_soc_register_card failed (-12)!
snd-soc-mop500: probe of snd-soc-mop500.0 failed with error -12

Apparently because the widget table for the codec looks like
this (sound/soc/codecs/ab8500-codec.c):

static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {

/* Clocks */
SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),

/* Regulators */
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),

So when we call snd_soc_register_codec() and any of these widgets
get a deferred probe we do not get an -EPROBE_DEFER (-517) back as
we should and instead we just fail. Apparently the code assumes
that clocks and regulators must be available at this point and
not defer.

After this patch it rather looks like this:

ab8500-codec.0: Failed to create new controls -517
snd-soc-mop500.0: ASoC: failed to instantiate card -517
snd-soc-mop500.0: Error: snd_soc_register_card failed (-517)!
(...)
abx500-clk.0: registered clocks for ab850x
snd-soc-mop500.0: ab8500-codec-dai.0 <-> ux500-msp-i2s.1 mapping ok
snd-soc-mop500.0: ab8500-codec-dai.1 <-> ux500-msp-i2s.3 mapping ok

I'm pretty happy about the patch as it it, but I'm a bit
uncertain on how to proceed: there are a lot of users of the
external functions snd_soc_dapm_new_control() (111 sites)
and that will now return an occassional error pointer, which
is not handled in the calling sites.

I want an indication from the maintainers whether I should just
go in and augment all these call sites, or if deferred probe
is frowned upon when it leads to this much overhead.

Signed-off-by: Linus Walleij 
Signed-off-by: Mark Brown 
Signed-off-by: Sasha Levin 
---
 sound/soc/soc-dapm.c | 42 ++
 sound/soc/soc-topology.c |  9 +
 2 files changed, 51 insertions(+)

diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b8a256dfed7e..df036afb2197 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -358,6 +358,10 @@ static int dapm_kcontrol_data_alloc(struct 
snd_soc_dapm_widget *widget,
snd_soc_dapm_new_control_unlocked(widget->dapm,
);
kfree(name);
+   if (IS_ERR(data->widget)) {
+   ret = PTR_ERR(data->widget);
+   goto err_data;
+   }
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
@@ -392,6 +396,10 @@ static int dapm_kcontrol_data_alloc(struct 
snd_soc_dapm_widget *widget,
data->widget = snd_soc_dapm_new_control_unlocked(
widget->dapm, );
kfree(name);
+   if (IS_ERR(data->widget)) {
+   ret = PTR_ERR(data->widget);
+   goto err_data;
+   }
if (!data->widget) {
ret = -ENOMEM;
goto err_data;
@@ -3278,11 +3286,22 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context 
*dapm,
 
mutex_lock_nested(>card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
w = snd_soc_dapm_new_control_unlocked(dapm, widget);
+   /* Do not nag about probe deferrals */
+   if (IS_ERR(w)) {
+   int ret = PTR_ERR(w);
+
+   if (ret != -EPROBE_DEFER)
+   dev_err(dapm->dev,
+   "ASoC: Failed to create DAPM control %s (%d)\n",
+   widget->name, ret);
+   goto out_unlock;
+   }
if (!w)
dev_err(dapm->dev,
"ASoC: Failed to create DAPM control %s\n",
widget->name);
 
+out_unlock:
mutex_unlock(>card->dapm_mutex);
return w;
 }
@@ -3304,6 +3323,8 @@ snd_soc_dapm_new_control_unlocked(struct 
snd_soc_dapm_context *dapm,
w->regulator = devm_regulator_get(dapm->dev, w->name);
if (IS_ERR(w->regulator)) {
ret = PTR_ERR(w->regulator);
+   if (ret == 

[PATCH review for 4.4 38/47] MIPS: IRQ Stack: Unwind IRQ stack onto task stack

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Matt Redfearn 

[ Upstream commit db8466c581cca1a08b505f1319c3ecd246f16fa8 ]

When the separate IRQ stack was introduced, stack unwinding only
proceeded as far as the top of the IRQ stack, leading to kernel
backtraces being less useful, lacking the trace of what was interrupted.

Fix this by providing a means for the kernel to unwind the IRQ stack
onto the interrupted task stack. The processor state is saved to the
kernel task stack on interrupt. The IRQ_STACK_START macro reserves an
unsigned long at the top of the IRQ stack where the interrupted task
stack pointer can be saved. After the active stack is switched to the
IRQ stack, save the interrupted tasks stack pointer to the reserved
location.

Fix the stack unwinding code to look for the frame being the top of the
IRQ stack and if so get the next frame from the saved location. The
existing test does not work with the separate stack since the ra is no
longer pointed at ret_from_{irq,exception}.

The test to stop unwinding the stack 32 bytes from the top of a stack
must be modified to allow unwinding to continue up to the location of
the saved task stack pointer when on the IRQ stack. The low / high marks
of the stack are set depending on whether the sp is on an irq stack or
not.

Signed-off-by: Matt Redfearn 
Cc: Paolo Bonzini 
Cc: Marcin Nowakowski 
Cc: Masanari Iida 
Cc: Chris Metcalf 
Cc: James Hogan 
Cc: Paul Burton 
Cc: Ingo Molnar 
Cc: Jason A. Donenfeld 
Cc: Andrew Morton 
Cc: linux-m...@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/15788/
Signed-off-by: Ralf Baechle 
Signed-off-by: Sasha Levin 
---
 arch/mips/include/asm/irq.h| 15 +++
 arch/mips/kernel/asm-offsets.c |  1 +
 arch/mips/kernel/genex.S   |  8 --
 arch/mips/kernel/process.c | 56 --
 4 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index ebb9efb02502..77edb22f855d 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -18,9 +18,24 @@
 #include 
 
 #define IRQ_STACK_SIZE THREAD_SIZE
+#define IRQ_STACK_START(IRQ_STACK_SIZE - 
sizeof(unsigned long))
 
 extern void *irq_stack[NR_CPUS];
 
+/*
+ * The highest address on the IRQ stack contains a dummy frame put down in
+ * genex.S (handle_int & except_vec_vi_handler) which is structured as follows:
+ *
+ *   top 
+ *   | task sp  | <- irq_stack[cpu] + IRQ_STACK_START
+ *   
+ *   |  | <- First frame of IRQ context
+ *   
+ *
+ * task sp holds a copy of the task stack pointer where the struct pt_regs
+ * from exception entry can be found.
+ */
+
 static inline bool on_irq_stack(int cpu, unsigned long sp)
 {
unsigned long low = (unsigned long)irq_stack[cpu];
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ec053ce7bb38..7ab8004c1659 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -102,6 +102,7 @@ void output_thread_info_defines(void)
DEFINE(_THREAD_SIZE, THREAD_SIZE);
DEFINE(_THREAD_MASK, THREAD_MASK);
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
+   DEFINE(_IRQ_STACK_START, IRQ_STACK_START);
BLANK();
 }
 
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 619e30e2c4f0..bb72f3ce7e29 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -216,9 +216,11 @@ NESTED(handle_int, PT_SIZE, sp)
beq t0, t1, 2f
 
/* Switch to IRQ stack */
-   li  t1, _IRQ_STACK_SIZE
+   li  t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1
 
+   /* Save task's sp on IRQ stack so that unwinding can follow it */
+   LONG_S  s1, 0(sp)
 2:
jal plat_irq_dispatch
 
@@ -326,9 +328,11 @@ NESTED(except_vec_vi_handler, 0, sp)
beq t0, t1, 2f
 
/* Switch to IRQ stack */
-   li  t1, _IRQ_STACK_SIZE
+   li  t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1
 
+   /* Save task's sp on IRQ stack so that unwinding can follow it */
+   LONG_S  s1, 0(sp)
 2:
jalrv0
 
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 8c26ecac930d..477ba026c3e5 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -483,31 +483,52 @@ unsigned long notrace unwind_stack_by_address(unsigned 
long stack_page,
  unsigned long pc,
  unsigned long *ra)
 {
+   unsigned long low, high, irq_stack_high;
struct 

[PATCH review for 4.4 38/47] MIPS: IRQ Stack: Unwind IRQ stack onto task stack

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Matt Redfearn 

[ Upstream commit db8466c581cca1a08b505f1319c3ecd246f16fa8 ]

When the separate IRQ stack was introduced, stack unwinding only
proceeded as far as the top of the IRQ stack, leading to kernel
backtraces being less useful, lacking the trace of what was interrupted.

Fix this by providing a means for the kernel to unwind the IRQ stack
onto the interrupted task stack. The processor state is saved to the
kernel task stack on interrupt. The IRQ_STACK_START macro reserves an
unsigned long at the top of the IRQ stack where the interrupted task
stack pointer can be saved. After the active stack is switched to the
IRQ stack, save the interrupted tasks stack pointer to the reserved
location.

Fix the stack unwinding code to look for the frame being the top of the
IRQ stack and if so get the next frame from the saved location. The
existing test does not work with the separate stack since the ra is no
longer pointed at ret_from_{irq,exception}.

The test to stop unwinding the stack 32 bytes from the top of a stack
must be modified to allow unwinding to continue up to the location of
the saved task stack pointer when on the IRQ stack. The low / high marks
of the stack are set depending on whether the sp is on an irq stack or
not.

Signed-off-by: Matt Redfearn 
Cc: Paolo Bonzini 
Cc: Marcin Nowakowski 
Cc: Masanari Iida 
Cc: Chris Metcalf 
Cc: James Hogan 
Cc: Paul Burton 
Cc: Ingo Molnar 
Cc: Jason A. Donenfeld 
Cc: Andrew Morton 
Cc: linux-m...@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/15788/
Signed-off-by: Ralf Baechle 
Signed-off-by: Sasha Levin 
---
 arch/mips/include/asm/irq.h| 15 +++
 arch/mips/kernel/asm-offsets.c |  1 +
 arch/mips/kernel/genex.S   |  8 --
 arch/mips/kernel/process.c | 56 --
 4 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index ebb9efb02502..77edb22f855d 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -18,9 +18,24 @@
 #include 
 
 #define IRQ_STACK_SIZE THREAD_SIZE
+#define IRQ_STACK_START(IRQ_STACK_SIZE - 
sizeof(unsigned long))
 
 extern void *irq_stack[NR_CPUS];
 
+/*
+ * The highest address on the IRQ stack contains a dummy frame put down in
+ * genex.S (handle_int & except_vec_vi_handler) which is structured as follows:
+ *
+ *   top 
+ *   | task sp  | <- irq_stack[cpu] + IRQ_STACK_START
+ *   
+ *   |  | <- First frame of IRQ context
+ *   
+ *
+ * task sp holds a copy of the task stack pointer where the struct pt_regs
+ * from exception entry can be found.
+ */
+
 static inline bool on_irq_stack(int cpu, unsigned long sp)
 {
unsigned long low = (unsigned long)irq_stack[cpu];
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ec053ce7bb38..7ab8004c1659 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -102,6 +102,7 @@ void output_thread_info_defines(void)
DEFINE(_THREAD_SIZE, THREAD_SIZE);
DEFINE(_THREAD_MASK, THREAD_MASK);
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
+   DEFINE(_IRQ_STACK_START, IRQ_STACK_START);
BLANK();
 }
 
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 619e30e2c4f0..bb72f3ce7e29 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -216,9 +216,11 @@ NESTED(handle_int, PT_SIZE, sp)
beq t0, t1, 2f
 
/* Switch to IRQ stack */
-   li  t1, _IRQ_STACK_SIZE
+   li  t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1
 
+   /* Save task's sp on IRQ stack so that unwinding can follow it */
+   LONG_S  s1, 0(sp)
 2:
jal plat_irq_dispatch
 
@@ -326,9 +328,11 @@ NESTED(except_vec_vi_handler, 0, sp)
beq t0, t1, 2f
 
/* Switch to IRQ stack */
-   li  t1, _IRQ_STACK_SIZE
+   li  t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1
 
+   /* Save task's sp on IRQ stack so that unwinding can follow it */
+   LONG_S  s1, 0(sp)
 2:
jalrv0
 
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 8c26ecac930d..477ba026c3e5 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -483,31 +483,52 @@ unsigned long notrace unwind_stack_by_address(unsigned 
long stack_page,
  unsigned long pc,
  unsigned long *ra)
 {
+   unsigned long low, high, irq_stack_high;
struct mips_frame_info info;
unsigned long size, ofs;
+   struct pt_regs *regs;
int leaf;
-   extern void ret_from_irq(void);
-   extern void ret_from_exception(void);
 
if (!stack_page)
return 0;
 
/*
-* If we reached the bottom of interrupt 

[PATCH review for 4.4 33/47] team: fix memory leaks

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Pan Bian 

[ Upstream commit 72ec0bc64b9a5d8e0efcb717abfc757746b101b7 ]

In functions team_nl_send_port_list_get() and
team_nl_send_options_get(), pointer skb keeps the return value of
nlmsg_new(). When the call to genlmsg_put() fails, the memory is not
freed(). This will result in memory leak bugs.

Fixes: 9b00cf2d1024 ("team: implement multipart netlink messages for options 
transfers")
Signed-off-by: Pan Bian 
Acked-by: Jiri Pirko 
Signed-off-by: David S. Miller 
Signed-off-by: Sasha Levin 
---
 drivers/net/team/team.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index a5f392ae30d5..61cd53838360 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2343,8 +2343,10 @@ start_again:
 
hdr = genlmsg_put(skb, portid, seq, _nl_family, flags | 
NLM_F_MULTI,
  TEAM_CMD_OPTIONS_GET);
-   if (!hdr)
+   if (!hdr) {
+   nlmsg_free(skb);
return -EMSGSIZE;
+   }
 
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
@@ -2611,8 +2613,10 @@ start_again:
 
hdr = genlmsg_put(skb, portid, seq, _nl_family, flags | 
NLM_F_MULTI,
  TEAM_CMD_PORT_LIST_GET);
-   if (!hdr)
+   if (!hdr) {
+   nlmsg_free(skb);
return -EMSGSIZE;
+   }
 
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
-- 
2.11.0


[PATCH review for 4.4 33/47] team: fix memory leaks

2017-09-19 Thread Levin, Alexander (Sasha Levin)
From: Pan Bian 

[ Upstream commit 72ec0bc64b9a5d8e0efcb717abfc757746b101b7 ]

In functions team_nl_send_port_list_get() and
team_nl_send_options_get(), pointer skb keeps the return value of
nlmsg_new(). When the call to genlmsg_put() fails, the memory is not
freed(). This will result in memory leak bugs.

Fixes: 9b00cf2d1024 ("team: implement multipart netlink messages for options 
transfers")
Signed-off-by: Pan Bian 
Acked-by: Jiri Pirko 
Signed-off-by: David S. Miller 
Signed-off-by: Sasha Levin 
---
 drivers/net/team/team.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index a5f392ae30d5..61cd53838360 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2343,8 +2343,10 @@ start_again:
 
hdr = genlmsg_put(skb, portid, seq, _nl_family, flags | 
NLM_F_MULTI,
  TEAM_CMD_OPTIONS_GET);
-   if (!hdr)
+   if (!hdr) {
+   nlmsg_free(skb);
return -EMSGSIZE;
+   }
 
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
@@ -2611,8 +2613,10 @@ start_again:
 
hdr = genlmsg_put(skb, portid, seq, _nl_family, flags | 
NLM_F_MULTI,
  TEAM_CMD_PORT_LIST_GET);
-   if (!hdr)
+   if (!hdr) {
+   nlmsg_free(skb);
return -EMSGSIZE;
+   }
 
if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
goto nla_put_failure;
-- 
2.11.0


  1   2   3   4   5   6   7   8   9   10   >