Re: [PATCH v1] DMA:omap-dma:Avoid build error by changing the function name

2017-12-17 Thread Peter Ujfalusi


On 2017-12-18 07:29, Vinod Koul wrote:
> On Tue, Dec 12, 2017 at 12:58:41PM +0530, venkat.prashanth2...@gmail.com 
> wrote:
>> From: Venkat Prashanth B U 
>>
>> Change the name of the function omap_dma_filter_fn to avoid
>> the following build error in linux kernel version 4.4 :
>>
>> drivers/dma/dma-omap.c:1273:6: error:
>> redefinition of 'omap_dma_filter_fn'

What is your config regarding to omap_dma?

in the include/linux/omap-dmaengine.h :

#if defined(CONFIG_DMA_OMAP) || (defined(CONFIG_DMA_OMAP_MODULE) &&
defined(MODULE))
bool omap_dma_filter_fn(struct dma_chan *, void *);
#else
static inline bool omap_dma_filter_fn(struct dma_chan *c, void *d)
{
return false;
}
#endif

DMA_OMAP enables the build of drivers/dma/omap-dma.c

> 
> Okay I do not see this error, which tree are you running?

I have not seen this either, and looking at the code I don't think it is
possible. Not with what we have upstream.

> In code is see omap_dma_filter_fn is used everywhere and no reference to
> omap_dma_filter_func
> 
> Adding peter too..
> 
> 
>>
>> Signed-off-by: Venkat Prashanth B U 
>> Changes for v1:
>> - Edited subject and description of the patch to fit with the change
>>   done in the code base, as suggested by Vinod Koul.
>>
>> - In order to avoid  issues like backporting on stable the
>>   checkpatch.pl issues are dropped as suggested by Vinod Koul.
>> ---
>>  drivers/dma/omap-dma.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
>> index 1dfc71c..8545dda 100644
>> --- a/drivers/dma/omap-dma.c
>> +++ b/drivers/dma/omap-dma.c
>> @@ -1269,7 +1269,7 @@ static struct platform_driver omap_dma_driver = {
>>  },
>>  };
>>  
>> -bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
>> +bool omap_dma_filter_func(struct dma_chan *chan, void *param)

this certainly breaks the omap_dma driver on non DT booted systems.

>>  {
>>  if (chan->device->dev->driver == _dma_driver.driver) {
>>  struct omap_dmadev *od = to_omap_dma_dev(chan->device);
>> -- 
>> 1.9.1
>> --
>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH v1] DMA:omap-dma:Avoid build error by changing the function name

2017-12-17 Thread Peter Ujfalusi


On 2017-12-18 07:29, Vinod Koul wrote:
> On Tue, Dec 12, 2017 at 12:58:41PM +0530, venkat.prashanth2...@gmail.com 
> wrote:
>> From: Venkat Prashanth B U 
>>
>> Change the name of the function omap_dma_filter_fn to avoid
>> the following build error in linux kernel version 4.4 :
>>
>> drivers/dma/dma-omap.c:1273:6: error:
>> redefinition of 'omap_dma_filter_fn'

What is your config regarding to omap_dma?

in the include/linux/omap-dmaengine.h :

#if defined(CONFIG_DMA_OMAP) || (defined(CONFIG_DMA_OMAP_MODULE) &&
defined(MODULE))
bool omap_dma_filter_fn(struct dma_chan *, void *);
#else
static inline bool omap_dma_filter_fn(struct dma_chan *c, void *d)
{
return false;
}
#endif

DMA_OMAP enables the build of drivers/dma/omap-dma.c

> 
> Okay I do not see this error, which tree are you running?

I have not seen this either, and looking at the code I don't think it is
possible. Not with what we have upstream.

> In code is see omap_dma_filter_fn is used everywhere and no reference to
> omap_dma_filter_func
> 
> Adding peter too..
> 
> 
>>
>> Signed-off-by: Venkat Prashanth B U 
>> Changes for v1:
>> - Edited subject and description of the patch to fit with the change
>>   done in the code base, as suggested by Vinod Koul.
>>
>> - In order to avoid  issues like backporting on stable the
>>   checkpatch.pl issues are dropped as suggested by Vinod Koul.
>> ---
>>  drivers/dma/omap-dma.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
>> index 1dfc71c..8545dda 100644
>> --- a/drivers/dma/omap-dma.c
>> +++ b/drivers/dma/omap-dma.c
>> @@ -1269,7 +1269,7 @@ static struct platform_driver omap_dma_driver = {
>>  },
>>  };
>>  
>> -bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
>> +bool omap_dma_filter_func(struct dma_chan *chan, void *param)

this certainly breaks the omap_dma driver on non DT booted systems.

>>  {
>>  if (chan->device->dev->driver == _dma_driver.driver) {
>>  struct omap_dmadev *od = to_omap_dma_dev(chan->device);
>> -- 
>> 1.9.1
>> --
>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH 4/5] arm: dts: sun8i: a83t: Add support for the ir interface

2017-12-17 Thread Maxime Ripard
On Sun, Dec 17, 2017 at 11:45:46PM +0100, Philipp Rossak wrote:
> The ir interface is like on the H3 located at 0x01f02000 and is exactly
> the same. This patch adds support for the ir interface on the A83T.
> 
> Signed-off-by: Philipp Rossak 
> ---
>  arch/arm/boot/dts/sun8i-a83t.dtsi | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
> b/arch/arm/boot/dts/sun8i-a83t.dtsi
> index 954c2393325f..9e7ed3b9a6b8 100644
> --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
> @@ -503,6 +503,16 @@
>   #reset-cells = <1>;
>   };
>  
> + ir: ir@01f02000 {
> + compatible = "allwinner,sun5i-a13-ir";
> + clocks = <_ccu CLK_APB0_IR>, <_ccu CLK_IR>;
> + clock-names = "apb", "ir";
> + resets = <_ccu RST_APB0_IR>;
> + interrupts = ;
> + reg = <0x01f02000 0x40>;

The size should be the size of the whole memory block, not just the
registers you need.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH 4/5] arm: dts: sun8i: a83t: Add support for the ir interface

2017-12-17 Thread Maxime Ripard
On Sun, Dec 17, 2017 at 11:45:46PM +0100, Philipp Rossak wrote:
> The ir interface is like on the H3 located at 0x01f02000 and is exactly
> the same. This patch adds support for the ir interface on the A83T.
> 
> Signed-off-by: Philipp Rossak 
> ---
>  arch/arm/boot/dts/sun8i-a83t.dtsi | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
> b/arch/arm/boot/dts/sun8i-a83t.dtsi
> index 954c2393325f..9e7ed3b9a6b8 100644
> --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
> @@ -503,6 +503,16 @@
>   #reset-cells = <1>;
>   };
>  
> + ir: ir@01f02000 {
> + compatible = "allwinner,sun5i-a13-ir";
> + clocks = <_ccu CLK_APB0_IR>, <_ccu CLK_IR>;
> + clock-names = "apb", "ir";
> + resets = <_ccu RST_APB0_IR>;
> + interrupts = ;
> + reg = <0x01f02000 0x40>;

The size should be the size of the whole memory block, not just the
registers you need.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: block: oopses on 4.13.*, 4.14.* and 4.15-rc2 (bisected)

2017-12-17 Thread Ming Lei
On Sat, Dec 9, 2017 at 7:27 AM, Michele Ballabio
 wrote:
> On Fri, 8 Dec 2017 13:08:37 -0700
> Jens Axboe  wrote:
>
>> On 12/08/2017 08:38 AM, Michele Ballabio wrote:
>> > Hi,
>> > kernels 4.13.*, 4.14.* 4.15-rc2 crash on occasion,
>> > especially on x86-32 systems. To trigger the problem, run as root:
>> >
>> > while true
>> > do
>> > /sbin/udevadm trigger --type=subsystems --action=change
>> > /sbin/udevadm trigger --type=devices --action=change
>> > /sbin/udevadm settle --timeout=120
>> > done
>> >
>> > (Thanks to Patrick Volkerding for the reproducer).
>> >
>> > Sometimes the kernel oopses immediately, sometimes a bit later
>> > (less than five minutes).
>> >
>> > The bisection pointed to commit
>> > caa4b02476e31fc7933d2138062f7f355d3cd8f7 (blk-map: call
>> > blk_queue_bounce from blk_rq_append_bio). A revert fixes the
>> > problem (tested on 4.13 and master).
>>
>> Thanks for your report - can you try the below patch? Totally
>> untested...
>
> I applied the patch on master
> (968edbd93c0cbb40ab48aca972392d377713a0c3), I tried two times to boot
> the system but couldn't get to the shell. I found this in the log:

Hi Michele,

Please test the patches I sent out and see if it fixes your issue. In
my environment
the two just works fine.

https://marc.info/?l=linux-block=151358285916762=2

-- 
Ming Lei


Re: [PATCH 2/5] media: dt: bindings: Update binding documentation for sunxi IR controller

2017-12-17 Thread Maxime Ripard
Hi,

On Sun, Dec 17, 2017 at 11:45:44PM +0100, Philipp Rossak wrote:
> This patch updates documentation for Device-Tree bindings for sunxi IR
> controller and adds the new optional property for the base clock
> frequency.
> 
> Signed-off-by: Philipp Rossak 
> ---
>  Documentation/devicetree/bindings/media/sunxi-ir.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt 
> b/Documentation/devicetree/bindings/media/sunxi-ir.txt
> index 91648c569b1e..9f45bab07d6e 100644
> --- a/Documentation/devicetree/bindings/media/sunxi-ir.txt
> +++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt
> @@ -11,6 +11,7 @@ Required properties:
>  Optional properties:
>  - linux,rc-map-name: see rc.txt file in the same directory.
>  - resets : phandle + reset specifier pair
> +- clock-frequency  : overrides the default base clock frequency (8 MHz)

You're at least missing the unit one needs to use, but something like:
IR Receiver clock frequency, in Hertz. Defaults to 8MHz if missing.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: block: oopses on 4.13.*, 4.14.* and 4.15-rc2 (bisected)

2017-12-17 Thread Ming Lei
On Sat, Dec 9, 2017 at 7:27 AM, Michele Ballabio
 wrote:
> On Fri, 8 Dec 2017 13:08:37 -0700
> Jens Axboe  wrote:
>
>> On 12/08/2017 08:38 AM, Michele Ballabio wrote:
>> > Hi,
>> > kernels 4.13.*, 4.14.* 4.15-rc2 crash on occasion,
>> > especially on x86-32 systems. To trigger the problem, run as root:
>> >
>> > while true
>> > do
>> > /sbin/udevadm trigger --type=subsystems --action=change
>> > /sbin/udevadm trigger --type=devices --action=change
>> > /sbin/udevadm settle --timeout=120
>> > done
>> >
>> > (Thanks to Patrick Volkerding for the reproducer).
>> >
>> > Sometimes the kernel oopses immediately, sometimes a bit later
>> > (less than five minutes).
>> >
>> > The bisection pointed to commit
>> > caa4b02476e31fc7933d2138062f7f355d3cd8f7 (blk-map: call
>> > blk_queue_bounce from blk_rq_append_bio). A revert fixes the
>> > problem (tested on 4.13 and master).
>>
>> Thanks for your report - can you try the below patch? Totally
>> untested...
>
> I applied the patch on master
> (968edbd93c0cbb40ab48aca972392d377713a0c3), I tried two times to boot
> the system but couldn't get to the shell. I found this in the log:

Hi Michele,

Please test the patches I sent out and see if it fixes your issue. In
my environment
the two just works fine.

https://marc.info/?l=linux-block=151358285916762=2

-- 
Ming Lei


Re: [PATCH 2/5] media: dt: bindings: Update binding documentation for sunxi IR controller

2017-12-17 Thread Maxime Ripard
Hi,

On Sun, Dec 17, 2017 at 11:45:44PM +0100, Philipp Rossak wrote:
> This patch updates documentation for Device-Tree bindings for sunxi IR
> controller and adds the new optional property for the base clock
> frequency.
> 
> Signed-off-by: Philipp Rossak 
> ---
>  Documentation/devicetree/bindings/media/sunxi-ir.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt 
> b/Documentation/devicetree/bindings/media/sunxi-ir.txt
> index 91648c569b1e..9f45bab07d6e 100644
> --- a/Documentation/devicetree/bindings/media/sunxi-ir.txt
> +++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt
> @@ -11,6 +11,7 @@ Required properties:
>  Optional properties:
>  - linux,rc-map-name: see rc.txt file in the same directory.
>  - resets : phandle + reset specifier pair
> +- clock-frequency  : overrides the default base clock frequency (8 MHz)

You're at least missing the unit one needs to use, but something like:
IR Receiver clock frequency, in Hertz. Defaults to 8MHz if missing.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


signature.asc
Description: PGP signature


Re: [PATCH -V3 -mm] mm, swap: Fix race between swapoff and some swap operations

2017-12-17 Thread Huang, Ying
"Huang, Ying"  writes:

> From: Huang Ying 
>
> When the swapin is performed, after getting the swap entry information
> from the page table, system will swap in the swap entry, without any
> lock held to prevent the swap device from being swapoff.  This may
> cause the race like below,
>
> CPU 1 CPU 2
> - -
>   do_swap_page
> swapin_readahead
>   __read_swap_cache_async
> swapoff swapcache_prepare
>   p->swap_map = NULL  __swap_duplicate
> p->swap_map[?] /* !!! NULL pointer 
> access */
>
> Because swapoff is usually done when system shutdown only, the race
> may not hit many people in practice.  But it is still a race need to
> be fixed.
>
> To fix the race, get_swap_device() is added to check whether the
> specified swap entry is valid in its swap device.  If so, it will keep
> the swap entry valid via preventing the swap device from being
> swapoff, until put_swap_device() is called.
>
> Because swapoff() is very race code path, to make the normal path runs
> as fast as possible, RCU instead of reference count is used to
> implement get/put_swap_device().  From get_swap_device() to
> put_swap_device(), the RCU read lock is held, so synchronize_rcu() in
> swapoff() will wait until put_swap_device() is called.
>
> In addition to swap_map, cluster_info, etc. data structure in the
> struct swap_info_struct, the swap cache radix tree will be freed after
> swapoff, so this patch fixes the race between swap cache looking up
> and swapoff too.
>
> Cc: Hugh Dickins 
> Cc: Paul E. McKenney 
> Cc: Minchan Kim 
> Cc: Johannes Weiner 
> Cc: Tim Chen 
> Cc: Shaohua Li 
> Cc: Mel Gorman 
> Cc: "Jérôme Glisse" 
> Cc: Michal Hocko 
> Cc: Andrea Arcangeli 
> Cc: David Rientjes 
> Cc: Rik van Riel 
> Cc: Jan Kara 
> Cc: Dave Jiang 
> Cc: Aaron Lu 
> Signed-off-by: "Huang, Ying" 
>
> Changelog:
>
> v3:
>
> - Re-implemented with RCU to reduce the overhead of normal paths
>
> v2:
>
> - Re-implemented with SRCU to reduce the overhead of normal paths.
>
> - Avoid to check whether the swap device has been swapoff in
>   get_swap_device().  Because we can check the origin of the swap
>   entry to make sure the swap device hasn't bee swapoff.

A version implemented via stop_machine() could be gotten via a small
patch as below.  If you still prefer stop_machine(), I can resend a
version implemented with stop_machine().

And, it appears that if we replace smp_wmb() in _enable_swap_info() with
stop_machine() in some way, we can avoid smp_rmb() in get_swap_device().
This can reduce overhead in normal path further.  Can we get same effect
with RCU?  For example, use synchronize_rcu() instead of stop_machine()?

Hi, Paul, can you help me on this?

Best Regards,
Huang, Ying

8<--
---
 include/linux/swap.h |  2 +-
 mm/swapfile.c| 12 +---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index f7e8f26cf07f..1027169d5a04 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -475,7 +475,7 @@ extern struct swap_info_struct *get_swap_device(swp_entry_t 
entry);
 
 static inline void put_swap_device(struct swap_info_struct *si)
 {
-   rcu_read_unlock();
+   preempt_enable();
 }
 
 #else /* CONFIG_SWAP */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index ca7b4c5ebe34..feb13ce01045 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1125,7 +1126,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t 
entry)
goto bad_nofile;
si = swap_info[type];
 
-   rcu_read_lock();
+   preempt_disable();
if (!(si->flags & SWP_VALID))
goto unlock_out;
/*
@@ -1143,7 +1144,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t 
entry)
 out:
return NULL;
 unlock_out:
-   rcu_read_unlock();
+   preempt_enable();
return NULL;
 }
 
@@ -2581,6 +2582,11 @@ bool has_usable_swap(void)
return ret;
 }
 
+static int swapoff_stop(void *arg)
+{
+   return 0;
+}
+
 SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 {
struct swap_info_struct *p = NULL;
@@ -2677,7 +2683,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 * wait for swap operations protected by get/put_swap_device()
 * to complete
 */

Re: [PATCH -V3 -mm] mm, swap: Fix race between swapoff and some swap operations

2017-12-17 Thread Huang, Ying
"Huang, Ying"  writes:

> From: Huang Ying 
>
> When the swapin is performed, after getting the swap entry information
> from the page table, system will swap in the swap entry, without any
> lock held to prevent the swap device from being swapoff.  This may
> cause the race like below,
>
> CPU 1 CPU 2
> - -
>   do_swap_page
> swapin_readahead
>   __read_swap_cache_async
> swapoff swapcache_prepare
>   p->swap_map = NULL  __swap_duplicate
> p->swap_map[?] /* !!! NULL pointer 
> access */
>
> Because swapoff is usually done when system shutdown only, the race
> may not hit many people in practice.  But it is still a race need to
> be fixed.
>
> To fix the race, get_swap_device() is added to check whether the
> specified swap entry is valid in its swap device.  If so, it will keep
> the swap entry valid via preventing the swap device from being
> swapoff, until put_swap_device() is called.
>
> Because swapoff() is very race code path, to make the normal path runs
> as fast as possible, RCU instead of reference count is used to
> implement get/put_swap_device().  From get_swap_device() to
> put_swap_device(), the RCU read lock is held, so synchronize_rcu() in
> swapoff() will wait until put_swap_device() is called.
>
> In addition to swap_map, cluster_info, etc. data structure in the
> struct swap_info_struct, the swap cache radix tree will be freed after
> swapoff, so this patch fixes the race between swap cache looking up
> and swapoff too.
>
> Cc: Hugh Dickins 
> Cc: Paul E. McKenney 
> Cc: Minchan Kim 
> Cc: Johannes Weiner 
> Cc: Tim Chen 
> Cc: Shaohua Li 
> Cc: Mel Gorman 
> Cc: "Jérôme Glisse" 
> Cc: Michal Hocko 
> Cc: Andrea Arcangeli 
> Cc: David Rientjes 
> Cc: Rik van Riel 
> Cc: Jan Kara 
> Cc: Dave Jiang 
> Cc: Aaron Lu 
> Signed-off-by: "Huang, Ying" 
>
> Changelog:
>
> v3:
>
> - Re-implemented with RCU to reduce the overhead of normal paths
>
> v2:
>
> - Re-implemented with SRCU to reduce the overhead of normal paths.
>
> - Avoid to check whether the swap device has been swapoff in
>   get_swap_device().  Because we can check the origin of the swap
>   entry to make sure the swap device hasn't bee swapoff.

A version implemented via stop_machine() could be gotten via a small
patch as below.  If you still prefer stop_machine(), I can resend a
version implemented with stop_machine().

And, it appears that if we replace smp_wmb() in _enable_swap_info() with
stop_machine() in some way, we can avoid smp_rmb() in get_swap_device().
This can reduce overhead in normal path further.  Can we get same effect
with RCU?  For example, use synchronize_rcu() instead of stop_machine()?

Hi, Paul, can you help me on this?

Best Regards,
Huang, Ying

8<--
---
 include/linux/swap.h |  2 +-
 mm/swapfile.c| 12 +---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index f7e8f26cf07f..1027169d5a04 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -475,7 +475,7 @@ extern struct swap_info_struct *get_swap_device(swp_entry_t 
entry);
 
 static inline void put_swap_device(struct swap_info_struct *si)
 {
-   rcu_read_unlock();
+   preempt_enable();
 }
 
 #else /* CONFIG_SWAP */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index ca7b4c5ebe34..feb13ce01045 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1125,7 +1126,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t 
entry)
goto bad_nofile;
si = swap_info[type];
 
-   rcu_read_lock();
+   preempt_disable();
if (!(si->flags & SWP_VALID))
goto unlock_out;
/*
@@ -1143,7 +1144,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t 
entry)
 out:
return NULL;
 unlock_out:
-   rcu_read_unlock();
+   preempt_enable();
return NULL;
 }
 
@@ -2581,6 +2582,11 @@ bool has_usable_swap(void)
return ret;
 }
 
+static int swapoff_stop(void *arg)
+{
+   return 0;
+}
+
 SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 {
struct swap_info_struct *p = NULL;
@@ -2677,7 +2683,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 * wait for swap operations protected by get/put_swap_device()
 * to complete
 */
-   synchronize_rcu();
+   stop_machine(swapoff_stop, NULL, cpu_online_mask);
 
flush_work(>discard_work);
 


Re: [PATCH net-next v5 1/4] phylib: Add device reset delay support

2017-12-17 Thread Richard Leitner
Hi Rob,

On 12/15/2017 11:17 PM, Rob Herring wrote:
> On Mon, Dec 11, 2017 at 01:16:57PM +0100, Richard Leitner wrote:
>> From: Richard Leitner 
>>
>> Some PHYs need a minimum time after the reset gpio was asserted and/or
>> deasserted. To ensure we meet these timing requirements add two new
>> optional devicetree parameters for the phy: reset-delay-us and
>> reset-post-delay-us.
>>
>> Signed-off-by: Richard Leitner 
>> Reviewed-by: Geert Uytterhoeven 
>> ---
>>  Documentation/devicetree/bindings/net/phy.txt | 10 ++
>>  drivers/net/phy/mdio_device.c | 13 +++--
>>  drivers/of/of_mdio.c  |  4 
>>  include/linux/mdio.h  |  2 ++
>>  4 files changed, 27 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/phy.txt 
>> b/Documentation/devicetree/bindings/net/phy.txt
>> index c05479f5ac7c..72860ce7f610 100644
>> --- a/Documentation/devicetree/bindings/net/phy.txt
>> +++ b/Documentation/devicetree/bindings/net/phy.txt
>> @@ -55,6 +55,12 @@ Optional Properties:
>>  
>>  - reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
>>  
>> +- reset-delay-us: Delay after the reset was asserted in microseconds.
>> +  If this property is missing the delay will be skipped.
>> +
>> +- reset-post-delay-us: Delay after the reset was deasserted in microseconds.
>> +  If this property is missing the delay will be skipped.
> 
> I think these names could be clearer as to exactly what they mean. 
> Looking at existing properties with "reset-delay" there's a mixture of 
> definitions whether it is the assert time or the time after deassert.
> 
> So I'd call these "reset-assert-us" and "reset-deassert-us".

Ok, that would be fine with me, but are you sure that we should omit the
"-delay" term completely?

What would be the best approach to post this change (as the patchset was
already merged to net-next)? A separate patch or a v6 of the complete
patchset?

> 
> Rob
> 

regards;Richard.L


Re: [PATCH net-next v5 1/4] phylib: Add device reset delay support

2017-12-17 Thread Richard Leitner
Hi Rob,

On 12/15/2017 11:17 PM, Rob Herring wrote:
> On Mon, Dec 11, 2017 at 01:16:57PM +0100, Richard Leitner wrote:
>> From: Richard Leitner 
>>
>> Some PHYs need a minimum time after the reset gpio was asserted and/or
>> deasserted. To ensure we meet these timing requirements add two new
>> optional devicetree parameters for the phy: reset-delay-us and
>> reset-post-delay-us.
>>
>> Signed-off-by: Richard Leitner 
>> Reviewed-by: Geert Uytterhoeven 
>> ---
>>  Documentation/devicetree/bindings/net/phy.txt | 10 ++
>>  drivers/net/phy/mdio_device.c | 13 +++--
>>  drivers/of/of_mdio.c  |  4 
>>  include/linux/mdio.h  |  2 ++
>>  4 files changed, 27 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/phy.txt 
>> b/Documentation/devicetree/bindings/net/phy.txt
>> index c05479f5ac7c..72860ce7f610 100644
>> --- a/Documentation/devicetree/bindings/net/phy.txt
>> +++ b/Documentation/devicetree/bindings/net/phy.txt
>> @@ -55,6 +55,12 @@ Optional Properties:
>>  
>>  - reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
>>  
>> +- reset-delay-us: Delay after the reset was asserted in microseconds.
>> +  If this property is missing the delay will be skipped.
>> +
>> +- reset-post-delay-us: Delay after the reset was deasserted in microseconds.
>> +  If this property is missing the delay will be skipped.
> 
> I think these names could be clearer as to exactly what they mean. 
> Looking at existing properties with "reset-delay" there's a mixture of 
> definitions whether it is the assert time or the time after deassert.
> 
> So I'd call these "reset-assert-us" and "reset-deassert-us".

Ok, that would be fine with me, but are you sure that we should omit the
"-delay" term completely?

What would be the best approach to post this change (as the patchset was
already merged to net-next)? A separate patch or a v6 of the complete
patchset?

> 
> Rob
> 

regards;Richard.L


Re: Detecting RWF_NOWAIT support

2017-12-17 Thread Avi Kivity



On 12/18/2017 05:28 AM, Goldwyn Rodrigues wrote:


On 12/16/2017 08:49 AM, Avi Kivity wrote:


On 12/14/2017 09:15 PM, Goldwyn Rodrigues wrote:

On 12/14/2017 11:38 AM, Avi Kivity wrote:

I'm looking to add support for RWF_NOWAIT within a linux-aio iocb.
Naturally, I need to detect at runtime whether the kernel support
RWF_NOWAIT or not.


The only method I could find was to issue an I/O with RWF_NOWAIT set,
and look for errors. This is somewhat less than perfect:

   - from the error, I can't tell whether RWF_NOWAIT was the problem, or
something else. If I enable a number of new features, I have to run
through all combinations to figure out which ones are supported and
which are not.

Here is the return codes for RWF_NOWAIT
EINVAL - not supported (older kernel)
EOPNOTSUPP - not supported
EAGAIN - supported but could not complete because I/O will be delayed

Which of these are returned from io_submit() and which are returned in
the iocb?

These are returned in iocb.


Thanks.




0 - supported and I/O completed (success).


   - RWF_NOWAIT support is per-filesystem, so I can't just remember
not to
enable RWF_NOWAIT globally, I have to track it per file.

Yes, the support is per filesystem. So, the application must know if the
filesystem supports it, possibly by performing a small I/O.

So the application must know about filesystem mount points, and be
prepared to create a file and try to write it (in case the filesystem is
empty) or alter its behavior during runtime depending on the errors it
sees.

Well yes. Hopefully, the application knows what it is doing when it
performs RWF_NOWAIT.


This type of interface makes it very hard to consume new kernel 
facilities in a backward compatible way. The kernel should advertise 
what support it provides; for example this support could be advertised 
via statx(2).


For examples of facilities that advertise their capabilities, see 
membarrier(2) and KVM.




Re: Detecting RWF_NOWAIT support

2017-12-17 Thread Avi Kivity



On 12/18/2017 05:28 AM, Goldwyn Rodrigues wrote:


On 12/16/2017 08:49 AM, Avi Kivity wrote:


On 12/14/2017 09:15 PM, Goldwyn Rodrigues wrote:

On 12/14/2017 11:38 AM, Avi Kivity wrote:

I'm looking to add support for RWF_NOWAIT within a linux-aio iocb.
Naturally, I need to detect at runtime whether the kernel support
RWF_NOWAIT or not.


The only method I could find was to issue an I/O with RWF_NOWAIT set,
and look for errors. This is somewhat less than perfect:

   - from the error, I can't tell whether RWF_NOWAIT was the problem, or
something else. If I enable a number of new features, I have to run
through all combinations to figure out which ones are supported and
which are not.

Here is the return codes for RWF_NOWAIT
EINVAL - not supported (older kernel)
EOPNOTSUPP - not supported
EAGAIN - supported but could not complete because I/O will be delayed

Which of these are returned from io_submit() and which are returned in
the iocb?

These are returned in iocb.


Thanks.




0 - supported and I/O completed (success).


   - RWF_NOWAIT support is per-filesystem, so I can't just remember
not to
enable RWF_NOWAIT globally, I have to track it per file.

Yes, the support is per filesystem. So, the application must know if the
filesystem supports it, possibly by performing a small I/O.

So the application must know about filesystem mount points, and be
prepared to create a file and try to write it (in case the filesystem is
empty) or alter its behavior during runtime depending on the errors it
sees.

Well yes. Hopefully, the application knows what it is doing when it
performs RWF_NOWAIT.


This type of interface makes it very hard to consume new kernel 
facilities in a backward compatible way. The kernel should advertise 
what support it provides; for example this support could be advertised 
via statx(2).


For examples of facilities that advertise their capabilities, see 
membarrier(2) and KVM.




Re: [PATCH V3 2/2] Xen/PCIback: Implement PCI flr/slot/bus reset with 'reset' SysFS attribute

2017-12-17 Thread Jan Beulich
>>> On 15.12.17 at 20:52,  wrote:
 +static int pcistub_device_reset(struct pci_dev *dev)
 +{
 +  struct xen_pcibk_dev_data *dev_data;
 +  bool slot = false, bus = false;
 +  struct pcistub_args arg = {};
 +
 +  if (!dev)
 +  return -EINVAL;
 +
 +  dev_dbg(>dev, "[%s]\n", __func__);
 +
 +  /* First check and try FLR */
 +  if (pcie_has_flr(dev)) {
 +  dev_dbg(>dev, "resetting %s device using FLR\n",
 +  pci_name(dev));
 +  pcie_flr(dev);
>>> The lack of error check here puzzled me, but I see the function
>>> indeed returns void right now. I think the prereq patch should
>>> change this along with exporting the function - you really don't
>>> want the device to be handed to a guest when the FLR timed
>>> out.
>> We will change pcie_flr() to return error code. I will make this change
>> in the next version of this patch.
> I exchanged some emails with Bjorn/Christoph and it looks like Christoph
> as some planto restructure pcie flr specific functions but I don't know
> the exact time-frame. For now,I am planning to use existing pcie_flr()
> after checking FLR capability. We will switchto revised pcie_flr() once
> it is available.
> 
> I hope you are fine with this approach. Please let me know. Thanks.

I've seen that other discussion. I don't think the change here
should be done prior to the error reporting being put in place,
for security reasons. But in the end it'll be Konrad as the
maintainer to judge.

Or wait, looks like there's some confusion in ./MAINTAINERS:
Konrad is listed as maintainer for "XEN PCI SUBSYSTEM", but the
list of files doesn't include pciback. So it would instead be Boris
or Jürgen to give you a final word.

Jan


Re: [PATCH V3 2/2] Xen/PCIback: Implement PCI flr/slot/bus reset with 'reset' SysFS attribute

2017-12-17 Thread Jan Beulich
>>> On 15.12.17 at 20:52,  wrote:
 +static int pcistub_device_reset(struct pci_dev *dev)
 +{
 +  struct xen_pcibk_dev_data *dev_data;
 +  bool slot = false, bus = false;
 +  struct pcistub_args arg = {};
 +
 +  if (!dev)
 +  return -EINVAL;
 +
 +  dev_dbg(>dev, "[%s]\n", __func__);
 +
 +  /* First check and try FLR */
 +  if (pcie_has_flr(dev)) {
 +  dev_dbg(>dev, "resetting %s device using FLR\n",
 +  pci_name(dev));
 +  pcie_flr(dev);
>>> The lack of error check here puzzled me, but I see the function
>>> indeed returns void right now. I think the prereq patch should
>>> change this along with exporting the function - you really don't
>>> want the device to be handed to a guest when the FLR timed
>>> out.
>> We will change pcie_flr() to return error code. I will make this change
>> in the next version of this patch.
> I exchanged some emails with Bjorn/Christoph and it looks like Christoph
> as some planto restructure pcie flr specific functions but I don't know
> the exact time-frame. For now,I am planning to use existing pcie_flr()
> after checking FLR capability. We will switchto revised pcie_flr() once
> it is available.
> 
> I hope you are fine with this approach. Please let me know. Thanks.

I've seen that other discussion. I don't think the change here
should be done prior to the error reporting being put in place,
for security reasons. But in the end it'll be Konrad as the
maintainer to judge.

Or wait, looks like there's some confusion in ./MAINTAINERS:
Konrad is listed as maintainer for "XEN PCI SUBSYSTEM", but the
list of files doesn't include pciback. So it would instead be Boris
or Jürgen to give you a final word.

Jan


[PATCH -V3 -mm] mm, swap: Fix race between swapoff and some swap operations

2017-12-17 Thread Huang, Ying
From: Huang Ying 

When the swapin is performed, after getting the swap entry information
from the page table, system will swap in the swap entry, without any
lock held to prevent the swap device from being swapoff.  This may
cause the race like below,

CPU 1   CPU 2
-   -
do_swap_page
  swapin_readahead
__read_swap_cache_async
swapoff   swapcache_prepare
  p->swap_map = NULL__swap_duplicate
  p->swap_map[?] /* !!! NULL pointer 
access */

Because swapoff is usually done when system shutdown only, the race
may not hit many people in practice.  But it is still a race need to
be fixed.

To fix the race, get_swap_device() is added to check whether the
specified swap entry is valid in its swap device.  If so, it will keep
the swap entry valid via preventing the swap device from being
swapoff, until put_swap_device() is called.

Because swapoff() is very race code path, to make the normal path runs
as fast as possible, RCU instead of reference count is used to
implement get/put_swap_device().  From get_swap_device() to
put_swap_device(), the RCU read lock is held, so synchronize_rcu() in
swapoff() will wait until put_swap_device() is called.

In addition to swap_map, cluster_info, etc. data structure in the
struct swap_info_struct, the swap cache radix tree will be freed after
swapoff, so this patch fixes the race between swap cache looking up
and swapoff too.

Cc: Hugh Dickins 
Cc: Paul E. McKenney 
Cc: Minchan Kim 
Cc: Johannes Weiner 
Cc: Tim Chen 
Cc: Shaohua Li 
Cc: Mel Gorman 
Cc: "Jérôme Glisse" 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: David Rientjes 
Cc: Rik van Riel 
Cc: Jan Kara 
Cc: Dave Jiang 
Cc: Aaron Lu 
Signed-off-by: "Huang, Ying" 

Changelog:

v3:

- Re-implemented with RCU to reduce the overhead of normal paths

v2:

- Re-implemented with SRCU to reduce the overhead of normal paths.

- Avoid to check whether the swap device has been swapoff in
  get_swap_device().  Because we can check the origin of the swap
  entry to make sure the swap device hasn't bee swapoff.
---
 include/linux/swap.h |  11 +-
 mm/memory.c  |   2 +-
 mm/swap_state.c  |  16 ++--
 mm/swapfile.c| 105 +++
 4 files changed, 103 insertions(+), 31 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 2417d288e016..f7e8f26cf07f 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -172,8 +172,9 @@ enum {
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 */
+   SWP_VALID   = (1 << 12),/* swap is valid to be operated on? */
/* add others here before... */
-   SWP_SCANNING= (1 << 12),/* refcount in scan_swap_map */
+   SWP_SCANNING= (1 << 13),/* refcount in scan_swap_map */
 };
 
 #define SWAP_CLUSTER_MAX 32UL
@@ -460,7 +461,7 @@ extern unsigned int count_swap_pages(int, int);
 extern sector_t map_swap_page(struct page *, struct block_device **);
 extern sector_t swapdev_block(int, pgoff_t);
 extern int page_swapcount(struct page *);
-extern int __swap_count(struct swap_info_struct *si, swp_entry_t entry);
+extern int __swap_count(swp_entry_t entry);
 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 *);
@@ -470,6 +471,12 @@ extern int try_to_free_swap(struct page *);
 struct backing_dev_info;
 extern int init_swap_address_space(unsigned int type, unsigned long nr_pages);
 extern void exit_swap_address_space(unsigned int type);
+extern struct swap_info_struct *get_swap_device(swp_entry_t entry);
+
+static inline void put_swap_device(struct swap_info_struct *si)
+{
+   rcu_read_unlock();
+}
 
 #else /* CONFIG_SWAP */
 
diff --git a/mm/memory.c b/mm/memory.c
index 1a969992f76b..77a7d6191218 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2909,7 +2909,7 @@ int do_swap_page(struct vm_fault *vmf)
struct swap_info_struct *si = swp_swap_info(entry);
 
if (si->flags & SWP_SYNCHRONOUS_IO &&
-   __swap_count(si, entry) == 1) {
+   __swap_count(entry) == 1) {
/* skip swapcache */

[PATCH -V3 -mm] mm, swap: Fix race between swapoff and some swap operations

2017-12-17 Thread Huang, Ying
From: Huang Ying 

When the swapin is performed, after getting the swap entry information
from the page table, system will swap in the swap entry, without any
lock held to prevent the swap device from being swapoff.  This may
cause the race like below,

CPU 1   CPU 2
-   -
do_swap_page
  swapin_readahead
__read_swap_cache_async
swapoff   swapcache_prepare
  p->swap_map = NULL__swap_duplicate
  p->swap_map[?] /* !!! NULL pointer 
access */

Because swapoff is usually done when system shutdown only, the race
may not hit many people in practice.  But it is still a race need to
be fixed.

To fix the race, get_swap_device() is added to check whether the
specified swap entry is valid in its swap device.  If so, it will keep
the swap entry valid via preventing the swap device from being
swapoff, until put_swap_device() is called.

Because swapoff() is very race code path, to make the normal path runs
as fast as possible, RCU instead of reference count is used to
implement get/put_swap_device().  From get_swap_device() to
put_swap_device(), the RCU read lock is held, so synchronize_rcu() in
swapoff() will wait until put_swap_device() is called.

In addition to swap_map, cluster_info, etc. data structure in the
struct swap_info_struct, the swap cache radix tree will be freed after
swapoff, so this patch fixes the race between swap cache looking up
and swapoff too.

Cc: Hugh Dickins 
Cc: Paul E. McKenney 
Cc: Minchan Kim 
Cc: Johannes Weiner 
Cc: Tim Chen 
Cc: Shaohua Li 
Cc: Mel Gorman 
Cc: "Jérôme Glisse" 
Cc: Michal Hocko 
Cc: Andrea Arcangeli 
Cc: David Rientjes 
Cc: Rik van Riel 
Cc: Jan Kara 
Cc: Dave Jiang 
Cc: Aaron Lu 
Signed-off-by: "Huang, Ying" 

Changelog:

v3:

- Re-implemented with RCU to reduce the overhead of normal paths

v2:

- Re-implemented with SRCU to reduce the overhead of normal paths.

- Avoid to check whether the swap device has been swapoff in
  get_swap_device().  Because we can check the origin of the swap
  entry to make sure the swap device hasn't bee swapoff.
---
 include/linux/swap.h |  11 +-
 mm/memory.c  |   2 +-
 mm/swap_state.c  |  16 ++--
 mm/swapfile.c| 105 +++
 4 files changed, 103 insertions(+), 31 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 2417d288e016..f7e8f26cf07f 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -172,8 +172,9 @@ enum {
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 */
+   SWP_VALID   = (1 << 12),/* swap is valid to be operated on? */
/* add others here before... */
-   SWP_SCANNING= (1 << 12),/* refcount in scan_swap_map */
+   SWP_SCANNING= (1 << 13),/* refcount in scan_swap_map */
 };
 
 #define SWAP_CLUSTER_MAX 32UL
@@ -460,7 +461,7 @@ extern unsigned int count_swap_pages(int, int);
 extern sector_t map_swap_page(struct page *, struct block_device **);
 extern sector_t swapdev_block(int, pgoff_t);
 extern int page_swapcount(struct page *);
-extern int __swap_count(struct swap_info_struct *si, swp_entry_t entry);
+extern int __swap_count(swp_entry_t entry);
 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 *);
@@ -470,6 +471,12 @@ extern int try_to_free_swap(struct page *);
 struct backing_dev_info;
 extern int init_swap_address_space(unsigned int type, unsigned long nr_pages);
 extern void exit_swap_address_space(unsigned int type);
+extern struct swap_info_struct *get_swap_device(swp_entry_t entry);
+
+static inline void put_swap_device(struct swap_info_struct *si)
+{
+   rcu_read_unlock();
+}
 
 #else /* CONFIG_SWAP */
 
diff --git a/mm/memory.c b/mm/memory.c
index 1a969992f76b..77a7d6191218 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2909,7 +2909,7 @@ int do_swap_page(struct vm_fault *vmf)
struct swap_info_struct *si = swp_swap_info(entry);
 
if (si->flags & SWP_SYNCHRONOUS_IO &&
-   __swap_count(si, entry) == 1) {
+   __swap_count(entry) == 1) {
/* skip swapcache */
page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
vmf->address);
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 0b8ae361981f..8dde719e973c 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -337,8 +337,13 @@ struct page *lookup_swap_cache(swp_entry_t entry, struct 

Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-17 Thread Michal Simek
Hi guys,

On 15.12.2017 10:27, Mauro Carvalho Chehab wrote:
> Em Fri, 15 Dec 2017 10:55:26 +0530
> Dhaval Shah  escreveu:
> 
>> Hi Laurent/Mauro/Greg,
>>
>> On Fri, Dec 15, 2017 at 3:32 AM, Laurent Pinchart
>>  wrote:
>>> Hi Mauro,
>>>
>>> On Thursday, 14 December 2017 23:50:03 EET Mauro Carvalho Chehab wrote:
 Em Thu, 14 Dec 2017 21:57:06 +0100 Greg KH escreveu:
> On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
>> On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
>>> On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
 On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
>> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
>>> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
 On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab
 wrote:
> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
>> SPDX-License-Identifier is used for the Xilinx Video IP and
>> related drivers.
>>
>> Signed-off-by: Dhaval Shah 
>
> Hi Dhaval,
>
> You're not listed as one of the Xilinx driver maintainers. I'm
> afraid that, without their explicit acks, sent to the ML, I
> can't accept a patch touching at the driver's license tags.

 The patch doesn't change the license, I don't see why it would
 cause any issue. Greg isn't listed as the maintainer or copyright
 holder of any of the 10k+ files to which he added an SPDX license
 header in the last kernel release.
>>>
>>> Adding a comment line that describes an implicit or
>>> explicit license is different than removing the license
>>> text itself.
>>
>> The SPDX license header is meant to be equivalent to the license
>> text.
>
> I understand that.
> At a minimum, removing BSD license text is undesirable
>
> as that license states:
>  ** Redistributions of source code must retain the above copyright
>  *  notice, this list of conditions and the following disclaimer.
>
> etc...

 But this patch only removes the following text:

 - * 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.

 and replaces it by the corresponding SPDX header.

>> The only reason why the large SPDX patch didn't touch the whole
>> kernel in one go was that it was easier to split in in multiple
>> chunks.
>
> Not really, it was scripted.

 But still manually reviewed as far as I know.

>> This is no different than not including the full GPL license in
>> every header file but only pointing to it through its name and
>> reference, as every kernel source file does.
>
> Not every kernel source file had a license text
> or a reference to another license file.

 Correct, but the files touched by this patch do.

 This issue is in no way specific to linux-media and should be
 decided upon at the top level, not on a per-subsystem basis. Greg,
 could you comment on this ?
>>>
>>> Comment on what exactly?  I don't understand the problem here, care to
>>> summarize it?
>>
>> In a nutshell (if I understand it correctly), Dhaval Shah submitted
>> https:// patchwork.kernel.org/patch/10102451/ which replaces
>>
>> +// SPDX-License-Identifier: GPL-2.0
>> [...]
>> - *
>> - * 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.
>>
>> in all .c and .h files of the Xilinx V4L2 driver
>> (drivers/media/platform/
>> xilinx). I have reviewed the patch and acked it. Mauro then rejected it,
>> stating that he can't accept a change to license text without an
>> explicit ack from the official driver's maintainers. My position is
>> that such a change doesn't change the license and thus doesn't need to
>> track all copyright holders, and can be merged without an explicit ack
>> from the respective maintainers.
>
> Yes, I agree with you, no license is being changed here, and no
> copyright is either.
>
> BUT, I know that most major companies are reviewing this process right
> now.  We have gotten 

Re: [PATCH] media: v4l: xilinx: Use SPDX-License-Identifier

2017-12-17 Thread Michal Simek
Hi guys,

On 15.12.2017 10:27, Mauro Carvalho Chehab wrote:
> Em Fri, 15 Dec 2017 10:55:26 +0530
> Dhaval Shah  escreveu:
> 
>> Hi Laurent/Mauro/Greg,
>>
>> On Fri, Dec 15, 2017 at 3:32 AM, Laurent Pinchart
>>  wrote:
>>> Hi Mauro,
>>>
>>> On Thursday, 14 December 2017 23:50:03 EET Mauro Carvalho Chehab wrote:
 Em Thu, 14 Dec 2017 21:57:06 +0100 Greg KH escreveu:
> On Thu, Dec 14, 2017 at 10:44:16PM +0200, Laurent Pinchart wrote:
>> On Thursday, 14 December 2017 22:08:51 EET Greg KH wrote:
>>> On Thu, Dec 14, 2017 at 09:05:27PM +0200, Laurent Pinchart wrote:
 On Thursday, 14 December 2017 20:54:39 EET Joe Perches wrote:
> On Thu, 2017-12-14 at 20:37 +0200, Laurent Pinchart wrote:
>> On Thursday, 14 December 2017 20:32:20 EET Joe Perches wrote:
>>> On Thu, 2017-12-14 at 20:28 +0200, Laurent Pinchart wrote:
 On Thursday, 14 December 2017 19:05:27 EET Mauro Carvalho Chehab
 wrote:
> Em Fri,  8 Dec 2017 18:05:37 +0530 Dhaval Shah escreveu:
>> SPDX-License-Identifier is used for the Xilinx Video IP and
>> related drivers.
>>
>> Signed-off-by: Dhaval Shah 
>
> Hi Dhaval,
>
> You're not listed as one of the Xilinx driver maintainers. I'm
> afraid that, without their explicit acks, sent to the ML, I
> can't accept a patch touching at the driver's license tags.

 The patch doesn't change the license, I don't see why it would
 cause any issue. Greg isn't listed as the maintainer or copyright
 holder of any of the 10k+ files to which he added an SPDX license
 header in the last kernel release.
>>>
>>> Adding a comment line that describes an implicit or
>>> explicit license is different than removing the license
>>> text itself.
>>
>> The SPDX license header is meant to be equivalent to the license
>> text.
>
> I understand that.
> At a minimum, removing BSD license text is undesirable
>
> as that license states:
>  ** Redistributions of source code must retain the above copyright
>  *  notice, this list of conditions and the following disclaimer.
>
> etc...

 But this patch only removes the following text:

 - * 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.

 and replaces it by the corresponding SPDX header.

>> The only reason why the large SPDX patch didn't touch the whole
>> kernel in one go was that it was easier to split in in multiple
>> chunks.
>
> Not really, it was scripted.

 But still manually reviewed as far as I know.

>> This is no different than not including the full GPL license in
>> every header file but only pointing to it through its name and
>> reference, as every kernel source file does.
>
> Not every kernel source file had a license text
> or a reference to another license file.

 Correct, but the files touched by this patch do.

 This issue is in no way specific to linux-media and should be
 decided upon at the top level, not on a per-subsystem basis. Greg,
 could you comment on this ?
>>>
>>> Comment on what exactly?  I don't understand the problem here, care to
>>> summarize it?
>>
>> In a nutshell (if I understand it correctly), Dhaval Shah submitted
>> https:// patchwork.kernel.org/patch/10102451/ which replaces
>>
>> +// SPDX-License-Identifier: GPL-2.0
>> [...]
>> - *
>> - * 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.
>>
>> in all .c and .h files of the Xilinx V4L2 driver
>> (drivers/media/platform/
>> xilinx). I have reviewed the patch and acked it. Mauro then rejected it,
>> stating that he can't accept a change to license text without an
>> explicit ack from the official driver's maintainers. My position is
>> that such a change doesn't change the license and thus doesn't need to
>> track all copyright holders, and can be merged without an explicit ack
>> from the respective maintainers.
>
> Yes, I agree with you, no license is being changed here, and no
> copyright is either.
>
> BUT, I know that most major companies are reviewing this process right
> now.  We have gotten approval from almost all of the major kernel
> developer companies to do this, which 

Re: [PATCH] trace: reenable preemption if we modify the ip

2017-12-17 Thread Masami Hiramatsu
On Fri, 15 Dec 2017 21:42:57 -0500
Josef Bacik  wrote:

> From: Josef Bacik 
> 
> Things got moved around between the original bpf_override_return patches
> and the final version, and now the ftrace kprobe dispatcher assumes if
> you modified the ip that you also enabled preemption.  Make a comment of
> this and enable preemption, this fixes the lockdep splat that happened
> when using this feature.
> 
> Signed-off-by: Josef Bacik 
> ---
>  kernel/trace/trace_kprobe.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 5db849809a56..91f4b57dab82 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -1322,8 +1322,15 @@ static int kprobe_dispatcher(struct kprobe *kp, struct 
> pt_regs *regs)
>   if (tk->tp.flags & TP_FLAG_TRACE)
>   kprobe_trace_func(tk, regs);
>  #ifdef CONFIG_PERF_EVENTS
> - if (tk->tp.flags & TP_FLAG_PROFILE)
> + if (tk->tp.flags & TP_FLAG_PROFILE) {
>   ret = kprobe_perf_func(tk, regs);
> + /*
> +  * The ftrace kprobe handler leaves it up to us to re-enable
> +  * preemption here before returning if we've modified the ip.
> +  */
> + if (ret)
> + preempt_enable_no_resched();

Where is reset_current_kprobe()?
Since kprobes still expects this modification is used by jprobes,
we need to call it in caller-side.

Thank you,

> + }
>  #endif
>   return ret;
>  }
> -- 
> 2.7.5
> 


-- 
Masami Hiramatsu 


Re: [PATCH] trace: reenable preemption if we modify the ip

2017-12-17 Thread Masami Hiramatsu
On Fri, 15 Dec 2017 21:42:57 -0500
Josef Bacik  wrote:

> From: Josef Bacik 
> 
> Things got moved around between the original bpf_override_return patches
> and the final version, and now the ftrace kprobe dispatcher assumes if
> you modified the ip that you also enabled preemption.  Make a comment of
> this and enable preemption, this fixes the lockdep splat that happened
> when using this feature.
> 
> Signed-off-by: Josef Bacik 
> ---
>  kernel/trace/trace_kprobe.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 5db849809a56..91f4b57dab82 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -1322,8 +1322,15 @@ static int kprobe_dispatcher(struct kprobe *kp, struct 
> pt_regs *regs)
>   if (tk->tp.flags & TP_FLAG_TRACE)
>   kprobe_trace_func(tk, regs);
>  #ifdef CONFIG_PERF_EVENTS
> - if (tk->tp.flags & TP_FLAG_PROFILE)
> + if (tk->tp.flags & TP_FLAG_PROFILE) {
>   ret = kprobe_perf_func(tk, regs);
> + /*
> +  * The ftrace kprobe handler leaves it up to us to re-enable
> +  * preemption here before returning if we've modified the ip.
> +  */
> + if (ret)
> + preempt_enable_no_resched();

Where is reset_current_kprobe()?
Since kprobes still expects this modification is used by jprobes,
we need to call it in caller-side.

Thank you,

> + }
>  #endif
>   return ret;
>  }
> -- 
> 2.7.5
> 


-- 
Masami Hiramatsu 


[PATCH v4 01/36] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

It allows some architectures to use this generic macro instead of
defining theirs.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
Acked-by: Arnd Bergmann 
---
 include/asm-generic/io.h |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index b4531e3..7c6a39e 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -852,7 +852,16 @@ static inline void __iomem *__ioremap(phys_addr_t offset, 
size_t size,
 }
 #endif
 
+#ifndef iounmap
+#define iounmap iounmap
+
+static inline void iounmap(void __iomem *addr)
+{
+}
+#endif
+#endif /* CONFIG_MMU */
 #ifndef ioremap_nocache
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
 #define ioremap_nocache ioremap_nocache
 static inline void __iomem *ioremap_nocache(phys_addr_t offset, size_t size)
 {
@@ -884,15 +893,6 @@ static inline void __iomem *ioremap_wt(phys_addr_t offset, 
size_t size)
 }
 #endif
 
-#ifndef iounmap
-#define iounmap iounmap
-
-static inline void iounmap(void __iomem *addr)
-{
-}
-#endif
-#endif /* CONFIG_MMU */
-
 #ifdef CONFIG_HAS_IOPORT_MAP
 #ifndef CONFIG_GENERIC_IOMAP
 #ifndef ioport_map
-- 
1.7.9.5



[PATCH 2/2] perf-probe: Skip searching debuginfo if we know no debuginfo

2017-12-17 Thread Masami Hiramatsu
Skip searching debuginfo if we have already searched and
there is no debuginfo for given file.
This also reduce debuginfo mismatch warnings for listing
events on same binary.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/probe-finder.c |   16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5bb71e056b21..cafc3e5b9863 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -119,6 +119,8 @@ enum dso_binary_type distro_dwarf_types[] = {
 
 struct debuginfo *debuginfo__new(const char *path)
 {
+   static struct strlist *no_debuginfo_files;
+
u8 bid[BUILD_ID_SIZE], bid2[BUILD_ID_SIZE];
enum dso_binary_type *type;
char buf[PATH_MAX], nil = '\0';
@@ -126,6 +128,12 @@ struct debuginfo *debuginfo__new(const char *path)
bool have_build_id = false;
struct debuginfo *dinfo = NULL;
 
+   /* Skip if we already know it has no debuginfo */
+   if (!no_debuginfo_files)
+   no_debuginfo_files = strlist__new(NULL, NULL);
+   else if (strlist__find(no_debuginfo_files, path))
+   return NULL;
+
/* Try to open distro debuginfo files */
dso = dso__new(path);
if (!dso)
@@ -159,7 +167,13 @@ struct debuginfo *debuginfo__new(const char *path)
 
 out:
/* if failed to open all distro debuginfo, open given binary */
-   return dinfo ? : __debuginfo__new(path);
+   if (!dinfo) {
+   dinfo = __debuginfo__new(path);
+   if (!dinfo)
+   strlist__add(no_debuginfo_files, path);
+   }
+
+   return dinfo;
 }
 
 void debuginfo__delete(struct debuginfo *dbg)



[PATCH v4 01/36] asm-generic/io.h: move ioremap_nocache/ioremap_uc/ioremap_wc/ioremap_wt out of ifndef CONFIG_MMU

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

It allows some architectures to use this generic macro instead of
defining theirs.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
Acked-by: Arnd Bergmann 
---
 include/asm-generic/io.h |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index b4531e3..7c6a39e 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -852,7 +852,16 @@ static inline void __iomem *__ioremap(phys_addr_t offset, 
size_t size,
 }
 #endif
 
+#ifndef iounmap
+#define iounmap iounmap
+
+static inline void iounmap(void __iomem *addr)
+{
+}
+#endif
+#endif /* CONFIG_MMU */
 #ifndef ioremap_nocache
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
 #define ioremap_nocache ioremap_nocache
 static inline void __iomem *ioremap_nocache(phys_addr_t offset, size_t size)
 {
@@ -884,15 +893,6 @@ static inline void __iomem *ioremap_wt(phys_addr_t offset, 
size_t size)
 }
 #endif
 
-#ifndef iounmap
-#define iounmap iounmap
-
-static inline void iounmap(void __iomem *addr)
-{
-}
-#endif
-#endif /* CONFIG_MMU */
-
 #ifdef CONFIG_HAS_IOPORT_MAP
 #ifndef CONFIG_GENERIC_IOMAP
 #ifndef ioport_map
-- 
1.7.9.5



[PATCH 2/2] perf-probe: Skip searching debuginfo if we know no debuginfo

2017-12-17 Thread Masami Hiramatsu
Skip searching debuginfo if we have already searched and
there is no debuginfo for given file.
This also reduce debuginfo mismatch warnings for listing
events on same binary.

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/probe-finder.c |   16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5bb71e056b21..cafc3e5b9863 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -119,6 +119,8 @@ enum dso_binary_type distro_dwarf_types[] = {
 
 struct debuginfo *debuginfo__new(const char *path)
 {
+   static struct strlist *no_debuginfo_files;
+
u8 bid[BUILD_ID_SIZE], bid2[BUILD_ID_SIZE];
enum dso_binary_type *type;
char buf[PATH_MAX], nil = '\0';
@@ -126,6 +128,12 @@ struct debuginfo *debuginfo__new(const char *path)
bool have_build_id = false;
struct debuginfo *dinfo = NULL;
 
+   /* Skip if we already know it has no debuginfo */
+   if (!no_debuginfo_files)
+   no_debuginfo_files = strlist__new(NULL, NULL);
+   else if (strlist__find(no_debuginfo_files, path))
+   return NULL;
+
/* Try to open distro debuginfo files */
dso = dso__new(path);
if (!dso)
@@ -159,7 +167,13 @@ struct debuginfo *debuginfo__new(const char *path)
 
 out:
/* if failed to open all distro debuginfo, open given binary */
-   return dinfo ? : __debuginfo__new(path);
+   if (!dinfo) {
+   dinfo = __debuginfo__new(path);
+   if (!dinfo)
+   strlist__add(no_debuginfo_files, path);
+   }
+
+   return dinfo;
 }
 
 void debuginfo__delete(struct debuginfo *dbg)



[PATCH 0/2] perf-probe: Improve warning message for buildid mismatch

2017-12-17 Thread Masami Hiramatsu
Hello,

This series ensure the build-ids for target binary and debuginfo
are matched. If there is a mismatch, it warns user to check the
package versions.

To reproduce the problematic environment (on Fedora26),
I did following operations;

  =
  # rpm -q glibc glibc-debuginfo
  glibc-2.25-12.fc26.x86_64
  package glibc-debuginfo is not installed

  # dnf debuginfo-install glibc
  [...]
  Installed:
glibc-debuginfo.x86_64 2.25-12.fc26
glibc-debuginfo-common.x86_64 2.25-12.fc26

  Complete!

  # dnf downgrade glibc
  [...]
  Downgraded:
glibc.x86_64 2.25-6.fc26 glibc-common.x86_64 2.25-6.fc26   
glibc-devel.x86_64 2.25-6.fc26   glibc-headers.x86_64 2.25-6.fc26  
glibc-langpack-en.x86_64 2.25-6.fc26 libcrypt-nss.x86_64 2.25-6.fc26   

  Complete!

  # rpm -q glibc glibc-debuginfo
  glibc-2.25-6.fc26.x86_64
  glibc-debuginfo-2.25-12.fc26.x86_64
  =

OK, so you can see now we have different versions of glibc and
glibc-debuginfo. Each debuginfo must be different.

With this series, defining new events also warns :)

  =
  # perf probe -x /usr/lib64/libc-2.25.so -a malloc_get_state\\@GLIBC_2.2.5
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
  Added new event:
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)

  You can now use it in all perf tools, such as:

  perf record -e probe_libc:malloc_get_state -aR sleep 1

  =

And listing up events warns.

  =
  # perf probe -l | more
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
  =

With [1/2], this warning messages repeated on same target (glibc). To suppress
this, [2/2] introduces no-debuginfo blacklist to skip it 2nd time as below.

  =
  # perf probe -l | more
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
probe_libc:malloc_get_state_1 (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
probe_libc:malloc_get_state_2 (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
  =

Arnaldo, would this match to your request?


Thank you,
---

Masami Hiramatsu (2):
  perf-probe: Ensure debuginfo's build-id is correct
  perf-probe: Skip searching debuginfo if we know no debuginfo


 tools/perf/util/probe-finder.c |   34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

--
Masami Hiramatsu (Linaro Ltd.) 


[PATCH 0/2] perf-probe: Improve warning message for buildid mismatch

2017-12-17 Thread Masami Hiramatsu
Hello,

This series ensure the build-ids for target binary and debuginfo
are matched. If there is a mismatch, it warns user to check the
package versions.

To reproduce the problematic environment (on Fedora26),
I did following operations;

  =
  # rpm -q glibc glibc-debuginfo
  glibc-2.25-12.fc26.x86_64
  package glibc-debuginfo is not installed

  # dnf debuginfo-install glibc
  [...]
  Installed:
glibc-debuginfo.x86_64 2.25-12.fc26
glibc-debuginfo-common.x86_64 2.25-12.fc26

  Complete!

  # dnf downgrade glibc
  [...]
  Downgraded:
glibc.x86_64 2.25-6.fc26 glibc-common.x86_64 2.25-6.fc26   
glibc-devel.x86_64 2.25-6.fc26   glibc-headers.x86_64 2.25-6.fc26  
glibc-langpack-en.x86_64 2.25-6.fc26 libcrypt-nss.x86_64 2.25-6.fc26   

  Complete!

  # rpm -q glibc glibc-debuginfo
  glibc-2.25-6.fc26.x86_64
  glibc-debuginfo-2.25-12.fc26.x86_64
  =

OK, so you can see now we have different versions of glibc and
glibc-debuginfo. Each debuginfo must be different.

With this series, defining new events also warns :)

  =
  # perf probe -x /usr/lib64/libc-2.25.so -a malloc_get_state\\@GLIBC_2.2.5
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
  Added new event:
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)

  You can now use it in all perf tools, such as:

  perf record -e probe_libc:malloc_get_state -aR sleep 1

  =

And listing up events warns.

  =
  # perf probe -l | more
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
  =

With [1/2], this warning messages repeated on same target (glibc). To suppress
this, [2/2] introduces no-debuginfo blacklist to skip it 2nd time as below.

  =
  # perf probe -l | more
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check the 
versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
probe_libc:malloc_get_state_1 (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
probe_libc:malloc_get_state_2 (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)
  =

Arnaldo, would this match to your request?


Thank you,
---

Masami Hiramatsu (2):
  perf-probe: Ensure debuginfo's build-id is correct
  perf-probe: Skip searching debuginfo if we know no debuginfo


 tools/perf/util/probe-finder.c |   34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

--
Masami Hiramatsu (Linaro Ltd.) 


Re: [f2fs-dev] [PATCH 1/2] f2fs: pass down write hints to block layer for bufferd write

2017-12-17 Thread Hyunchul Lee
Hi Jaegeuk,

Agreed. If Chao agrees with this policy, I will implement it.

Thanks for the comment.

On 12/15/2017 11:06 AM, Jaegeuk Kim wrote:
> On 12/14, Hyunchul Lee wrote:
>> Hi Jaegeuk,
>>
>> I need your comment about the fs_iohint mount option.
>>
>> a) w/o fs_iohint, propagate user hints to low layer.
>> b) w/ fs_iohint, ignore user hints, and use hints which is generated
>> with F2FS.
>>
>> Chao suggests this option. because user hints are more accurate than
>> file system.
>>
>> This is resonable, But I have some concerns about this option. 
>> The first thing is that blocks of a segments have different hints. This
>> could make GC less effective. 
>> The second is that the separation between LIFE_MEDIUM and LIFE_LONG is 
>> really needed. I think that difference between them is a little ambigous 
>> for users, and LIFE_SHORT and LIFE_EXTREME is converted to different 
>> hints by F2FS.
> 
> I think what we really can do would assign many user hints to our 3 DATA
> logs likewise rw_hint_to_seg_type(), since it's just hints for user data.
> Then, we can decide how to keep that as much as possible, since we have
> another filesystem metadata such as meta and nodes. In addition, I don't
> think we have to keep the original user-hints which makes F2FS logs be
> messed up.
> 
> With that mind, I can think of the below cases. Especially, if user wants
> to keep their io_hints, we'd better recommend to use direct_io w/o fs_iohints.
> In order to keep this policy, I think fs_iohints would be better to be a
> feature set by mkfs.f2fs and detected by sysfs entries for users.
> 
> 1) w/ fs_iohints
> 
> UserF2FS   Block
> ---
> Meta   WRITE_LIFE_MEDIUM
> HOT_NODE   WRITE_LIFE_NOTSET
> WARM_NODE  -'
> COLD_NODE  WRITE_LIFE_NONE
> ioctl(cold) COLD_DATA  WRITE_LIFE_EXTREME
> extention list  -' -'
> WRITE_LIFE_EXTREME  -' -'
> WRITE_LIFE_SHORTHOT_DATA   WRITE_LIFE_SHORT
> 
> -- buffered_io
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_LONG
> WRITE_LIFE_NONE -' -'
> WRITE_LIFE_MEDIUM   -' -'
> WRITE_LIFE_LONG -' -'
> 
> -- direct_io (Not recommendable)
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_NOT_SET
> WRITE_LIFE_NONE -' WRITE_LIFE_NONE
> WRITE_LIFE_MEDIUM   -' WRITE_LIFE_MEDIUM
> WRITE_LIFE_LONG -' WRITE_LIFE_LONG
> 
> 2) w/o fs_iohints
> 
> UserF2FS   Block
> ---
> Meta   -
> HOT_NODE   -
> WARM_NODE  -
> COLD_NODE  -
> ioctl(cold) COLD_DATA  -
> extention list  -' -
> 
> -- buffered_io
> WRITE_LIFE_EXTREME  COLD_DATA  -
> WRITE_LIFE_SHORTHOT_DATA   -
> WRITE_LIFE_NOT_SET  WARM_DATA  -
> WRITE_LIFE_NONE -' -
> WRITE_LIFE_MEDIUM   -' -
> WRITE_LIFE_LONG -' -
> 
> -- direct_io
> WRITE_LIFE_EXTREME  COLD_DATA  WRITE_LIFE_EXTREME
> WRITE_LIFE_SHORTHOT_DATA   WRITE_LIFE_SHORT
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_NOT_SET
> WRITE_LIFE_NONE -' WRITE_LIFE_NONE
> WRITE_LIFE_MEDIUM   -' WRITE_LIFE_MEDIUM
> WRITE_LIFE_LONG -' WRITE_LIFE_LONG
> 
> 
> Note that, I don't much care about how to manipulate streamid in nvme driver
> in terms of LIFE_NONE or LIFE_NOTSET, since other drivers can handle them
> in different ways. Taking a look at the definition, at least, we don't need
> to assume that those are same at all. For example, if we can expolit this in
> UFS driver, we can pass all the stream ids to the device as context ids.
> 
> Thanks,
> 
>>
>> Thanks.
>>
>> On 12/12/2017 11:45 AM, Chao Yu wrote:
>>> Hi Hyunchul,
>>>
>>> On 2017/12/12 10:15, Hyunchul Lee wrote:
 Hi Chao,

 On 12/11/2017 10:15 PM, Chao Yu wrote:
> Hi Hyunchul,
>
> On 2017/12/1 16:28, Hyunchul Lee wrote:
>> Hi Chao,
>>
>> On 11/30/2017 04:06 PM, Chao Yu wrote:
>>> Hi Hyunchul,
>>>
>>> On 2017/11/28 8:23, Hyunchul Lee wrote:
 From: Hyunchul Lee 

 This implements which hint is passed down to block layer
 for datas from the specific segment type.

 segment 

[PATCH 1/2] perf-probe: Ensure debuginfo's build-id is correct

2017-12-17 Thread Masami Hiramatsu
Ensure that the build-id of debuginfo is correctly
matched to target build-id, if not, it warns user
to check the system debuginfo package is correctly
installed.

E.g. on such environment, you will see below warning.
  ==
  # perf probe -l
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check
  the versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in /us
  r/lib64/libc-2.25.so)
  ==

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/probe-finder.c |   18 ++
 1 file changed, 18 insertions(+)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a5731de0e5eb..5bb71e056b21 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -119,9 +119,11 @@ enum dso_binary_type distro_dwarf_types[] = {
 
 struct debuginfo *debuginfo__new(const char *path)
 {
+   u8 bid[BUILD_ID_SIZE], bid2[BUILD_ID_SIZE];
enum dso_binary_type *type;
char buf[PATH_MAX], nil = '\0';
struct dso *dso;
+   bool have_build_id = false;
struct debuginfo *dinfo = NULL;
 
/* Try to open distro debuginfo files */
@@ -129,12 +131,28 @@ struct debuginfo *debuginfo__new(const char *path)
if (!dso)
goto out;
 
+   if (filename__read_build_id(path, bid, BUILD_ID_SIZE) > 0)
+   have_build_id = true;
+
for (type = distro_dwarf_types;
 !dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
 type++) {
if (dso__read_binary_type_filename(dso, *type, ,
   buf, PATH_MAX) < 0)
continue;
+
+   if (have_build_id) {
+   /* This can be fail because the file doesn't exist */
+   if (filename__read_build_id(buf, bid2,
+   BUILD_ID_SIZE) < 0)
+   continue;
+   if (memcmp(bid, bid2, BUILD_ID_SIZE)) {
+   pr_warning("WARN: There is a build-id mismatch 
between\n %s\n and\n %s\n"
+   "Please check your system's debuginfo 
files for mismatches, e.g. check the "
+   "versions for the target package and 
debuginfo package.\n", buf, path);
+   continue;
+   }
+   }
dinfo = __debuginfo__new(buf);
}
dso__put(dso);



Re: [f2fs-dev] [PATCH 1/2] f2fs: pass down write hints to block layer for bufferd write

2017-12-17 Thread Hyunchul Lee
Hi Jaegeuk,

Agreed. If Chao agrees with this policy, I will implement it.

Thanks for the comment.

On 12/15/2017 11:06 AM, Jaegeuk Kim wrote:
> On 12/14, Hyunchul Lee wrote:
>> Hi Jaegeuk,
>>
>> I need your comment about the fs_iohint mount option.
>>
>> a) w/o fs_iohint, propagate user hints to low layer.
>> b) w/ fs_iohint, ignore user hints, and use hints which is generated
>> with F2FS.
>>
>> Chao suggests this option. because user hints are more accurate than
>> file system.
>>
>> This is resonable, But I have some concerns about this option. 
>> The first thing is that blocks of a segments have different hints. This
>> could make GC less effective. 
>> The second is that the separation between LIFE_MEDIUM and LIFE_LONG is 
>> really needed. I think that difference between them is a little ambigous 
>> for users, and LIFE_SHORT and LIFE_EXTREME is converted to different 
>> hints by F2FS.
> 
> I think what we really can do would assign many user hints to our 3 DATA
> logs likewise rw_hint_to_seg_type(), since it's just hints for user data.
> Then, we can decide how to keep that as much as possible, since we have
> another filesystem metadata such as meta and nodes. In addition, I don't
> think we have to keep the original user-hints which makes F2FS logs be
> messed up.
> 
> With that mind, I can think of the below cases. Especially, if user wants
> to keep their io_hints, we'd better recommend to use direct_io w/o fs_iohints.
> In order to keep this policy, I think fs_iohints would be better to be a
> feature set by mkfs.f2fs and detected by sysfs entries for users.
> 
> 1) w/ fs_iohints
> 
> UserF2FS   Block
> ---
> Meta   WRITE_LIFE_MEDIUM
> HOT_NODE   WRITE_LIFE_NOTSET
> WARM_NODE  -'
> COLD_NODE  WRITE_LIFE_NONE
> ioctl(cold) COLD_DATA  WRITE_LIFE_EXTREME
> extention list  -' -'
> WRITE_LIFE_EXTREME  -' -'
> WRITE_LIFE_SHORTHOT_DATA   WRITE_LIFE_SHORT
> 
> -- buffered_io
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_LONG
> WRITE_LIFE_NONE -' -'
> WRITE_LIFE_MEDIUM   -' -'
> WRITE_LIFE_LONG -' -'
> 
> -- direct_io (Not recommendable)
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_NOT_SET
> WRITE_LIFE_NONE -' WRITE_LIFE_NONE
> WRITE_LIFE_MEDIUM   -' WRITE_LIFE_MEDIUM
> WRITE_LIFE_LONG -' WRITE_LIFE_LONG
> 
> 2) w/o fs_iohints
> 
> UserF2FS   Block
> ---
> Meta   -
> HOT_NODE   -
> WARM_NODE  -
> COLD_NODE  -
> ioctl(cold) COLD_DATA  -
> extention list  -' -
> 
> -- buffered_io
> WRITE_LIFE_EXTREME  COLD_DATA  -
> WRITE_LIFE_SHORTHOT_DATA   -
> WRITE_LIFE_NOT_SET  WARM_DATA  -
> WRITE_LIFE_NONE -' -
> WRITE_LIFE_MEDIUM   -' -
> WRITE_LIFE_LONG -' -
> 
> -- direct_io
> WRITE_LIFE_EXTREME  COLD_DATA  WRITE_LIFE_EXTREME
> WRITE_LIFE_SHORTHOT_DATA   WRITE_LIFE_SHORT
> WRITE_LIFE_NOT_SET  WARM_DATA  WRITE_LIFE_NOT_SET
> WRITE_LIFE_NONE -' WRITE_LIFE_NONE
> WRITE_LIFE_MEDIUM   -' WRITE_LIFE_MEDIUM
> WRITE_LIFE_LONG -' WRITE_LIFE_LONG
> 
> 
> Note that, I don't much care about how to manipulate streamid in nvme driver
> in terms of LIFE_NONE or LIFE_NOTSET, since other drivers can handle them
> in different ways. Taking a look at the definition, at least, we don't need
> to assume that those are same at all. For example, if we can expolit this in
> UFS driver, we can pass all the stream ids to the device as context ids.
> 
> Thanks,
> 
>>
>> Thanks.
>>
>> On 12/12/2017 11:45 AM, Chao Yu wrote:
>>> Hi Hyunchul,
>>>
>>> On 2017/12/12 10:15, Hyunchul Lee wrote:
 Hi Chao,

 On 12/11/2017 10:15 PM, Chao Yu wrote:
> Hi Hyunchul,
>
> On 2017/12/1 16:28, Hyunchul Lee wrote:
>> Hi Chao,
>>
>> On 11/30/2017 04:06 PM, Chao Yu wrote:
>>> Hi Hyunchul,
>>>
>>> On 2017/11/28 8:23, Hyunchul Lee wrote:
 From: Hyunchul Lee 

 This implements which hint is passed down to block layer
 for datas from the specific segment type.

 segment type

[PATCH 1/2] perf-probe: Ensure debuginfo's build-id is correct

2017-12-17 Thread Masami Hiramatsu
Ensure that the build-id of debuginfo is correctly
matched to target build-id, if not, it warns user
to check the system debuginfo package is correctly
installed.

E.g. on such environment, you will see below warning.
  ==
  # perf probe -l
  WARN: There is a build-id mismatch between
   /usr/lib/debug/usr/lib64/libc-2.25.so.debug
   and
   /usr/lib64/libc-2.25.so
  Please check your system's debuginfo files for mismatches, e.g. check
  the versions for the target package and debuginfo package.
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in /us
  r/lib64/libc-2.25.so)
  ==

Signed-off-by: Masami Hiramatsu 
---
 tools/perf/util/probe-finder.c |   18 ++
 1 file changed, 18 insertions(+)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a5731de0e5eb..5bb71e056b21 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -119,9 +119,11 @@ enum dso_binary_type distro_dwarf_types[] = {
 
 struct debuginfo *debuginfo__new(const char *path)
 {
+   u8 bid[BUILD_ID_SIZE], bid2[BUILD_ID_SIZE];
enum dso_binary_type *type;
char buf[PATH_MAX], nil = '\0';
struct dso *dso;
+   bool have_build_id = false;
struct debuginfo *dinfo = NULL;
 
/* Try to open distro debuginfo files */
@@ -129,12 +131,28 @@ struct debuginfo *debuginfo__new(const char *path)
if (!dso)
goto out;
 
+   if (filename__read_build_id(path, bid, BUILD_ID_SIZE) > 0)
+   have_build_id = true;
+
for (type = distro_dwarf_types;
 !dinfo && *type != DSO_BINARY_TYPE__NOT_FOUND;
 type++) {
if (dso__read_binary_type_filename(dso, *type, ,
   buf, PATH_MAX) < 0)
continue;
+
+   if (have_build_id) {
+   /* This can be fail because the file doesn't exist */
+   if (filename__read_build_id(buf, bid2,
+   BUILD_ID_SIZE) < 0)
+   continue;
+   if (memcmp(bid, bid2, BUILD_ID_SIZE)) {
+   pr_warning("WARN: There is a build-id mismatch 
between\n %s\n and\n %s\n"
+   "Please check your system's debuginfo 
files for mismatches, e.g. check the "
+   "versions for the target package and 
debuginfo package.\n", buf, path);
+   continue;
+   }
+   }
dinfo = __debuginfo__new(buf);
}
dso__put(dso);



[PATCH v4 03/36] nds32: Assembly macros and definitions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes assembly macros, bit field definitions used in .S
files across arch/nds32/.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/assembler.h |   39 ++
 arch/nds32/include/asm/bitfield.h  |  963 
 arch/nds32/include/asm/nds32.h |   83 
 arch/nds32/kernel/asm-offsets.c|   28 ++
 4 files changed, 1113 insertions(+)
 create mode 100644 arch/nds32/include/asm/assembler.h
 create mode 100644 arch/nds32/include/asm/bitfield.h
 create mode 100644 arch/nds32/include/asm/nds32.h
 create mode 100644 arch/nds32/kernel/asm-offsets.c

diff --git a/arch/nds32/include/asm/assembler.h 
b/arch/nds32/include/asm/assembler.h
new file mode 100644
index 000..c385578
--- /dev/null
+++ b/arch/nds32/include/asm/assembler.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_ASSEMBLER_H__
+#define __NDS32_ASSEMBLER_H__
+
+.macro gie_disable
+   setgie.d
+   dsb
+.endm
+
+.macro gie_enable
+   setgie.e
+   dsb
+.endm
+
+.macro gie_save oldpsw
+   mfsr \oldpsw, $ir0
+   setgie.d
+dsb
+.endm
+
+.macro gie_restore oldpsw
+   andi \oldpsw, \oldpsw, #0x1
+   beqz \oldpsw, 7001f
+   setgie.e
+   dsb
+7001:
+.endm
+
+
+#define USER(insn,  reg, addr, opr)\
+:  insn  reg, addr, opr;   \
+   .section __ex_table,"a";\
+   .align 3;   \
+   .long   b, 9001f;   \
+   .previous
+
+#endif /* __NDS32_ASSEMBLER_H__ */
diff --git a/arch/nds32/include/asm/bitfield.h 
b/arch/nds32/include/asm/bitfield.h
new file mode 100644
index 000..c73f71d
--- /dev/null
+++ b/arch/nds32/include/asm/bitfield.h
@@ -0,0 +1,963 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_BITFIELD_H__
+#define __NDS32_BITFIELD_H__
+/**
+ * cr0: CPU_VER (CPU Version Register)
+ */
+#define CPU_VER_offCFGID   0   /* Minor configuration */
+#define CPU_VER_offREV 16  /* Revision of the CPU version */
+#define CPU_VER_offCPUID   24  /* Major CPU versions */
+
+#define CPU_VER_mskCFGID   ( 0x  << CPU_VER_offCFGID )
+#define CPU_VER_mskREV ( 0xFF  << CPU_VER_offREV )
+#define CPU_VER_mskCPUID   ( 0xFF  << CPU_VER_offCPUID )
+
+/**
+ * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register)
+ */
+#define ICM_CFG_offISET0   /* I-cache sets (# of cache 
lines) per way */
+#define ICM_CFG_offIWAY3   /* I-cache ways */
+#define ICM_CFG_offISZ 6   /* I-cache line size */
+#define ICM_CFG_offILCK9   /* I-cache locking support */
+#define ICM_CFG_offILMB10  /* On-chip ILM banks */
+#define ICM_CFG_offBSAV13  /* ILM base register alignment 
version */
+/* bit 15:31 reserved */
+
+#define ICM_CFG_mskISET( 0x7  << ICM_CFG_offISET )
+#define ICM_CFG_mskIWAY( 0x7  << ICM_CFG_offIWAY )
+#define ICM_CFG_mskISZ ( 0x7  << ICM_CFG_offISZ )
+#define ICM_CFG_mskILCK( 0x1  << ICM_CFG_offILCK )
+#define ICM_CFG_mskILMB( 0x7  << ICM_CFG_offILMB )
+#define ICM_CFG_mskBSAV( 0x3  << ICM_CFG_offBSAV )
+
+/**
+ * cr2: DCM_CFG (Data Cache/Memory Configuration Register)
+ */
+#define DCM_CFG_offDSET0   /* D-cache sets (# of cache 
lines) per way */
+#define DCM_CFG_offDWAY3   /* D-cache ways */
+#define DCM_CFG_offDSZ 6   /* D-cache line size */
+#define DCM_CFG_offDLCK9   /* D-cache locking support */
+#define DCM_CFG_offDLMB10  /* On-chip DLM banks */
+#define DCM_CFG_offBSAV13  /* DLM base register alignment 
version */
+/* bit 15:31 reserved */
+
+#define DCM_CFG_mskDSET( 0x7  << DCM_CFG_offDSET )
+#define DCM_CFG_mskDWAY( 0x7  << DCM_CFG_offDWAY )
+#define DCM_CFG_mskDSZ ( 0x7  << DCM_CFG_offDSZ )
+#define DCM_CFG_mskDLCK( 0x1  << DCM_CFG_offDLCK )
+#define DCM_CFG_mskDLMB( 0x7  << DCM_CFG_offDLMB )
+#define DCM_CFG_mskBSAV( 0x3  << DCM_CFG_offBSAV )
+
+/**
+ * cr3: MMU_CFG (MMU 

[PATCH v4 03/36] nds32: Assembly macros and definitions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes assembly macros, bit field definitions used in .S
files across arch/nds32/.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/assembler.h |   39 ++
 arch/nds32/include/asm/bitfield.h  |  963 
 arch/nds32/include/asm/nds32.h |   83 
 arch/nds32/kernel/asm-offsets.c|   28 ++
 4 files changed, 1113 insertions(+)
 create mode 100644 arch/nds32/include/asm/assembler.h
 create mode 100644 arch/nds32/include/asm/bitfield.h
 create mode 100644 arch/nds32/include/asm/nds32.h
 create mode 100644 arch/nds32/kernel/asm-offsets.c

diff --git a/arch/nds32/include/asm/assembler.h 
b/arch/nds32/include/asm/assembler.h
new file mode 100644
index 000..c385578
--- /dev/null
+++ b/arch/nds32/include/asm/assembler.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_ASSEMBLER_H__
+#define __NDS32_ASSEMBLER_H__
+
+.macro gie_disable
+   setgie.d
+   dsb
+.endm
+
+.macro gie_enable
+   setgie.e
+   dsb
+.endm
+
+.macro gie_save oldpsw
+   mfsr \oldpsw, $ir0
+   setgie.d
+dsb
+.endm
+
+.macro gie_restore oldpsw
+   andi \oldpsw, \oldpsw, #0x1
+   beqz \oldpsw, 7001f
+   setgie.e
+   dsb
+7001:
+.endm
+
+
+#define USER(insn,  reg, addr, opr)\
+:  insn  reg, addr, opr;   \
+   .section __ex_table,"a";\
+   .align 3;   \
+   .long   b, 9001f;   \
+   .previous
+
+#endif /* __NDS32_ASSEMBLER_H__ */
diff --git a/arch/nds32/include/asm/bitfield.h 
b/arch/nds32/include/asm/bitfield.h
new file mode 100644
index 000..c73f71d
--- /dev/null
+++ b/arch/nds32/include/asm/bitfield.h
@@ -0,0 +1,963 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_BITFIELD_H__
+#define __NDS32_BITFIELD_H__
+/**
+ * cr0: CPU_VER (CPU Version Register)
+ */
+#define CPU_VER_offCFGID   0   /* Minor configuration */
+#define CPU_VER_offREV 16  /* Revision of the CPU version */
+#define CPU_VER_offCPUID   24  /* Major CPU versions */
+
+#define CPU_VER_mskCFGID   ( 0x  << CPU_VER_offCFGID )
+#define CPU_VER_mskREV ( 0xFF  << CPU_VER_offREV )
+#define CPU_VER_mskCPUID   ( 0xFF  << CPU_VER_offCPUID )
+
+/**
+ * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register)
+ */
+#define ICM_CFG_offISET0   /* I-cache sets (# of cache 
lines) per way */
+#define ICM_CFG_offIWAY3   /* I-cache ways */
+#define ICM_CFG_offISZ 6   /* I-cache line size */
+#define ICM_CFG_offILCK9   /* I-cache locking support */
+#define ICM_CFG_offILMB10  /* On-chip ILM banks */
+#define ICM_CFG_offBSAV13  /* ILM base register alignment 
version */
+/* bit 15:31 reserved */
+
+#define ICM_CFG_mskISET( 0x7  << ICM_CFG_offISET )
+#define ICM_CFG_mskIWAY( 0x7  << ICM_CFG_offIWAY )
+#define ICM_CFG_mskISZ ( 0x7  << ICM_CFG_offISZ )
+#define ICM_CFG_mskILCK( 0x1  << ICM_CFG_offILCK )
+#define ICM_CFG_mskILMB( 0x7  << ICM_CFG_offILMB )
+#define ICM_CFG_mskBSAV( 0x3  << ICM_CFG_offBSAV )
+
+/**
+ * cr2: DCM_CFG (Data Cache/Memory Configuration Register)
+ */
+#define DCM_CFG_offDSET0   /* D-cache sets (# of cache 
lines) per way */
+#define DCM_CFG_offDWAY3   /* D-cache ways */
+#define DCM_CFG_offDSZ 6   /* D-cache line size */
+#define DCM_CFG_offDLCK9   /* D-cache locking support */
+#define DCM_CFG_offDLMB10  /* On-chip DLM banks */
+#define DCM_CFG_offBSAV13  /* DLM base register alignment 
version */
+/* bit 15:31 reserved */
+
+#define DCM_CFG_mskDSET( 0x7  << DCM_CFG_offDSET )
+#define DCM_CFG_mskDWAY( 0x7  << DCM_CFG_offDWAY )
+#define DCM_CFG_mskDSZ ( 0x7  << DCM_CFG_offDSZ )
+#define DCM_CFG_mskDLCK( 0x1  << DCM_CFG_offDLCK )
+#define DCM_CFG_mskDLMB( 0x7  << DCM_CFG_offDLMB )
+#define DCM_CFG_mskBSAV( 0x3  << DCM_CFG_offBSAV )
+
+/**
+ * cr3: MMU_CFG (MMU Configuration Register)
+ 

[PATCH v4 05/36] nds32: Exception handling

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes the exception/interrupt entries, pt_reg structure and
related accessors.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/ptrace.h |   66 +
 arch/nds32/kernel/ex-entry.S|  157 ++
 arch/nds32/kernel/ex-exit.S |  193 +
 arch/nds32/kernel/stacktrace.c  |   47 +++
 arch/nds32/kernel/traps.c   |  428 +++
 arch/nds32/mm/alignment.c   |  609 +++
 6 files changed, 1500 insertions(+)
 create mode 100644 arch/nds32/include/asm/ptrace.h
 create mode 100644 arch/nds32/kernel/ex-entry.S
 create mode 100644 arch/nds32/kernel/ex-exit.S
 create mode 100644 arch/nds32/kernel/stacktrace.c
 create mode 100644 arch/nds32/kernel/traps.c
 create mode 100644 arch/nds32/mm/alignment.c

diff --git a/arch/nds32/include/asm/ptrace.h b/arch/nds32/include/asm/ptrace.h
new file mode 100644
index 000..db7856c
--- /dev/null
+++ b/arch/nds32/include/asm/ptrace.h
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_PTRACE_H
+#define __ASM_NDS32_PTRACE_H
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS   14
+#define PTRACE_SETFPREGS   15
+
+#include 
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+   union {
+   struct user_pt_regs user_regs;
+   struct {
+   long uregs[26];
+   long fp;
+   long gp;
+   long lp;
+   long sp;
+   long ipc;
+#if defined(CONFIG_HWZOL)
+   long lb;
+   long le;
+   long lc;
+#else
+   long dummy[3];
+#endif
+   long syscallno;
+   };
+   };
+   long orig_r0;
+   long ir0;
+   long ipsw;
+   long pipsw;
+   long pipc;
+   long pp0;
+   long pp1;
+   long fucop_ctl;
+   long osp;
+};
+
+#include 
+extern void show_regs(struct pt_regs *);
+/* Avoid circular header include via sched.h */
+struct task_struct;
+extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+int error_code, int si_code);
+
+#define arch_has_single_step() (1)
+#define user_mode(regs)(((regs)->ipsw & PSW_mskPOM) == 
0)
+#define interrupts_enabled(regs)   (!!((regs)->ipsw & PSW_mskGIE))
+#define valid_user_regs(regs)  (user_mode(regs) && 
interrupts_enabled(regs))
+#define regs_return_value(regs)((regs)->uregs[0])
+#define instruction_pointer(regs)  ((regs)->ipc)
+#define user_stack_pointer(regs)((regs)->sp)
+#define profile_pc(regs)   instruction_pointer(regs)
+
+#define ARCH_HAS_USER_SINGLE_STEP_INFO
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/nds32/kernel/ex-entry.S b/arch/nds32/kernel/ex-entry.S
new file mode 100644
index 000..d2b3b8a
--- /dev/null
+++ b/arch/nds32/kernel/ex-entry.S
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_HWZOL
+   .macro push_zol
+   mfusr   $r14, $LB
+   mfusr   $r15, $LE
+   mfusr   $r16, $LC
+   .endm
+#endif
+
+   .macro  save_user_regs
+
+   smw.adm $sp, [$sp], $sp, #0x1
+   /* move $SP to the bottom of pt_regs */
+   addi$sp, $sp, -OSP_OFFSET
+
+   /* push $r0 ~ $r25 */
+   smw.bim $r0, [$sp], $r25
+   /* push $fp, $gp, $lp */
+   smw.bim $sp, [$sp], $sp, #0xe
+
+   mfsr$r12, $SP_USR
+   mfsr$r13, $IPC
+#ifdef CONFIG_HWZOL
+   push_zol
+#endif
+   movi$r17, -1
+   move$r18, $r0
+   mfsr$r19, $PSW
+   mfsr$r20, $IPSW
+   mfsr$r21, $P_IPSW
+   mfsr$r22, $P_IPC
+   mfsr$r23, $P_P0
+   mfsr$r24, $P_P1
+   smw.bim $r12, [$sp], $r24, #0
+   addi$sp, $sp, -FUCOP_CTL_OFFSET
+
+   /* Initialize kernel space $fp */
+   andi$p0, $r20, #PSW_mskPOM
+   movi$p1, #0x0
+   cmovz   $fp, $p1, $p0
+
+   andi$r16, $r19, #PSW_mskINTL
+   slti$r17, $r16, #4
+   bnez$r17, 1f
+   addi$r17, $r19, #-2
+   mtsr$r17, $PSW
+   isb
+1:
+   /* If it was superuser mode, we don't need to update $r25 */
+   bnez$p0, 2f
+   la  $p0, __entry_task
+   lw  $r25, [$p0]
+2:
+   .endm
+
+   .text
+
+/*
+ * Exception Vector
+ */
+exception_handlers:
+   .long   unhandled_exceptions!Reset/NMI
+   .long   unhandled_exceptions!TLB fill
+   .long   do_page_fault   !PTE not present
+   .long   

[PATCH v4 05/36] nds32: Exception handling

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes the exception/interrupt entries, pt_reg structure and
related accessors.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/ptrace.h |   66 +
 arch/nds32/kernel/ex-entry.S|  157 ++
 arch/nds32/kernel/ex-exit.S |  193 +
 arch/nds32/kernel/stacktrace.c  |   47 +++
 arch/nds32/kernel/traps.c   |  428 +++
 arch/nds32/mm/alignment.c   |  609 +++
 6 files changed, 1500 insertions(+)
 create mode 100644 arch/nds32/include/asm/ptrace.h
 create mode 100644 arch/nds32/kernel/ex-entry.S
 create mode 100644 arch/nds32/kernel/ex-exit.S
 create mode 100644 arch/nds32/kernel/stacktrace.c
 create mode 100644 arch/nds32/kernel/traps.c
 create mode 100644 arch/nds32/mm/alignment.c

diff --git a/arch/nds32/include/asm/ptrace.h b/arch/nds32/include/asm/ptrace.h
new file mode 100644
index 000..db7856c
--- /dev/null
+++ b/arch/nds32/include/asm/ptrace.h
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_PTRACE_H
+#define __ASM_NDS32_PTRACE_H
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS   14
+#define PTRACE_SETFPREGS   15
+
+#include 
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+   union {
+   struct user_pt_regs user_regs;
+   struct {
+   long uregs[26];
+   long fp;
+   long gp;
+   long lp;
+   long sp;
+   long ipc;
+#if defined(CONFIG_HWZOL)
+   long lb;
+   long le;
+   long lc;
+#else
+   long dummy[3];
+#endif
+   long syscallno;
+   };
+   };
+   long orig_r0;
+   long ir0;
+   long ipsw;
+   long pipsw;
+   long pipc;
+   long pp0;
+   long pp1;
+   long fucop_ctl;
+   long osp;
+};
+
+#include 
+extern void show_regs(struct pt_regs *);
+/* Avoid circular header include via sched.h */
+struct task_struct;
+extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+int error_code, int si_code);
+
+#define arch_has_single_step() (1)
+#define user_mode(regs)(((regs)->ipsw & PSW_mskPOM) == 
0)
+#define interrupts_enabled(regs)   (!!((regs)->ipsw & PSW_mskGIE))
+#define valid_user_regs(regs)  (user_mode(regs) && 
interrupts_enabled(regs))
+#define regs_return_value(regs)((regs)->uregs[0])
+#define instruction_pointer(regs)  ((regs)->ipc)
+#define user_stack_pointer(regs)((regs)->sp)
+#define profile_pc(regs)   instruction_pointer(regs)
+
+#define ARCH_HAS_USER_SINGLE_STEP_INFO
+
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/nds32/kernel/ex-entry.S b/arch/nds32/kernel/ex-entry.S
new file mode 100644
index 000..d2b3b8a
--- /dev/null
+++ b/arch/nds32/kernel/ex-entry.S
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_HWZOL
+   .macro push_zol
+   mfusr   $r14, $LB
+   mfusr   $r15, $LE
+   mfusr   $r16, $LC
+   .endm
+#endif
+
+   .macro  save_user_regs
+
+   smw.adm $sp, [$sp], $sp, #0x1
+   /* move $SP to the bottom of pt_regs */
+   addi$sp, $sp, -OSP_OFFSET
+
+   /* push $r0 ~ $r25 */
+   smw.bim $r0, [$sp], $r25
+   /* push $fp, $gp, $lp */
+   smw.bim $sp, [$sp], $sp, #0xe
+
+   mfsr$r12, $SP_USR
+   mfsr$r13, $IPC
+#ifdef CONFIG_HWZOL
+   push_zol
+#endif
+   movi$r17, -1
+   move$r18, $r0
+   mfsr$r19, $PSW
+   mfsr$r20, $IPSW
+   mfsr$r21, $P_IPSW
+   mfsr$r22, $P_IPC
+   mfsr$r23, $P_P0
+   mfsr$r24, $P_P1
+   smw.bim $r12, [$sp], $r24, #0
+   addi$sp, $sp, -FUCOP_CTL_OFFSET
+
+   /* Initialize kernel space $fp */
+   andi$p0, $r20, #PSW_mskPOM
+   movi$p1, #0x0
+   cmovz   $fp, $p1, $p0
+
+   andi$r16, $r19, #PSW_mskINTL
+   slti$r17, $r16, #4
+   bnez$r17, 1f
+   addi$r17, $r19, #-2
+   mtsr$r17, $PSW
+   isb
+1:
+   /* If it was superuser mode, we don't need to update $r25 */
+   bnez$p0, 2f
+   la  $p0, __entry_task
+   lw  $r25, [$p0]
+2:
+   .endm
+
+   .text
+
+/*
+ * Exception Vector
+ */
+exception_handlers:
+   .long   unhandled_exceptions!Reset/NMI
+   .long   unhandled_exceptions!TLB fill
+   .long   do_page_fault   !PTE not present
+   .long   do_dispatch_tlb_misc!TLB misc
+   .long   unhandled_exceptions!TLB VLPT
+  

[PATCH v4 07/36] nds32: MMU initialization

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes memory initializations and highmem supporting.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/mm/highmem.c  |   79 +
 arch/nds32/mm/init.c |  277 ++
 arch/nds32/mm/mm-nds32.c |   90 +++
 3 files changed, 446 insertions(+)
 create mode 100644 arch/nds32/mm/highmem.c
 create mode 100644 arch/nds32/mm/init.c
 create mode 100644 arch/nds32/mm/mm-nds32.c

diff --git a/arch/nds32/mm/highmem.c b/arch/nds32/mm/highmem.c
new file mode 100644
index 000..e17cb8a
--- /dev/null
+++ b/arch/nds32/mm/highmem.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void *kmap(struct page *page)
+{
+   unsigned long vaddr;
+   might_sleep();
+   if (!PageHighMem(page))
+   return page_address(page);
+   vaddr = (unsigned long)kmap_high(page);
+   return (void *)vaddr;
+}
+
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+   BUG_ON(in_interrupt());
+   if (!PageHighMem(page))
+   return;
+   kunmap_high(page);
+}
+
+EXPORT_SYMBOL(kunmap);
+
+void *kmap_atomic(struct page *page)
+{
+   unsigned int idx;
+   unsigned long vaddr, pte;
+   int type;
+   pte_t *ptep;
+
+   preempt_disable();
+   pagefault_disable();
+   if (!PageHighMem(page))
+   return page_address(page);
+
+   type = kmap_atomic_idx_push();
+
+   idx = type + KM_TYPE_NR * smp_processor_id();
+   vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+   pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL);
+   ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+   set_pte(ptep, pte);
+
+   __nds32__tlbop_inv(vaddr);
+   __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);
+   __nds32__tlbop_rwr(pte);
+   __nds32__isb();
+   return (void *)vaddr;
+}
+
+EXPORT_SYMBOL(kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+   if (kvaddr >= (void *)FIXADDR_START) {
+   unsigned long vaddr = (unsigned long)kvaddr;
+   pte_t *ptep;
+   kmap_atomic_idx_pop();
+   __nds32__tlbop_inv(vaddr);
+   __nds32__isb();
+   ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+   set_pte(ptep, 0);
+   }
+   pagefault_enable();
+   preempt_enable();
+}
+
+EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c
new file mode 100644
index 000..93ee016
--- /dev/null
+++ b/arch/nds32/mm/init.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 1995-2005 Russell King
+// Copyright (C) 2012 ARM Ltd.
+// Copyright (C) 2013-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+DEFINE_SPINLOCK(anon_alias_lock);
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern unsigned long phys_initrd_start;
+extern unsigned long phys_initrd_size;
+
+/*
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
+ */
+struct page *empty_zero_page;
+
+static void __init zone_sizes_init(void)
+{
+   unsigned long zones_size[MAX_NR_ZONES];
+
+   /* Clear the zone sizes */
+   memset(zones_size, 0, sizeof(zones_size));
+
+   zones_size[ZONE_NORMAL] = max_low_pfn;
+#ifdef CONFIG_HIGHMEM
+   zones_size[ZONE_HIGHMEM] = max_pfn;
+#endif
+   free_area_init(zones_size);
+
+}
+
+/*
+ * Map all physical memory under high_memory into kernel's address space.
+ *
+ * This is explicitly coded for two-level page tables, so if you need
+ * something else then this needs to change.
+ */
+static void __init map_ram(void)
+{
+   unsigned long v, p, e;
+   pgd_t *pge;
+   pud_t *pue;
+   pmd_t *pme;
+   pte_t *pte;
+   /* These mark extents of read-only kernel pages...
+* ...from vmlinux.lds.S
+*/
+
+   p = (u32) memblock_start_of_DRAM() & PAGE_MASK;
+   e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory));
+
+   v = (u32) __va(p);
+   pge = pgd_offset_k(v);
+
+   while (p < e) {
+   int j;
+   pue = pud_offset(pge, v);
+   pme = pmd_offset(pue, v);
+
+   if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
+   panic("%s: Kernel hardcoded for "
+ "two-level page tables", __func__);
+   }
+
+   /* Alloc one page for holding PTE's... */
+   pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+   memset(pte, 0, 

[PATCH v4 07/36] nds32: MMU initialization

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes memory initializations and highmem supporting.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/mm/highmem.c  |   79 +
 arch/nds32/mm/init.c |  277 ++
 arch/nds32/mm/mm-nds32.c |   90 +++
 3 files changed, 446 insertions(+)
 create mode 100644 arch/nds32/mm/highmem.c
 create mode 100644 arch/nds32/mm/init.c
 create mode 100644 arch/nds32/mm/mm-nds32.c

diff --git a/arch/nds32/mm/highmem.c b/arch/nds32/mm/highmem.c
new file mode 100644
index 000..e17cb8a
--- /dev/null
+++ b/arch/nds32/mm/highmem.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void *kmap(struct page *page)
+{
+   unsigned long vaddr;
+   might_sleep();
+   if (!PageHighMem(page))
+   return page_address(page);
+   vaddr = (unsigned long)kmap_high(page);
+   return (void *)vaddr;
+}
+
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+   BUG_ON(in_interrupt());
+   if (!PageHighMem(page))
+   return;
+   kunmap_high(page);
+}
+
+EXPORT_SYMBOL(kunmap);
+
+void *kmap_atomic(struct page *page)
+{
+   unsigned int idx;
+   unsigned long vaddr, pte;
+   int type;
+   pte_t *ptep;
+
+   preempt_disable();
+   pagefault_disable();
+   if (!PageHighMem(page))
+   return page_address(page);
+
+   type = kmap_atomic_idx_push();
+
+   idx = type + KM_TYPE_NR * smp_processor_id();
+   vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+   pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL);
+   ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+   set_pte(ptep, pte);
+
+   __nds32__tlbop_inv(vaddr);
+   __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);
+   __nds32__tlbop_rwr(pte);
+   __nds32__isb();
+   return (void *)vaddr;
+}
+
+EXPORT_SYMBOL(kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+   if (kvaddr >= (void *)FIXADDR_START) {
+   unsigned long vaddr = (unsigned long)kvaddr;
+   pte_t *ptep;
+   kmap_atomic_idx_pop();
+   __nds32__tlbop_inv(vaddr);
+   __nds32__isb();
+   ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+   set_pte(ptep, 0);
+   }
+   pagefault_enable();
+   preempt_enable();
+}
+
+EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/nds32/mm/init.c b/arch/nds32/mm/init.c
new file mode 100644
index 000..93ee016
--- /dev/null
+++ b/arch/nds32/mm/init.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 1995-2005 Russell King
+// Copyright (C) 2012 ARM Ltd.
+// Copyright (C) 2013-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+DEFINE_SPINLOCK(anon_alias_lock);
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern unsigned long phys_initrd_start;
+extern unsigned long phys_initrd_size;
+
+/*
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
+ */
+struct page *empty_zero_page;
+
+static void __init zone_sizes_init(void)
+{
+   unsigned long zones_size[MAX_NR_ZONES];
+
+   /* Clear the zone sizes */
+   memset(zones_size, 0, sizeof(zones_size));
+
+   zones_size[ZONE_NORMAL] = max_low_pfn;
+#ifdef CONFIG_HIGHMEM
+   zones_size[ZONE_HIGHMEM] = max_pfn;
+#endif
+   free_area_init(zones_size);
+
+}
+
+/*
+ * Map all physical memory under high_memory into kernel's address space.
+ *
+ * This is explicitly coded for two-level page tables, so if you need
+ * something else then this needs to change.
+ */
+static void __init map_ram(void)
+{
+   unsigned long v, p, e;
+   pgd_t *pge;
+   pud_t *pue;
+   pmd_t *pme;
+   pte_t *pte;
+   /* These mark extents of read-only kernel pages...
+* ...from vmlinux.lds.S
+*/
+
+   p = (u32) memblock_start_of_DRAM() & PAGE_MASK;
+   e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory));
+
+   v = (u32) __va(p);
+   pge = pgd_offset_k(v);
+
+   while (p < e) {
+   int j;
+   pue = pud_offset(pge, v);
+   pme = pmd_offset(pue, v);
+
+   if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
+   panic("%s: Kernel hardcoded for "
+ "two-level page tables", __func__);
+   }
+
+   /* Alloc one page for holding PTE's... */
+   pte = (pte_t *) __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
+   memset(pte, 0, PAGE_SIZE);
+   set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));

[PATCH v4 09/36] nds32: Cache and TLB routines

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch contains cache and TLB maintenance functions.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/cache.h |   12 +
 arch/nds32/include/asm/cache_info.h|   13 +
 arch/nds32/include/asm/cacheflush.h|   44 +++
 arch/nds32/include/asm/mmu_context.h   |   68 
 arch/nds32/include/asm/proc-fns.h  |   44 +++
 arch/nds32/include/asm/tlb.h   |   28 ++
 arch/nds32/include/asm/tlbflush.h  |   47 +++
 arch/nds32/include/uapi/asm/cachectl.h |   14 +
 arch/nds32/kernel/cacheinfo.c  |   49 +++
 arch/nds32/mm/cacheflush.c |  322 +++
 arch/nds32/mm/proc.c   |  540 
 arch/nds32/mm/tlb.c|   50 +++
 12 files changed, 1231 insertions(+)
 create mode 100644 arch/nds32/include/asm/cache.h
 create mode 100644 arch/nds32/include/asm/cache_info.h
 create mode 100644 arch/nds32/include/asm/cacheflush.h
 create mode 100644 arch/nds32/include/asm/mmu_context.h
 create mode 100644 arch/nds32/include/asm/proc-fns.h
 create mode 100644 arch/nds32/include/asm/tlb.h
 create mode 100644 arch/nds32/include/asm/tlbflush.h
 create mode 100644 arch/nds32/include/uapi/asm/cachectl.h
 create mode 100644 arch/nds32/kernel/cacheinfo.c
 create mode 100644 arch/nds32/mm/cacheflush.c
 create mode 100644 arch/nds32/mm/proc.c
 create mode 100644 arch/nds32/mm/tlb.c

diff --git a/arch/nds32/include/asm/cache.h b/arch/nds32/include/asm/cache.h
new file mode 100644
index 000..347db48
--- /dev/null
+++ b/arch/nds32/include/asm/cache.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_CACHE_H__
+#define __NDS32_CACHE_H__
+
+#define L1_CACHE_BYTES 32
+#define L1_CACHE_SHIFT 5
+
+#define ARCH_DMA_MINALIGN   L1_CACHE_BYTES
+
+#endif /* __NDS32_CACHE_H__ */
diff --git a/arch/nds32/include/asm/cache_info.h 
b/arch/nds32/include/asm/cache_info.h
new file mode 100644
index 000..38ec458
--- /dev/null
+++ b/arch/nds32/include/asm/cache_info.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+struct cache_info {
+   unsigned char ways;
+   unsigned char line_size;
+   unsigned short sets;
+   unsigned short size;
+#if defined(CONFIG_CPU_CACHE_ALIASING)
+   unsigned short aliasing_num;
+   unsigned int aliasing_mask;
+#endif
+};
diff --git a/arch/nds32/include/asm/cacheflush.h 
b/arch/nds32/include/asm/cacheflush.h
new file mode 100644
index 000..7b9b20a
--- /dev/null
+++ b/arch/nds32/include/asm/cacheflush.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_CACHEFLUSH_H__
+#define __NDS32_CACHEFLUSH_H__
+
+#include 
+
+#define PG_dcache_dirty PG_arch_1
+
+#ifdef CONFIG_CPU_CACHE_ALIASING
+void flush_cache_mm(struct mm_struct *mm);
+void flush_cache_dup_mm(struct mm_struct *mm);
+void flush_cache_range(struct vm_area_struct *vma,
+  unsigned long start, unsigned long end);
+void flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn);
+void flush_cache_kmaps(void);
+void flush_cache_vmap(unsigned long start, unsigned long end);
+void flush_cache_vunmap(unsigned long start, unsigned long end);
+
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+void flush_dcache_page(struct page *page);
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+  unsigned long vaddr, void *dst, void *src, int len);
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+unsigned long vaddr, void *dst, void *src, int len);
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+void flush_anon_page(struct vm_area_struct *vma,
+struct page *page, unsigned long vaddr);
+
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+void flush_kernel_dcache_page(struct page *page);
+void flush_icache_range(unsigned long start, unsigned long end);
+void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+#define flush_dcache_mmap_lock(mapping)   spin_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping) 
spin_unlock_irq(&(mapping)->tree_lock)
+
+#else
+#include 
+#endif
+
+#endif /* __NDS32_CACHEFLUSH_H__ */
diff --git a/arch/nds32/include/asm/mmu_context.h 
b/arch/nds32/include/asm/mmu_context.h
new file mode 100644
index 000..fd7d13c
--- /dev/null
+++ b/arch/nds32/include/asm/mmu_context.h
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_MMU_CONTEXT_H
+#define __ASM_NDS32_MMU_CONTEXT_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)

[PATCH v4 09/36] nds32: Cache and TLB routines

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch contains cache and TLB maintenance functions.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/cache.h |   12 +
 arch/nds32/include/asm/cache_info.h|   13 +
 arch/nds32/include/asm/cacheflush.h|   44 +++
 arch/nds32/include/asm/mmu_context.h   |   68 
 arch/nds32/include/asm/proc-fns.h  |   44 +++
 arch/nds32/include/asm/tlb.h   |   28 ++
 arch/nds32/include/asm/tlbflush.h  |   47 +++
 arch/nds32/include/uapi/asm/cachectl.h |   14 +
 arch/nds32/kernel/cacheinfo.c  |   49 +++
 arch/nds32/mm/cacheflush.c |  322 +++
 arch/nds32/mm/proc.c   |  540 
 arch/nds32/mm/tlb.c|   50 +++
 12 files changed, 1231 insertions(+)
 create mode 100644 arch/nds32/include/asm/cache.h
 create mode 100644 arch/nds32/include/asm/cache_info.h
 create mode 100644 arch/nds32/include/asm/cacheflush.h
 create mode 100644 arch/nds32/include/asm/mmu_context.h
 create mode 100644 arch/nds32/include/asm/proc-fns.h
 create mode 100644 arch/nds32/include/asm/tlb.h
 create mode 100644 arch/nds32/include/asm/tlbflush.h
 create mode 100644 arch/nds32/include/uapi/asm/cachectl.h
 create mode 100644 arch/nds32/kernel/cacheinfo.c
 create mode 100644 arch/nds32/mm/cacheflush.c
 create mode 100644 arch/nds32/mm/proc.c
 create mode 100644 arch/nds32/mm/tlb.c

diff --git a/arch/nds32/include/asm/cache.h b/arch/nds32/include/asm/cache.h
new file mode 100644
index 000..347db48
--- /dev/null
+++ b/arch/nds32/include/asm/cache.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_CACHE_H__
+#define __NDS32_CACHE_H__
+
+#define L1_CACHE_BYTES 32
+#define L1_CACHE_SHIFT 5
+
+#define ARCH_DMA_MINALIGN   L1_CACHE_BYTES
+
+#endif /* __NDS32_CACHE_H__ */
diff --git a/arch/nds32/include/asm/cache_info.h 
b/arch/nds32/include/asm/cache_info.h
new file mode 100644
index 000..38ec458
--- /dev/null
+++ b/arch/nds32/include/asm/cache_info.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+struct cache_info {
+   unsigned char ways;
+   unsigned char line_size;
+   unsigned short sets;
+   unsigned short size;
+#if defined(CONFIG_CPU_CACHE_ALIASING)
+   unsigned short aliasing_num;
+   unsigned int aliasing_mask;
+#endif
+};
diff --git a/arch/nds32/include/asm/cacheflush.h 
b/arch/nds32/include/asm/cacheflush.h
new file mode 100644
index 000..7b9b20a
--- /dev/null
+++ b/arch/nds32/include/asm/cacheflush.h
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_CACHEFLUSH_H__
+#define __NDS32_CACHEFLUSH_H__
+
+#include 
+
+#define PG_dcache_dirty PG_arch_1
+
+#ifdef CONFIG_CPU_CACHE_ALIASING
+void flush_cache_mm(struct mm_struct *mm);
+void flush_cache_dup_mm(struct mm_struct *mm);
+void flush_cache_range(struct vm_area_struct *vma,
+  unsigned long start, unsigned long end);
+void flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn);
+void flush_cache_kmaps(void);
+void flush_cache_vmap(unsigned long start, unsigned long end);
+void flush_cache_vunmap(unsigned long start, unsigned long end);
+
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+void flush_dcache_page(struct page *page);
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+  unsigned long vaddr, void *dst, void *src, int len);
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+unsigned long vaddr, void *dst, void *src, int len);
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+void flush_anon_page(struct vm_area_struct *vma,
+struct page *page, unsigned long vaddr);
+
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+void flush_kernel_dcache_page(struct page *page);
+void flush_icache_range(unsigned long start, unsigned long end);
+void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+#define flush_dcache_mmap_lock(mapping)   spin_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping) 
spin_unlock_irq(&(mapping)->tree_lock)
+
+#else
+#include 
+#endif
+
+#endif /* __NDS32_CACHEFLUSH_H__ */
diff --git a/arch/nds32/include/asm/mmu_context.h 
b/arch/nds32/include/asm/mmu_context.h
new file mode 100644
index 000..fd7d13c
--- /dev/null
+++ b/arch/nds32/include/asm/mmu_context.h
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_MMU_CONTEXT_H
+#define __ASM_NDS32_MMU_CONTEXT_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+   mm->context.id = 0;
+   return 0;
+}
+
+#define 

[PATCH v4 11/36] nds32: IRQ handling

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes irq related functions and irqchip_init().

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/irqflags.h |   36 
 arch/nds32/kernel/irq.c   |9 +
 2 files changed, 45 insertions(+)
 create mode 100644 arch/nds32/include/asm/irqflags.h
 create mode 100644 arch/nds32/kernel/irq.c

diff --git a/arch/nds32/include/asm/irqflags.h 
b/arch/nds32/include/asm/irqflags.h
new file mode 100644
index 000..2bfd00f
--- /dev/null
+++ b/arch/nds32/include/asm/irqflags.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+
+#define arch_local_irq_disable()   \
+   GIE_DISABLE();
+
+#define arch_local_irq_enable()\
+   GIE_ENABLE();
+static inline unsigned long arch_local_irq_save(void)
+{
+   unsigned long flags;
+   flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
+   GIE_DISABLE();
+   return flags;
+}
+
+static inline unsigned long arch_local_save_flags(void)
+{
+   unsigned long flags;
+   flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
+   return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+   if(flags)
+   GIE_ENABLE();
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+   return !flags;
+}
diff --git a/arch/nds32/kernel/irq.c b/arch/nds32/kernel/irq.c
new file mode 100644
index 000..6ff5a67
--- /dev/null
+++ b/arch/nds32/kernel/irq.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+
+void __init init_IRQ(void)
+{
+   irqchip_init();
+}
-- 
1.7.9.5



[PATCH v4 11/36] nds32: IRQ handling

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes irq related functions and irqchip_init().

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/irqflags.h |   36 
 arch/nds32/kernel/irq.c   |9 +
 2 files changed, 45 insertions(+)
 create mode 100644 arch/nds32/include/asm/irqflags.h
 create mode 100644 arch/nds32/kernel/irq.c

diff --git a/arch/nds32/include/asm/irqflags.h 
b/arch/nds32/include/asm/irqflags.h
new file mode 100644
index 000..2bfd00f
--- /dev/null
+++ b/arch/nds32/include/asm/irqflags.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+
+#define arch_local_irq_disable()   \
+   GIE_DISABLE();
+
+#define arch_local_irq_enable()\
+   GIE_ENABLE();
+static inline unsigned long arch_local_irq_save(void)
+{
+   unsigned long flags;
+   flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
+   GIE_DISABLE();
+   return flags;
+}
+
+static inline unsigned long arch_local_save_flags(void)
+{
+   unsigned long flags;
+   flags = __nds32__mfsr(NDS32_SR_PSW) & PSW_mskGIE;
+   return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+   if(flags)
+   GIE_ENABLE();
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+   return !flags;
+}
diff --git a/arch/nds32/kernel/irq.c b/arch/nds32/kernel/irq.c
new file mode 100644
index 000..6ff5a67
--- /dev/null
+++ b/arch/nds32/kernel/irq.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+
+void __init init_IRQ(void)
+{
+   irqchip_init();
+}
-- 
1.7.9.5



[PATCH v4 15/36] nds32: ELF definitions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds definitions for the ELF format, relocation types, vdso
locations and EXEC_PAGESIZE.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/elf.h |  179 ++
 arch/nds32/include/uapi/asm/auxvec.h |   12 +++
 arch/nds32/include/uapi/asm/param.h  |   11 +++
 3 files changed, 202 insertions(+)
 create mode 100644 arch/nds32/include/asm/elf.h
 create mode 100644 arch/nds32/include/uapi/asm/auxvec.h
 create mode 100644 arch/nds32/include/uapi/asm/param.h

diff --git a/arch/nds32/include/asm/elf.h b/arch/nds32/include/asm/elf.h
new file mode 100644
index 000..99203f1
--- /dev/null
+++ b/arch/nds32/include/asm/elf.h
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASMNDS32_ELF_H
+#define __ASMNDS32_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include 
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+extern unsigned int elf_hwcap;
+
+#define EM_NDS32   167
+
+#define R_NDS32_NONE   0
+#define R_NDS32_16_RELA19
+#define R_NDS32_32_RELA20
+#define R_NDS32_9_PCREL_RELA   22
+#define R_NDS32_15_PCREL_RELA  23
+#define R_NDS32_17_PCREL_RELA  24
+#define R_NDS32_25_PCREL_RELA  25
+#define R_NDS32_HI20_RELA  26
+#define R_NDS32_LO12S3_RELA27
+#define R_NDS32_LO12S2_RELA28
+#define R_NDS32_LO12S1_RELA29
+#define R_NDS32_LO12S0_RELA30
+#define R_NDS32_SDA15S3_RELA   31
+#define R_NDS32_SDA15S2_RELA   32
+#define R_NDS32_SDA15S1_RELA   33
+#define R_NDS32_SDA15S0_RELA   34
+#define R_NDS32_GOT20  37
+#define R_NDS32_25_PLTREL  38
+#define R_NDS32_COPY   39
+#define R_NDS32_GLOB_DAT   40
+#define R_NDS32_JMP_SLOT   41
+#define R_NDS32_RELATIVE   42
+#define R_NDS32_GOTOFF 43
+#define R_NDS32_GOTPC2044
+#define R_NDS32_GOT_HI20   45
+#define R_NDS32_GOT_LO12   46
+#define R_NDS32_GOTPC_HI20 47
+#define R_NDS32_GOTPC_LO12 48
+#define R_NDS32_GOTOFF_HI2049
+#define R_NDS32_GOTOFF_LO1250
+#define R_NDS32_INSN16 51
+#define R_NDS32_LABEL  52
+#define R_NDS32_LONGCALL1  53
+#define R_NDS32_LONGCALL2  54
+#define R_NDS32_LONGCALL3  55
+#define R_NDS32_LONGJUMP1  56
+#define R_NDS32_LONGJUMP2  57
+#define R_NDS32_LONGJUMP3  58
+#define R_NDS32_LOADSTORE  59
+#define R_NDS32_9_FIXED_RELA   60
+#define R_NDS32_15_FIXED_RELA  61
+#define R_NDS32_17_FIXED_RELA  62
+#define R_NDS32_25_FIXED_RELA  63
+#define R_NDS32_PLTREL_HI2064
+#define R_NDS32_PLTREL_LO1265
+#define R_NDS32_PLT_GOTREL_HI2066
+#define R_NDS32_PLT_GOTREL_LO1267
+#define R_NDS32_LO12S0_ORI_RELA72
+#define R_NDS32_DWARF2_OP1_RELA77
+#define R_NDS32_DWARF2_OP2_RELA78
+#define R_NDS32_DWARF2_LEB_RELA79
+#define R_NDS32_WORD_9_PCREL_RELA  94
+#define R_NDS32_LONGCALL4  107
+#define R_NDS32_RELA_NOP_MIX   192
+#define R_NDS32_RELA_NOP_MAX   255
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is 

[PATCH v4 12/36] nds32: Atomic operations

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes the atomic and futex operations. Many atomic operations use
the load-lock word(llw) and store-condition word(scw) operations.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/barrier.h |   15 ++
 arch/nds32/include/asm/futex.h   |  103 ++
 2 files changed, 118 insertions(+)
 create mode 100644 arch/nds32/include/asm/barrier.h
 create mode 100644 arch/nds32/include/asm/futex.h

diff --git a/arch/nds32/include/asm/barrier.h b/arch/nds32/include/asm/barrier.h
new file mode 100644
index 000..faafc37
--- /dev/null
+++ b/arch/nds32/include/asm/barrier.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_ASM_BARRIER_H
+#define __NDS32_ASM_BARRIER_H
+
+#ifndef __ASSEMBLY__
+#define mb()   asm volatile("msync all":::"memory")
+#define rmb()  asm volatile("msync all":::"memory")
+#define wmb()  asm volatile("msync store":::"memory")
+#include 
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __NDS32_ASM_BARRIER_H */
diff --git a/arch/nds32/include/asm/futex.h b/arch/nds32/include/asm/futex.h
new file mode 100644
index 000..eab5e84
--- /dev/null
+++ b/arch/nds32/include/asm/futex.h
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_FUTEX_H__
+#define __NDS32_FUTEX_H__
+
+#include 
+#include 
+#include 
+
+#define __futex_atomic_ex_table(err_reg)   \
+   "   .pushsection __ex_table,\"a\"\n"\
+   "   .align  3\n"\
+   "   .long   1b, 4f\n"   \
+   "   .long   2b, 4f\n"   \
+   "   .popsection\n"  \
+   "   .pushsection .fixup,\"ax\"\n"   \
+   "4: move%0, " err_reg "\n"  \
+   "   j   3b\n"   \
+   "   .popsection"
+
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)\
+   smp_mb();   \
+   asm volatile(   \
+   "   movi$ta, #0\n"  \
+   "1: llw %1, [%2+$ta]\n" \
+   "   " insn "\n" \
+   "2: scw %0, [%2+$ta]\n" \
+   "   beqz%0, 1b\n"   \
+   "   movi%0, #0\n"   \
+   "3:\n"  \
+   __futex_atomic_ex_table("%4")   \
+   : "=" (ret), "=" (oldval)   \
+   : "r" (uaddr), "r" (oparg), "i" (-EFAULT)   \
+   : "cc", "memory")
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 * uval, u32 __user * uaddr,
+ u32 oldval, u32 newval)
+{
+   int ret = 0;
+   u32 val, tmp, flags;
+
+   if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+   return -EFAULT;
+
+   smp_mb();
+   asm volatile ("   movi$ta, #0\n"
+ "1: llw %1, [%6 + $ta]\n"
+ "   sub %3, %1, %4\n"
+ "   cmovz   %2, %5, %3\n"
+ "   cmovn   %2, %1, %3\n"
+ "2: scw %2, [%6 + $ta]\n"
+ "   beqz%2, 1b\n"
+ "3:\n   " __futex_atomic_ex_table("%7")
+ :"+"(ret), "="(val), "="(tmp), "="(flags)
+ :"r"(oldval), "r"(newval), "r"(uaddr), "i"(-EFAULT)
+ :"$ta", "memory");
+   smp_mb();
+
+   *uval = val;
+   return ret;
+}
+
+static inline int
+arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
+{
+   int oldval = 0, ret;
+
+
+   pagefault_disable();
+   switch (op) {
+   case FUTEX_OP_SET:
+   __futex_atomic_op("move %0, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_ADD:
+   __futex_atomic_op("add  %0, %1, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_OR:
+   __futex_atomic_op("or   %0, %1, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_ANDN:
+   __futex_atomic_op("and  %0, %1, %3", ret, oldval, tmp, uaddr,
+ ~oparg);
+   break;
+   case FUTEX_OP_XOR:
+   

[PATCH v4 13/36] nds32: Device specific operations

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch introduces ioremap implementations.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/io.h |   83 +++
 arch/nds32/mm/ioremap.c |   62 
 2 files changed, 145 insertions(+)
 create mode 100644 arch/nds32/include/asm/io.h
 create mode 100644 arch/nds32/mm/ioremap.c

diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
new file mode 100644
index 000..81b4616
--- /dev/null
+++ b/arch/nds32/include/asm/io.h
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_IO_H
+#define __ASM_NDS32_IO_H
+
+extern void iounmap(void __iomem *addr);
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+   asm volatile("sbi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+   asm volatile("shi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+   asm volatile("swi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+   u8 val;
+
+   asm volatile("lbi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+   u16 val;
+
+   asm volatile("lhi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+   u32 val;
+
+   asm volatile("lwi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __iormb()   rmb()
+#define __iowmb()   wmb()
+
+#define mmiowb()__asm__ __volatile__ ("msync all" : : : "memory");
+
+/*
+ * {read,write}{b,w,l,q}_relaxed() are like the regular version, but
+ * are not guaranteed to provide ordering against spinlocks or memory
+ * accesses.
+ */
+
+#define readb_relaxed(c)   ({ u8  __v = __raw_readb(c); __v; })
+#define readw_relaxed(c)   ({ u16 __v = le16_to_cpu((__force 
__le16)__raw_readw(c)); __v; })
+#define readl_relaxed(c)   ({ u32 __v = le32_to_cpu((__force 
__le32)__raw_readl(c)); __v; })
+#define writeb_relaxed(v,c)((void)__raw_writeb((v),(c)))
+#define writew_relaxed(v,c)((void)__raw_writew((__force 
u16)cpu_to_le16(v),(c)))
+#define writel_relaxed(v,c)((void)__raw_writel((__force 
u32)cpu_to_le32(v),(c)))
+
+/*
+ * {read,write}{b,w,l,q}() access little endian memory and return result in
+ * native endianness.
+ */
+#define readb(c)   ({ u8  __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c)   ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c)   ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+
+#define writeb(v,c)({ __iowmb(); writeb_relaxed((v),(c)); })
+#define writew(v,c)({ __iowmb(); writew_relaxed((v),(c)); })
+#define writel(v,c)({ __iowmb(); writel_relaxed((v),(c)); })
+#include 
+#endif /* __ASM_NDS32_IO_H */
diff --git a/arch/nds32/mm/ioremap.c b/arch/nds32/mm/ioremap.c
new file mode 100644
index 000..2f6741c
--- /dev/null
+++ b/arch/nds32/mm/ioremap.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
+
+static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
+ void *caller)
+{
+   struct vm_struct *area;
+   unsigned long addr, offset, last_addr;
+   pgprot_t prot;
+
+   /* Don't allow wraparound or zero size */
+   last_addr = phys_addr + size - 1;
+   if (!size || last_addr < phys_addr)
+   return NULL;
+
+   /*
+* Mappings have to be page-aligned
+*/
+   offset = phys_addr & ~PAGE_MASK;
+   phys_addr &= PAGE_MASK;
+   size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+   /*
+* Ok, go for it..
+*/
+   area = get_vm_area_caller(size, VM_IOREMAP, caller);
+   if (!area)
+   return NULL;
+
+   area->phys_addr = phys_addr;
+   addr = (unsigned long)area->addr;
+   prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D |
+   _PAGE_G | _PAGE_C_DEV);
+   if (ioremap_page_range(addr, addr + size, phys_addr, prot)) {
+   vunmap((void *)addr);
+   return NULL;
+   }
+   return (__force void __iomem *)(offset + (char *)addr);
+
+}
+
+void __iomem *ioremap(phys_addr_t phys_addr, 

[PATCH v4 15/36] nds32: ELF definitions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds definitions for the ELF format, relocation types, vdso
locations and EXEC_PAGESIZE.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/elf.h |  179 ++
 arch/nds32/include/uapi/asm/auxvec.h |   12 +++
 arch/nds32/include/uapi/asm/param.h  |   11 +++
 3 files changed, 202 insertions(+)
 create mode 100644 arch/nds32/include/asm/elf.h
 create mode 100644 arch/nds32/include/uapi/asm/auxvec.h
 create mode 100644 arch/nds32/include/uapi/asm/param.h

diff --git a/arch/nds32/include/asm/elf.h b/arch/nds32/include/asm/elf.h
new file mode 100644
index 000..99203f1
--- /dev/null
+++ b/arch/nds32/include/asm/elf.h
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASMNDS32_ELF_H
+#define __ASMNDS32_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include 
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+extern unsigned int elf_hwcap;
+
+#define EM_NDS32   167
+
+#define R_NDS32_NONE   0
+#define R_NDS32_16_RELA19
+#define R_NDS32_32_RELA20
+#define R_NDS32_9_PCREL_RELA   22
+#define R_NDS32_15_PCREL_RELA  23
+#define R_NDS32_17_PCREL_RELA  24
+#define R_NDS32_25_PCREL_RELA  25
+#define R_NDS32_HI20_RELA  26
+#define R_NDS32_LO12S3_RELA27
+#define R_NDS32_LO12S2_RELA28
+#define R_NDS32_LO12S1_RELA29
+#define R_NDS32_LO12S0_RELA30
+#define R_NDS32_SDA15S3_RELA   31
+#define R_NDS32_SDA15S2_RELA   32
+#define R_NDS32_SDA15S1_RELA   33
+#define R_NDS32_SDA15S0_RELA   34
+#define R_NDS32_GOT20  37
+#define R_NDS32_25_PLTREL  38
+#define R_NDS32_COPY   39
+#define R_NDS32_GLOB_DAT   40
+#define R_NDS32_JMP_SLOT   41
+#define R_NDS32_RELATIVE   42
+#define R_NDS32_GOTOFF 43
+#define R_NDS32_GOTPC2044
+#define R_NDS32_GOT_HI20   45
+#define R_NDS32_GOT_LO12   46
+#define R_NDS32_GOTPC_HI20 47
+#define R_NDS32_GOTPC_LO12 48
+#define R_NDS32_GOTOFF_HI2049
+#define R_NDS32_GOTOFF_LO1250
+#define R_NDS32_INSN16 51
+#define R_NDS32_LABEL  52
+#define R_NDS32_LONGCALL1  53
+#define R_NDS32_LONGCALL2  54
+#define R_NDS32_LONGCALL3  55
+#define R_NDS32_LONGJUMP1  56
+#define R_NDS32_LONGJUMP2  57
+#define R_NDS32_LONGJUMP3  58
+#define R_NDS32_LOADSTORE  59
+#define R_NDS32_9_FIXED_RELA   60
+#define R_NDS32_15_FIXED_RELA  61
+#define R_NDS32_17_FIXED_RELA  62
+#define R_NDS32_25_FIXED_RELA  63
+#define R_NDS32_PLTREL_HI2064
+#define R_NDS32_PLTREL_LO1265
+#define R_NDS32_PLT_GOTREL_HI2066
+#define R_NDS32_PLT_GOTREL_LO1267
+#define R_NDS32_LO12S0_ORI_RELA72
+#define R_NDS32_DWARF2_OP1_RELA77
+#define R_NDS32_DWARF2_OP2_RELA78
+#define R_NDS32_DWARF2_LEB_RELA79
+#define R_NDS32_WORD_9_PCREL_RELA  94
+#define R_NDS32_LONGCALL4  107
+#define R_NDS32_RELA_NOP_MIX   192
+#define R_NDS32_RELA_NOP_MAX   255
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/* Core file format: The core file is written in such a way that gdb
+   can understand it and provide useful information to the user (under
+   linux we use the 'trad-core' bfd).  There are quite a number of
+   obstacles to being able to view the contents of the floating point
+   registers, and until these are solved you will not be able to view the
+   contents of them.  Actually, you can read in the core file and look at
+   the contents of the user struct to find out what the floating point
+   registers contain.
+   The actual file contents are as follows:
+   UPAGE: 1 page consisting of a user struct that tells gdb what is present
+   in the file.  Directly after this is a copy of the task_struct, which
+   is currently not used by gdb, but it may come in useful at some point.
+   All of the registers are stored as part of the upage.  The upage should
+   always be only one page.
+   DATA: The data area is stored.  We use current->end_text to
+   current->brk to pick up all of the user variables, plus any memory
+   that may have been malloced.  No attempt is made to determine if a page
+   is demand-zero or if a page is totally unused, we just cover the entire
+   range.  All of the addresses are rounded in such a way that an integral
+   number of pages is written.
+   STACK: We need the stack information in order to get a 

[PATCH v4 12/36] nds32: Atomic operations

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch includes the atomic and futex operations. Many atomic operations use
the load-lock word(llw) and store-condition word(scw) operations.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/barrier.h |   15 ++
 arch/nds32/include/asm/futex.h   |  103 ++
 2 files changed, 118 insertions(+)
 create mode 100644 arch/nds32/include/asm/barrier.h
 create mode 100644 arch/nds32/include/asm/futex.h

diff --git a/arch/nds32/include/asm/barrier.h b/arch/nds32/include/asm/barrier.h
new file mode 100644
index 000..faafc37
--- /dev/null
+++ b/arch/nds32/include/asm/barrier.h
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_ASM_BARRIER_H
+#define __NDS32_ASM_BARRIER_H
+
+#ifndef __ASSEMBLY__
+#define mb()   asm volatile("msync all":::"memory")
+#define rmb()  asm volatile("msync all":::"memory")
+#define wmb()  asm volatile("msync store":::"memory")
+#include 
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __NDS32_ASM_BARRIER_H */
diff --git a/arch/nds32/include/asm/futex.h b/arch/nds32/include/asm/futex.h
new file mode 100644
index 000..eab5e84
--- /dev/null
+++ b/arch/nds32/include/asm/futex.h
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_FUTEX_H__
+#define __NDS32_FUTEX_H__
+
+#include 
+#include 
+#include 
+
+#define __futex_atomic_ex_table(err_reg)   \
+   "   .pushsection __ex_table,\"a\"\n"\
+   "   .align  3\n"\
+   "   .long   1b, 4f\n"   \
+   "   .long   2b, 4f\n"   \
+   "   .popsection\n"  \
+   "   .pushsection .fixup,\"ax\"\n"   \
+   "4: move%0, " err_reg "\n"  \
+   "   j   3b\n"   \
+   "   .popsection"
+
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)\
+   smp_mb();   \
+   asm volatile(   \
+   "   movi$ta, #0\n"  \
+   "1: llw %1, [%2+$ta]\n" \
+   "   " insn "\n" \
+   "2: scw %0, [%2+$ta]\n" \
+   "   beqz%0, 1b\n"   \
+   "   movi%0, #0\n"   \
+   "3:\n"  \
+   __futex_atomic_ex_table("%4")   \
+   : "=" (ret), "=" (oldval)   \
+   : "r" (uaddr), "r" (oparg), "i" (-EFAULT)   \
+   : "cc", "memory")
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 * uval, u32 __user * uaddr,
+ u32 oldval, u32 newval)
+{
+   int ret = 0;
+   u32 val, tmp, flags;
+
+   if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+   return -EFAULT;
+
+   smp_mb();
+   asm volatile ("   movi$ta, #0\n"
+ "1: llw %1, [%6 + $ta]\n"
+ "   sub %3, %1, %4\n"
+ "   cmovz   %2, %5, %3\n"
+ "   cmovn   %2, %1, %3\n"
+ "2: scw %2, [%6 + $ta]\n"
+ "   beqz%2, 1b\n"
+ "3:\n   " __futex_atomic_ex_table("%7")
+ :"+"(ret), "="(val), "="(tmp), "="(flags)
+ :"r"(oldval), "r"(newval), "r"(uaddr), "i"(-EFAULT)
+ :"$ta", "memory");
+   smp_mb();
+
+   *uval = val;
+   return ret;
+}
+
+static inline int
+arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
+{
+   int oldval = 0, ret;
+
+
+   pagefault_disable();
+   switch (op) {
+   case FUTEX_OP_SET:
+   __futex_atomic_op("move %0, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_ADD:
+   __futex_atomic_op("add  %0, %1, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_OR:
+   __futex_atomic_op("or   %0, %1, %3", ret, oldval, tmp, uaddr,
+ oparg);
+   break;
+   case FUTEX_OP_ANDN:
+   __futex_atomic_op("and  %0, %1, %3", ret, oldval, tmp, uaddr,
+ ~oparg);
+   break;
+   case FUTEX_OP_XOR:
+   __futex_atomic_op("xor  %0, %1, %3", ret, oldval, tmp, uaddr,
+  

[PATCH v4 13/36] nds32: Device specific operations

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch introduces ioremap implementations.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/io.h |   83 +++
 arch/nds32/mm/ioremap.c |   62 
 2 files changed, 145 insertions(+)
 create mode 100644 arch/nds32/include/asm/io.h
 create mode 100644 arch/nds32/mm/ioremap.c

diff --git a/arch/nds32/include/asm/io.h b/arch/nds32/include/asm/io.h
new file mode 100644
index 000..81b4616
--- /dev/null
+++ b/arch/nds32/include/asm/io.h
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_IO_H
+#define __ASM_NDS32_IO_H
+
+extern void iounmap(void __iomem *addr);
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+   asm volatile("sbi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+   asm volatile("shi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+   asm volatile("swi %0, [%1]" : : "r" (val), "r" (addr));
+}
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+   u8 val;
+
+   asm volatile("lbi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+   u16 val;
+
+   asm volatile("lhi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+   u32 val;
+
+   asm volatile("lwi %0, [%1]" : "=r" (val) : "r" (addr));
+   return val;
+}
+
+#define __iormb()   rmb()
+#define __iowmb()   wmb()
+
+#define mmiowb()__asm__ __volatile__ ("msync all" : : : "memory");
+
+/*
+ * {read,write}{b,w,l,q}_relaxed() are like the regular version, but
+ * are not guaranteed to provide ordering against spinlocks or memory
+ * accesses.
+ */
+
+#define readb_relaxed(c)   ({ u8  __v = __raw_readb(c); __v; })
+#define readw_relaxed(c)   ({ u16 __v = le16_to_cpu((__force 
__le16)__raw_readw(c)); __v; })
+#define readl_relaxed(c)   ({ u32 __v = le32_to_cpu((__force 
__le32)__raw_readl(c)); __v; })
+#define writeb_relaxed(v,c)((void)__raw_writeb((v),(c)))
+#define writew_relaxed(v,c)((void)__raw_writew((__force 
u16)cpu_to_le16(v),(c)))
+#define writel_relaxed(v,c)((void)__raw_writel((__force 
u32)cpu_to_le32(v),(c)))
+
+/*
+ * {read,write}{b,w,l,q}() access little endian memory and return result in
+ * native endianness.
+ */
+#define readb(c)   ({ u8  __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c)   ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c)   ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+
+#define writeb(v,c)({ __iowmb(); writeb_relaxed((v),(c)); })
+#define writew(v,c)({ __iowmb(); writew_relaxed((v),(c)); })
+#define writel(v,c)({ __iowmb(); writel_relaxed((v),(c)); })
+#include 
+#endif /* __ASM_NDS32_IO_H */
diff --git a/arch/nds32/mm/ioremap.c b/arch/nds32/mm/ioremap.c
new file mode 100644
index 000..2f6741c
--- /dev/null
+++ b/arch/nds32/mm/ioremap.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
+
+static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
+ void *caller)
+{
+   struct vm_struct *area;
+   unsigned long addr, offset, last_addr;
+   pgprot_t prot;
+
+   /* Don't allow wraparound or zero size */
+   last_addr = phys_addr + size - 1;
+   if (!size || last_addr < phys_addr)
+   return NULL;
+
+   /*
+* Mappings have to be page-aligned
+*/
+   offset = phys_addr & ~PAGE_MASK;
+   phys_addr &= PAGE_MASK;
+   size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+   /*
+* Ok, go for it..
+*/
+   area = get_vm_area_caller(size, VM_IOREMAP, caller);
+   if (!area)
+   return NULL;
+
+   area->phys_addr = phys_addr;
+   addr = (unsigned long)area->addr;
+   prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D |
+   _PAGE_G | _PAGE_C_DEV);
+   if (ioremap_page_range(addr, addr + size, phys_addr, prot)) {
+   vunmap((void *)addr);
+   return NULL;
+   }
+   return (__force void __iomem *)(offset + (char *)addr);
+
+}
+
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size)
+{
+   return __ioremap_caller(phys_addr, size,
+  

[PATCH v4 17/36] nds32: VDSO support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds VDSO support. The VDSO code is currently used for
sys_rt_sigreturn() and optimised gettimeofday() (using the SoC timer counter).

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/vdso.h  |   24 +++
 arch/nds32/include/asm/vdso_datapage.h |   36 
 arch/nds32/include/asm/vdso_timer_info.h   |   14 ++
 arch/nds32/kernel/vdso.c   |  233 
 arch/nds32/kernel/vdso/Makefile|   82 +
 arch/nds32/kernel/vdso/datapage.S  |   21 +++
 arch/nds32/kernel/vdso/gen_vdso_offsets.sh |   15 ++
 arch/nds32/kernel/vdso/gettimeofday.c  |  271 
 arch/nds32/kernel/vdso/note.S  |   11 ++
 arch/nds32/kernel/vdso/sigreturn.S |   19 ++
 arch/nds32/kernel/vdso/vdso.S  |   18 ++
 arch/nds32/kernel/vdso/vdso.lds.S  |   76 
 12 files changed, 820 insertions(+)
 create mode 100644 arch/nds32/include/asm/vdso.h
 create mode 100644 arch/nds32/include/asm/vdso_datapage.h
 create mode 100644 arch/nds32/include/asm/vdso_timer_info.h
 create mode 100644 arch/nds32/kernel/vdso.c
 create mode 100644 arch/nds32/kernel/vdso/Makefile
 create mode 100644 arch/nds32/kernel/vdso/datapage.S
 create mode 100755 arch/nds32/kernel/vdso/gen_vdso_offsets.sh
 create mode 100644 arch/nds32/kernel/vdso/gettimeofday.c
 create mode 100644 arch/nds32/kernel/vdso/note.S
 create mode 100644 arch/nds32/kernel/vdso/sigreturn.S
 create mode 100644 arch/nds32/kernel/vdso/vdso.S
 create mode 100644 arch/nds32/kernel/vdso/vdso.lds.S

diff --git a/arch/nds32/include/asm/vdso.h b/arch/nds32/include/asm/vdso.h
new file mode 100644
index 000..af2c6af
--- /dev/null
+++ b/arch/nds32/include/asm/vdso.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (C) 2005-2017 Andes Technology Corporation
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include 
+
+#define VDSO_SYMBOL(base, name)
   \
+({\
+   (unsigned long)(vdso_offset_##name + (unsigned long)(base)); \
+})
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/nds32/include/asm/vdso_datapage.h 
b/arch/nds32/include/asm/vdso_datapage.h
new file mode 100644
index 000..79db5a1
--- /dev/null
+++ b/arch/nds32/include/asm/vdso_datapage.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012 ARM Limited
+// Copyright (C) 2005-2017 Andes Technology Corporation
+#ifndef __ASM_VDSO_DATAPAGE_H
+#define __ASM_VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+struct vdso_data {
+   bool cycle_count_down;  /* timer cyclye counter is decrease with time */
+   u32 cycle_count_offset; /* offset of timer cycle counter register */
+   u32 seq_count;  /* sequence count - odd during updates */
+   u32 xtime_coarse_sec;   /* coarse time */
+   u32 xtime_coarse_nsec;
+
+   u32 wtm_clock_sec;  /* wall to monotonic offset */
+   u32 wtm_clock_nsec;
+   u32 xtime_clock_sec;/* CLOCK_REALTIME - seconds */
+   u32 cs_mult;/* clocksource multiplier */
+   u32 cs_shift;   /* Cycle to nanosecond divisor (power of two) */
+
+   u64 cs_cycle_last;  /* last cycle value */
+   u64 cs_mask;/* clocksource mask */
+
+   u64 xtime_clock_nsec;   /* CLOCK_REALTIME sub-ns base */
+   u32 tz_minuteswest; /* timezone info for gettimeofday(2) */
+   u32 tz_dsttime;
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/nds32/include/asm/vdso_timer_info.h 
b/arch/nds32/include/asm/vdso_timer_info.h
new file mode 100644
index 000..50ba117
--- /dev/null
+++ b/arch/nds32/include/asm/vdso_timer_info.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+extern struct timer_info_t timer_info;
+#define EMPTY_VALUE ~(0UL)
+#define EMPTY_TIMER_MAPPING EMPTY_VALUE
+#define EMPTY_REG_OFFSET EMPTY_VALUE
+
+struct timer_info_t
+{
+   bool cycle_count_down;
+   unsigned long mapping_base;
+   unsigned long cycle_count_reg_offset;
+};
diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c
new file mode 100644
index 000..2eb01f4
--- /dev/null
+++ b/arch/nds32/kernel/vdso.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012 ARM Limited
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 

[PATCH v4 17/36] nds32: VDSO support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds VDSO support. The VDSO code is currently used for
sys_rt_sigreturn() and optimised gettimeofday() (using the SoC timer counter).

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/vdso.h  |   24 +++
 arch/nds32/include/asm/vdso_datapage.h |   36 
 arch/nds32/include/asm/vdso_timer_info.h   |   14 ++
 arch/nds32/kernel/vdso.c   |  233 
 arch/nds32/kernel/vdso/Makefile|   82 +
 arch/nds32/kernel/vdso/datapage.S  |   21 +++
 arch/nds32/kernel/vdso/gen_vdso_offsets.sh |   15 ++
 arch/nds32/kernel/vdso/gettimeofday.c  |  271 
 arch/nds32/kernel/vdso/note.S  |   11 ++
 arch/nds32/kernel/vdso/sigreturn.S |   19 ++
 arch/nds32/kernel/vdso/vdso.S  |   18 ++
 arch/nds32/kernel/vdso/vdso.lds.S  |   76 
 12 files changed, 820 insertions(+)
 create mode 100644 arch/nds32/include/asm/vdso.h
 create mode 100644 arch/nds32/include/asm/vdso_datapage.h
 create mode 100644 arch/nds32/include/asm/vdso_timer_info.h
 create mode 100644 arch/nds32/kernel/vdso.c
 create mode 100644 arch/nds32/kernel/vdso/Makefile
 create mode 100644 arch/nds32/kernel/vdso/datapage.S
 create mode 100755 arch/nds32/kernel/vdso/gen_vdso_offsets.sh
 create mode 100644 arch/nds32/kernel/vdso/gettimeofday.c
 create mode 100644 arch/nds32/kernel/vdso/note.S
 create mode 100644 arch/nds32/kernel/vdso/sigreturn.S
 create mode 100644 arch/nds32/kernel/vdso/vdso.S
 create mode 100644 arch/nds32/kernel/vdso/vdso.lds.S

diff --git a/arch/nds32/include/asm/vdso.h b/arch/nds32/include/asm/vdso.h
new file mode 100644
index 000..af2c6af
--- /dev/null
+++ b/arch/nds32/include/asm/vdso.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (C) 2005-2017 Andes Technology Corporation
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include 
+
+#define VDSO_SYMBOL(base, name)
   \
+({\
+   (unsigned long)(vdso_offset_##name + (unsigned long)(base)); \
+})
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/nds32/include/asm/vdso_datapage.h 
b/arch/nds32/include/asm/vdso_datapage.h
new file mode 100644
index 000..79db5a1
--- /dev/null
+++ b/arch/nds32/include/asm/vdso_datapage.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012 ARM Limited
+// Copyright (C) 2005-2017 Andes Technology Corporation
+#ifndef __ASM_VDSO_DATAPAGE_H
+#define __ASM_VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+struct vdso_data {
+   bool cycle_count_down;  /* timer cyclye counter is decrease with time */
+   u32 cycle_count_offset; /* offset of timer cycle counter register */
+   u32 seq_count;  /* sequence count - odd during updates */
+   u32 xtime_coarse_sec;   /* coarse time */
+   u32 xtime_coarse_nsec;
+
+   u32 wtm_clock_sec;  /* wall to monotonic offset */
+   u32 wtm_clock_nsec;
+   u32 xtime_clock_sec;/* CLOCK_REALTIME - seconds */
+   u32 cs_mult;/* clocksource multiplier */
+   u32 cs_shift;   /* Cycle to nanosecond divisor (power of two) */
+
+   u64 cs_cycle_last;  /* last cycle value */
+   u64 cs_mask;/* clocksource mask */
+
+   u64 xtime_clock_nsec;   /* CLOCK_REALTIME sub-ns base */
+   u32 tz_minuteswest; /* timezone info for gettimeofday(2) */
+   u32 tz_dsttime;
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/nds32/include/asm/vdso_timer_info.h 
b/arch/nds32/include/asm/vdso_timer_info.h
new file mode 100644
index 000..50ba117
--- /dev/null
+++ b/arch/nds32/include/asm/vdso_timer_info.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+extern struct timer_info_t timer_info;
+#define EMPTY_VALUE ~(0UL)
+#define EMPTY_TIMER_MAPPING EMPTY_VALUE
+#define EMPTY_REG_OFFSET EMPTY_VALUE
+
+struct timer_info_t
+{
+   bool cycle_count_down;
+   unsigned long mapping_base;
+   unsigned long cycle_count_reg_offset;
+};
diff --git a/arch/nds32/kernel/vdso.c b/arch/nds32/kernel/vdso.c
new file mode 100644
index 000..2eb01f4
--- /dev/null
+++ b/arch/nds32/kernel/vdso.c
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2012 ARM Limited
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+extern struct cache_info L1_cache_info[2];

[PATCH v4 21/36] nds32: L2 cache support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds L2 cache support.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/l2_cache.h |  142 +
 arch/nds32/kernel/atl2c.c |   64 +
 2 files changed, 206 insertions(+)
 create mode 100644 arch/nds32/include/asm/l2_cache.h
 create mode 100644 arch/nds32/kernel/atl2c.c

diff --git a/arch/nds32/include/asm/l2_cache.h 
b/arch/nds32/include/asm/l2_cache.h
new file mode 100644
index 000..7706dd0
--- /dev/null
+++ b/arch/nds32/include/asm/l2_cache.h
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef L2_CACHE_H
+#define L2_CACHE_H
+
+/* CCTL_CMD_OP */
+#define L2_CA_CONF_OFF 0x0
+#define L2_IF_CONF_OFF 0x4
+#define L2CC_SETUP_OFF 0x8
+#define L2CC_PROT_OFF  0xC
+#define L2CC_CTRL_OFF  0x10
+#define L2_INT_EN_OFF   0x20
+#define L2_STA_OFF  0x24
+#define RDERR_ADDR_OFF 0x28
+#define WRERR_ADDR_OFF 0x2c
+#define EVDPTERR_ADDR_OFF  0x30
+#define IMPL3ERR_ADDR_OFF  0x34
+#define L2_CNT0_CTRL_OFF0x40
+#define L2_EVNT_CNT0_OFF0x44
+#define L2_CNT1_CTRL_OFF0x48
+#define L2_EVNT_CNT1_OFF0x4c
+#define L2_CCTL_CMD_OFF0x60
+#define L2_CCTL_STATUS_OFF 0x64
+#define L2_LINE_TAG_OFF0x68
+#define L2_LINE_DPT_OFF0x70
+
+#define CCTL_CMD_L2_IX_INVAL0x0
+#define CCTL_CMD_L2_PA_INVAL0x1
+#define CCTL_CMD_L2_IX_WB   0x2
+#define CCTL_CMD_L2_PA_WB   0x3
+#define CCTL_CMD_L2_PA_WBINVAL  0x5
+#define CCTL_CMD_L2_SYNC0xa
+
+/* CCTL_CMD_TYPE */
+#define CCTL_SINGLE_CMD 0
+#define CCTL_BLOCK_CMD  0x10
+#define CCTL_ALL_CMD   0x10
+
+/**
+ * L2_CA_CONF (Cache architecture configuration)
+ */
+#define L2_CA_CONF_offL2SET0
+#define L2_CA_CONF_offL2WAY4
+#define L2_CA_CONF_offL2CLSZ8
+#define L2_CA_CONF_offL2DW 11
+#define L2_CA_CONF_offL2PT 14
+#define L2_CA_CONF_offL2VER16
+
+#define L2_CA_CONF_mskL2SET(0xFUL << L2_CA_CONF_offL2SET)
+#define L2_CA_CONF_mskL2WAY(0xFUL << L2_CA_CONF_offL2WAY)
+#define L2_CA_CONF_mskL2CLSZ(0x7UL << L2_CA_CONF_offL2CLSZ)
+#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW)
+#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT)
+#define L2_CA_CONF_mskL2VER(0xUL << L2_CA_CONF_offL2VER)
+
+/**
+ * L2CC_SETUP (L2CC Setup register)
+ */
+#define L2CC_SETUP_offPART  0
+#define L2CC_SETUP_mskPART  (0x3UL << L2CC_SETUP_offPART)
+#define L2CC_SETUP_offDDLATC4
+#define L2CC_SETUP_mskDDLATC(0x3UL << L2CC_SETUP_offDDLATC)
+#define L2CC_SETUP_offTDLATC8
+#define L2CC_SETUP_mskTDLATC(0x3UL << L2CC_SETUP_offTDLATC)
+
+/**
+ * L2CC_PROT (L2CC Protect register)
+ */
+#define L2CC_PROT_offMRWEN  31
+#define L2CC_PROT_mskMRWEN  (0x1UL << L2CC_PROT_offMRWEN)
+
+/**
+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
+ */
+#define L2CC_CTRL_offEN 31
+#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN)
+
+/**
+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
+ */
+#define L2_CCTL_STATUS_offCMD_COMP  31
+#define L2_CCTL_STATUS_mskCMD_COMP  (0x1 << L2_CCTL_STATUS_offCMD_COMP)
+
+#ifndef __ASSEMBLY__
+extern void __iomem *atl2c_base;
+
+#include 
+#include 
+#include 
+
+#define L2C_R_REG(offset)   readl(atl2c_base + offset)
+#define L2C_W_REG(offset, value)writel(value, atl2c_base + offset)
+
+#define L2_CMD_RDY()\
+do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & 
L2_CCTL_STATUS_mskCMD_COMP) == 0)
+
+static inline unsigned long L2_CACHE_SET(void)
+{
+   return 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >>
+ L2_CA_CONF_offL2SET);
+}
+
+static inline unsigned long L2_CACHE_WAY(void)
+{
+   return 1 +
+   ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >>
+ 

[PATCH v4 21/36] nds32: L2 cache support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds L2 cache support.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/l2_cache.h |  142 +
 arch/nds32/kernel/atl2c.c |   64 +
 2 files changed, 206 insertions(+)
 create mode 100644 arch/nds32/include/asm/l2_cache.h
 create mode 100644 arch/nds32/kernel/atl2c.c

diff --git a/arch/nds32/include/asm/l2_cache.h 
b/arch/nds32/include/asm/l2_cache.h
new file mode 100644
index 000..7706dd0
--- /dev/null
+++ b/arch/nds32/include/asm/l2_cache.h
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef L2_CACHE_H
+#define L2_CACHE_H
+
+/* CCTL_CMD_OP */
+#define L2_CA_CONF_OFF 0x0
+#define L2_IF_CONF_OFF 0x4
+#define L2CC_SETUP_OFF 0x8
+#define L2CC_PROT_OFF  0xC
+#define L2CC_CTRL_OFF  0x10
+#define L2_INT_EN_OFF   0x20
+#define L2_STA_OFF  0x24
+#define RDERR_ADDR_OFF 0x28
+#define WRERR_ADDR_OFF 0x2c
+#define EVDPTERR_ADDR_OFF  0x30
+#define IMPL3ERR_ADDR_OFF  0x34
+#define L2_CNT0_CTRL_OFF0x40
+#define L2_EVNT_CNT0_OFF0x44
+#define L2_CNT1_CTRL_OFF0x48
+#define L2_EVNT_CNT1_OFF0x4c
+#define L2_CCTL_CMD_OFF0x60
+#define L2_CCTL_STATUS_OFF 0x64
+#define L2_LINE_TAG_OFF0x68
+#define L2_LINE_DPT_OFF0x70
+
+#define CCTL_CMD_L2_IX_INVAL0x0
+#define CCTL_CMD_L2_PA_INVAL0x1
+#define CCTL_CMD_L2_IX_WB   0x2
+#define CCTL_CMD_L2_PA_WB   0x3
+#define CCTL_CMD_L2_PA_WBINVAL  0x5
+#define CCTL_CMD_L2_SYNC0xa
+
+/* CCTL_CMD_TYPE */
+#define CCTL_SINGLE_CMD 0
+#define CCTL_BLOCK_CMD  0x10
+#define CCTL_ALL_CMD   0x10
+
+/**
+ * L2_CA_CONF (Cache architecture configuration)
+ */
+#define L2_CA_CONF_offL2SET0
+#define L2_CA_CONF_offL2WAY4
+#define L2_CA_CONF_offL2CLSZ8
+#define L2_CA_CONF_offL2DW 11
+#define L2_CA_CONF_offL2PT 14
+#define L2_CA_CONF_offL2VER16
+
+#define L2_CA_CONF_mskL2SET(0xFUL << L2_CA_CONF_offL2SET)
+#define L2_CA_CONF_mskL2WAY(0xFUL << L2_CA_CONF_offL2WAY)
+#define L2_CA_CONF_mskL2CLSZ(0x7UL << L2_CA_CONF_offL2CLSZ)
+#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW)
+#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT)
+#define L2_CA_CONF_mskL2VER(0xUL << L2_CA_CONF_offL2VER)
+
+/**
+ * L2CC_SETUP (L2CC Setup register)
+ */
+#define L2CC_SETUP_offPART  0
+#define L2CC_SETUP_mskPART  (0x3UL << L2CC_SETUP_offPART)
+#define L2CC_SETUP_offDDLATC4
+#define L2CC_SETUP_mskDDLATC(0x3UL << L2CC_SETUP_offDDLATC)
+#define L2CC_SETUP_offTDLATC8
+#define L2CC_SETUP_mskTDLATC(0x3UL << L2CC_SETUP_offTDLATC)
+
+/**
+ * L2CC_PROT (L2CC Protect register)
+ */
+#define L2CC_PROT_offMRWEN  31
+#define L2CC_PROT_mskMRWEN  (0x1UL << L2CC_PROT_offMRWEN)
+
+/**
+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
+ */
+#define L2CC_CTRL_offEN 31
+#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN)
+
+/**
+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
+ */
+#define L2_CCTL_STATUS_offCMD_COMP  31
+#define L2_CCTL_STATUS_mskCMD_COMP  (0x1 << L2_CCTL_STATUS_offCMD_COMP)
+
+#ifndef __ASSEMBLY__
+extern void __iomem *atl2c_base;
+
+#include 
+#include 
+#include 
+
+#define L2C_R_REG(offset)   readl(atl2c_base + offset)
+#define L2C_W_REG(offset, value)writel(value, atl2c_base + offset)
+
+#define L2_CMD_RDY()\
+do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & 
L2_CCTL_STATUS_mskCMD_COMP) == 0)
+
+static inline unsigned long L2_CACHE_SET(void)
+{
+   return 64 << ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >>
+ L2_CA_CONF_offL2SET);
+}
+
+static inline unsigned long L2_CACHE_WAY(void)
+{
+   return 1 +
+   ((L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >>
+L2_CA_CONF_offL2WAY);
+}
+
+static inline unsigned long 

[PATCH v4 19/36] nds32: Library functions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch add support for various library functions.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/string.h  |   17 +++
 arch/nds32/include/asm/swab.h|   35 +
 arch/nds32/include/asm/uaccess.h |  283 ++
 arch/nds32/kernel/nds32_ksyms.c  |   31 +
 arch/nds32/lib/Makefile  |3 +
 arch/nds32/lib/clear_user.S  |   42 ++
 arch/nds32/lib/copy_from_user.S  |   45 ++
 arch/nds32/lib/copy_template.S   |   70 ++
 arch/nds32/lib/copy_to_user.S|   45 ++
 arch/nds32/lib/memcpy.S  |   30 
 arch/nds32/lib/memmove.S |   70 ++
 arch/nds32/lib/memset.S  |   33 +
 arch/nds32/lib/memzero.S |   18 +++
 13 files changed, 722 insertions(+)
 create mode 100644 arch/nds32/include/asm/string.h
 create mode 100644 arch/nds32/include/asm/swab.h
 create mode 100644 arch/nds32/include/asm/uaccess.h
 create mode 100644 arch/nds32/kernel/nds32_ksyms.c
 create mode 100644 arch/nds32/lib/Makefile
 create mode 100644 arch/nds32/lib/clear_user.S
 create mode 100644 arch/nds32/lib/copy_from_user.S
 create mode 100644 arch/nds32/lib/copy_template.S
 create mode 100644 arch/nds32/lib/copy_to_user.S
 create mode 100644 arch/nds32/lib/memcpy.S
 create mode 100644 arch/nds32/lib/memmove.S
 create mode 100644 arch/nds32/lib/memset.S
 create mode 100644 arch/nds32/lib/memzero.S

diff --git a/arch/nds32/include/asm/string.h b/arch/nds32/include/asm/string.h
new file mode 100644
index 000..179272c
--- /dev/null
+++ b/arch/nds32/include/asm/string.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_STRING_H
+#define __ASM_NDS32_STRING_H
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, __kernel_size_t);
+
+extern void *memzero(void *ptr, __kernel_size_t n);
+#endif
diff --git a/arch/nds32/include/asm/swab.h b/arch/nds32/include/asm/swab.h
new file mode 100644
index 000..e01a755
--- /dev/null
+++ b/arch/nds32/include/asm/swab.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_SWAB_H__
+#define __NDS32_SWAB_H__
+
+#include 
+#include 
+
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+   __asm__("wsbh   %0, %0\n\t" /* word swap byte within halfword */
+   "rotri  %0, %0, #16\n"
+   :"=r"(x)
+   :"0"(x));
+   return x;
+}
+
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+{
+   __asm__("wsbh   %0, %0\n"   /* word swap byte within halfword */
+   :"=r"(x)
+   :"0"(x));
+   return x;
+}
+
+#define __arch_swab32(x) ___arch__swab32(x)
+#define __arch_swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __BYTEORDER_HAS_U64__
+#define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __NDS32_SWAB_H__ */
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h
new file mode 100644
index 000..18a009f
--- /dev/null
+++ b/arch/nds32/include/asm/uaccess.h
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef _ASMANDES_UACCESS_H
+#define _ASMANDES_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VERIFY_READ0
+#define VERIFY_WRITE   1
+
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+   unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#define KERNEL_DS  ((mm_segment_t) { ~0UL })
+#define USER_DS((mm_segment_t) {TASK_SIZE - 1})
+
+#define get_ds()   (KERNEL_DS)
+#define get_fs()   (current_thread_info()->addr_limit)
+#define user_addr_max  get_fs
+
+static inline void set_fs(mm_segment_t fs)
+{
+   current_thread_info()->addr_limit = fs;
+}
+
+#define segment_eq(a, b)((a) == (b))
+
+#define __range_ok(addr, size) (size <= 

[PATCH v4 19/36] nds32: Library functions

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch add support for various library functions.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/include/asm/string.h  |   17 +++
 arch/nds32/include/asm/swab.h|   35 +
 arch/nds32/include/asm/uaccess.h |  283 ++
 arch/nds32/kernel/nds32_ksyms.c  |   31 +
 arch/nds32/lib/Makefile  |3 +
 arch/nds32/lib/clear_user.S  |   42 ++
 arch/nds32/lib/copy_from_user.S  |   45 ++
 arch/nds32/lib/copy_template.S   |   70 ++
 arch/nds32/lib/copy_to_user.S|   45 ++
 arch/nds32/lib/memcpy.S  |   30 
 arch/nds32/lib/memmove.S |   70 ++
 arch/nds32/lib/memset.S  |   33 +
 arch/nds32/lib/memzero.S |   18 +++
 13 files changed, 722 insertions(+)
 create mode 100644 arch/nds32/include/asm/string.h
 create mode 100644 arch/nds32/include/asm/swab.h
 create mode 100644 arch/nds32/include/asm/uaccess.h
 create mode 100644 arch/nds32/kernel/nds32_ksyms.c
 create mode 100644 arch/nds32/lib/Makefile
 create mode 100644 arch/nds32/lib/clear_user.S
 create mode 100644 arch/nds32/lib/copy_from_user.S
 create mode 100644 arch/nds32/lib/copy_template.S
 create mode 100644 arch/nds32/lib/copy_to_user.S
 create mode 100644 arch/nds32/lib/memcpy.S
 create mode 100644 arch/nds32/lib/memmove.S
 create mode 100644 arch/nds32/lib/memset.S
 create mode 100644 arch/nds32/lib/memzero.S

diff --git a/arch/nds32/include/asm/string.h b/arch/nds32/include/asm/string.h
new file mode 100644
index 000..179272c
--- /dev/null
+++ b/arch/nds32/include/asm/string.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __ASM_NDS32_STRING_H
+#define __ASM_NDS32_STRING_H
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, __kernel_size_t);
+
+extern void *memzero(void *ptr, __kernel_size_t n);
+#endif
diff --git a/arch/nds32/include/asm/swab.h b/arch/nds32/include/asm/swab.h
new file mode 100644
index 000..e01a755
--- /dev/null
+++ b/arch/nds32/include/asm/swab.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef __NDS32_SWAB_H__
+#define __NDS32_SWAB_H__
+
+#include 
+#include 
+
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+   __asm__("wsbh   %0, %0\n\t" /* word swap byte within halfword */
+   "rotri  %0, %0, #16\n"
+   :"=r"(x)
+   :"0"(x));
+   return x;
+}
+
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+{
+   __asm__("wsbh   %0, %0\n"   /* word swap byte within halfword */
+   :"=r"(x)
+   :"0"(x));
+   return x;
+}
+
+#define __arch_swab32(x) ___arch__swab32(x)
+#define __arch_swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __BYTEORDER_HAS_U64__
+#define __SWAB_64_THRU_32__
+#endif
+
+#endif /* __NDS32_SWAB_H__ */
diff --git a/arch/nds32/include/asm/uaccess.h b/arch/nds32/include/asm/uaccess.h
new file mode 100644
index 000..18a009f
--- /dev/null
+++ b/arch/nds32/include/asm/uaccess.h
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#ifndef _ASMANDES_UACCESS_H
+#define _ASMANDES_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define VERIFY_READ0
+#define VERIFY_WRITE   1
+
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+   unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#define KERNEL_DS  ((mm_segment_t) { ~0UL })
+#define USER_DS((mm_segment_t) {TASK_SIZE - 1})
+
+#define get_ds()   (KERNEL_DS)
+#define get_fs()   (current_thread_info()->addr_limit)
+#define user_addr_max  get_fs
+
+static inline void set_fs(mm_segment_t fs)
+{
+   current_thread_info()->addr_limit = fs;
+}
+
+#define segment_eq(a, b)((a) == (b))
+
+#define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
+
+#define access_ok(type, addr, 

[PATCH SERIES 5: 00/16] staging: lustre: use standard wait_event macros

2017-12-17 Thread NeilBrown
Lustre has l_wait_event() which is a complex macro that does
similar things to the wait_event macro family in Linux.
This patch series converts all l_wait_event to something more
familiar to Linux developers.

Some of the conversions are subtle.  I think I've understood the code
and got the conversion correct, but I've quite possibly messed up.
If you only review one series, this is the one that demands review.

I haven't converted the single use of l_wait_event_exclusive_head().
That needs more thought.

This is the last series for today.  I do have some more patches, but
that are all individual patches that I hope to send as a  set of
ad-hoc patches tomorrow.

Thanks,
NeilBrown


---

NeilBrown (16):
  staging: lustre: discard SVC_SIGNAL and related functions
  staging: lustre: replace simple cases of l_wait_event() with wait_event().
  staging: lustre: discard cfs_time_seconds()
  staging: lustre: use wait_event_timeout() where appropriate.
  staging: lustre: introduce and use l_wait_event_abortable()
  staging: lustre: simplify l_wait_event when intr handler but no timeout.
  staging: lustre: simplify waiting in ldlm_completion_ast()
  staging: lustre: open code polling loop instead of using l_wait_event()
  staging: lustre: simplify waiting in ptlrpc_invalidate_import()
  staging: lustre: remove back_to_sleep() and use loops.
  staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
  staging: lustre: use wait_event_timeout in ptlrpcd()
  staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
  staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
  staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
  staging: lustre: remove l_wait_event from ptlrpc_set_wait


 .../lustre/include/linux/libcfs/libcfs_debug.h |4 -
 .../lustre/include/linux/libcfs/libcfs_time.h  |2 
 .../lustre/include/linux/libcfs/linux/linux-time.h |7 -
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c|8 +
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |4 -
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c|6 -
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++-
 drivers/staging/lustre/lnet/libcfs/debug.c |2 
 drivers/staging/lustre/lnet/libcfs/fail.c  |2 
 drivers/staging/lustre/lnet/libcfs/tracefile.c |4 -
 drivers/staging/lustre/lnet/lnet/acceptor.c|2 
 drivers/staging/lustre/lnet/lnet/api-ni.c  |4 -
 drivers/staging/lustre/lnet/lnet/lib-move.c|4 -
 drivers/staging/lustre/lnet/lnet/net_fault.c   |   14 +-
 drivers/staging/lustre/lnet/lnet/peer.c|2 
 drivers/staging/lustre/lnet/lnet/router.c  |8 +
 drivers/staging/lustre/lnet/selftest/conrpc.c  |4 -
 drivers/staging/lustre/lnet/selftest/rpc.c |2 
 drivers/staging/lustre/lnet/selftest/selftest.h|2 
 drivers/staging/lustre/lnet/selftest/timer.c   |2 
 drivers/staging/lustre/lustre/include/lustre_dlm.h |2 
 drivers/staging/lustre/lustre/include/lustre_lib.h |  126 ++--
 drivers/staging/lustre/lustre/include/lustre_mdc.h |2 
 drivers/staging/lustre/lustre/include/lustre_net.h |8 -
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c|   30 +
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |   14 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|   12 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |   17 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   51 +++-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   14 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|   23 +---
 drivers/staging/lustre/lustre/llite/statahead.c|   60 --
 drivers/staging/lustre/lustre/lov/lov_object.c |6 -
 drivers/staging/lustre/lustre/lov/lov_request.c|   12 +-
 drivers/staging/lustre/lustre/mdc/mdc_request.c|5 -
 drivers/staging/lustre/lustre/mgc/mgc_request.c|   19 +--
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   23 ++--
 drivers/staging/lustre/lustre/obdclass/genops.c|   24 +---
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |5 -
 .../staging/lustre/lustre/obdecho/echo_client.c|2 
 drivers/staging/lustre/lustre/osc/osc_cache.c  |   28 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c |6 -
 drivers/staging/lustre/lustre/osc/osc_page.c   |6 -
 drivers/staging/lustre/lustre/osc/osc_request.c|6 -
 drivers/staging/lustre/lustre/ptlrpc/client.c  |  101 +++-
 drivers/staging/lustre/lustre/ptlrpc/events.c  |7 -
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   51 +++-
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c  |   14 +-
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|9 +
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   28 ++--
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 

[PATCH SERIES 5: 00/16] staging: lustre: use standard wait_event macros

2017-12-17 Thread NeilBrown
Lustre has l_wait_event() which is a complex macro that does
similar things to the wait_event macro family in Linux.
This patch series converts all l_wait_event to something more
familiar to Linux developers.

Some of the conversions are subtle.  I think I've understood the code
and got the conversion correct, but I've quite possibly messed up.
If you only review one series, this is the one that demands review.

I haven't converted the single use of l_wait_event_exclusive_head().
That needs more thought.

This is the last series for today.  I do have some more patches, but
that are all individual patches that I hope to send as a  set of
ad-hoc patches tomorrow.

Thanks,
NeilBrown


---

NeilBrown (16):
  staging: lustre: discard SVC_SIGNAL and related functions
  staging: lustre: replace simple cases of l_wait_event() with wait_event().
  staging: lustre: discard cfs_time_seconds()
  staging: lustre: use wait_event_timeout() where appropriate.
  staging: lustre: introduce and use l_wait_event_abortable()
  staging: lustre: simplify l_wait_event when intr handler but no timeout.
  staging: lustre: simplify waiting in ldlm_completion_ast()
  staging: lustre: open code polling loop instead of using l_wait_event()
  staging: lustre: simplify waiting in ptlrpc_invalidate_import()
  staging: lustre: remove back_to_sleep() and use loops.
  staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
  staging: lustre: use wait_event_timeout in ptlrpcd()
  staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
  staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
  staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
  staging: lustre: remove l_wait_event from ptlrpc_set_wait


 .../lustre/include/linux/libcfs/libcfs_debug.h |4 -
 .../lustre/include/linux/libcfs/libcfs_time.h  |2 
 .../lustre/include/linux/libcfs/linux/linux-time.h |7 -
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c|8 +
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |4 -
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c|6 -
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++-
 drivers/staging/lustre/lnet/libcfs/debug.c |2 
 drivers/staging/lustre/lnet/libcfs/fail.c  |2 
 drivers/staging/lustre/lnet/libcfs/tracefile.c |4 -
 drivers/staging/lustre/lnet/lnet/acceptor.c|2 
 drivers/staging/lustre/lnet/lnet/api-ni.c  |4 -
 drivers/staging/lustre/lnet/lnet/lib-move.c|4 -
 drivers/staging/lustre/lnet/lnet/net_fault.c   |   14 +-
 drivers/staging/lustre/lnet/lnet/peer.c|2 
 drivers/staging/lustre/lnet/lnet/router.c  |8 +
 drivers/staging/lustre/lnet/selftest/conrpc.c  |4 -
 drivers/staging/lustre/lnet/selftest/rpc.c |2 
 drivers/staging/lustre/lnet/selftest/selftest.h|2 
 drivers/staging/lustre/lnet/selftest/timer.c   |2 
 drivers/staging/lustre/lustre/include/lustre_dlm.h |2 
 drivers/staging/lustre/lustre/include/lustre_lib.h |  126 ++--
 drivers/staging/lustre/lustre/include/lustre_mdc.h |2 
 drivers/staging/lustre/lustre/include/lustre_net.h |8 -
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c|   30 +
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |   14 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|   12 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |   17 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   51 +++-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   14 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|   23 +---
 drivers/staging/lustre/lustre/llite/statahead.c|   60 --
 drivers/staging/lustre/lustre/lov/lov_object.c |6 -
 drivers/staging/lustre/lustre/lov/lov_request.c|   12 +-
 drivers/staging/lustre/lustre/mdc/mdc_request.c|5 -
 drivers/staging/lustre/lustre/mgc/mgc_request.c|   19 +--
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   23 ++--
 drivers/staging/lustre/lustre/obdclass/genops.c|   24 +---
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |5 -
 .../staging/lustre/lustre/obdecho/echo_client.c|2 
 drivers/staging/lustre/lustre/osc/osc_cache.c  |   28 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c |6 -
 drivers/staging/lustre/lustre/osc/osc_page.c   |6 -
 drivers/staging/lustre/lustre/osc/osc_request.c|6 -
 drivers/staging/lustre/lustre/ptlrpc/client.c  |  101 +++-
 drivers/staging/lustre/lustre/ptlrpc/events.c  |7 -
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   51 +++-
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c  |   14 +-
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|9 +
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   28 ++--
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 

[PATCH 16/16] staging: lustre: remove l_wait_event from ptlrpc_set_wait

2017-12-17 Thread NeilBrown
This is the last remaining use of l_wait_event().
It is the only use of LWI_TIMEOUT_INTR_ALL() which
has a meaning that timeouts can be interrupted.
Only interrupts by "fatal" signals are allowed, so
introduce l_wait_event_abortable_timeout() to
support this.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   10 ++
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   86 
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 
 3 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index d157ed35a0bf..b23d3015b1c0 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -440,6 +440,16 @@ do {   
\
__ret;  \
 })
 
+#define l_wait_event_abortable_timeout(wq, condition, timeout) \
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible_timeout(wq, condition, timeout);\
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
+
 #define l_wait_event_abortable_exclusive(wq, condition)
\
 ({ \
sigset_t __blocked; \
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index bb8c9ab68f5f..95131a34a98f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1774,7 +1774,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct 
ptlrpc_request_set *set)
}
 
/*
-* ptlrpc_set_wait->l_wait_event sets lwi_allow_intr
+* ptlrpc_set_wait allow signal to abort the timeout
 * so it sets rq_intr regardless of individual rpc
 * timeouts. The synchronous IO waiting path sets
 * rq_intr irrespective of whether ptlrpcd
@@ -2122,10 +2122,9 @@ int ptlrpc_expire_one_request(struct ptlrpc_request 
*req, int async_unlink)
 
 /**
  * Time out all uncompleted requests in request set pointed by \a data
- * Callback used when waiting on sets with l_wait_event.
- * Always returns 1.
+ * Called when wait_event_timeout times out.
  */
-int ptlrpc_expired_set(struct ptlrpc_request_set *set)
+void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
@@ -2155,18 +2154,6 @@ int ptlrpc_expired_set(struct ptlrpc_request_set *set)
 */
ptlrpc_expire_one_request(req, 1);
}
-
-   /*
-* When waiting for a whole set, we always break out of the
-* sleep so we can recalculate the timeout, or enable interrupts
-* if everyone's timed out.
-*/
-   return 1;
-}
-static int ptlrpc_expired_set_void(void *data)
-{
-   struct ptlrpc_request_set *set = data;
-   return ptlrpc_expired_set(set);
 }
 
 /**
@@ -2182,11 +2169,10 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted);
 
 /**
  * Interrupts (sets interrupted flag) all uncompleted requests in
- * a set \a data. Callback for l_wait_event for interruptible waits.
+ * a set \a data. Called when wait_event_timeout receives signal.
  */
-static void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set)
 {
-   struct ptlrpc_request_set *set = data;
struct list_head *tmp;
 
CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set);
@@ -2256,7 +2242,6 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 {
struct list_head *tmp;
struct ptlrpc_request *req;
-   struct l_wait_info lwi;
int rc, timeout;
 
if (set->set_producer)
@@ -2282,46 +2267,47 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
   set, timeout);
 
-   if (timeout == 0 && !signal_pending(current))
+   if (timeout == 0 && !signal_pending(current)) {
/*
 * No requests are in-flight (ether timed out
 * or delayed), so we can allow interrupts.
 * We still want to block for a limited time,
 * so we allow interrupts during the 

[PATCH 16/16] staging: lustre: remove l_wait_event from ptlrpc_set_wait

2017-12-17 Thread NeilBrown
This is the last remaining use of l_wait_event().
It is the only use of LWI_TIMEOUT_INTR_ALL() which
has a meaning that timeouts can be interrupted.
Only interrupts by "fatal" signals are allowed, so
introduce l_wait_event_abortable_timeout() to
support this.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   10 ++
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   86 
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 
 3 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index d157ed35a0bf..b23d3015b1c0 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -440,6 +440,16 @@ do {   
\
__ret;  \
 })
 
+#define l_wait_event_abortable_timeout(wq, condition, timeout) \
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible_timeout(wq, condition, timeout);\
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
+
 #define l_wait_event_abortable_exclusive(wq, condition)
\
 ({ \
sigset_t __blocked; \
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index bb8c9ab68f5f..95131a34a98f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1774,7 +1774,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct 
ptlrpc_request_set *set)
}
 
/*
-* ptlrpc_set_wait->l_wait_event sets lwi_allow_intr
+* ptlrpc_set_wait allow signal to abort the timeout
 * so it sets rq_intr regardless of individual rpc
 * timeouts. The synchronous IO waiting path sets
 * rq_intr irrespective of whether ptlrpcd
@@ -2122,10 +2122,9 @@ int ptlrpc_expire_one_request(struct ptlrpc_request 
*req, int async_unlink)
 
 /**
  * Time out all uncompleted requests in request set pointed by \a data
- * Callback used when waiting on sets with l_wait_event.
- * Always returns 1.
+ * Called when wait_event_timeout times out.
  */
-int ptlrpc_expired_set(struct ptlrpc_request_set *set)
+void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
@@ -2155,18 +2154,6 @@ int ptlrpc_expired_set(struct ptlrpc_request_set *set)
 */
ptlrpc_expire_one_request(req, 1);
}
-
-   /*
-* When waiting for a whole set, we always break out of the
-* sleep so we can recalculate the timeout, or enable interrupts
-* if everyone's timed out.
-*/
-   return 1;
-}
-static int ptlrpc_expired_set_void(void *data)
-{
-   struct ptlrpc_request_set *set = data;
-   return ptlrpc_expired_set(set);
 }
 
 /**
@@ -2182,11 +2169,10 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted);
 
 /**
  * Interrupts (sets interrupted flag) all uncompleted requests in
- * a set \a data. Callback for l_wait_event for interruptible waits.
+ * a set \a data. Called when wait_event_timeout receives signal.
  */
-static void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set)
 {
-   struct ptlrpc_request_set *set = data;
struct list_head *tmp;
 
CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set);
@@ -2256,7 +2242,6 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 {
struct list_head *tmp;
struct ptlrpc_request *req;
-   struct l_wait_info lwi;
int rc, timeout;
 
if (set->set_producer)
@@ -2282,46 +2267,47 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
   set, timeout);
 
-   if (timeout == 0 && !signal_pending(current))
+   if (timeout == 0 && !signal_pending(current)) {
/*
 * No requests are in-flight (ether timed out
 * or delayed), so we can allow interrupts.
 * We still want to block for a limited time,
 * so we allow interrupts during the timeout.
   

[PATCH 14/16] staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd

2017-12-17 Thread NeilBrown
Rather an using l_wait_event(), use wait_event_timeout()
with an explicit loop so it is easier to see what is happening.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c 
b/drivers/staging/lustre/lustre/ptlrpc/service.c
index c568baf8c28f..8c77693510a1 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2617,7 +2617,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 {
struct ptlrpc_service_part *svcpt;
struct ptlrpc_request_buffer_desc *rqbd;
-   struct l_wait_info lwi;
+   int cnt;
int rc;
int i;
 
@@ -2657,12 +2657,13 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 * the HUGE timeout lets us CWARN for visibility
 * of sluggish LNDs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(
-   LONG_UNLINK * HZ,
-   HZ, NULL, NULL);
-   rc = l_wait_event(svcpt->scp_waitq,
- svcpt->scp_nrqbds_posted == 0, );
-   if (rc == -ETIMEDOUT) {
+   cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(svcpt->scp_waitq,
+   
svcpt->scp_nrqbds_posted == 0,
+   HZ)) == 0)
+   cnt ++;
+   if (rc == 0) {
CWARN("Service %s waiting for request 
buffers\n",
  svcpt->scp_service->srv_name);
}




[PATCH 14/16] staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd

2017-12-17 Thread NeilBrown
Rather an using l_wait_event(), use wait_event_timeout()
with an explicit loop so it is easier to see what is happening.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c 
b/drivers/staging/lustre/lustre/ptlrpc/service.c
index c568baf8c28f..8c77693510a1 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2617,7 +2617,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 {
struct ptlrpc_service_part *svcpt;
struct ptlrpc_request_buffer_desc *rqbd;
-   struct l_wait_info lwi;
+   int cnt;
int rc;
int i;
 
@@ -2657,12 +2657,13 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 * the HUGE timeout lets us CWARN for visibility
 * of sluggish LNDs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(
-   LONG_UNLINK * HZ,
-   HZ, NULL, NULL);
-   rc = l_wait_event(svcpt->scp_waitq,
- svcpt->scp_nrqbds_posted == 0, );
-   if (rc == -ETIMEDOUT) {
+   cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(svcpt->scp_waitq,
+   
svcpt->scp_nrqbds_posted == 0,
+   HZ)) == 0)
+   cnt ++;
+   if (rc == 0) {
CWARN("Service %s waiting for request 
buffers\n",
  svcpt->scp_service->srv_name);
}




[PATCH 15/16] staging: lustre: use explicit poll loop in ptlrpc_unregister_reply

2017-12-17 Thread NeilBrown
replace l_wait_event() with wait_event_timeout() and explicit
loop.  This approach is easier to understand.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 3e6d22beb9f5..bb8c9ab68f5f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2500,7 +2500,6 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request 
*request, int async)
 {
int rc;
wait_queue_head_t *wq;
-   struct l_wait_info lwi;
 
/* Might sleep. */
LASSERT(!in_interrupt());
@@ -2543,16 +2542,17 @@ static int ptlrpc_unregister_reply(struct 
ptlrpc_request *request, int async)
 * Network access will complete in finite time but the HUGE
 * timeout lets us CWARN for visibility of sluggish NALs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-  HZ, NULL, NULL);
-   rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
- );
-   if (rc == 0) {
+   int cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(*wq,
+   
!ptlrpc_client_recv_or_unlink(request),
+   HZ)) == 0)
+   cnt += 1;
+   if (rc > 0) {
ptlrpc_rqphase_move(request, request->rq_next_phase);
return 1;
}
 
-   LASSERT(rc == -ETIMEDOUT);
DEBUG_REQ(D_WARNING, request,
  "Unexpectedly long timeout receiving_reply=%d 
req_ulinked=%d reply_unlinked=%d",
  request->rq_receiving_reply,




[PATCH 13/16] staging: lustre: improve waiting in sptlrpc_req_refresh_ctx

2017-12-17 Thread NeilBrown
Replace l_wait_event with wait_event_timeout() and call the
handler function explicitly.  This makes it more clear
what is happening.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/sec.c |   23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c 
b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 617e004d00f8..6292840f1fca 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -554,9 +554,8 @@ int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
 }
 
 static
-int ctx_refresh_timeout(void *data)
+int ctx_refresh_timeout(struct ptlrpc_request *req)
 {
-   struct ptlrpc_request *req = data;
int rc;
 
/* conn_cnt is needed in expire_one_request */
@@ -575,10 +574,8 @@ int ctx_refresh_timeout(void *data)
 }
 
 static
-void ctx_refresh_interrupt(void *data)
+void ctx_refresh_interrupt(struct ptlrpc_request *req)
 {
-   struct ptlrpc_request *req = data;
-
spin_lock(>rq_lock);
req->rq_intr = 1;
spin_unlock(>rq_lock);
@@ -611,7 +608,6 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, 
long timeout)
 {
struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
struct ptlrpc_sec *sec;
-   struct l_wait_info lwi;
int rc;
 
LASSERT(ctx);
@@ -743,10 +739,17 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, 
long timeout)
req->rq_restart = 0;
spin_unlock(>rq_lock);
 
-   lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
-  ctx_refresh_timeout, ctx_refresh_interrupt,
-  req);
-   rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), );
+   rc = wait_event_timeout(req->rq_reply_waitq,
+   ctx_check_refresh(ctx),
+   timeout * HZ);
+   if (rc > 0)
+   rc = 0;
+   else if (ctx_refresh_timeout(req))
+   rc = -ETIMEDOUT;
+   else if (l_fatal_signal_pending(current)) {
+   rc = -EINTR;
+   ctx_refresh_interrupt(req);
+   }
 
/*
 * following cases could lead us here:




[PATCH 15/16] staging: lustre: use explicit poll loop in ptlrpc_unregister_reply

2017-12-17 Thread NeilBrown
replace l_wait_event() with wait_event_timeout() and explicit
loop.  This approach is easier to understand.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 3e6d22beb9f5..bb8c9ab68f5f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2500,7 +2500,6 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request 
*request, int async)
 {
int rc;
wait_queue_head_t *wq;
-   struct l_wait_info lwi;
 
/* Might sleep. */
LASSERT(!in_interrupt());
@@ -2543,16 +2542,17 @@ static int ptlrpc_unregister_reply(struct 
ptlrpc_request *request, int async)
 * Network access will complete in finite time but the HUGE
 * timeout lets us CWARN for visibility of sluggish NALs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-  HZ, NULL, NULL);
-   rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
- );
-   if (rc == 0) {
+   int cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(*wq,
+   
!ptlrpc_client_recv_or_unlink(request),
+   HZ)) == 0)
+   cnt += 1;
+   if (rc > 0) {
ptlrpc_rqphase_move(request, request->rq_next_phase);
return 1;
}
 
-   LASSERT(rc == -ETIMEDOUT);
DEBUG_REQ(D_WARNING, request,
  "Unexpectedly long timeout receiving_reply=%d 
req_ulinked=%d reply_unlinked=%d",
  request->rq_receiving_reply,




[PATCH 13/16] staging: lustre: improve waiting in sptlrpc_req_refresh_ctx

2017-12-17 Thread NeilBrown
Replace l_wait_event with wait_event_timeout() and call the
handler function explicitly.  This makes it more clear
what is happening.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/sec.c |   23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c 
b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 617e004d00f8..6292840f1fca 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -554,9 +554,8 @@ int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
 }
 
 static
-int ctx_refresh_timeout(void *data)
+int ctx_refresh_timeout(struct ptlrpc_request *req)
 {
-   struct ptlrpc_request *req = data;
int rc;
 
/* conn_cnt is needed in expire_one_request */
@@ -575,10 +574,8 @@ int ctx_refresh_timeout(void *data)
 }
 
 static
-void ctx_refresh_interrupt(void *data)
+void ctx_refresh_interrupt(struct ptlrpc_request *req)
 {
-   struct ptlrpc_request *req = data;
-
spin_lock(>rq_lock);
req->rq_intr = 1;
spin_unlock(>rq_lock);
@@ -611,7 +608,6 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, 
long timeout)
 {
struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
struct ptlrpc_sec *sec;
-   struct l_wait_info lwi;
int rc;
 
LASSERT(ctx);
@@ -743,10 +739,17 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, 
long timeout)
req->rq_restart = 0;
spin_unlock(>rq_lock);
 
-   lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
-  ctx_refresh_timeout, ctx_refresh_interrupt,
-  req);
-   rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), );
+   rc = wait_event_timeout(req->rq_reply_waitq,
+   ctx_check_refresh(ctx),
+   timeout * HZ);
+   if (rc > 0)
+   rc = 0;
+   else if (ctx_refresh_timeout(req))
+   rc = -ETIMEDOUT;
+   else if (l_fatal_signal_pending(current)) {
+   rc = -EINTR;
+   ctx_refresh_interrupt(req);
+   }
 
/*
 * following cases could lead us here:




[PATCH 06/16] staging: lustre: simplify l_wait_event when intr handler but no timeout.

2017-12-17 Thread NeilBrown
If l_wait_event() is given a function to be called on a signal,
but no timeout or timeout handler, then the intr function is simply
called at the end if the wait was aborted by a signal.
So a simpler way to write the code (in the one place this case is
used) it to open-code the body of the function after the
wait_event, if -ERESTARTSYS was returned.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c |   30 +--
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 657ab95091a0..411b540b96d9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -310,24 +310,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req)
return LDLM_ITER_CONTINUE;
 }
 
-struct ldlm_flock_wait_data {
-   struct ldlm_lock *fwd_lock;
-};
-
-static void
-ldlm_flock_interrupted_wait(void *data)
-{
-   struct ldlm_lock *lock;
-
-   lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
-
-   lock_res_and_lock(lock);
-
-   /* client side - set flag to prevent lock from being put on LRU list */
-   ldlm_set_cbpending(lock);
-   unlock_res_and_lock(lock);
-}
-
 /**
  * Flock completion callback function.
  *
@@ -342,8 +324,6 @@ int
 ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
struct file_lock*getlk = lock->l_ast_data;
-   struct ldlm_flock_wait_data fwd;
-   struct l_wait_info  lwi;
int rc = 0;
 
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT2, 4);
@@ -372,13 +352,17 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 
flags, void *data)
 
LDLM_DEBUG(lock,
   "client-side enqueue returned a blocked lock, sleeping");
-   fwd.fwd_lock = lock;
-   lwi = LWI_TIMEOUT_INTR(0, NULL, ldlm_flock_interrupted_wait, );
 
/* Go to sleep until the lock is granted. */
-   rc = l_wait_event(lock->l_waitq, is_granted_or_cancelled(lock), );
+   rc = l_wait_event_abortable(lock->l_waitq, 
is_granted_or_cancelled(lock));
 
if (rc) {
+   lock_res_and_lock(lock);
+
+   /* client side - set flag to prevent lock from being put on LRU 
list */
+   ldlm_set_cbpending(lock);
+   unlock_res_and_lock(lock);
+
LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
   rc);
return rc;




[PATCH 11/16] staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious

2017-12-17 Thread NeilBrown
This use of l_wait_event() is a polling loop that re-checks
every second.  Make this more obvious with a while loop
and wait_event_timeout().

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c 
b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 0c2ded721c49..5606c8f01b5b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -229,7 +229,6 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int 
async)
 {
struct ptlrpc_bulk_desc *desc = req->rq_bulk;
wait_queue_head_t *wq;
-   struct l_wait_info lwi;
int rc;
 
LASSERT(!in_interrupt()); /* might sleep */
@@ -246,7 +245,7 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int 
async)
 
/* the unlink ensures the callback happens ASAP and is the last
 * one.  If it fails, it must be because completion just happened,
-* but we must still l_wait_event() in this case to give liblustre
+* but we must still wait_event() in this case to give liblustre
 * a chance to run client_bulk_callback()
 */
mdunlink_iterate_helper(desc->bd_mds, desc->bd_md_max_brw);
@@ -270,15 +269,16 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, 
int async)
/* Network access will complete in finite time but the HUGE
 * timeout lets us CWARN for visibility of sluggish LNDs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-  HZ, NULL, NULL);
-   rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), );
-   if (rc == 0) {
+   int cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(*wq, 
!ptlrpc_client_bulk_active(req),
+   HZ)) == 0)
+   cnt += 1;
+   if (rc > 0) {
ptlrpc_rqphase_move(req, req->rq_next_phase);
return 1;
}
 
-   LASSERT(rc == -ETIMEDOUT);
DEBUG_REQ(D_WARNING, req, "Unexpectedly long timeout: desc %p",
  desc);
}




[PATCH 06/16] staging: lustre: simplify l_wait_event when intr handler but no timeout.

2017-12-17 Thread NeilBrown
If l_wait_event() is given a function to be called on a signal,
but no timeout or timeout handler, then the intr function is simply
called at the end if the wait was aborted by a signal.
So a simpler way to write the code (in the one place this case is
used) it to open-code the body of the function after the
wait_event, if -ERESTARTSYS was returned.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c |   30 +--
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 657ab95091a0..411b540b96d9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -310,24 +310,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req)
return LDLM_ITER_CONTINUE;
 }
 
-struct ldlm_flock_wait_data {
-   struct ldlm_lock *fwd_lock;
-};
-
-static void
-ldlm_flock_interrupted_wait(void *data)
-{
-   struct ldlm_lock *lock;
-
-   lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
-
-   lock_res_and_lock(lock);
-
-   /* client side - set flag to prevent lock from being put on LRU list */
-   ldlm_set_cbpending(lock);
-   unlock_res_and_lock(lock);
-}
-
 /**
  * Flock completion callback function.
  *
@@ -342,8 +324,6 @@ int
 ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
struct file_lock*getlk = lock->l_ast_data;
-   struct ldlm_flock_wait_data fwd;
-   struct l_wait_info  lwi;
int rc = 0;
 
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT2, 4);
@@ -372,13 +352,17 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 
flags, void *data)
 
LDLM_DEBUG(lock,
   "client-side enqueue returned a blocked lock, sleeping");
-   fwd.fwd_lock = lock;
-   lwi = LWI_TIMEOUT_INTR(0, NULL, ldlm_flock_interrupted_wait, );
 
/* Go to sleep until the lock is granted. */
-   rc = l_wait_event(lock->l_waitq, is_granted_or_cancelled(lock), );
+   rc = l_wait_event_abortable(lock->l_waitq, 
is_granted_or_cancelled(lock));
 
if (rc) {
+   lock_res_and_lock(lock);
+
+   /* client side - set flag to prevent lock from being put on LRU 
list */
+   ldlm_set_cbpending(lock);
+   unlock_res_and_lock(lock);
+
LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
   rc);
return rc;




[PATCH 11/16] staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious

2017-12-17 Thread NeilBrown
This use of l_wait_event() is a polling loop that re-checks
every second.  Make this more obvious with a while loop
and wait_event_timeout().

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c 
b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 0c2ded721c49..5606c8f01b5b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -229,7 +229,6 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int 
async)
 {
struct ptlrpc_bulk_desc *desc = req->rq_bulk;
wait_queue_head_t *wq;
-   struct l_wait_info lwi;
int rc;
 
LASSERT(!in_interrupt()); /* might sleep */
@@ -246,7 +245,7 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int 
async)
 
/* the unlink ensures the callback happens ASAP and is the last
 * one.  If it fails, it must be because completion just happened,
-* but we must still l_wait_event() in this case to give liblustre
+* but we must still wait_event() in this case to give liblustre
 * a chance to run client_bulk_callback()
 */
mdunlink_iterate_helper(desc->bd_mds, desc->bd_md_max_brw);
@@ -270,15 +269,16 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, 
int async)
/* Network access will complete in finite time but the HUGE
 * timeout lets us CWARN for visibility of sluggish LNDs
 */
-   lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-  HZ, NULL, NULL);
-   rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), );
-   if (rc == 0) {
+   int cnt = 0;
+   while (cnt < LONG_UNLINK &&
+  (rc = wait_event_timeout(*wq, 
!ptlrpc_client_bulk_active(req),
+   HZ)) == 0)
+   cnt += 1;
+   if (rc > 0) {
ptlrpc_rqphase_move(req, req->rq_next_phase);
return 1;
}
 
-   LASSERT(rc == -ETIMEDOUT);
DEBUG_REQ(D_WARNING, req, "Unexpectedly long timeout: desc %p",
  desc);
}




[PATCH 12/16] staging: lustre: use wait_event_timeout in ptlrpcd()

2017-12-17 Thread NeilBrown
We can replace l_wait_event() with
wait_event_noload_timeout() here providing we call the
timeout function when wait_event_timeout() returns zero.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   12 
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 +-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |9 +
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 81b7a7046d82..3e6d22beb9f5 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2125,9 +2125,8 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, 
int async_unlink)
  * Callback used when waiting on sets with l_wait_event.
  * Always returns 1.
  */
-int ptlrpc_expired_set(void *data)
+int ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
-   struct ptlrpc_request_set *set = data;
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
 
@@ -2164,6 +2163,11 @@ int ptlrpc_expired_set(void *data)
 */
return 1;
 }
+static int ptlrpc_expired_set_void(void *data)
+{
+   struct ptlrpc_request_set *set = data;
+   return ptlrpc_expired_set(set);
+}
 
 /**
  * Sets rq_intr flag in \a req under spinlock.
@@ -2286,7 +2290,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 * so we allow interrupts during the timeout.
 */
lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-  ptlrpc_expired_set,
+  ptlrpc_expired_set_void,
   ptlrpc_interrupted_set, set);
else
/*
@@ -2295,7 +2299,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 * complete, or an in-flight req times out.
 */
lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
- ptlrpc_expired_set, set);
+ ptlrpc_expired_set_void, set);
 
rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), 
);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index f9decbd1459d..6dd52d99d454 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -68,7 +68,7 @@ void ptlrpc_request_cache_free(struct ptlrpc_request *req);
 void ptlrpc_init_xid(void);
 void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
struct ptlrpc_request *req);
-int ptlrpc_expired_set(void *data);
+int ptlrpc_expired_set(struct ptlrpc_request_set *set);
 int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set);
 void ptlrpc_resend_req(struct ptlrpc_request *request);
 void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 0bdf1f54629b..b7df38e71946 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -434,16 +434,17 @@ static int ptlrpcd(void *arg)
 * new_req_list and ptlrpcd_check() moves them into the set.
 */
do {
-   struct l_wait_info lwi;
int timeout;
 
timeout = ptlrpc_set_next_timeout(set);
-   lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
- ptlrpc_expired_set, set);
 
lu_context_enter(_ctx);
lu_context_enter(env.le_ses);
-   l_wait_event(set->set_waitq, ptlrpcd_check(, pc), );
+   if (wait_event_noload_timeout(set->set_waitq,
+ ptlrpcd_check(, pc),
+ (timeout ? timeout : 1) * HZ) == 
0)
+   ptlrpc_expired_set(set);
+
lu_context_exit(_ctx);
lu_context_exit(env.le_ses);
 




[PATCH 08/16] staging: lustre: open code polling loop instead of using l_wait_event()

2017-12-17 Thread NeilBrown
Two places that LWI_TIMEOUT_INTERVAL() is used, the outcome is a
simple polling loop that polls every second for some event (with a
limit).

So write a simple loop to make this more apparent.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/llite/llite_lib.c |   11 +--
 drivers/staging/lustre/lustre/lov/lov_request.c |   12 +---
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 33dc15e9aebb..f6642fa30428 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1984,8 +1984,7 @@ void ll_umount_begin(struct super_block *sb)
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct obd_device *obd;
struct obd_ioctl_data *ioc_data;
-   wait_queue_head_t waitq;
-   struct l_wait_info lwi;
+   int cnt = 0;
 
CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb,
   sb->s_count, atomic_read(>s_active));
@@ -2021,10 +2020,10 @@ void ll_umount_begin(struct super_block *sb)
 * and then continue. For now, we just periodically checking for vfs
 * to decrement mnt_cnt and hope to finish it within 10sec.
 */
-   init_waitqueue_head();
-   lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
-  HZ, NULL, NULL);
-   l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), );
+   while (cnt < 10 && !may_umount(sbi->ll_mnt.mnt)) {
+   schedule_timeout_uninterruptible(HZ);
+   cnt ++;
+   }
 
schedule();
 }
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c 
b/drivers/staging/lustre/lustre/lov/lov_request.c
index fb3b7a7fa32a..c1e58fcc30b3 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -99,8 +99,7 @@ static int lov_check_set(struct lov_obd *lov, int idx)
  */
 static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 {
-   wait_queue_head_t waitq;
-   struct l_wait_info lwi;
+   int cnt = 0;
struct lov_tgt_desc *tgt;
int rc = 0;
 
@@ -125,11 +124,10 @@ static int lov_check_and_wait_active(struct lov_obd *lov, 
int ost_idx)
 
mutex_unlock(>lov_lock);
 
-   init_waitqueue_head();
-   lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
-  HZ, NULL, NULL);
-
-   rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), );
+   while (cnt < obd_timeout && !lov_check_set(lov, ost_idx)) {
+   schedule_timeout_uninterruptible(HZ);
+   cnt ++;
+   }
if (tgt->ltd_active)
return 1;
 




[PATCH 10/16] staging: lustre: remove back_to_sleep() and use loops.

2017-12-17 Thread NeilBrown
When 'back_to_sleep()' is passed as the 'timeout' function,
the effect is to wait indefinitely for the event, polling
on the timeout in case we missed a wake_up.
If LWI_ON_SIGNAL_NOOP is given, then also abort (at the timeout)
if a "fatal" signal is pending.

Make this more obvious is both places "back_to_sleep()" is
used, adding l_fatal_signal_pending() to allow testing for
"fatal" signals.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |8 
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   11 ++-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |8 
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index d64306291b47..d157ed35a0bf 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -140,10 +140,6 @@ void target_send_reply(struct ptlrpc_request *req, int rc, 
int fail_id);
  * XXX nikita: some ptlrpc daemon threads have races of that sort.
  *
  */
-static inline int back_to_sleep(void *arg)
-{
-   return 0;
-}
 
 #define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
 
@@ -200,6 +196,10 @@ struct l_wait_info {
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |
\
   sigmask(SIGTERM) | sigmask(SIGQUIT) |\
   sigmask(SIGALRM))
+static inline int l_fatal_signal_pending(struct task_struct *p)
+{
+   return signal_pending(p) && sigtestsetmask(>pending.signal, 
LUSTRE_FATAL_SIGS);
+}
 
 /**
  * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for 
exclusively
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c 
b/drivers/staging/lustre/lustre/ptlrpc/import.c
index b6cef8e97435..decaa9bccdc8 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -1496,7 +1496,6 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int 
noclose)
}
 
if (ptlrpc_import_in_recovery(imp)) {
-   struct l_wait_info lwi;
long timeout;
 
if (AT_OFF) {
@@ -1510,10 +1509,12 @@ int ptlrpc_disconnect_import(struct obd_import *imp, 
int noclose)
timeout = 
at_get(>imp_at.iat_service_estimate[idx]) * HZ;
}
 
-   lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
-  back_to_sleep, LWI_ON_SIGNAL_NOOP, NULL);
-   rc = l_wait_event(imp->imp_recovery_waitq,
- !ptlrpc_import_in_recovery(imp), );
+   while (wait_event_timeout(imp->imp_recovery_waitq,
+ !ptlrpc_import_in_recovery(imp),
+ cfs_timeout_cap(timeout)) == 0)
+   if (l_fatal_signal_pending(current))
+   break;
+   /* else just keep waiting */
}
 
spin_lock(>imp_lock);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index dad2f9290f70..0bdf1f54629b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,12 +230,12 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
spin_lock(>rq_lock);
if (req->rq_invalid_rqset) {
-   struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
-back_to_sleep, NULL);
-
req->rq_invalid_rqset = 0;
spin_unlock(>rq_lock);
-   l_wait_event(req->rq_set_waitq, !req->rq_set, );
+   while (wait_event_timeout(req->rq_set_waitq,
+ !req->rq_set,
+ 5 * HZ) == 0)
+   ;
} else if (req->rq_set) {
/* If we have a valid "rq_set", just reuse it to avoid double
 * linked.




[PATCH 09/16] staging: lustre: simplify waiting in ptlrpc_invalidate_import()

2017-12-17 Thread NeilBrown
This wait current wakes up every second to re-test if
imp_flight is zero.  If we ensure wakeup is called whenever
imp_flight is decremented to zero, we can just have a simple
wait_event_timeout().

So add a wake_up_all to the one place it is missing, and simplify
the wait_event.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |3 ++-
 drivers/staging/lustre/lustre/ptlrpc/import.c |   21 -
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 0ab13f8e5993..81b7a7046d82 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1588,7 +1588,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
spin_lock(>imp_lock);
if (!list_empty(>rq_list)) {
list_del_init(>rq_list);
-   atomic_dec(>rq_import->imp_inflight);
+   if (atomic_dec_and_test(>rq_import->imp_inflight))
+   
wake_up_all(>rq_import->imp_recovery_waitq);
}
spin_unlock(>imp_lock);
ptlrpc_rqphase_move(req, RQ_PHASE_NEW);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c 
b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 34b4075fac42..b6cef8e97435 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -265,7 +265,6 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 {
struct list_head *tmp, *n;
struct ptlrpc_request *req;
-   struct l_wait_info lwi;
unsigned int timeout;
int rc;
 
@@ -306,19 +305,15 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 * callbacks. Cap it at obd_timeout -- these should all
 * have been locally cancelled by ptlrpc_abort_inflight.
 */
-   lwi = LWI_TIMEOUT_INTERVAL(
-   cfs_timeout_cap(timeout * HZ),
-   (timeout > 1) ? HZ :
-   HZ / 2,
-   NULL, NULL);
-   rc = l_wait_event(imp->imp_recovery_waitq,
- (atomic_read(>imp_inflight) == 0),
- );
-   if (rc) {
+   rc = wait_event_timeout(imp->imp_recovery_waitq,
+   atomic_read(>imp_inflight) == 0,
+   obd_timeout * HZ);
+
+   if (rc == 0) {
const char *cli_tgt = obd2cli_tgt(imp->imp_obd);
 
-   CERROR("%s: rc = %d waiting for callback (%d != 0)\n",
-  cli_tgt, rc,
+   CERROR("%s: timeout waiting for callback (%d != 0)\n",
+  cli_tgt,
   atomic_read(>imp_inflight));
 
spin_lock(>imp_lock);
@@ -365,7 +360,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
}
spin_unlock(>imp_lock);
}
-   } while (rc != 0);
+   } while (rc == 0);
 
/*
 * Let's additionally check that no new rpcs added to import in




[PATCH 07/16] staging: lustre: simplify waiting in ldlm_completion_ast()

2017-12-17 Thread NeilBrown
If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.
If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

So treat the two cases separately. In one, use
l_wait_event_abortable().  In the other, use wait_event_timeout(),
and if the timeout happens - perform the timeout-call function
(opencoded).

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   51 +++--
 1 file changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..05bec9fd629b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout 
minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-   struct ldlm_lock *lwd_lock;
-   __u32lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static int ldlm_expired_completion_wait(struct ldlm_lock *lock, struct 
obd_import *imp2)
 {
-   struct lock_wait_data *lwd = data;
-   struct ldlm_lock *lock = lwd->lwd_lock;
struct obd_import *imp;
struct obd_device *obd;
 
@@ -140,7 +129,7 @@ static int ldlm_expired_completion_wait(void *data)
 
obd = lock->l_conn_export->exp_obd;
imp = obd->u.cli.cl_import;
-   ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+   ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
LDLM_ERROR(lock,
   "lock timed out (enqueued at %lld, %llds ago), entering 
recovery for %s@%s",
   (s64)lock->l_last_activity,
@@ -251,10 +240,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
/* XXX ALLOCATE - 160 bytes */
-   struct lock_wait_data lwd;
struct obd_device *obd;
struct obd_import *imp = NULL;
-   struct l_wait_info lwi;
__u32 timeout;
int rc = 0;
 
@@ -281,32 +268,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 
flags, void *data)
 
timeout = ldlm_cp_timeout(lock);
 
-   lwd.lwd_lock = lock;
lock->l_last_activity = ktime_get_real_seconds();
 
-   if (ldlm_is_no_timeout(lock)) {
-   LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-   lwi = LWI_INTR(interrupted_completion_wait, );
-   } else {
-   lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-  ldlm_expired_completion_wait,
-  interrupted_completion_wait, );
-   }
-
-   if (imp) {
-   spin_lock(>imp_lock);
-   lwd.lwd_conn_cnt = imp->imp_conn_cnt;
-   spin_unlock(>imp_lock);
-   }
-
if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
ldlm_set_fail_loc(lock);
rc = -EINTR;
} else {
-   /* Go to sleep until the lock is granted or cancelled. */
-   rc = l_wait_event(lock->l_waitq,
- is_granted_or_cancelled(lock), );
+   /* Go to sleep until the lock is granted or canceled. */
+   if (ldlm_is_no_timeout(lock)) {
+   LDLM_DEBUG(lock, "waiting indefinitely because of 
NO_TIMEOUT");
+   rc = l_wait_event_abortable(lock->l_waitq,
+   
is_granted_or_cancelled(lock));
+   } else {
+   rc = wait_event_timeout(lock->l_waitq,
+   is_granted_or_cancelled(lock),
+   timeout * HZ);
+   if (rc == 0) {
+   ldlm_expired_completion_wait(lock, imp);
+   rc = -ETIMEDOUT;
+   } else
+   rc = 0;
+   }
}
 
if (rc) {




[PATCH 10/16] staging: lustre: remove back_to_sleep() and use loops.

2017-12-17 Thread NeilBrown
When 'back_to_sleep()' is passed as the 'timeout' function,
the effect is to wait indefinitely for the event, polling
on the timeout in case we missed a wake_up.
If LWI_ON_SIGNAL_NOOP is given, then also abort (at the timeout)
if a "fatal" signal is pending.

Make this more obvious is both places "back_to_sleep()" is
used, adding l_fatal_signal_pending() to allow testing for
"fatal" signals.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |8 
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   11 ++-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |8 
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index d64306291b47..d157ed35a0bf 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -140,10 +140,6 @@ void target_send_reply(struct ptlrpc_request *req, int rc, 
int fail_id);
  * XXX nikita: some ptlrpc daemon threads have races of that sort.
  *
  */
-static inline int back_to_sleep(void *arg)
-{
-   return 0;
-}
 
 #define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
 
@@ -200,6 +196,10 @@ struct l_wait_info {
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |
\
   sigmask(SIGTERM) | sigmask(SIGQUIT) |\
   sigmask(SIGALRM))
+static inline int l_fatal_signal_pending(struct task_struct *p)
+{
+   return signal_pending(p) && sigtestsetmask(>pending.signal, 
LUSTRE_FATAL_SIGS);
+}
 
 /**
  * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for 
exclusively
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c 
b/drivers/staging/lustre/lustre/ptlrpc/import.c
index b6cef8e97435..decaa9bccdc8 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -1496,7 +1496,6 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int 
noclose)
}
 
if (ptlrpc_import_in_recovery(imp)) {
-   struct l_wait_info lwi;
long timeout;
 
if (AT_OFF) {
@@ -1510,10 +1509,12 @@ int ptlrpc_disconnect_import(struct obd_import *imp, 
int noclose)
timeout = 
at_get(>imp_at.iat_service_estimate[idx]) * HZ;
}
 
-   lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
-  back_to_sleep, LWI_ON_SIGNAL_NOOP, NULL);
-   rc = l_wait_event(imp->imp_recovery_waitq,
- !ptlrpc_import_in_recovery(imp), );
+   while (wait_event_timeout(imp->imp_recovery_waitq,
+ !ptlrpc_import_in_recovery(imp),
+ cfs_timeout_cap(timeout)) == 0)
+   if (l_fatal_signal_pending(current))
+   break;
+   /* else just keep waiting */
}
 
spin_lock(>imp_lock);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index dad2f9290f70..0bdf1f54629b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,12 +230,12 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
spin_lock(>rq_lock);
if (req->rq_invalid_rqset) {
-   struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
-back_to_sleep, NULL);
-
req->rq_invalid_rqset = 0;
spin_unlock(>rq_lock);
-   l_wait_event(req->rq_set_waitq, !req->rq_set, );
+   while (wait_event_timeout(req->rq_set_waitq,
+ !req->rq_set,
+ 5 * HZ) == 0)
+   ;
} else if (req->rq_set) {
/* If we have a valid "rq_set", just reuse it to avoid double
 * linked.




[PATCH 09/16] staging: lustre: simplify waiting in ptlrpc_invalidate_import()

2017-12-17 Thread NeilBrown
This wait current wakes up every second to re-test if
imp_flight is zero.  If we ensure wakeup is called whenever
imp_flight is decremented to zero, we can just have a simple
wait_event_timeout().

So add a wake_up_all to the one place it is missing, and simplify
the wait_event.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |3 ++-
 drivers/staging/lustre/lustre/ptlrpc/import.c |   21 -
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 0ab13f8e5993..81b7a7046d82 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1588,7 +1588,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
spin_lock(>imp_lock);
if (!list_empty(>rq_list)) {
list_del_init(>rq_list);
-   atomic_dec(>rq_import->imp_inflight);
+   if (atomic_dec_and_test(>rq_import->imp_inflight))
+   
wake_up_all(>rq_import->imp_recovery_waitq);
}
spin_unlock(>imp_lock);
ptlrpc_rqphase_move(req, RQ_PHASE_NEW);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c 
b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 34b4075fac42..b6cef8e97435 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -265,7 +265,6 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 {
struct list_head *tmp, *n;
struct ptlrpc_request *req;
-   struct l_wait_info lwi;
unsigned int timeout;
int rc;
 
@@ -306,19 +305,15 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 * callbacks. Cap it at obd_timeout -- these should all
 * have been locally cancelled by ptlrpc_abort_inflight.
 */
-   lwi = LWI_TIMEOUT_INTERVAL(
-   cfs_timeout_cap(timeout * HZ),
-   (timeout > 1) ? HZ :
-   HZ / 2,
-   NULL, NULL);
-   rc = l_wait_event(imp->imp_recovery_waitq,
- (atomic_read(>imp_inflight) == 0),
- );
-   if (rc) {
+   rc = wait_event_timeout(imp->imp_recovery_waitq,
+   atomic_read(>imp_inflight) == 0,
+   obd_timeout * HZ);
+
+   if (rc == 0) {
const char *cli_tgt = obd2cli_tgt(imp->imp_obd);
 
-   CERROR("%s: rc = %d waiting for callback (%d != 0)\n",
-  cli_tgt, rc,
+   CERROR("%s: timeout waiting for callback (%d != 0)\n",
+  cli_tgt,
   atomic_read(>imp_inflight));
 
spin_lock(>imp_lock);
@@ -365,7 +360,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
}
spin_unlock(>imp_lock);
}
-   } while (rc != 0);
+   } while (rc == 0);
 
/*
 * Let's additionally check that no new rpcs added to import in




[PATCH 07/16] staging: lustre: simplify waiting in ldlm_completion_ast()

2017-12-17 Thread NeilBrown
If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.
If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

So treat the two cases separately. In one, use
l_wait_event_abortable().  In the other, use wait_event_timeout(),
and if the timeout happens - perform the timeout-call function
(opencoded).

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   51 +++--
 1 file changed, 17 insertions(+), 34 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..05bec9fd629b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout 
minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-   struct ldlm_lock *lwd_lock;
-   __u32lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static int ldlm_expired_completion_wait(struct ldlm_lock *lock, struct 
obd_import *imp2)
 {
-   struct lock_wait_data *lwd = data;
-   struct ldlm_lock *lock = lwd->lwd_lock;
struct obd_import *imp;
struct obd_device *obd;
 
@@ -140,7 +129,7 @@ static int ldlm_expired_completion_wait(void *data)
 
obd = lock->l_conn_export->exp_obd;
imp = obd->u.cli.cl_import;
-   ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+   ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
LDLM_ERROR(lock,
   "lock timed out (enqueued at %lld, %llds ago), entering 
recovery for %s@%s",
   (s64)lock->l_last_activity,
@@ -251,10 +240,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
/* XXX ALLOCATE - 160 bytes */
-   struct lock_wait_data lwd;
struct obd_device *obd;
struct obd_import *imp = NULL;
-   struct l_wait_info lwi;
__u32 timeout;
int rc = 0;
 
@@ -281,32 +268,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 
flags, void *data)
 
timeout = ldlm_cp_timeout(lock);
 
-   lwd.lwd_lock = lock;
lock->l_last_activity = ktime_get_real_seconds();
 
-   if (ldlm_is_no_timeout(lock)) {
-   LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-   lwi = LWI_INTR(interrupted_completion_wait, );
-   } else {
-   lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-  ldlm_expired_completion_wait,
-  interrupted_completion_wait, );
-   }
-
-   if (imp) {
-   spin_lock(>imp_lock);
-   lwd.lwd_conn_cnt = imp->imp_conn_cnt;
-   spin_unlock(>imp_lock);
-   }
-
if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
ldlm_set_fail_loc(lock);
rc = -EINTR;
} else {
-   /* Go to sleep until the lock is granted or cancelled. */
-   rc = l_wait_event(lock->l_waitq,
- is_granted_or_cancelled(lock), );
+   /* Go to sleep until the lock is granted or canceled. */
+   if (ldlm_is_no_timeout(lock)) {
+   LDLM_DEBUG(lock, "waiting indefinitely because of 
NO_TIMEOUT");
+   rc = l_wait_event_abortable(lock->l_waitq,
+   
is_granted_or_cancelled(lock));
+   } else {
+   rc = wait_event_timeout(lock->l_waitq,
+   is_granted_or_cancelled(lock),
+   timeout * HZ);
+   if (rc == 0) {
+   ldlm_expired_completion_wait(lock, imp);
+   rc = -ETIMEDOUT;
+   } else
+   rc = 0;
+   }
}
 
if (rc) {




[PATCH 12/16] staging: lustre: use wait_event_timeout in ptlrpcd()

2017-12-17 Thread NeilBrown
We can replace l_wait_event() with
wait_event_noload_timeout() here providing we call the
timeout function when wait_event_timeout() returns zero.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   12 
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |2 +-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |9 +
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c 
b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 81b7a7046d82..3e6d22beb9f5 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2125,9 +2125,8 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, 
int async_unlink)
  * Callback used when waiting on sets with l_wait_event.
  * Always returns 1.
  */
-int ptlrpc_expired_set(void *data)
+int ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
-   struct ptlrpc_request_set *set = data;
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
 
@@ -2164,6 +2163,11 @@ int ptlrpc_expired_set(void *data)
 */
return 1;
 }
+static int ptlrpc_expired_set_void(void *data)
+{
+   struct ptlrpc_request_set *set = data;
+   return ptlrpc_expired_set(set);
+}
 
 /**
  * Sets rq_intr flag in \a req under spinlock.
@@ -2286,7 +2290,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 * so we allow interrupts during the timeout.
 */
lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-  ptlrpc_expired_set,
+  ptlrpc_expired_set_void,
   ptlrpc_interrupted_set, set);
else
/*
@@ -2295,7 +2299,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 * complete, or an in-flight req times out.
 */
lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
- ptlrpc_expired_set, set);
+ ptlrpc_expired_set_void, set);
 
rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), 
);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index f9decbd1459d..6dd52d99d454 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -68,7 +68,7 @@ void ptlrpc_request_cache_free(struct ptlrpc_request *req);
 void ptlrpc_init_xid(void);
 void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
struct ptlrpc_request *req);
-int ptlrpc_expired_set(void *data);
+int ptlrpc_expired_set(struct ptlrpc_request_set *set);
 int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set);
 void ptlrpc_resend_req(struct ptlrpc_request *request);
 void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c 
b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 0bdf1f54629b..b7df38e71946 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -434,16 +434,17 @@ static int ptlrpcd(void *arg)
 * new_req_list and ptlrpcd_check() moves them into the set.
 */
do {
-   struct l_wait_info lwi;
int timeout;
 
timeout = ptlrpc_set_next_timeout(set);
-   lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
- ptlrpc_expired_set, set);
 
lu_context_enter(_ctx);
lu_context_enter(env.le_ses);
-   l_wait_event(set->set_waitq, ptlrpcd_check(, pc), );
+   if (wait_event_noload_timeout(set->set_waitq,
+ ptlrpcd_check(, pc),
+ (timeout ? timeout : 1) * HZ) == 
0)
+   ptlrpc_expired_set(set);
+
lu_context_exit(_ctx);
lu_context_exit(env.le_ses);
 




[PATCH 08/16] staging: lustre: open code polling loop instead of using l_wait_event()

2017-12-17 Thread NeilBrown
Two places that LWI_TIMEOUT_INTERVAL() is used, the outcome is a
simple polling loop that polls every second for some event (with a
limit).

So write a simple loop to make this more apparent.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/llite/llite_lib.c |   11 +--
 drivers/staging/lustre/lustre/lov/lov_request.c |   12 +---
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 33dc15e9aebb..f6642fa30428 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1984,8 +1984,7 @@ void ll_umount_begin(struct super_block *sb)
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct obd_device *obd;
struct obd_ioctl_data *ioc_data;
-   wait_queue_head_t waitq;
-   struct l_wait_info lwi;
+   int cnt = 0;
 
CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb,
   sb->s_count, atomic_read(>s_active));
@@ -2021,10 +2020,10 @@ void ll_umount_begin(struct super_block *sb)
 * and then continue. For now, we just periodically checking for vfs
 * to decrement mnt_cnt and hope to finish it within 10sec.
 */
-   init_waitqueue_head();
-   lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
-  HZ, NULL, NULL);
-   l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), );
+   while (cnt < 10 && !may_umount(sbi->ll_mnt.mnt)) {
+   schedule_timeout_uninterruptible(HZ);
+   cnt ++;
+   }
 
schedule();
 }
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c 
b/drivers/staging/lustre/lustre/lov/lov_request.c
index fb3b7a7fa32a..c1e58fcc30b3 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -99,8 +99,7 @@ static int lov_check_set(struct lov_obd *lov, int idx)
  */
 static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 {
-   wait_queue_head_t waitq;
-   struct l_wait_info lwi;
+   int cnt = 0;
struct lov_tgt_desc *tgt;
int rc = 0;
 
@@ -125,11 +124,10 @@ static int lov_check_and_wait_active(struct lov_obd *lov, 
int ost_idx)
 
mutex_unlock(>lov_lock);
 
-   init_waitqueue_head();
-   lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
-  HZ, NULL, NULL);
-
-   rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), );
+   while (cnt < obd_timeout && !lov_check_set(lov, ost_idx)) {
+   schedule_timeout_uninterruptible(HZ);
+   cnt ++;
+   }
if (tgt->ltd_active)
return 1;
 




[PATCH 01/16] staging: lustre: discard SVC_SIGNAL and related functions

2017-12-17 Thread NeilBrown
This flag is never set, so remove checks and remove
the flag.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_net.h |6 --
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |4 +---
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h 
b/drivers/staging/lustre/lustre/include/lustre_net.h
index 3ff5de4770e8..4c665eca2467 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -1260,7 +1260,6 @@ enum {
SVC_STARTING= 1 << 2,
SVC_RUNNING = 1 << 3,
SVC_EVENT   = 1 << 4,
-   SVC_SIGNAL  = 1 << 5,
 };
 
 #define PTLRPC_THR_NAME_LEN32
@@ -1333,11 +1332,6 @@ static inline int thread_is_event(struct ptlrpc_thread 
*thread)
return !!(thread->t_flags & SVC_EVENT);
 }
 
-static inline int thread_is_signal(struct ptlrpc_thread *thread)
-{
-   return !!(thread->t_flags & SVC_SIGNAL);
-}
-
 static inline void thread_clear_flags(struct ptlrpc_thread *thread, __u32 
flags)
 {
thread->t_flags &= ~flags;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c 
b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 8d1e0edfcede..d85c8638c009 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -153,7 +153,6 @@ static int sec_gc_main(void *arg)
while (1) {
struct ptlrpc_sec *sec;
 
-   thread_clear_flags(thread, SVC_SIGNAL);
sec_process_ctx_list();
 again:
/* go through sec list do gc.
@@ -184,8 +183,7 @@ static int sec_gc_main(void *arg)
lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * 
MSEC_PER_SEC),
  NULL, NULL);
l_wait_event(thread->t_ctl_waitq,
-thread_is_stopping(thread) ||
-thread_is_signal(thread),
+thread_is_stopping(thread),
 );
 
if (thread_test_and_clear_flags(thread, SVC_STOPPING))




[PATCH 05/16] staging: lustre: introduce and use l_wait_event_abortable()

2017-12-17 Thread NeilBrown
lustre sometimes wants to wait for an event, but abort if
one of a specific list of signals arrives.  This is a little
bit like wait_event_killable(), except that the signals are
identified a different way.

So introduce l_wait_event_abortable() which provides this
functionality.
Having separate functions for separate needs is more in line
with the pattern set by include/linux/wait.h, than having a
single function which tries to include all possible needs.

Also introduce l_wait_event_abortable_exclusive().

Note that l_wait_event() return -EINTR on a signal, while
Linux wait_event functions return -ERESTARTSYS.
l_wait_event_abortable_exclusive follows the Linux pattern.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   24 
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|   12 +++---
 drivers/staging/lustre/lustre/obdclass/genops.c|9 +++-
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |5 ++--
 drivers/staging/lustre/lustre/osc/osc_page.c   |6 ++---
 drivers/staging/lustre/lustre/osc/osc_request.c|6 ++---
 7 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index fcf31c779e98..d64306291b47 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -425,4 +425,28 @@ do {   
\
__ret = __wait_event_noload_timeout(wq_head, condition, 
timeout);\
__ret;  
\
 })
+
+/* l_wait_event_abortable() is a bit like wait_event_killable()
+ * except there is a fix set of signals which will abort:
+ * LUSTRE_FATAL_SIGS
+ */
+#define l_wait_event_abortable(wq, condition)  \
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible(wq, condition);\
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
+
+#define l_wait_event_abortable_exclusive(wq, condition)
\
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible_exclusive(wq, condition);  \
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 2e66825c8f4b..30044357616d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, 
int force)
ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
 
if (atomic_read(>ns_bref) > 0) {
-   struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
int rc;
 
CDEBUG(D_DLMTRACE,
@@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace 
*ns, int force)
   ldlm_ns_name(ns), atomic_read(>ns_bref));
 force_wait:
if (force)
-   lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
- MSEC_PER_SEC) / 4, NULL, NULL);
-
-   rc = l_wait_event(ns->ns_waitq,
- atomic_read(>ns_bref) == 0, );
+   rc = wait_event_timeout(ns->ns_waitq,
+   atomic_read(>ns_bref) == 0,
+   obd_timeout * HZ / 4) ? 0 : 
-ETIMEDOUT;
+   else
+   rc = l_wait_event_abortable(ns->ns_waitq,
+   atomic_read(>ns_bref) 
== 0);
 
/* Forced cleanups should be able to reclaim all references,
 * so it's safe to wait forever... we can't leak locks...
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 0a9183f271f5..33dc15e9aebb 100644
--- 

[PATCH 01/16] staging: lustre: discard SVC_SIGNAL and related functions

2017-12-17 Thread NeilBrown
This flag is never set, so remove checks and remove
the flag.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_net.h |6 --
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |4 +---
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h 
b/drivers/staging/lustre/lustre/include/lustre_net.h
index 3ff5de4770e8..4c665eca2467 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -1260,7 +1260,6 @@ enum {
SVC_STARTING= 1 << 2,
SVC_RUNNING = 1 << 3,
SVC_EVENT   = 1 << 4,
-   SVC_SIGNAL  = 1 << 5,
 };
 
 #define PTLRPC_THR_NAME_LEN32
@@ -1333,11 +1332,6 @@ static inline int thread_is_event(struct ptlrpc_thread 
*thread)
return !!(thread->t_flags & SVC_EVENT);
 }
 
-static inline int thread_is_signal(struct ptlrpc_thread *thread)
-{
-   return !!(thread->t_flags & SVC_SIGNAL);
-}
-
 static inline void thread_clear_flags(struct ptlrpc_thread *thread, __u32 
flags)
 {
thread->t_flags &= ~flags;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c 
b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 8d1e0edfcede..d85c8638c009 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -153,7 +153,6 @@ static int sec_gc_main(void *arg)
while (1) {
struct ptlrpc_sec *sec;
 
-   thread_clear_flags(thread, SVC_SIGNAL);
sec_process_ctx_list();
 again:
/* go through sec list do gc.
@@ -184,8 +183,7 @@ static int sec_gc_main(void *arg)
lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * 
MSEC_PER_SEC),
  NULL, NULL);
l_wait_event(thread->t_ctl_waitq,
-thread_is_stopping(thread) ||
-thread_is_signal(thread),
+thread_is_stopping(thread),
 );
 
if (thread_test_and_clear_flags(thread, SVC_STOPPING))




[PATCH 05/16] staging: lustre: introduce and use l_wait_event_abortable()

2017-12-17 Thread NeilBrown
lustre sometimes wants to wait for an event, but abort if
one of a specific list of signals arrives.  This is a little
bit like wait_event_killable(), except that the signals are
identified a different way.

So introduce l_wait_event_abortable() which provides this
functionality.
Having separate functions for separate needs is more in line
with the pattern set by include/linux/wait.h, than having a
single function which tries to include all possible needs.

Also introduce l_wait_event_abortable_exclusive().

Note that l_wait_event() return -EINTR on a signal, while
Linux wait_event functions return -ERESTARTSYS.
l_wait_event_abortable_exclusive follows the Linux pattern.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   24 
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|   12 +++---
 drivers/staging/lustre/lustre/obdclass/genops.c|9 +++-
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |5 ++--
 drivers/staging/lustre/lustre/osc/osc_page.c   |6 ++---
 drivers/staging/lustre/lustre/osc/osc_request.c|6 ++---
 7 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index fcf31c779e98..d64306291b47 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -425,4 +425,28 @@ do {   
\
__ret = __wait_event_noload_timeout(wq_head, condition, 
timeout);\
__ret;  
\
 })
+
+/* l_wait_event_abortable() is a bit like wait_event_killable()
+ * except there is a fix set of signals which will abort:
+ * LUSTRE_FATAL_SIGS
+ */
+#define l_wait_event_abortable(wq, condition)  \
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible(wq, condition);\
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
+
+#define l_wait_event_abortable_exclusive(wq, condition)
\
+({ \
+   sigset_t __blocked; \
+   int __ret = 0;  \
+   __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);   \
+   __ret = wait_event_interruptible_exclusive(wq, condition);  \
+   cfs_restore_sigs(__blocked);\
+   __ret;  \
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 2e66825c8f4b..30044357616d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, 
int force)
ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
 
if (atomic_read(>ns_bref) > 0) {
-   struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
int rc;
 
CDEBUG(D_DLMTRACE,
@@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace 
*ns, int force)
   ldlm_ns_name(ns), atomic_read(>ns_bref));
 force_wait:
if (force)
-   lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
- MSEC_PER_SEC) / 4, NULL, NULL);
-
-   rc = l_wait_event(ns->ns_waitq,
- atomic_read(>ns_bref) == 0, );
+   rc = wait_event_timeout(ns->ns_waitq,
+   atomic_read(>ns_bref) == 0,
+   obd_timeout * HZ / 4) ? 0 : 
-ETIMEDOUT;
+   else
+   rc = l_wait_event_abortable(ns->ns_waitq,
+   atomic_read(>ns_bref) 
== 0);
 
/* Forced cleanups should be able to reclaim all references,
 * so it's safe to wait forever... we can't leak locks...
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c 
b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 0a9183f271f5..33dc15e9aebb 100644
--- 

[PATCH 02/16] staging: lustre: replace simple cases of l_wait_event() with wait_event().

2017-12-17 Thread NeilBrown
When the lwi arg is full of zeros, l_wait_event() behaves almost
identically to the standard wait_event() interface, so use that
instead.

The only difference in behavior is that l_wait_event() blocks all
signals and uses an TASK_INTERRUPTIBLE wait, while wait_event()
does not block signals, but waits in state TASK_UNINTERRUPTIBLE.
This means that processes blocked in wait_event() will contribute
to the load average.  This behavior is (arguably) more correct - in
most cases.

In some cases, the wait is in a service thread waiting for work to
do.  In these case we should wait TASK_NOLOAD order with
TASK_UNINTERRUPTIBLE.  To facilitate this, add a "wait_event_noload()"
macro.  This should eventually be moved into include/linux/wait.h.

There is one case where wait_event_exclusive_noload() is needed.
So we add a macro for that too.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   47 ---
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |4 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|8 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |5 +-
 drivers/staging/lustre/lustre/llite/statahead.c|   50 
 drivers/staging/lustre/lustre/lov/lov_object.c |6 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c|4 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c |6 +-
 drivers/staging/lustre/lustre/obdclass/genops.c|   15 ++
 drivers/staging/lustre/lustre/osc/osc_cache.c  |5 +-
 drivers/staging/lustre/lustre/osc/osc_object.c |4 --
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   10 ++--
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |   11 ++--
 drivers/staging/lustre/lustre/ptlrpc/service.c |   13 ++---
 14 files changed, 93 insertions(+), 95 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ca1dce15337e..08bdd618ea7d 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -333,12 +333,6 @@ do {   
   \
__ret;\
 })
 
-#define l_wait_condition(wq, condition) \
-({   \
-   struct l_wait_info lwi = { 0 };  \
-   l_wait_event(wq, condition, );\
-})
-
 #define l_wait_condition_exclusive(wq, condition) \
 ({   \
struct l_wait_info lwi = { 0 };  \
@@ -353,4 +347,45 @@ do {   
   \
 
 /** @} lib */
 
+#define __wait_event_noload(wq_head, condition)
\
+   (void)___wait_event(wq_head, condition, (TASK_UNINTERRUPTIBLE | 
TASK_NOLOAD), 0, 0, \
+   schedule())
+
+/**
+ * wait_event_noload - sleep, without registering load, until a condition gets 
true
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_UNINTERRUPTIBLE|TASK_NOLOAD) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * This can be used instead of wait_event() when the event
+ * being waited for is does not imply load on the system, but
+ * when responding to signals is no appropriate, such as in
+ * a kernel service thread.
+ */
+#define wait_event_noload(wq_head, condition)  
\
+do {   
\
+   might_sleep();  
\
+   if (condition)  
\
+   break;  
\
+   __wait_event_noload(wq_head, condition);
\
+} while (0)
+
+/*
+ * Just like wait_event_noload(), except it sets exclusive flag
+ */
+#define wait_event_exclusive_noload(wq_head, condition)
\
+do {   
\
+   if (condition)  
\
+   break;  
\
+   (void)___wait_event(wq_head, condition, 
\
+   (TASK_UNINTERRUPTIBLE | TASK_NOLOAD), 1, 0, 
\
+   schedule());
\
+} while (0)

[PATCH 02/16] staging: lustre: replace simple cases of l_wait_event() with wait_event().

2017-12-17 Thread NeilBrown
When the lwi arg is full of zeros, l_wait_event() behaves almost
identically to the standard wait_event() interface, so use that
instead.

The only difference in behavior is that l_wait_event() blocks all
signals and uses an TASK_INTERRUPTIBLE wait, while wait_event()
does not block signals, but waits in state TASK_UNINTERRUPTIBLE.
This means that processes blocked in wait_event() will contribute
to the load average.  This behavior is (arguably) more correct - in
most cases.

In some cases, the wait is in a service thread waiting for work to
do.  In these case we should wait TASK_NOLOAD order with
TASK_UNINTERRUPTIBLE.  To facilitate this, add a "wait_event_noload()"
macro.  This should eventually be moved into include/linux/wait.h.

There is one case where wait_event_exclusive_noload() is needed.
So we add a macro for that too.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   47 ---
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |4 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|8 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |5 +-
 drivers/staging/lustre/lustre/llite/statahead.c|   50 
 drivers/staging/lustre/lustre/lov/lov_object.c |6 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c|4 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c |6 +-
 drivers/staging/lustre/lustre/obdclass/genops.c|   15 ++
 drivers/staging/lustre/lustre/osc/osc_cache.c  |5 +-
 drivers/staging/lustre/lustre/osc/osc_object.c |4 --
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   10 ++--
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |   11 ++--
 drivers/staging/lustre/lustre/ptlrpc/service.c |   13 ++---
 14 files changed, 93 insertions(+), 95 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ca1dce15337e..08bdd618ea7d 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -333,12 +333,6 @@ do {   
   \
__ret;\
 })
 
-#define l_wait_condition(wq, condition) \
-({   \
-   struct l_wait_info lwi = { 0 };  \
-   l_wait_event(wq, condition, );\
-})
-
 #define l_wait_condition_exclusive(wq, condition) \
 ({   \
struct l_wait_info lwi = { 0 };  \
@@ -353,4 +347,45 @@ do {   
   \
 
 /** @} lib */
 
+#define __wait_event_noload(wq_head, condition)
\
+   (void)___wait_event(wq_head, condition, (TASK_UNINTERRUPTIBLE | 
TASK_NOLOAD), 0, 0, \
+   schedule())
+
+/**
+ * wait_event_noload - sleep, without registering load, until a condition gets 
true
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_UNINTERRUPTIBLE|TASK_NOLOAD) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * This can be used instead of wait_event() when the event
+ * being waited for is does not imply load on the system, but
+ * when responding to signals is no appropriate, such as in
+ * a kernel service thread.
+ */
+#define wait_event_noload(wq_head, condition)  
\
+do {   
\
+   might_sleep();  
\
+   if (condition)  
\
+   break;  
\
+   __wait_event_noload(wq_head, condition);
\
+} while (0)
+
+/*
+ * Just like wait_event_noload(), except it sets exclusive flag
+ */
+#define wait_event_exclusive_noload(wq_head, condition)
\
+do {   
\
+   if (condition)  
\
+   break;  
\
+   (void)___wait_event(wq_head, condition, 
\
+   (TASK_UNINTERRUPTIBLE | TASK_NOLOAD), 1, 0, 
\
+   schedule());
\
+} while (0)
+
 #endif /* 

[PATCH 03/16] staging: lustre: discard cfs_time_seconds()

2017-12-17 Thread NeilBrown
cfs_time_seconds() converts a number of second to the
matching number of jiffies.
The standard way to do this in Linux is  "* HZ".
So discard cfs_time_seconds() and use "* HZ" instead.

Signed-off-by: NeilBrown 
---
 .../lustre/include/linux/libcfs/libcfs_debug.h |4 ++--
 .../lustre/include/linux/libcfs/libcfs_time.h  |2 +-
 .../lustre/include/linux/libcfs/linux/linux-time.h |7 +-
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c|8 ---
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |4 ++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c|6 +++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++--
 drivers/staging/lustre/lnet/libcfs/debug.c |2 +-
 drivers/staging/lustre/lnet/libcfs/fail.c  |2 +-
 drivers/staging/lustre/lnet/libcfs/tracefile.c |4 ++--
 drivers/staging/lustre/lnet/lnet/acceptor.c|2 +-
 drivers/staging/lustre/lnet/lnet/api-ni.c  |4 ++--
 drivers/staging/lustre/lnet/lnet/lib-move.c|4 ++--
 drivers/staging/lustre/lnet/lnet/net_fault.c   |   14 +
 drivers/staging/lustre/lnet/lnet/peer.c|2 +-
 drivers/staging/lustre/lnet/lnet/router.c  |8 ---
 drivers/staging/lustre/lnet/selftest/conrpc.c  |4 ++--
 drivers/staging/lustre/lnet/selftest/rpc.c |2 +-
 drivers/staging/lustre/lnet/selftest/selftest.h|2 +-
 drivers/staging/lustre/lnet/selftest/timer.c   |2 +-
 drivers/staging/lustre/lustre/include/lustre_dlm.h |2 +-
 drivers/staging/lustre/lustre/include/lustre_mdc.h |2 +-
 drivers/staging/lustre/lustre/include/lustre_net.h |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|4 ++--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |2 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|4 ++--
 drivers/staging/lustre/lustre/llite/statahead.c|2 +-
 drivers/staging/lustre/lustre/lov/lov_request.c|4 ++--
 drivers/staging/lustre/lustre/mdc/mdc_request.c|2 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c|2 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |2 +-
 .../staging/lustre/lustre/obdecho/echo_client.c|2 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c  |4 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c |2 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   10 +
 drivers/staging/lustre/lustre/ptlrpc/events.c  |2 +-
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   15 ++
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c  |4 ++--
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|2 +-
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |8 ---
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |4 ++--
 drivers/staging/lustre/lustre/ptlrpc/recover.c |2 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c |8 ---
 46 files changed, 96 insertions(+), 106 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h 
b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index 1b98f0953afb..9290a19429e7 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -66,8 +66,8 @@ extern unsigned int libcfs_panic_on_lbug;
 # define DEBUG_SUBSYSTEM S_UNDEFINED
 #endif
 
-#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))/* jiffies */
-#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_MAX_DELAY (600 * HZ) /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((HZ + 1) / 2) /* jiffies */
 #define CDEBUG_DEFAULT_BACKOFF   2
 struct cfs_debug_limit_state {
unsigned long   cdls_next;
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h 
b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
index 9699646decb9..c4f25be78268 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
@@ -62,7 +62,7 @@ static inline int cfs_time_aftereq(unsigned long t1, unsigned 
long t2)
 
 static inline unsigned long cfs_time_shift(int seconds)
 {
-   return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+   return cfs_time_add(cfs_time_current(), seconds * HZ);
 }
 
 /*
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h 
b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
index aece13698eb4..805cb326af86 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
@@ -65,11 +65,6 @@ static inline 

[PATCH 04/16] staging: lustre: use wait_event_timeout() where appropriate.

2017-12-17 Thread NeilBrown
When the lwi arg has a timeout, but no timeout
callback function, l_wait_event() acts much the same as
wait_event_timeout() - the wait is not interruptible and
simply waits for the event or the timeouts.

The most noticable difference is that the return value is
-ETIMEDOUT or 0, rather than 0 or non-zero.

Another difference is that the process waiting is included in
the load-average.  This is probably more correct.

A final difference is that if the timeout is zero, l_wait_event()
will not time out at all.  In the one case where that is possible
we need to conditionally use wait_event_noload().

So replace all such calls with wait_event_timeout(), being
careful of the return value.

In one case, there is no event, so use
schedule_timeout_uninterruptible().


Note that the presence or absence of LWI_ON_SIGNAL_NOOP
has no effect in these cases.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   37 
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |   10 ++---
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |   12 ++
 drivers/staging/lustre/lustre/llite/statahead.c|   14 +++-
 drivers/staging/lustre/lustre/mdc/mdc_request.c|5 +--
 drivers/staging/lustre/lustre/mgc/mgc_request.c|   15 +++-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   17 +
 drivers/staging/lustre/lustre/osc/osc_cache.c  |   25 ++
 drivers/staging/lustre/lustre/ptlrpc/events.c  |7 +---
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   12 +++---
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|9 ++---
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   12 ++
 drivers/staging/lustre/lustre/ptlrpc/recover.c |   12 +++---
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |   10 ++---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   10 ++---
 15 files changed, 104 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 08bdd618ea7d..fcf31c779e98 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -388,4 +388,41 @@ do {   
\
schedule());
\
 } while (0)
 
+#define __wait_event_noload_timeout(wq_head, condition, timeout)   
\
+   ___wait_event(wq_head, ___wait_cond_timeout(condition), 
\
+ (TASK_UNINTERRUPTIBLE | TASK_NOLOAD), 0, timeout, 
\
+ __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_noload_timeout - sleep until a condition gets true or a timeout 
elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_UNINTERRUPTIBLE | TASK_NOLOAD) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * This is suitable for service threads that are waiting for work to do
+ * where there is no implication that the event not being true yet implies
+ * any load on the system, and where it is not appropriate for the
+ * soft-lockup detector to warning if the wait is unusually long.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_noload_timeout(wq_head, condition, timeout) 
\
+({ 
\
+   long __ret = timeout;   
\
+   might_sleep();  
\
+   if (!___wait_cond_timeout(condition))   
\
+   __ret = __wait_event_noload_timeout(wq_head, condition, 
timeout);\
+   __ret;  
\
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 53500883f243..ba720a888da3 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1349,7 +1349,6 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, 
__u64 flags,
if ((flags & LDLM_FL_LVB_READY) && !ldlm_is_lvb_ready(lock)) {
__u64 wait_flags = LDLM_FL_LVB_READY |

[PATCH v4 23/36] nds32: Generic timers support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds support for timer.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
Reviewed-by: Linus Walleij 
---
 arch/nds32/kernel/time.c |   11 +++
 1 file changed, 11 insertions(+)
 create mode 100644 arch/nds32/kernel/time.c

diff --git a/arch/nds32/kernel/time.c b/arch/nds32/kernel/time.c
new file mode 100644
index 000..ac9d78c
--- /dev/null
+++ b/arch/nds32/kernel/time.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+
+void __init time_init(void)
+{
+   of_clk_init(NULL);
+   timer_probe();
+}
-- 
1.7.9.5



[PATCH 03/16] staging: lustre: discard cfs_time_seconds()

2017-12-17 Thread NeilBrown
cfs_time_seconds() converts a number of second to the
matching number of jiffies.
The standard way to do this in Linux is  "* HZ".
So discard cfs_time_seconds() and use "* HZ" instead.

Signed-off-by: NeilBrown 
---
 .../lustre/include/linux/libcfs/libcfs_debug.h |4 ++--
 .../lustre/include/linux/libcfs/libcfs_time.h  |2 +-
 .../lustre/include/linux/libcfs/linux/linux-time.h |7 +-
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c|8 ---
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |4 ++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c|6 +++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++--
 drivers/staging/lustre/lnet/libcfs/debug.c |2 +-
 drivers/staging/lustre/lnet/libcfs/fail.c  |2 +-
 drivers/staging/lustre/lnet/libcfs/tracefile.c |4 ++--
 drivers/staging/lustre/lnet/lnet/acceptor.c|2 +-
 drivers/staging/lustre/lnet/lnet/api-ni.c  |4 ++--
 drivers/staging/lustre/lnet/lnet/lib-move.c|4 ++--
 drivers/staging/lustre/lnet/lnet/net_fault.c   |   14 +
 drivers/staging/lustre/lnet/lnet/peer.c|2 +-
 drivers/staging/lustre/lnet/lnet/router.c  |8 ---
 drivers/staging/lustre/lnet/selftest/conrpc.c  |4 ++--
 drivers/staging/lustre/lnet/selftest/rpc.c |2 +-
 drivers/staging/lustre/lnet/selftest/selftest.h|2 +-
 drivers/staging/lustre/lnet/selftest/timer.c   |2 +-
 drivers/staging/lustre/lustre/include/lustre_dlm.h |2 +-
 drivers/staging/lustre/lustre/include/lustre_mdc.h |2 +-
 drivers/staging/lustre/lustre/include/lustre_net.h |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c|4 ++--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |2 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c|4 ++--
 drivers/staging/lustre/lustre/llite/statahead.c|2 +-
 drivers/staging/lustre/lustre/lov/lov_request.c|4 ++--
 drivers/staging/lustre/lustre/mdc/mdc_request.c|2 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c|2 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |2 +-
 .../staging/lustre/lustre/obdecho/echo_client.c|2 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c  |4 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c |2 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c  |   10 +
 drivers/staging/lustre/lustre/ptlrpc/events.c  |2 +-
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   15 ++
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c  |4 ++--
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|2 +-
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |8 ---
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c |4 ++--
 drivers/staging/lustre/lustre/ptlrpc/recover.c |2 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c |8 ---
 46 files changed, 96 insertions(+), 106 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h 
b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index 1b98f0953afb..9290a19429e7 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -66,8 +66,8 @@ extern unsigned int libcfs_panic_on_lbug;
 # define DEBUG_SUBSYSTEM S_UNDEFINED
 #endif
 
-#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))/* jiffies */
-#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_MAX_DELAY (600 * HZ) /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((HZ + 1) / 2) /* jiffies */
 #define CDEBUG_DEFAULT_BACKOFF   2
 struct cfs_debug_limit_state {
unsigned long   cdls_next;
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h 
b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
index 9699646decb9..c4f25be78268 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
@@ -62,7 +62,7 @@ static inline int cfs_time_aftereq(unsigned long t1, unsigned 
long t2)
 
 static inline unsigned long cfs_time_shift(int seconds)
 {
-   return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+   return cfs_time_add(cfs_time_current(), seconds * HZ);
 }
 
 /*
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h 
b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
index aece13698eb4..805cb326af86 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
@@ -65,11 +65,6 @@ static inline unsigned long 

[PATCH 04/16] staging: lustre: use wait_event_timeout() where appropriate.

2017-12-17 Thread NeilBrown
When the lwi arg has a timeout, but no timeout
callback function, l_wait_event() acts much the same as
wait_event_timeout() - the wait is not interruptible and
simply waits for the event or the timeouts.

The most noticable difference is that the return value is
-ETIMEDOUT or 0, rather than 0 or non-zero.

Another difference is that the process waiting is included in
the load-average.  This is probably more correct.

A final difference is that if the timeout is zero, l_wait_event()
will not time out at all.  In the one case where that is possible
we need to conditionally use wait_event_noload().

So replace all such calls with wait_event_timeout(), being
careful of the return value.

In one case, there is no event, so use
schedule_timeout_uninterruptible().


Note that the presence or absence of LWI_ON_SIGNAL_NOOP
has no effect in these cases.

Signed-off-by: NeilBrown 
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   37 
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c |   10 ++---
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c |   12 ++
 drivers/staging/lustre/lustre/llite/statahead.c|   14 +++-
 drivers/staging/lustre/lustre/mdc/mdc_request.c|5 +--
 drivers/staging/lustre/lustre/mgc/mgc_request.c|   15 +++-
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   17 +
 drivers/staging/lustre/lustre/osc/osc_cache.c  |   25 ++
 drivers/staging/lustre/lustre/ptlrpc/events.c  |7 +---
 drivers/staging/lustre/lustre/ptlrpc/import.c  |   12 +++---
 .../staging/lustre/lustre/ptlrpc/pack_generic.c|9 ++---
 drivers/staging/lustre/lustre/ptlrpc/pinger.c  |   12 ++
 drivers/staging/lustre/lustre/ptlrpc/recover.c |   12 +++---
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c  |   10 ++---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   10 ++---
 15 files changed, 104 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h 
b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 08bdd618ea7d..fcf31c779e98 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -388,4 +388,41 @@ do {   
\
schedule());
\
 } while (0)
 
+#define __wait_event_noload_timeout(wq_head, condition, timeout)   
\
+   ___wait_event(wq_head, ___wait_cond_timeout(condition), 
\
+ (TASK_UNINTERRUPTIBLE | TASK_NOLOAD), 0, timeout, 
\
+ __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_noload_timeout - sleep until a condition gets true or a timeout 
elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_UNINTERRUPTIBLE | TASK_NOLOAD) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * This is suitable for service threads that are waiting for work to do
+ * where there is no implication that the event not being true yet implies
+ * any load on the system, and where it is not appropriate for the
+ * soft-lockup detector to warning if the wait is unusually long.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_noload_timeout(wq_head, condition, timeout) 
\
+({ 
\
+   long __ret = timeout;   
\
+   might_sleep();  
\
+   if (!___wait_cond_timeout(condition))   
\
+   __ret = __wait_event_noload_timeout(wq_head, condition, 
timeout);\
+   __ret;  
\
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 53500883f243..ba720a888da3 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1349,7 +1349,6 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, 
__u64 flags,
if ((flags & LDLM_FL_LVB_READY) && !ldlm_is_lvb_ready(lock)) {
__u64 wait_flags = LDLM_FL_LVB_READY |
LDLM_FL_DESTROYED | 

[PATCH v4 23/36] nds32: Generic timers support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds support for timer.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
Reviewed-by: Linus Walleij 
---
 arch/nds32/kernel/time.c |   11 +++
 1 file changed, 11 insertions(+)
 create mode 100644 arch/nds32/kernel/time.c

diff --git a/arch/nds32/kernel/time.c b/arch/nds32/kernel/time.c
new file mode 100644
index 000..ac9d78c
--- /dev/null
+++ b/arch/nds32/kernel/time.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+
+void __init time_init(void)
+{
+   of_clk_init(NULL);
+   timer_probe();
+}
-- 
1.7.9.5



[PATCH v4 24/36] nds32: Device tree support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds support for device tree.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/boot/dts/Makefile  |8 +
 arch/nds32/boot/dts/ae3xx.dts |   65 +
 arch/nds32/kernel/devtree.c   |   19 
 3 files changed, 92 insertions(+)
 create mode 100644 arch/nds32/boot/dts/Makefile
 create mode 100644 arch/nds32/boot/dts/ae3xx.dts
 create mode 100644 arch/nds32/kernel/devtree.c

diff --git a/arch/nds32/boot/dts/Makefile b/arch/nds32/boot/dts/Makefile
new file mode 100644
index 000..d31faa8
--- /dev/null
+++ b/arch/nds32/boot/dts/Makefile
@@ -0,0 +1,8 @@
+ifneq '$(CONFIG_NDS32_BUILTIN_DTB)' '""'
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_NDS32_BUILTIN_DTB)).dtb.o
+else
+BUILTIN_DTB :=
+endif
+obj-$(CONFIG_OF) += $(BUILTIN_DTB)
+
+clean-files := *.dtb *.dtb.S
diff --git a/arch/nds32/boot/dts/ae3xx.dts b/arch/nds32/boot/dts/ae3xx.dts
new file mode 100644
index 000..0ef2c44
--- /dev/null
+++ b/arch/nds32/boot/dts/ae3xx.dts
@@ -0,0 +1,65 @@
+/dts-v1/;
+/ {
+   compatible = "andestech,ae3xx";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+
+   chosen {
+   stdout-path = 
+   };
+
+   memory@0 {
+   device_type = "memory";
+   reg = <0x 0x4000>;
+   };
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   cpu@0 {
+   device_type = "cpu";
+   compatible = "andestech,n13", "andestech,nds32v3";
+   reg = <0>;
+   clock-frequency = <6000>;
+   };
+   };
+
+   apb: clk@0 {
+   #clock-cells = <0>;
+   compatible = "fixed-clock";
+   clock-frequency = <3000>;
+   };
+
+
+   intc: interrupt-controller {
+   compatible = "andestech,ativic32";
+   #interrupt-cells = <1>;
+   interrupt-controller;
+   };
+
+   serial0: serial@f030 {
+   compatible = "andestech,uart16550", "ns16550a";
+   reg = <0xf030 0x1000>;
+   interrupts = <8>;
+   clock-frequency = <14745600>;
+   reg-shift = <2>;
+   reg-offset = <32>;
+   no-loopback-test = <1>;
+   };
+
+   timer0: timer@f040 {
+   compatible = "andestech,atcpit100";
+   reg = <0xf040 0x1000>;
+   interrupts = <2>;
+   clocks = <>;
+   clock-names = "PCLK";
+   };
+
+   mac0: mac@e010 {
+   compatible = "andestech,atmac100";
+   reg = <0xe010 0x1000>;
+   interrupts = <18>;
+   };
+
+};
diff --git a/arch/nds32/kernel/devtree.c b/arch/nds32/kernel/devtree.c
new file mode 100644
index 000..bdce0fe
--- /dev/null
+++ b/arch/nds32/kernel/devtree.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+
+void __init early_init_devtree(void *params)
+{
+   if (!params || !early_init_dt_scan(params)) {
+   pr_crit("\n"
+   "Error: invalid device tree blob at (virtual address 
0x%p)\n"
+   "\nPlease check your bootloader.", params);
+
+   BUG_ON(1);
+   }
+
+   dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
+}
-- 
1.7.9.5



[PATCH v4 24/36] nds32: Device tree support

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds support for device tree.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/boot/dts/Makefile  |8 +
 arch/nds32/boot/dts/ae3xx.dts |   65 +
 arch/nds32/kernel/devtree.c   |   19 
 3 files changed, 92 insertions(+)
 create mode 100644 arch/nds32/boot/dts/Makefile
 create mode 100644 arch/nds32/boot/dts/ae3xx.dts
 create mode 100644 arch/nds32/kernel/devtree.c

diff --git a/arch/nds32/boot/dts/Makefile b/arch/nds32/boot/dts/Makefile
new file mode 100644
index 000..d31faa8
--- /dev/null
+++ b/arch/nds32/boot/dts/Makefile
@@ -0,0 +1,8 @@
+ifneq '$(CONFIG_NDS32_BUILTIN_DTB)' '""'
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_NDS32_BUILTIN_DTB)).dtb.o
+else
+BUILTIN_DTB :=
+endif
+obj-$(CONFIG_OF) += $(BUILTIN_DTB)
+
+clean-files := *.dtb *.dtb.S
diff --git a/arch/nds32/boot/dts/ae3xx.dts b/arch/nds32/boot/dts/ae3xx.dts
new file mode 100644
index 000..0ef2c44
--- /dev/null
+++ b/arch/nds32/boot/dts/ae3xx.dts
@@ -0,0 +1,65 @@
+/dts-v1/;
+/ {
+   compatible = "andestech,ae3xx";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+
+   chosen {
+   stdout-path = 
+   };
+
+   memory@0 {
+   device_type = "memory";
+   reg = <0x 0x4000>;
+   };
+
+   cpus {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   cpu@0 {
+   device_type = "cpu";
+   compatible = "andestech,n13", "andestech,nds32v3";
+   reg = <0>;
+   clock-frequency = <6000>;
+   };
+   };
+
+   apb: clk@0 {
+   #clock-cells = <0>;
+   compatible = "fixed-clock";
+   clock-frequency = <3000>;
+   };
+
+
+   intc: interrupt-controller {
+   compatible = "andestech,ativic32";
+   #interrupt-cells = <1>;
+   interrupt-controller;
+   };
+
+   serial0: serial@f030 {
+   compatible = "andestech,uart16550", "ns16550a";
+   reg = <0xf030 0x1000>;
+   interrupts = <8>;
+   clock-frequency = <14745600>;
+   reg-shift = <2>;
+   reg-offset = <32>;
+   no-loopback-test = <1>;
+   };
+
+   timer0: timer@f040 {
+   compatible = "andestech,atcpit100";
+   reg = <0xf040 0x1000>;
+   interrupts = <2>;
+   clocks = <>;
+   clock-names = "PCLK";
+   };
+
+   mac0: mac@e010 {
+   compatible = "andestech,atmac100";
+   reg = <0xe010 0x1000>;
+   interrupts = <18>;
+   };
+
+};
diff --git a/arch/nds32/kernel/devtree.c b/arch/nds32/kernel/devtree.c
new file mode 100644
index 000..bdce0fe
--- /dev/null
+++ b/arch/nds32/kernel/devtree.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+
+void __init early_init_devtree(void *params)
+{
+   if (!params || !early_init_dt_scan(params)) {
+   pr_crit("\n"
+   "Error: invalid device tree blob at (virtual address 
0x%p)\n"
+   "\nPlease check your bootloader.", params);
+
+   BUG_ON(1);
+   }
+
+   dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
+}
-- 
1.7.9.5



[PATCH v4 26/36] nds32: defconfig

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds nds32 defconfig.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/configs/defconfig |  108 ++
 1 file changed, 108 insertions(+)
 create mode 100644 arch/nds32/configs/defconfig

diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
new file mode 100644
index 000..4d79d2db
--- /dev/null
+++ b/arch/nds32/configs/defconfig
@@ -0,0 +1,108 @@
+CONFIG_CROSS_COMPILE="nds32le-linux-"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_USER_NS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CACHE_L2 is not set
+CONFIG_VMSPLIT_3G_OPT=y
+CONFIG_PREEMPT=y
+# CONFIG_COMPACTION is not set
+CONFIG_HZ_100=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_FTMAC100=y
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_RC_CORE is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_ITE is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_TIMER_ATCPIT100=y
+CONFIG_GENERIC_PHY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_USE_LEGACY_DNS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_READABLE_ASM=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+# CONFIG_CRYPTO_HW is not set
-- 
1.7.9.5



[PATCH v4 26/36] nds32: defconfig

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds nds32 defconfig.

Signed-off-by: Vincent Chen 
Signed-off-by: Greentime Hu 
---
 arch/nds32/configs/defconfig |  108 ++
 1 file changed, 108 insertions(+)
 create mode 100644 arch/nds32/configs/defconfig

diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
new file mode 100644
index 000..4d79d2db
--- /dev/null
+++ b/arch/nds32/configs/defconfig
@@ -0,0 +1,108 @@
+CONFIG_CROSS_COMPILE="nds32le-linux-"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_USER_NS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CACHE_L2 is not set
+CONFIG_VMSPLIT_3G_OPT=y
+CONFIG_PREEMPT=y
+# CONFIG_COMPACTION is not set
+CONFIG_HZ_100=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_FTMAC100=y
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_RC_CORE is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_ITE is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_TIMER_ATCPIT100=y
+CONFIG_GENERIC_PHY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_USE_LEGACY_DNS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_READABLE_ASM=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+# CONFIG_CRYPTO_HW is not set
-- 
1.7.9.5



[PATCH v4 28/36] MAINTAINERS: Add nds32

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

Signed-off-by: Greentime Hu 
---
 MAINTAINERS |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f4e462..20284c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -857,6 +857,17 @@ X: drivers/iio/*/adjd*
 F: drivers/staging/iio/*/ad*
 F: drivers/staging/iio/trigger/iio-trig-bfin-timer.c
 
+ANDES ARCHITECTURE
+M: Greentime Hu 
+M: Vincent Chen 
+T: git https://github.com/andestech/linux.git
+S: Supported
+F: arch/nds32
+F: 
Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt
+F: Documentation/devicetree/bindings/nds32
+K: nds32
+N: nds32
+
 ANDROID CONFIG FRAGMENTS
 M: Rob Herring 
 S: Supported
-- 
1.7.9.5



[PATCH v4 28/36] MAINTAINERS: Add nds32

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

Signed-off-by: Greentime Hu 
---
 MAINTAINERS |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f4e462..20284c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -857,6 +857,17 @@ X: drivers/iio/*/adjd*
 F: drivers/staging/iio/*/ad*
 F: drivers/staging/iio/trigger/iio-trig-bfin-timer.c
 
+ANDES ARCHITECTURE
+M: Greentime Hu 
+M: Vincent Chen 
+T: git https://github.com/andestech/linux.git
+S: Supported
+F: arch/nds32
+F: 
Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt
+F: Documentation/devicetree/bindings/nds32
+K: nds32
+N: nds32
+
 ANDROID CONFIG FRAGMENTS
 M: Rob Herring 
 S: Supported
-- 
1.7.9.5



[PATCH v4 30/36] dt-bindings: nds32 SoC Bindings

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds nds32 SoC(AE3XX and AG101P) binding documents.

Signed-off-by: Greentime Hu 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/nds32/andestech-boards |   40 
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nds32/andestech-boards

diff --git a/Documentation/devicetree/bindings/nds32/andestech-boards 
b/Documentation/devicetree/bindings/nds32/andestech-boards
new file mode 100644
index 000..f5d7569
--- /dev/null
+++ b/Documentation/devicetree/bindings/nds32/andestech-boards
@@ -0,0 +1,40 @@
+Andestech(nds32) AE3XX Platform
+-
+The AE3XX prototype demonstrates the AE3XX example platform on the FPGA. It
+is composed of one Andestech(nds32) processor and AE3XX.
+
+Required properties (in root node):
+- compatible = "andestech,ae3xx";
+
+Example:
+/dts-v1/;
+/ {
+   compatible = "andestech,ae3xx";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+};
+
+Andestech(nds32) AG101P Platform
+-
+AG101P is a generic SoC Platform IP that works with any of Andestech(nds32)
+processors to provide a cost-effective and high performance solution for
+majority of embedded systems in variety of application domains. Users may
+simply attach their IP on one of the system buses together with certain glue
+logics to complete a SoC solution for a specific application. With
+comprehensive simulation and design environments, users may evaluate the
+system performance of their applications and track bugs of their designs
+efficiently. The optional hardware development platform further provides real
+system environment for early prototyping and software/hardware co-development.
+
+Required properties (in root node):
+   compatible = "andestech,ag101p";
+
+Example:
+/dts-v1/;
+/ {
+   compatible = "andestech,ag101p";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+};
-- 
1.7.9.5



[PATCH v4 30/36] dt-bindings: nds32 SoC Bindings

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds nds32 SoC(AE3XX and AG101P) binding documents.

Signed-off-by: Greentime Hu 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/nds32/andestech-boards |   40 
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nds32/andestech-boards

diff --git a/Documentation/devicetree/bindings/nds32/andestech-boards 
b/Documentation/devicetree/bindings/nds32/andestech-boards
new file mode 100644
index 000..f5d7569
--- /dev/null
+++ b/Documentation/devicetree/bindings/nds32/andestech-boards
@@ -0,0 +1,40 @@
+Andestech(nds32) AE3XX Platform
+-
+The AE3XX prototype demonstrates the AE3XX example platform on the FPGA. It
+is composed of one Andestech(nds32) processor and AE3XX.
+
+Required properties (in root node):
+- compatible = "andestech,ae3xx";
+
+Example:
+/dts-v1/;
+/ {
+   compatible = "andestech,ae3xx";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+};
+
+Andestech(nds32) AG101P Platform
+-
+AG101P is a generic SoC Platform IP that works with any of Andestech(nds32)
+processors to provide a cost-effective and high performance solution for
+majority of embedded systems in variety of application domains. Users may
+simply attach their IP on one of the system buses together with certain glue
+logics to complete a SoC solution for a specific application. With
+comprehensive simulation and design environments, users may evaluate the
+system performance of their applications and track bugs of their designs
+efficiently. The optional hardware development platform further provides real
+system environment for early prototyping and software/hardware co-development.
+
+Required properties (in root node):
+   compatible = "andestech,ag101p";
+
+Example:
+/dts-v1/;
+/ {
+   compatible = "andestech,ag101p";
+   #address-cells = <1>;
+   #size-cells = <1>;
+   interrupt-parent = <>;
+};
-- 
1.7.9.5



[PATCH v4 32/36] irqchip: Andestech Internal Vector Interrupt Controller driver

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds the Andestech Internal Vector Interrupt Controller
driver. You can find the spec here. Ch4.9 of AndeStar SPA V3 Manual.
http://www.andestech.com/product.php?cls=9

Signed-off-by: Rick Chen 
Signed-off-by: Greentime Hu 
Reviewed-by: Marc Zyngier 
---
 drivers/irqchip/Makefile   |1 +
 drivers/irqchip/irq-ativic32.c |  107 
 2 files changed, 108 insertions(+)
 create mode 100644 drivers/irqchip/irq-ativic32.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b842dfd..201ca9f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o 
irq-aspeed-i2c-ic.o
 obj-$(CONFIG_STM32_EXTI)   += irq-stm32-exti.o
 obj-$(CONFIG_QCOM_IRQ_COMBINER)+= qcom-irq-combiner.o
 obj-$(CONFIG_IRQ_UNIPHIER_AIDET)   += irq-uniphier-aidet.o
+obj-$(CONFIG_NDS32)+= irq-ativic32.o
diff --git a/drivers/irqchip/irq-ativic32.c b/drivers/irqchip/irq-ativic32.c
new file mode 100644
index 000..f69a858
--- /dev/null
+++ b/drivers/irqchip/irq-ativic32.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void ativic32_ack_irq(struct irq_data *data)
+{
+   __nds32__mtsr_dsb(BIT(data->hwirq), NDS32_SR_INT_PEND2);
+}
+
+static void ativic32_mask_irq(struct irq_data *data)
+{
+   unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
+   __nds32__mtsr_dsb(int_mask2 & (~(BIT(data->hwirq))), 
NDS32_SR_INT_MASK2);
+}
+
+static void ativic32_unmask_irq(struct irq_data *data)
+{
+   unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
+   __nds32__mtsr_dsb(int_mask2 | (BIT(data->hwirq)), NDS32_SR_INT_MASK2);
+}
+
+static struct irq_chip ativic32_chip = {
+   .name = "ativic32",
+   .irq_ack = ativic32_ack_irq,
+   .irq_mask = ativic32_mask_irq,
+   .irq_unmask = ativic32_unmask_irq,
+};
+
+static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 };
+
+static struct irq_domain *root_domain;
+static int ativic32_irq_domain_map(struct irq_domain *id, unsigned int virq,
+ irq_hw_number_t hw)
+{
+
+   unsigned long int_trigger_type;
+   u32 type;
+   struct irq_data *irq_data;
+   int_trigger_type = __nds32__mfsr(NDS32_SR_INT_TRIGGER);
+   irq_data = irq_get_irq_data(virq);
+   if (!irq_data)
+   return -EINVAL;
+
+   if (int_trigger_type & (BIT(hw))) {
+   irq_set_chip_and_handler(virq, _chip, handle_edge_irq);
+   type = IRQ_TYPE_EDGE_RISING;
+   } else {
+   irq_set_chip_and_handler(virq, _chip, 
handle_level_irq);
+   type = IRQ_TYPE_LEVEL_HIGH;
+   }
+
+   irqd_set_trigger_type(irq_data, type);
+   return 0;
+}
+
+static struct irq_domain_ops ativic32_ops = {
+   .map = ativic32_irq_domain_map,
+   .xlate = irq_domain_xlate_onecell
+};
+
+static irq_hw_number_t get_intr_src(void)
+{
+   return ((__nds32__mfsr(NDS32_SR_ITYPE) & ITYPE_mskVECTOR) >> 
ITYPE_offVECTOR)
+   - NDS32_VECTOR_offINTERRUPT;
+}
+
+asmlinkage void asm_do_IRQ(struct pt_regs *regs)
+{
+   irq_hw_number_t hwirq = get_intr_src();
+   handle_domain_irq(root_domain, hwirq, regs);
+}
+
+int __init ativic32_init_irq(struct device_node *node, struct device_node 
*parent)
+{
+   unsigned long int_vec_base, nivic, nr_ints;
+
+   if (WARN(parent, "non-root ativic32 are not supported"))
+   return -EINVAL;
+
+   int_vec_base = __nds32__mfsr(NDS32_SR_IVB);
+
+   if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0)
+   panic("Unable to use atcivic32 for this cpu.\n");
+
+   nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC;
+   if (nivic >= ARRAY_SIZE(nivic_map))
+   panic("The number of input for ativic32 is not supported.\n");
+
+   nr_ints = nivic_map[nivic];
+
+   root_domain = irq_domain_add_linear(node, nr_ints,
+   _ops, NULL);
+
+   if (!root_domain)
+   panic("%s: unable to create IRQ domain\n", node->full_name);
+
+   return 0;
+}
+IRQCHIP_DECLARE(ativic32, "andestech,ativic32", ativic32_init_irq);
-- 
1.7.9.5



[PATCH v4 32/36] irqchip: Andestech Internal Vector Interrupt Controller driver

2017-12-17 Thread Greentime Hu
From: Greentime Hu 

This patch adds the Andestech Internal Vector Interrupt Controller
driver. You can find the spec here. Ch4.9 of AndeStar SPA V3 Manual.
http://www.andestech.com/product.php?cls=9

Signed-off-by: Rick Chen 
Signed-off-by: Greentime Hu 
Reviewed-by: Marc Zyngier 
---
 drivers/irqchip/Makefile   |1 +
 drivers/irqchip/irq-ativic32.c |  107 
 2 files changed, 108 insertions(+)
 create mode 100644 drivers/irqchip/irq-ativic32.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b842dfd..201ca9f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o 
irq-aspeed-i2c-ic.o
 obj-$(CONFIG_STM32_EXTI)   += irq-stm32-exti.o
 obj-$(CONFIG_QCOM_IRQ_COMBINER)+= qcom-irq-combiner.o
 obj-$(CONFIG_IRQ_UNIPHIER_AIDET)   += irq-uniphier-aidet.o
+obj-$(CONFIG_NDS32)+= irq-ativic32.o
diff --git a/drivers/irqchip/irq-ativic32.c b/drivers/irqchip/irq-ativic32.c
new file mode 100644
index 000..f69a858
--- /dev/null
+++ b/drivers/irqchip/irq-ativic32.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2005-2017 Andes Technology Corporation
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static void ativic32_ack_irq(struct irq_data *data)
+{
+   __nds32__mtsr_dsb(BIT(data->hwirq), NDS32_SR_INT_PEND2);
+}
+
+static void ativic32_mask_irq(struct irq_data *data)
+{
+   unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
+   __nds32__mtsr_dsb(int_mask2 & (~(BIT(data->hwirq))), 
NDS32_SR_INT_MASK2);
+}
+
+static void ativic32_unmask_irq(struct irq_data *data)
+{
+   unsigned long int_mask2 = __nds32__mfsr(NDS32_SR_INT_MASK2);
+   __nds32__mtsr_dsb(int_mask2 | (BIT(data->hwirq)), NDS32_SR_INT_MASK2);
+}
+
+static struct irq_chip ativic32_chip = {
+   .name = "ativic32",
+   .irq_ack = ativic32_ack_irq,
+   .irq_mask = ativic32_mask_irq,
+   .irq_unmask = ativic32_unmask_irq,
+};
+
+static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 };
+
+static struct irq_domain *root_domain;
+static int ativic32_irq_domain_map(struct irq_domain *id, unsigned int virq,
+ irq_hw_number_t hw)
+{
+
+   unsigned long int_trigger_type;
+   u32 type;
+   struct irq_data *irq_data;
+   int_trigger_type = __nds32__mfsr(NDS32_SR_INT_TRIGGER);
+   irq_data = irq_get_irq_data(virq);
+   if (!irq_data)
+   return -EINVAL;
+
+   if (int_trigger_type & (BIT(hw))) {
+   irq_set_chip_and_handler(virq, _chip, handle_edge_irq);
+   type = IRQ_TYPE_EDGE_RISING;
+   } else {
+   irq_set_chip_and_handler(virq, _chip, 
handle_level_irq);
+   type = IRQ_TYPE_LEVEL_HIGH;
+   }
+
+   irqd_set_trigger_type(irq_data, type);
+   return 0;
+}
+
+static struct irq_domain_ops ativic32_ops = {
+   .map = ativic32_irq_domain_map,
+   .xlate = irq_domain_xlate_onecell
+};
+
+static irq_hw_number_t get_intr_src(void)
+{
+   return ((__nds32__mfsr(NDS32_SR_ITYPE) & ITYPE_mskVECTOR) >> 
ITYPE_offVECTOR)
+   - NDS32_VECTOR_offINTERRUPT;
+}
+
+asmlinkage void asm_do_IRQ(struct pt_regs *regs)
+{
+   irq_hw_number_t hwirq = get_intr_src();
+   handle_domain_irq(root_domain, hwirq, regs);
+}
+
+int __init ativic32_init_irq(struct device_node *node, struct device_node 
*parent)
+{
+   unsigned long int_vec_base, nivic, nr_ints;
+
+   if (WARN(parent, "non-root ativic32 are not supported"))
+   return -EINVAL;
+
+   int_vec_base = __nds32__mfsr(NDS32_SR_IVB);
+
+   if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0)
+   panic("Unable to use atcivic32 for this cpu.\n");
+
+   nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC;
+   if (nivic >= ARRAY_SIZE(nivic_map))
+   panic("The number of input for ativic32 is not supported.\n");
+
+   nr_ints = nivic_map[nivic];
+
+   root_domain = irq_domain_add_linear(node, nr_ints,
+   _ops, NULL);
+
+   if (!root_domain)
+   panic("%s: unable to create IRQ domain\n", node->full_name);
+
+   return 0;
+}
+IRQCHIP_DECLARE(ativic32, "andestech,ativic32", ativic32_init_irq);
-- 
1.7.9.5



  1   2   3   4   5   6   7   8   9   >