Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: Low memory killer problem
From: zhiyuan_zhu @ 2017-05-17  2:47 UTC (permalink / raw)
  To: labbott, gregkh; +Cc: vinmenon, linux-mm, skhiani, torvalds, Jet_Li, zzyjsjcom
In-Reply-To: <1f0815e5-5cb7-81a4-24c8-b0608ef2684a@redhat.com>

Thanks Laura,
Indeed, some part of ION memory have registered shrinker.

/proc/meminfo have no account for the memory which ION can be shrinked part, but just have IonTotal and IonInUse.
And another problem is: ION memory is special, maybe hard to reclaim.
So, wating for Google's solution now.

By the way, which E-mail client do you use?  :)
Thanks
Zhiyuan zhu

-----Original Message-----
From: Laura Abbott [mailto:labbott@redhat.com] 
Sent: Wednesday, May 17, 2017 6:37 AM
To: Zhiyuan Zhu(朱志遠); gregkh@linuxfoundation.org
Cc: vinmenon@codeaurora.org; linux-mm@kvack.org; skhiani@codeaurora.org; torvalds@linux-foundation.org; Jet Li(李發傑)
Subject: Re: Low memory killer problem

On 05/15/2017 08:41 PM, zhiyuan_zhu@htc.com wrote:
> Thanks for your remind,
> I found lowmemorykiller.c have been removed, and ION module still exist since v4.12-rc1.
> I will pay attention to ION module.
> 
> But I still have 3 questions,
> Is there any substitute for low-memory-killer after kernel v4.12-rc1 ?
> Can I accounted the ION free to free memory?
> Is there any different from ION free and the normal system memory free?
> 
> ION free means:   IonTotal - IonInUse  - ION reserved memory.
> Thanks a lot.
> 

Issues like this are exactly why the LMK was deleted. The problem is the LMK is hooked up as a shrinker so it runs in parallel to any other shrinker. The short answer is yes if you want the LMK to do anything reasonable you probably need to tweak it to account for other memory that may be held in the system (Ion, zswap etc.).
There never seemed to be one universal heuristic that worked for everyone which was part of the reason why most changes exist downstream.
Using some combination of the Ion variables above would work if you experiment. If this sounds like a non-answer, that's because it is.

Thanks,
Laura

> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Monday, May 15, 2017 5:00 PM
> To: Zhiyuan Zhu(朱志遠)
> Cc: vinmenon@codeaurora.org; linux-mm@kvack.org; 
> skhiani@codeaurora.org; torvalds@linux-foundation.org; Jet Li(李發傑)
> Subject: Re: Low memory killer problem
> 
> On Mon, May 15, 2017 at 08:22:38AM +0000, zhiyuan_zhu@htc.com wrote:
>> Dear Greg,
>>
>> Very sorry my mail history is lost.
>>
>> I found a part of ION memory will be return to system in android 
>> platform, But these memorys  can’t accounted in low-memory-killer strategy.
>> …
>> And I also found ION memory comes from,  kmalloc/vmalloc/alloc pages/reserved memory.
>> I understand reserved memory shouldn't accounted to free memory.
>> But the memory which alloced by kmalloc/vmalloc/alloc pages, can be reclaimed.
>>
>> But the low-memory killer can't accounted this part, Many thanks.
>>
>> Code location, 
>>    ---> drivers/staging/android/lowmemorykiller.c   -> lowmem_scan
> 
> That file is gone from the latest kernel release, sorry.  So there's not much we can do about this code anymore.
> 
> See the mailing list archives for what should be used instead of this code, there is a plan for what to do.
> 
> Also note that the ION code has had a lot of reworks lately as well.
> 
> good luck!
> 
> greg k-h
> 
> N     r  zǧu   Ơ{\b   칻\x1c &ޖ)  i   ^n r     ݢj$  $  \x05     ~ '.)   ,y m  
>   
% {  j+   צj)Z   \x02f  \x1d {d  $  \x1e         /a==
> 



^ permalink raw reply

* Re: 8 Gigabytes and constantly swapping
From: Arthur Marsh @ 2017-05-17  1:27 UTC (permalink / raw)
  To: Michal Hocko; +Cc: linux-mm
In-Reply-To: <20170515080945.GA6062@dhcp22.suse.cz>



Michal Hocko wrote on 15/05/17 17:39:

> Is this 32b or 64b kernel? Could you take /proc/vmstat snapshots ever
> second while the kswapd is active?
>

This was with a 64 bit kernel.

Thankfully the problem does not seem to affect 4.12.0-rc1 and later 
kernels, with the amount of swap used and amount of time spent waiting 
on kswapd not being a problem even under heavy load.

Arthur.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [v3 0/9] parallelized "struct page" zeroing
From: Benjamin Herrenschmidt @ 2017-05-16 23:50 UTC (permalink / raw)
  To: David Miller, pasha.tatashin
  Cc: linux-s390, borntraeger, heiko.carstens, linux-kernel, mhocko,
	linux-mm, sparclinux, linuxppc-dev
In-Reply-To: <20170512.133742.2144484253675877904.davem@davemloft.net>

On Fri, 2017-05-12 at 13:37 -0400, David Miller wrote:
> > Right now it is larger, but what I suggested is to add a new optimized
> > routine just for this case, which would do STBI for 64-bytes but
> > without membar (do membar at the end of memmap_init_zone() and
> > deferred_init_memmap()
> > 
> > #define struct_page_clear(page)A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A  \
> > A A A A A A A A  __asm__ __volatile__(A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A  \
> > A A A A A A A A  "stxaA A  %%g0, [%0]%2\n"A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A  \
> > A A A A A A A A  "stxaA A  %%xg0, [%0 + %1]%2\n"A A A A A A A A A A A A A A A A A A A A A A A A A A  \
> > A A A A A A A A  : /* No output */A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A  \
> > A A A A A A A A  : "r" (page), "r" (0x20), "i"(ASI_BLK_INIT_QUAD_LDD_P))
> > 
> > And insert it into __init_single_page() instead of memset()
> > 
> > The final result is 4.01s/T which is even faster compared to current
> > 4.97s/T
> 
> Ok, indeed, that would work.

On ppc64, that might not. We have a dcbz instruction that clears an
entire cache line at once. That's what we use for memset's and page
clearing. However, 64 bytes is half a cache line on modern processors
so we can't use it with that semantic and would have to fallback to the
slower stores.

Cheers,
Ben.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: Low memory killer problem
From: Laura Abbott @ 2017-05-16 22:37 UTC (permalink / raw)
  To: zhiyuan_zhu, gregkh; +Cc: vinmenon, linux-mm, skhiani, torvalds, Jet_Li
In-Reply-To: <AF7C0ADF1FEABA4DABABB97411952A2EDD0A52C9@CN-MBX03.HTC.COM.TW>

On 05/15/2017 08:41 PM, zhiyuan_zhu@htc.com wrote:
> Thanks for your remind,
> I found lowmemorykiller.c have been removed, and ION module still exist since v4.12-rc1.
> I will pay attention to ION module.
> 
> But I still have 3 questions,
> Is there any substitute for low-memory-killer after kernel v4.12-rc1 ?
> Can I accounted the ION free to free memory?
> Is there any different from ION free and the normal system memory free?
> 
> ION free means:   IonTotal - IonInUse  - ION reserved memory.
> Thanks a lot.
> 

Issues like this are exactly why the LMK was deleted. The problem
is the LMK is hooked up as a shrinker so it runs in parallel to
any other shrinker. The short answer is yes if you want the LMK
to do anything reasonable you probably need to tweak it to account
for other memory that may be held in the system (Ion, zswap etc.).
There never seemed to be one universal heuristic that worked for
everyone which was part of the reason why most changes exist downstream.
Using some combination of the Ion variables above would work if
you experiment. If this sounds like a non-answer, that's because it is.

Thanks,
Laura

> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org] 
> Sent: Monday, May 15, 2017 5:00 PM
> To: Zhiyuan Zhu(ae?+-a??e? )
> Cc: vinmenon@codeaurora.org; linux-mm@kvack.org; skhiani@codeaurora.org; torvalds@linux-foundation.org; Jet Li(ae??c? 1/4 a??)
> Subject: Re: Low memory killer problem
> 
> On Mon, May 15, 2017 at 08:22:38AM +0000, zhiyuan_zhu@htc.com wrote:
>> Dear Greg,
>>
>> Very sorry my mail history is lost.
>>
>> I found a part of ION memory will be return to system in android 
>> platform, But these memorys  cana??t accounted in low-memory-killer strategy.
>> a?|
>> And I also found ION memory comes from,  kmalloc/vmalloc/alloc pages/reserved memory.
>> I understand reserved memory shouldn't accounted to free memory.
>> But the memory which alloced by kmalloc/vmalloc/alloc pages, can be reclaimed.
>>
>> But the low-memory killer can't accounted this part, Many thanks.
>>
>> Code location, 
>>    ---> drivers/staging/android/lowmemorykiller.c   -> lowmem_scan
> 
> That file is gone from the latest kernel release, sorry.  So there's not much we can do about this code anymore.
> 
> See the mailing list archives for what should be used instead of this code, there is a plan for what to do.
> 
> Also note that the ION code has had a lot of reworks lately as well.
> 
> good luck!
> 
> greg k-h
> 
> Ni? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 ri? 1/2 i? 1/2 zC?ui? 1/2 i? 1/2 i? 1/2 AE {\bi? 1/2 i? 1/2 i? 1/2 i1>>\x1ci? 1/2 &TH?)i? 1/2 i? 1/2 ii? 1/2 i? 1/2 i? 1/2 ^ni? 1/2 ri? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 Ycj$i? 1/2 i? 1/2 $i? 1/2 i? 1/2 \x05i? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 ~i? 1/2 '.)i? 1/2 i? 1/2 i? 1/2 ,yi? 1/2 mi? 1/2 i? 1/2 i? 1/2 i? 1/2 \f%i? 1/2 {i? 1/2 i? 1/2 j+i? 1/2 i? 1/2 i? 1/2 x|j)Zi? 1/2 i? 1/2 i? 1/2 \x02fi? 1/2 i? 1/2 \x1di? 1/2 {di? 1/2 i? 1/2 $i? 1/2 i? 1/2 \x1ei? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 i? 1/2 /a==
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [RFC summary] Enable Coherent Device Memory
From: Benjamin Herrenschmidt @ 2017-05-16 22:26 UTC (permalink / raw)
  To: Mel Gorman, Balbir Singh
  Cc: linux-mm, akpm@linux-foundation.org, Anshuman Khandual,
	Aneesh Kumar KV, Paul E. McKenney, Srikar Dronamraju,
	Haren Myneni, Jérôme Glisse, Reza Arbab,
	Vlastimil Babka, Christoph Lameter, Rik van Riel
In-Reply-To: <20170516084303.ag2lzvdohvh6weov@techsingularity.net>

On Tue, 2017-05-16 at 09:43 +0100, Mel Gorman wrote:
> I'm not sure what you're asking here. migration is only partially
> transparent but a move_pages call will be necessary to force pages onto
> CDM if binding policies are not used so the cost of migration will be
> invisible. Even if you made it "transparent", the migration cost would
> be incurred at fault time. If anything, using move_pages would be more
> predictable as you control when the cost is incurred.

One of the main point of this whole exercise is for applications to not
have to bother with any of this and now you are bringing all back into
their lap.

The base idea behind the counters we have on the link is for the HW to
know when memory is accessed "remotely", so that the device driver can
make decision about migrating pages into or away from the device,
especially so that applications don't have to concern themselves with
memory placement.

This is also to a certain extent the programming model provided by HMM
for non-coherent devices.

While some customers want the last % of performance and will explicitly
place their memory, the general case out there is to have "plug in"
libraries using GPU to accelerate common computational problems behind
the scene with no awareness of memory placement. Explicit memory
placement becomes unmanageable is heavily shared environment too.

Thus we want to reply on the GPU driver moving the pages around where
most appropriate (where they are being accessed, either core memory or
GPU memory) based on inputs from the HW counters monitoring the link.

Cheers,
Ben.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH] mm: per-cgroup memory reclaim stats
From: Balbir Singh @ 2017-05-16 22:03 UTC (permalink / raw)
  To: Johannes Weiner
  Cc: Roman Gushchin, Tejun Heo, Li Zefan, Michal Hocko,
	Vladimir Davydov, cgroups@vger.kernel.org,
	open list:DOCUMENTATION, linux-kernel@vger.kernel.org, linux-mm
In-Reply-To: <20170512164206.GA22367@cmpxchg.org>

On Sat, May 13, 2017 at 2:42 AM, Johannes Weiner <hannes@cmpxchg.org> wrote:
> On Fri, May 12, 2017 at 12:25:22PM +1000, Balbir Singh wrote:
>> On Thu, 2017-05-11 at 20:16 +0100, Roman Gushchin wrote:
>> > The meaning of each value is the same as for global counters,
>> > available using /proc/vmstat.
>> >
>> > Also, for consistency, rename mem_cgroup_count_vm_event() to
>> > count_memcg_event_mm().
>> >
>>
>> I still prefer the mem_cgroup_count_vm_event() name, or memcg_count_vm_event(),
>> the namespace upfront makes it easier to parse where to look for the the
>> implementation and also grep. In any case the rename should be independent
>> patch, but I don't like the name you've proposed.
>
> The memory controller is no longer a tacked-on feature to the VM - the
> entire reclaim path is designed around cgroups at this point. The
> namespacing is just cumbersome and doesn't add add any value, IMO.
>
> This name is also more consistent with the stats interface, where we
> use nodes, zones, memcgs all equally to describe scopes/containers:
>
> inc_node_state(), inc_zone_state(), inc_memcg_state()
>

I don't have a very strong opinion, but I find memcg_* easier to parse
than inc_memcg_*
If memcg is going to be present everywhere we may consider abstracting
them inside
the main routines

>> > @@ -357,6 +357,17 @@ static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
>> >  }
>> >  struct mem_cgroup *mem_cgroup_from_id(unsigned short id);
>> >
>> > +static inline struct mem_cgroup *lruvec_memcg(struct lruvec *lruvec)
>>
>> mem_cgroup_from_lruvec()?
>
> This name is consistent with other lruvec accessors such as
> lruvec_pgdat() and lruvec_lru_size() etc.
>

lruvec_ being the namespace, the same comment as above.

>> > @@ -1741,11 +1748,16 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
>> >
>> >     spin_lock_irq(&pgdat->lru_lock);
>> >
>> > -   if (global_reclaim(sc)) {
>> > -           if (current_is_kswapd())
>> > +   if (current_is_kswapd()) {
>> > +           if (global_reclaim(sc))
>> >                     __count_vm_events(PGSTEAL_KSWAPD, nr_reclaimed);
>> > -           else
>> > +           count_memcg_events(lruvec_memcg(lruvec), PGSTEAL_KSWAPD,
>> > +                              nr_reclaimed);
>>
>> Has the else gone missing? What happens if it's global_reclaim(), do
>> we still account the count in memcg?
>>
>> > +   } else {
>> > +           if (global_reclaim(sc))
>> >                     __count_vm_events(PGSTEAL_DIRECT, nr_reclaimed);
>> > +           count_memcg_events(lruvec_memcg(lruvec), PGSTEAL_DIRECT,
>> > +                              nr_reclaimed);
>>
>> It sounds like memcg accumlates both global and memcg reclaim driver
>> counts -- is this what we want?
>
> Yes.
>
> Consider a fully containerized system that is using only memory.low
> and thus exclusively global reclaim to enforce the partitioning, NOT
> artificial limits and limit reclaim. In this case, we still want to
> know how much reclaim activity each group is experiencing.

But its also confusing to see memcg.stat's value being greater
than the global value? At-least for me. For example PGSTEAL_DIRECT
inside a memcg > global value of PGSTEAL_DIRECT. Do we make
memcg.stat values sum of all impact on memcg or local to memcg?

Balbir Singh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 14/32] efi: Add an EFI table address match function
From: Tom Lendacky @ 2017-05-16 21:53 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170515180913.lhma7xw52irrdtvr@pd.tnic>

On 5/15/2017 1:09 PM, Borislav Petkov wrote:
> On Tue, Apr 18, 2017 at 04:18:48PM -0500, Tom Lendacky wrote:
>> Add a function that will determine if a supplied physical address matches
>> the address of an EFI table.
>>
>> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
>> ---
>>  drivers/firmware/efi/efi.c |   33 +++++++++++++++++++++++++++++++++
>>  include/linux/efi.h        |    7 +++++++
>>  2 files changed, 40 insertions(+)
>>
>> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
>> index b372aad..8f606a3 100644
>> --- a/drivers/firmware/efi/efi.c
>> +++ b/drivers/firmware/efi/efi.c
>> @@ -55,6 +55,25 @@ struct efi __read_mostly efi = {
>>  };
>>  EXPORT_SYMBOL(efi);
>>
>> +static unsigned long *efi_tables[] = {
>> +	&efi.mps,
>> +	&efi.acpi,
>> +	&efi.acpi20,
>> +	&efi.smbios,
>> +	&efi.smbios3,
>> +	&efi.sal_systab,
>> +	&efi.boot_info,
>> +	&efi.hcdp,
>> +	&efi.uga,
>> +	&efi.uv_systab,
>> +	&efi.fw_vendor,
>> +	&efi.runtime,
>> +	&efi.config_table,
>> +	&efi.esrt,
>> +	&efi.properties_table,
>> +	&efi.mem_attr_table,
>> +};
>> +
>>  static bool disable_runtime;
>>  static int __init setup_noefi(char *arg)
>>  {
>> @@ -854,6 +873,20 @@ int efi_status_to_err(efi_status_t status)
>>  	return err;
>>  }
>>
>> +bool efi_table_address_match(unsigned long phys_addr)
>
> efi_is_table_address() reads easier/better in the code.

Will do.

Thanks,
Tom

>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v1 00/11] mm/kasan: support per-page shadow memory to reduce memory consumption
From: Dmitry Vyukov @ 2017-05-16 20:49 UTC (permalink / raw)
  To: Joonsoo Kim
  Cc: Andrew Morton, Andrey Ryabinin, Alexander Potapenko, kasan-dev,
	linux-mm@kvack.org, LKML, Thomas Gleixner, Ingo Molnar,
	H . Peter Anvin, kernel-team
In-Reply-To: <20170516062318.GC16015@js1304-desktop>

On Mon, May 15, 2017 at 11:23 PM, Joonsoo Kim <js1304@gmail.com> wrote:
>> >
>> > Hello, all.
>> >
>> > This is an attempt to recude memory consumption of KASAN. Please see
>> > following description to get the more information.
>> >
>> > 1. What is per-page shadow memory
>>
>> Hi Joonsoo,
>
> Hello, Dmitry.
>
>>
>> First I need to say that this is great work. I wanted KASAN to consume
>
> Thanks!
>
>> 1/8-th of _kernel_ memory rather than total physical memory for a long
>> time.
>>
>> However, this implementation does not work inline instrumentation. And
>> the inline instrumentation is the main mode for KASAN. Outline
>> instrumentation is merely a rudiment to support gcc 4.9, and it needs
>> to be removed as soon as we stop caring about gcc 4.9 (do we at all?
>> is it the current compiler in any distro? Ubuntu 12 has 4.8, Ubuntu 14
>> already has 5.4. And if you build gcc yourself or get a fresher
>> compiler from somewhere else, you hopefully get something better than
>> 4.9).
>
> Hmm... I don't think that outline instrumentation is something to be
> removed. In embedded world, there is a fixed partition table and
> enlarging the kernel binary would cause the problem. Changing that
> table is possible but is really uncomfortable thing for debugging
> something. So, I think that outline instrumentation has it's own merit.

Fair. Let's consider both as important.

> Anyway, I have missed inline instrumentation completely.
>
> I will attach the fix in the bottom. It doesn't look beautiful
> since it breaks layer design (some check will be done at report
> function). However, I think that it's a good trade-off.


I can confirm that inline works with that patch.

I can also confirm that it reduces memory usage. I've booted qemu with
2G ram and run some fixed workload. Before:
31853 dvyukov   20   0 3043200 765464  21312 S 366.0  4.7   2:39.53
qemu-system-x86
 7528 dvyukov   20   0 3043200 732444  21676 S 333.3  4.5   2:23.19
qemu-system-x86
After:
6192 dvyukov   20   0 3043200 394244  20636 S  17.9  2.4   2:32.95
qemu-system-x86
 6265 dvyukov   20   0 3043200 388860  21416 S 399.3  2.4   3:02.88
qemu-system-x86
 9005 dvyukov   20   0 3043200 383564  21220 S 397.1  2.3   2:35.33
qemu-system-x86

However, I see some very significant slowdowns with inline
instrumentation. I did 3 tests:
1. Boot speed, I measured time for a particular message to appear on
console. Before:
[    2.504652] random: crng init done
[    2.435861] random: crng init done
[    2.537135] random: crng init done
After:
[    7.263402] random: crng init done
[    7.263402] random: crng init done
[    7.174395] random: crng init done

That's ~3x slowdown.

2. I've run bench_readv benchmark:
https://raw.githubusercontent.com/google/sanitizers/master/address-sanitizer/kernel_buildbot/slave/bench_readv.c
as:
while true; do time ./bench_readv bench_readv 300000 1; done

Before:
sys 0m7.299s
sys 0m7.218s
sys 0m6.973s
sys 0m6.892s
sys 0m7.035s
sys 0m6.982s
sys 0m6.921s
sys 0m6.940s
sys 0m6.905s
sys 0m7.006s

After:
sys 0m8.141s
sys 0m8.077s
sys 0m8.067s
sys 0m8.116s
sys 0m8.128s
sys 0m8.115s
sys 0m8.108s
sys 0m8.326s
sys 0m8.529s
sys 0m8.164s
sys 0m8.380s

This is ~19% slowdown.

3. I've run bench_pipes benchmark:
https://raw.githubusercontent.com/google/sanitizers/master/address-sanitizer/kernel_buildbot/slave/bench_pipes.c
as:
while true; do time ./bench_pipes 10 10000 1; done

Before:
sys 0m5.393s
sys 0m6.178s
sys 0m5.909s
sys 0m6.024s
sys 0m5.874s
sys 0m5.737s
sys 0m5.826s
sys 0m5.664s
sys 0m5.758s
sys 0m5.421s
sys 0m5.444s
sys 0m5.479s
sys 0m5.461s
sys 0m5.417s

After:
sys 0m8.718s
sys 0m8.281s
sys 0m8.268s
sys 0m8.334s
sys 0m8.246s
sys 0m8.267s
sys 0m8.265s
sys 0m8.437s
sys 0m8.228s
sys 0m8.312s
sys 0m8.556s
sys 0m8.680s

This is ~52% slowdown.


This does not look acceptable to me. I would ready to pay for this,
say, 10% of performance. But it seems that this can have up to 2-4x
slowdown for some workloads.


Your use-case is embed devices where you care a lot about both code
size and memory consumption, right?

I see 2 possible ways forward:
1. Enable this new mode only for outline, but keep current scheme for
inline. Then outline will be "small but slow" type of configuration.
2. Somehow fix slowness (at least in inline mode).


> Mapping zero page to non-kernel memory could cause true-negative
> problem since we cannot flush the TLB in all cpus. We will read zero
> shadow value value in this case even if actual shadow value is not
> zero. This is one of the reason that black page is introduced in this
> patchset.

What does make your current patch work then?
Say we map a new shadow page, update the page shadow to say that there
is mapped shadow. Then another CPU loads the page shadow and then
loads from the newly mapped shadow. If we don't flush TLB, what makes
the second CPU see the newly mapped shadow?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 2/4] thp: fix MADV_DONTNEED vs. numa balancing race
From: Andrea Arcangeli @ 2017-05-16 20:29 UTC (permalink / raw)
  To: Vlastimil Babka; +Cc: Kirill A. Shutemov, Andrew Morton, linux-mm, linux-kernel
In-Reply-To: <f105f6a5-bb5e-9480-6b2e-d2d15f631af9@suse.cz>

On Wed, Apr 12, 2017 at 03:33:35PM +0200, Vlastimil Babka wrote:
> On 03/02/2017 04:10 PM, Kirill A. Shutemov wrote:
> > In case prot_numa, we are under down_read(mmap_sem). It's critical
> > to not clear pmd intermittently to avoid race with MADV_DONTNEED
> > which is also under down_read(mmap_sem):
> > 
> > 	CPU0:				CPU1:
> > 				change_huge_pmd(prot_numa=1)
> > 				 pmdp_huge_get_and_clear_notify()
> > madvise_dontneed()
> >  zap_pmd_range()
> >   pmd_trans_huge(*pmd) == 0 (without ptl)
> >   // skip the pmd
> > 				 set_pmd_at();
> > 				 // pmd is re-established
> > 
> > The race makes MADV_DONTNEED miss the huge pmd and don't clear it
> > which may break userspace.
> > 
> > Found by code analysis, never saw triggered.
> > 
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> > ---
> >  mm/huge_memory.c | 34 +++++++++++++++++++++++++++++++++-
> >  1 file changed, 33 insertions(+), 1 deletion(-)
> > 
> > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > index e7ce73b2b208..bb2b3646bd78 100644
> > --- a/mm/huge_memory.c
> > +++ b/mm/huge_memory.c
> > @@ -1744,7 +1744,39 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
> >  	if (prot_numa && pmd_protnone(*pmd))
> >  		goto unlock;
> >  
> > -	entry = pmdp_huge_get_and_clear_notify(mm, addr, pmd);
> > +	/*
> > +	 * In case prot_numa, we are under down_read(mmap_sem). It's critical
> > +	 * to not clear pmd intermittently to avoid race with MADV_DONTNEED
> > +	 * which is also under down_read(mmap_sem):
> > +	 *
> > +	 *	CPU0:				CPU1:
> > +	 *				change_huge_pmd(prot_numa=1)
> > +	 *				 pmdp_huge_get_and_clear_notify()
> > +	 * madvise_dontneed()
> > +	 *  zap_pmd_range()
> > +	 *   pmd_trans_huge(*pmd) == 0 (without ptl)
> > +	 *   // skip the pmd
> > +	 *				 set_pmd_at();
> > +	 *				 // pmd is re-established
> > +	 *
> > +	 * The race makes MADV_DONTNEED miss the huge pmd and don't clear it
> > +	 * which may break userspace.
> > +	 *
> > +	 * pmdp_invalidate() is required to make sure we don't miss
> > +	 * dirty/young flags set by hardware.
> > +	 */
> > +	entry = *pmd;
> > +	pmdp_invalidate(vma, addr, pmd);
> > +
> > +	/*
> > +	 * Recover dirty/young flags.  It relies on pmdp_invalidate to not
> > +	 * corrupt them.
> > +	 */
> 
> pmdp_invalidate() does:
> 
>         pmd_t entry = *pmdp;
>         set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry));
> 
> so it's not atomic and if CPU sets dirty or accessed in the middle of
> this, they will be lost?

I agree it looks like the dirty bit can be lost. Furthermore this also
loses a MMU notifier invalidate that will lead to corruption at the
secondary MMU level (which will keep using the old protection
permission, potentially keeping writing to a wrprotected page).

> 
> But I don't see how the other invalidate caller
> __split_huge_pmd_locked() deals with this either. Andrea, any idea?

The original code I wrote did this in __split_huge_page_map to create
the "entry" to establish in the pte pagetables:

    	       entry = mk_pte(page + i, vma->vm_page_prot);
	       entry = maybe_mkwrite(pte_mkdirty(entry),
	       	       		   vma);

For anonymous memory the dirty bit is only meaningful for swapping,
and THP couldn't be swapped so setting it unconditional avoided any
issue with the pmdp_invalidate; pmdp_establish.

pmdp_invalidate is needed primarily to avoid aliasing of two different
TLB translation pointing from the same virtual address to the the same
physical address that triggered machine checks (while needing to keep
the pmd huge at all times, back then it was also splitting huge,
splitting is a software bit so userland could still access the data,
splitting bit only blocked kernel code to manipulate on it similar to
what migration entry does right now upstream, except those prevent
userland to access the page during split which is less efficient than
the splitting bit, but at least it's only used for the physical split,
back then there was no difference between virtual and physical split
and physical split is less frequent than the virtual one right now).

It looks like this needs a pmdp_populate that atomically grabs the
value of the pmd and returns it like pmdp_huge_get_and_clear_notify
does and a _notify variant to use "freeze" is false (if freeze is true
the MMU notifier invalidate must have happened when the pmd was set to
a migration entry). If pmdp_populate_notify (freeze==true)
/pmd_populate (freeze==false) would return the old pmd value
atomically with xchg() (just instead of setting it to 0 we should set
it to the mknotpresent one), then we can set the dirty bit on the ptes
(__split_huge_pmd_locked) or in the pmd itself in the change_huge_pmd
accordingly.

If the "dirty" flag information is obtained by the pmd read before
calling pmdp_invalidate is not ok (losing _notify also not ok).

Thanks!
Andrea

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 06/32] x86/mm: Add Secure Memory Encryption (SME) support
From: Tom Lendacky @ 2017-05-16 19:28 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170504143622.zy2f66e4mkm6xvsq@pd.tnic>

On 5/4/2017 9:36 AM, Borislav Petkov wrote:
> On Thu, May 04, 2017 at 09:24:11AM -0500, Tom Lendacky wrote:
>> I did this so that an the include order wouldn't cause issues (including
>> asm/mem_encrypt.h followed by later by a linux/mem_encrypt.h include).
>> I can make this a bit clearer by having separate #defines for each
>> thing, e.g.:
>>
>> #ifndef sme_me_mask
>> #define sme_me_mask 0UL
>> #endif
>>
>> #ifndef sme_active
>> #define sme_active sme_active
>> static inline ...
>> #endif
>>
>> Is that better/clearer?
>
> I guess but where do we have to include both the asm/ and the linux/
> version?

It's more of the sequence of various includes.  For example,
init/do_mounts.c includes <linux/module.h> that eventually gets down
to <asm/pgtable_types.h> and then <asm/mem_encrypt.h>.  However, a
bit further down <linux/nfs_fs.h> is included which eventually gets
down to <linux/dma-mapping.h> and then <linux/mem_encyrpt.h>.

>
> IOW, can we avoid these issues altogether by partitioning symbol
> declarations differently among the headers?

It's most problematic when CONFIG_AMD_MEM_ENCRYPT is not defined since
we never include an asm/ version from the linux/ path.  I could create
a mem_encrypt.h in include/asm-generic/ that contains the info that
is in the !CONFIG_AMD_MEM_ENCRYPT path of the linux/ version. Let me
look into that.

Thanks,
Tom

>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [patch V2 15/17] mm/vmscan: Adjust system_state checks
From: Thomas Gleixner @ 2017-05-16 18:42 UTC (permalink / raw)
  To: LKML
  Cc: Peter Zijlstra, Ingo Molnar, Steven Rostedt, Mark Rutland,
	Greg Kroah-Hartman, Andrew Morton, Johannes Weiner, Mel Gorman,
	Michal Hocko, Vlastimil Babka, linux-mm
In-Reply-To: <20170516184231.564888231@linutronix.de>

[-- Attachment #1: mm-vmscan--Adjust-system_state-checks.patch --]
[-- Type: text/plain, Size: 1271 bytes --]

To enable smp_processor_id() and might_sleep() debug checks earlier, it's
required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING.

Adjust the system_state check in kswapd_run() to handle the extra states.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org
---
 mm/vmscan.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3643,7 +3643,7 @@ int kswapd_run(int nid)
 	pgdat->kswapd = kthread_run(kswapd, pgdat, "kswapd%d", nid);
 	if (IS_ERR(pgdat->kswapd)) {
 		/* failure at boot is fatal */
-		BUG_ON(system_state == SYSTEM_BOOTING);
+		BUG_ON(system_state < SYSTEM_RUNNING);
 		pr_err("Failed to start kswapd on node %d\n", nid);
 		ret = PTR_ERR(pgdat->kswapd);
 		pgdat->kswapd = NULL;


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 26/32] x86, drm, fbdev: Do not specify encrypted memory for video mappings
From: Borislav Petkov @ 2017-05-16 17:35 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170418212056.10190.25468.stgit@tlendack-t1.amdoffice.net>

On Tue, Apr 18, 2017 at 04:20:56PM -0500, Tom Lendacky wrote:
> Since video memory needs to be accessed decrypted, be sure that the
> memory encryption mask is not set for the video ranges.
> 
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>  arch/x86/include/asm/vga.h       |   13 +++++++++++++
>  arch/x86/mm/pageattr.c           |    2 ++
>  drivers/gpu/drm/drm_gem.c        |    2 ++
>  drivers/gpu/drm/drm_vm.c         |    4 ++++
>  drivers/gpu/drm/ttm/ttm_bo_vm.c  |    7 +++++--
>  drivers/gpu/drm/udl/udl_fb.c     |    4 ++++
>  drivers/video/fbdev/core/fbmem.c |   12 ++++++++++++
>  7 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/include/asm/vga.h b/arch/x86/include/asm/vga.h
> index c4b9dc2..5c7567a 100644
> --- a/arch/x86/include/asm/vga.h
> +++ b/arch/x86/include/asm/vga.h
> @@ -7,12 +7,25 @@
>  #ifndef _ASM_X86_VGA_H
>  #define _ASM_X86_VGA_H
>  
> +#include <asm/cacheflush.h>
> +
>  /*
>   *	On the PC, we can just recalculate addresses and then
>   *	access the videoram directly without any black magic.
> + *	To support memory encryption however, we need to access
> + *	the videoram as decrypted memory.
>   */
>  
> +#ifdef CONFIG_AMD_MEM_ENCRYPT
> +#define VGA_MAP_MEM(x, s)					\
> +({								\
> +	unsigned long start = (unsigned long)phys_to_virt(x);	\
> +	set_memory_decrypted(start, (s) >> PAGE_SHIFT);		\
> +	start;							\
> +})
> +#else
>  #define VGA_MAP_MEM(x, s) (unsigned long)phys_to_virt(x)
> +#endif

Can we push the check in and save us the ifdeffery?

#define VGA_MAP_MEM(x, s)                                       \
({                                                              \
        unsigned long start = (unsigned long)phys_to_virt(x);   \
                                                                \
        if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))                 \
                set_memory_decrypted(start, (s) >> PAGE_SHIFT); \
                                                                \
        start;                                                  \
})

It does build here. :)

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH RFC] hugetlbfs 'noautofill' mount option
From: Prakash Sangappa @ 2017-05-16 16:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Dave Hansen, linux-kernel, linux-mm, Andrea Arcangeli
In-Reply-To: <1031e0d4-cdbb-db8b-dae7-7c733921e20e@oracle.com>



On 5/9/17 1:59 PM, Prakash Sangappa wrote:
>
>
> On 5/9/17 1:58 AM, Christoph Hellwig wrote:
>> On Mon, May 08, 2017 at 03:12:42PM -0700, prakash.sangappa wrote:
>>> Regarding #3 as a general feature, do we want to
>>> consider this and the complexity associated with the
>>> implementation?
>> We have to.  Given that no one has exclusive access to hugetlbfs
>> a mount option is fundamentally the wrong interface.
>
>
> A hugetlbfs filesystem may need to be mounted for exclusive use by
> an application. Note, recently the 'min_size' mount option was added
> to hugetlbfs, which would reserve minimum number of huge pages
> for that filesystem for use by an application. If the filesystem with
> min size specified, is not setup for exclusive use by an application,
> then the purpose of reserving huge pages is defeated.  The
> min_size option was for use by applications like the database.
>
> Also, I am investigating enabling hugetlbfs mounts within user
> namespace's mount namespace. That would allow an application
> to mount a hugetlbfs filesystem inside a namespace exclusively for
> its use, running as a non root user. For this it seems like the 
> 'min_size'
> should be subject to some user limits. Anyways, mounting inside
> user namespaces is  a different discussion.
>
> So, if a filesystem has to be setup for exclusive use by an application,
> then different mount options can be used for that filesystem.
>

Any further comments?

Cc'ing Andrea as we had discussed this requirement for the Database.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH] Patch for remapping pages around the fault page
From: Sarunya Pumma @ 2017-05-16 16:16 UTC (permalink / raw)
  To: akpm, kirill.shutemov, jack, ross.zwisler, mhocko, aneesh.kumar,
	lstoakes, dave.jiang
  Cc: linux-mm

[-- Attachment #1: Type: text/plain, Size: 6863 bytes --]

After the fault handler performs the __do_fault function to read a fault
page when a page fault occurs, it does not map other pages that have been
read together with the fault page. This can cause a number of minor page
faults to be large. Therefore, this patch is developed to remap pages
around the fault page by aiming to map the pages that have been read
with the fault page.

The major function of this patch is the redo_fault_around function. This
function computes the start and end offsets of the pages to be mapped,
determines whether to do the page remapping, remaps pages using the
map_pages function, and returns. In the redo_fault_around function, the
start and end offsets are computed the same way as the do_fault_around
function. To determine whether to do the remapping, we determine if the
pages around the fault page are already mapped. If they are, the remapping
will not be performed.

As checking every page can be inefficient if a number of pages to be mapped
is large, we have added a threshold called "vm_nr_rempping" to consider
whether to check the status of every page around the fault page or just
some pages. Note that the vm_nr_rempping parameter can be adjusted via the
Sysctl interface. In the case that a number of pages to be mapped is
smaller than the vm_nr_rempping threshold, we check all pages around the
fault page (within the start and end offsets). Otherwise, we check only the
adjacent pages (left and right).

The page remapping is beneficial when performing the "almost sequential"
page accesses, where pages are accessed in order but some pages are
skipped.

The following is one example scenario that we can reduce one page fault
every 16 page:

Assume that we want to access pages sequentially and skip every page that
marked as PG_readahead. Assume that the read-ahead size is 32 pages and the
number of pages to be mapped each time (fault_around_pages) is 16.

When accessing a page at offset 0, a major page fault occurs, so pages from
page 0 to page 31 is read from the disk to the page cache. With this, page
24 is marked as a read-ahead page (PG_readahead). Then only page 0 is
mapped to the virtual memory space.

When accessing a page at offset 1, a minor page fault occurs, pages from
page 0 to page 15 will be mapped.

We keep accessing pages until page 31. Note that we skip page 24.

When accessing a page at offset 32, a major page fault occurs.  The same
process will be repeated. The other 32 pages will be read from the disk.
Only page 32 is mapped. Then a minor page fault at the next page (page
33) will occur.

>From this example, two page faults occur every 16 page. With this patch, we
can eliminate the minor page fault in every 16 page.

Thank you very much for your time for reviewing the patch.

Signed-off-by: Sarunya Pumma <sarunya@vt.edu>
---
 include/linux/mm.h |  2 ++
 kernel/sysctl.c    |  8 +++++
 mm/memory.c        | 90
++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7cb17c6..2d533a3 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -34,6 +34,8 @@ struct bdi_writeback;

 void init_mm_internals(void);

+extern unsigned long vm_nr_remapping;
+
 #ifndef CONFIG_NEED_MULTIPLE_NODES /* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 4dfba1a..16c7efe 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1332,6 +1332,14 @@ static struct ctl_table vm_table[] = {
  .extra1 = &zero,
  .extra2 = &one_hundred,
  },
+ {
+ .procname = "nr_remapping",
+ .data = &vm_nr_remapping,
+ .maxlen = sizeof(vm_nr_remapping),
+ .mode = 0644,
+ .proc_handler = proc_doulongvec_minmax,
+ .extra1 = &zero,
+ },
 #ifdef CONFIG_HUGETLB_PAGE
  {
  .procname = "nr_hugepages",
diff --git a/mm/memory.c b/mm/memory.c
index 6ff5d72..3d0dca9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -83,6 +83,9 @@
 #warning Unfortunate NUMA and NUMA Balancing config, growing page-frame
for last_cpupid.
 #endif

+/* A preset threshold for considering page remapping */
+unsigned long vm_nr_remapping = 32;
+
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
@@ -3374,6 +3377,82 @@ static int do_fault_around(struct vm_fault *vmf)
  return ret;
 }

+static int redo_fault_around(struct vm_fault *vmf)
+{
+ unsigned long address = vmf->address, nr_pages, mask;
+ pgoff_t start_pgoff = vmf->pgoff;
+ pgoff_t end_pgoff;
+ pte_t *lpte, *rpte;
+ int off, ret = 0, is_mapped = 0;
+
+ nr_pages = READ_ONCE(fault_around_bytes) >> PAGE_SHIFT;
+ mask = ~(nr_pages * PAGE_SIZE - 1) & PAGE_MASK;
+
+ vmf->address = max(address & mask, vmf->vma->vm_start);
+ off = ((address - vmf->address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ start_pgoff -= off;
+
+ /*
+ *  end_pgoff is either end of page table or end of vma
+ *  or fault_around_pages() from start_pgoff, depending what is nearest.
+ */
+ end_pgoff = start_pgoff -
+ ((vmf->address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +
+ PTRS_PER_PTE - 1;
+ end_pgoff = min3(end_pgoff, vma_pages(vmf->vma) + vmf->vma->vm_pgoff - 1,
+ start_pgoff + nr_pages - 1);
+
+ if (nr_pages < vm_nr_remapping) {
+ int i, start_off = 0, end_off = 0;
+
+ lpte = vmf->pte - off;
+ for (i = 0; i < nr_pages; i++) {
+ if (!pte_none(*lpte)) {
+ is_mapped++;
+ } else {
+ if (!start_off)
+ start_off = i;
+ end_off = i;
+ }
+ lpte++;
+ }
+ if (is_mapped != nr_pages) {
+ is_mapped = 0;
+ end_pgoff = start_pgoff + end_off;
+ start_pgoff += start_off;
+ vmf->pte += start_off;
+ }
+ lpte = NULL;
+ } else {
+ lpte = vmf->pte - 1;
+ rpte = vmf->pte + 1;
+ if (!pte_none(*lpte) && !pte_none(*rpte))
+ is_mapped = 1;
+ lpte = NULL;
+ rpte = NULL;
+ }
+
+ if (!is_mapped) {
+ vmf->pte -= off;
+ vmf->vma->vm_ops->map_pages(vmf, start_pgoff, end_pgoff);
+ vmf->pte -= (vmf->address >> PAGE_SHIFT) - (address >> PAGE_SHIFT);
+ }
+
+ /* Huge page is mapped? Page fault is solved */
+ if (pmd_trans_huge(*vmf->pmd)) {
+ ret = VM_FAULT_NOPAGE;
+ goto out;
+ }
+
+ if (vmf->pte)
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+
+out:
+ vmf->address = address;
+ vmf->pte = NULL;
+ return ret;
+}
+
 static int do_read_fault(struct vm_fault *vmf)
 {
  struct vm_area_struct *vma = vmf->vma;
@@ -3394,6 +3473,17 @@ static int do_read_fault(struct vm_fault *vmf)
  if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
  return ret;

+ /*
+ * Remap pages after read
+ */
+ if (!(vma->vm_flags & VM_RAND_READ) && vma->vm_ops->map_pages
+ && fault_around_bytes >> PAGE_SHIFT > 1) {
+ ret |= alloc_set_pte(vmf, vmf->memcg, vmf->page);
+ unlock_page(vmf->page);
+ redo_fault_around(vmf);
+ return ret;
+ }
+
  ret |= finish_fault(vmf);
  unlock_page(vmf->page);
  if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
-- 
2.7.4

[-- Attachment #2: Type: text/html, Size: 16275 bytes --]

^ permalink raw reply related

* Re: [PATCH v2 1/2] mm/hugetlb: Cleanup ARCH_HAS_GIGANTIC_PAGE
From: Aneesh Kumar K.V @ 2017-05-16 15:29 UTC (permalink / raw)
  To: Anshuman Khandual, akpm, mpe; +Cc: linux-mm, linux-kernel, linuxppc-dev
In-Reply-To: <87c68117-3163-b092-ec51-1d618fc42b85@linux.vnet.ibm.com>



On Tuesday 16 May 2017 03:52 PM, Anshuman Khandual wrote:
> On 05/16/2017 02:47 PM, Aneesh Kumar K.V wrote:
>> This moves the #ifdef in C code to a Kconfig dependency. Also we move the
>> gigantic_page_supported() function to be arch specific. This gives arch to
>> conditionally enable runtime allocation of gigantic huge page. Architectures
>> like ppc64 supports different gigantic huge page size (16G and 1G) based on the
>> translation mode selected. This provides an opportunity for ppc64 to enable
>> runtime allocation only w.r.t 1G hugepage.
>
> Right.
>
>>
>> No functional change in this patch.
>>
>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>> ---
>>  arch/arm64/Kconfig               | 2 +-
>>  arch/arm64/include/asm/hugetlb.h | 4 ++++
>>  arch/s390/Kconfig                | 2 +-
>>  arch/s390/include/asm/hugetlb.h  | 3 +++
>>  arch/x86/Kconfig                 | 2 +-
>>  mm/hugetlb.c                     | 7 ++-----
>>  6 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3741859765cf..1f8c1f73aada 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -11,7 +11,7 @@ config ARM64
>>  	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
>>  	select ARCH_HAS_ELF_RANDOMIZE
>>  	select ARCH_HAS_GCOV_PROFILE_ALL
>> -	select ARCH_HAS_GIGANTIC_PAGE
>> +	select ARCH_HAS_GIGANTIC_PAGE if MEMORY_ISOLATION && COMPACTION && CMA
>>  	select ARCH_HAS_KCOV
>>  	select ARCH_HAS_SET_MEMORY
>>  	select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
>> index bbc1e35aa601..793bd73b0d07 100644
>> --- a/arch/arm64/include/asm/hugetlb.h
>> +++ b/arch/arm64/include/asm/hugetlb.h
>> @@ -83,4 +83,8 @@ extern void huge_ptep_set_wrprotect(struct mm_struct *mm,
>>  extern void huge_ptep_clear_flush(struct vm_area_struct *vma,
>>  				  unsigned long addr, pte_t *ptep);
>>
>> +#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
>> +static inline bool gigantic_page_supported(void) { return true; }
>> +#endif
>> +
>>  #endif /* __ASM_HUGETLB_H */
>> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
>> index a2dcef0aacc7..a41bbf420dda 100644
>> --- a/arch/s390/Kconfig
>> +++ b/arch/s390/Kconfig
>> @@ -67,7 +67,7 @@ config S390
>>  	select ARCH_HAS_DEVMEM_IS_ALLOWED
>>  	select ARCH_HAS_ELF_RANDOMIZE
>>  	select ARCH_HAS_GCOV_PROFILE_ALL
>> -	select ARCH_HAS_GIGANTIC_PAGE
>> +	select ARCH_HAS_GIGANTIC_PAGE if MEMORY_ISOLATION && COMPACTION && CMA
>>  	select ARCH_HAS_KCOV
>>  	select ARCH_HAS_SET_MEMORY
>>  	select ARCH_HAS_SG_CHAIN
>> diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
>> index cd546a245c68..89057b2cc8fe 100644
>> --- a/arch/s390/include/asm/hugetlb.h
>> +++ b/arch/s390/include/asm/hugetlb.h
>> @@ -112,4 +112,7 @@ static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
>>  	return pte_modify(pte, newprot);
>>  }
>>
>> +#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
>> +static inline bool gigantic_page_supported(void) { return true; }
>> +#endif
>>  #endif /* _ASM_S390_HUGETLB_H */
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index cc98d5a294ee..30a6328136ac 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -22,7 +22,7 @@ config X86_64
>>  	def_bool y
>>  	depends on 64BIT
>>  	# Options that are inherently 64-bit kernel only:
>> -	select ARCH_HAS_GIGANTIC_PAGE
>> +	select ARCH_HAS_GIGANTIC_PAGE if MEMORY_ISOLATION && COMPACTION && CMA
>>  	select ARCH_SUPPORTS_INT128
>>  	select ARCH_USE_CMPXCHG_LOCKREF
>>  	select HAVE_ARCH_SOFT_DIRTY
>
> Should not we define gigantic_page_supported() function for X86 as well
> like the other two archs above ?
>

yes. Will update the patch.

-aneesh

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v4] arm64: fix the overlap between the kernel image and vmalloc address
From: Ard Biesheuvel @ 2017-05-16 15:03 UTC (permalink / raw)
  To: zhongjiang
  Cc: Catalin Marinas, Mark Rutland, linux-mm@kvack.org, Tanxiaojun,
	Laura Abbott, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1494944127-41737-1-git-send-email-zhongjiang@huawei.com>

On 16 May 2017 at 15:15, zhongjiang <zhongjiang@huawei.com> wrote:
> Recently, xiaojun report the following issue.
>
> [ 4544.984139] Unable to handle kernel paging request at virtual address ffff804392800000
> [ 4544.991995] pgd = ffff80096745f000
> [ 4544.995369] [ffff804392800000] *pgd=0000000000000000
> [ 4545.000297] Internal error: Oops: 96000005 [#1] PREEMPT SMP
> [ 4545.005815] Modules linked in:
> [ 4545.008843] CPU: 1 PID: 8976 Comm: cat Not tainted 4.11.0-rc6 #1
> [ 4545.014790] Hardware name: ARM Juno development board (r1) (DT)
> [ 4545.020653] task: ffff8009753fdb00 task.stack: ffff80097533c000
> [ 4545.026520] PC is at __memcpy+0x100/0x180
> [ 4545.030491] LR is at vread+0x144/0x280
> [ 4545.034202] pc : [<ffff0000083a1000>] lr : [<ffff0000081c126c>] pstate: 20000145
> [ 4545.041530] sp : ffff80097533fcb0
> [ 4545.044811] x29: ffff80097533fcb0 x28: ffff800962d24000
> [ 4545.050074] x27: 0000000000001000 x26: ffff8009753fdb00
> [ 4545.055337] x25: ffff000008200000 x24: ffff800977801380
> [ 4545.060600] x23: ffff8009753fdb00 x22: ffff800962d24000
> [ 4545.065863] x21: 0000000000001000 x20: ffff000008200000
> [ 4545.071125] x19: 0000000000001000 x18: 0000ffffefa323c0
> [ 4545.076387] x17: 0000ffffa9c87440 x16: ffff0000081fdfd0
> [ 4545.081649] x15: 0000ffffa9d01588 x14: 72a77346b2407be7
> [ 4545.086911] x13: 5299400690000000 x12: b0000001f9001a79
> [ 4545.092173] x11: 97fc098d91042260 x10: 0000000000000000
> [ 4545.097435] x9 : 0000000000000000 x8 : 9110626091260021
> [ 4545.102698] x7 : 0000000000001000 x6 : ffff800962d24000
> [ 4545.107960] x5 : ffff8009778013b0 x4 : 0000000000000000
> [ 4545.113222] x3 : 0400000000000001 x2 : 0000000000000f80
> [ 4545.118484] x1 : ffff804392800000 x0 : ffff800962d24000
> [ 4545.123745]
> [ 4545.125220] Process cat (pid: 8976, stack limit = 0xffff80097533c000)
> [ 4545.131598] Stack: (0xffff80097533fcb0 to 0xffff800975340000)
> [ 4545.137289] fca0:                                   ffff80097533fd30 ffff000008270f64
> [ 4545.145049] fcc0: 000000000000e000 000000003956f000 ffff000008f950d0 ffff80097533feb8
> [ 4545.152809] fce0: 0000000000002000 ffff8009753fdb00 ffff800962d24000 ffff000008e8d3d8
> [ 4545.160568] fd00: 0000000000001000 ffff000008200000 0000000000001000 ffff800962d24000
> [ 4545.168327] fd20: 0000000000001000 ffff000008e884a0 ffff80097533fdb0 ffff00000826340c
> [ 4545.176086] fd40: ffff800976bf2800 fffffffffffffffb 000000003956d000 ffff80097533feb8
> [ 4545.183846] fd60: 0000000060000000 0000000000000015 0000000000000124 000000000000003f
> [ 4545.191605] fd80: ffff000008962000 ffff8009753fdb00 ffff8009753fdb00 ffff8009753fdb00
> [ 4545.199364] fda0: 0000000300000124 0000000000002000 ffff80097533fdd0 ffff0000081fb83c
> [ 4545.207123] fdc0: 0000000000010000 ffff80097514f900 ffff80097533fe50 ffff0000081fcb28
> [ 4545.214883] fde0: 0000000000010000 ffff80097514f900 0000000000000000 0000000000000000
> [ 4545.222642] fe00: ffff80097533fe30 ffff0000081fca1c ffff80097514f900 0000000000000000
> [ 4545.230401] fe20: 000000003956d000 ffff80097533feb8 ffff80097533fe50 ffff0000081fcb04
> [ 4545.238160] fe40: 0000000000010000 ffff80097514f900 ffff80097533fe80 ffff0000081fe014
> [ 4545.245919] fe60: ffff80097514f900 ffff80097514f900 000000003956d000 0000000000010000
> [ 4545.253678] fe80: 0000000000000000 ffff000008082f30 0000000000000000 0000800977146000
> [ 4545.261438] fea0: ffffffffffffffff 0000ffffa9c8745c 0000000000000124 0000000008202000
> [ 4545.269197] fec0: 0000000000000003 000000003956d000 0000000000010000 0000000000000000
> [ 4545.276956] fee0: 0000000000011011 0000000000000001 0000000000000011 0000000000000002
> [ 4545.284715] ff00: 000000000000003f 1f3c201f7372686b 00000000ffffffff 0000000000000030
> [ 4545.292474] ff20: 0000000000000038 0000000000000000 0000ffffa9bcca94 0000ffffa9d01588
> [ 4545.300233] ff40: 0000000000000000 0000ffffa9c87440 0000ffffefa323c0 0000000000010000
> [ 4545.307993] ff60: 000000000041a310 000000003956d000 0000000000000003 000000007fffe000
> [ 4545.315751] ff80: 00000000004088d0 0000000000010000 0000000000000000 0000000000000000
> [ 4545.323511] ffa0: 0000000000010000 0000ffffefa32690 0000000000404dcc 0000ffffefa32690
> [ 4545.331270] ffc0: 0000ffffa9c8745c 0000000060000000 0000000000000003 000000000000003f
> [ 4545.339029] ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> [ 4545.346786] Call trace:
> [ 4545.349207] Exception stack(0xffff80097533fae0 to 0xffff80097533fc10)
> [ 4545.355586] fae0: 0000000000001000 0001000000000000 ffff80097533fcb0 ffff0000083a1000
> [ 4545.363345] fb00: 000000003957c000 ffff80097533fc00 0000000020000145 0000000000000025
> [ 4545.371105] fb20: ffff800962d24000 ffff000008e8d3d8 0000000000001000 ffff8009753fdb00
> [ 4545.378864] fb40: 0000000000000000 0000000000000002 ffff80097533fd30 ffff000008082604
> [ 4545.386623] fb60: 0000000000001000 0001000000000000 ffff80097533fd30 ffff0000083a0a90
> [ 4545.394382] fb80: ffff800962d24000 ffff804392800000 0000000000000f80 0400000000000001
> [ 4545.402140] fba0: 0000000000000000 ffff8009778013b0 ffff800962d24000 0000000000001000
> [ 4545.409899] fbc0: 9110626091260021 0000000000000000 0000000000000000 97fc098d91042260
> [ 4545.417658] fbe0: b0000001f9001a79 5299400690000000 72a77346b2407be7 0000ffffa9d01588
> [ 4545.425416] fc00: ffff0000081fdfd0 0000ffffa9c87440
> [ 4545.430248] [<ffff0000083a1000>] __memcpy+0x100/0x180
> [ 4545.435253] [<ffff000008270f64>] read_kcore+0x21c/0x3b0
> [ 4545.440429] [<ffff00000826340c>] proc_reg_read+0x64/0x90
> [ 4545.445691] [<ffff0000081fb83c>] __vfs_read+0x1c/0x108
> [ 4545.450779] [<ffff0000081fcb28>] vfs_read+0x80/0x130
> [ 4545.455696] [<ffff0000081fe014>] SyS_read+0x44/0xa0
> [ 4545.460528] [<ffff000008082f30>] el0_svc_naked+0x24/0x28
> [ 4545.465790] Code: d503201f d503201f d503201f d503201f (a8c12027)
> [ 4545.471852] ---[ end trace 4d1897f94759f461 ]---
> [ 4545.476435] note: cat[8976] exited with preempt_count 2
>
> I find the issue is introduced when applying commit f9040773b7bb
> ("arm64: move kernel image to base of vmalloc area"). This patch
> make the kernel image overlap with vmalloc area. It will result in
> vmalloc area have the huge page table. but the vmalloc_to_page is
> not realize the change. and the function is public to any arch.
>
> I fix it by adding the another kernel image condition in vmalloc_to_page
> to make it keep the accordance with previous vmalloc mapping.
>
> Fixes: f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
> Reported-by: tan xiaojun <tanxiaojun@huawei.com>
> Signed-off-by: zhongjiang <zhongjiang@huawei.com>
> Reviewed-by: Laura Abbott <labbott@redhat.com>
> ---
>  arch/arm64/mm/mmu.c     |  2 +-
>  include/linux/vmalloc.h |  1 +
>  mm/vmalloc.c            | 34 +++++++++++++++++++++++++++-------
>  3 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 0c429ec..2265c39 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -509,7 +509,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
>         vma->addr       = va_start;
>         vma->phys_addr  = pa_start;
>         vma->size       = size;
> -       vma->flags      = VM_MAP;
> +       vma->flags      = VM_KERNEL;
>         vma->caller     = __builtin_return_address(0);
>
>         vm_area_add_early(vma);
> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> index 0328ce0..c9245af 100644
> --- a/include/linux/vmalloc.h
> +++ b/include/linux/vmalloc.h
> @@ -17,6 +17,7 @@
>  #define VM_ALLOC               0x00000002      /* vmalloc() */
>  #define VM_MAP                 0x00000004      /* vmap()ed pages */
>  #define VM_USERMAP             0x00000008      /* suitable for remap_vmalloc_range */
> +#define VM_KERNEL              0x00000010      /* kernel pages */

Is it necessary to define this for all architectures? The VM_
namespace explicitly declares a subrange as having architecture scope
iirc

>  #define VM_UNINITIALIZED       0x00000020      /* vm_struct is not fully initialized */
>  #define VM_NO_GUARD            0x00000040      /* don't add guard page */
>  #define VM_KASAN               0x00000080      /* has allocated kasan shadow memory */
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 1dda6d8..b456803 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1967,11 +1967,27 @@ void *vmalloc_32_user(unsigned long size)
>  EXPORT_SYMBOL(vmalloc_32_user);
>
>  /*
> + * VM_KERNEL indicates an address is mapped linearly.The linear mapping may
> + * use larger pages which vmalloc_to_page cannot handle.

Please don't overload 'linear mapping' . We often refer to the direct
kernel mapping mapping of DRAM as 'linear mapping', but in this
context, it is not clear at all what 'linear' means.

> + */
> +static inline struct page *aligned_get_page(char *addr, struct vm_struct *vm)

This function needs a better name

> +{
> +       struct page *p = NULL;
> +
> +       if (vm->flags & VM_KERNEL)
> +               p = virt_to_page(lm_alias(addr));
> +       else
> +               p = vmalloc_to_page(addr);
> +
> +       return p;
> +}
> +
> +/*
>   * small helper routine , copy contents to buf from addr.
>   * If the page is not present, fill zero.
>   */
> -
> -static int aligned_vread(char *buf, char *addr, unsigned long count)
> +static int aligned_vread(char *buf, char *addr, unsigned long count,
> +                                       struct vm_struct *vm)
>  {
>         struct page *p;
>         int copied = 0;
> @@ -1983,7 +1999,7 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>                 length = PAGE_SIZE - offset;
>                 if (length > count)
>                         length = count;
> -               p = vmalloc_to_page(addr);
> +               p = aligned_get_page(addr, vm);
>                 /*
>                  * To do safe access to this _mapped_ area, we need
>                  * lock. But adding lock here means that we need to add
> @@ -2010,7 +2026,8 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>         return copied;
>  }
>
> -static int aligned_vwrite(char *buf, char *addr, unsigned long count)
> +static int aligned_vwrite(char *buf, char *addr, unsigned long count,
> +                                       struct vm_struct *vm)
>  {
>         struct page *p;
>         int copied = 0;
> @@ -2022,7 +2039,7 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
>                 length = PAGE_SIZE - offset;
>                 if (length > count)
>                         length = count;
> -               p = vmalloc_to_page(addr);
> +               p = aligned_get_page(addr, vm);
>                 /*
>                  * To do safe access to this _mapped_ area, we need
>                  * lock. But adding lock here means that we need to add
> @@ -2109,7 +2126,7 @@ long vread(char *buf, char *addr, unsigned long count)
>                 if (n > count)
>                         n = count;
>                 if (!(vm->flags & VM_IOREMAP))
> -                       aligned_vread(buf, addr, n);
> +                       aligned_vread(buf, addr, n, vm);
>                 else /* IOREMAP area is treated as memory hole */
>                         memset(buf, 0, n);
>                 buf += n;
> @@ -2190,7 +2207,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
>                 if (n > count)
>                         n = count;
>                 if (!(vm->flags & VM_IOREMAP)) {
> -                       aligned_vwrite(buf, addr, n);
> +                       aligned_vwrite(buf, addr, n, vm);
>                         copied++;
>                 }
>                 buf += n;
> @@ -2710,6 +2727,9 @@ static int s_show(struct seq_file *m, void *p)
>         if (v->flags & VM_USERMAP)
>                 seq_puts(m, " user");
>
> +       if (v->flags & VM_KERNEL)
> +               seq_puts(m, " kernel");
> +
>         if (is_vmalloc_addr(v->pages))
>                 seq_puts(m, " vpages");
>
> --
> 1.7.12.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 2/4] thp: fix MADV_DONTNEED vs. numa balancing race
From: Vlastimil Babka @ 2017-05-16 14:54 UTC (permalink / raw)
  To: Kirill A. Shutemov, Andrea Arcangeli, Andrew Morton
  Cc: linux-mm, linux-kernel, Andy Lutomirski
In-Reply-To: <f105f6a5-bb5e-9480-6b2e-d2d15f631af9@suse.cz>

On 04/12/2017 03:33 PM, Vlastimil Babka wrote:
> On 03/02/2017 04:10 PM, Kirill A. Shutemov wrote:
>> In case prot_numa, we are under down_read(mmap_sem). It's critical
>> to not clear pmd intermittently to avoid race with MADV_DONTNEED
>> which is also under down_read(mmap_sem):
>>
>> 	CPU0:				CPU1:
>> 				change_huge_pmd(prot_numa=1)
>> 				 pmdp_huge_get_and_clear_notify()
>> madvise_dontneed()
>>  zap_pmd_range()
>>   pmd_trans_huge(*pmd) == 0 (without ptl)
>>   // skip the pmd
>> 				 set_pmd_at();
>> 				 // pmd is re-established
>>
>> The race makes MADV_DONTNEED miss the huge pmd and don't clear it
>> which may break userspace.
>>
>> Found by code analysis, never saw triggered.
>>
>> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
>> ---
>>  mm/huge_memory.c | 34 +++++++++++++++++++++++++++++++++-
>>  1 file changed, 33 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>> index e7ce73b2b208..bb2b3646bd78 100644
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -1744,7 +1744,39 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
>>  	if (prot_numa && pmd_protnone(*pmd))
>>  		goto unlock;
>>  
>> -	entry = pmdp_huge_get_and_clear_notify(mm, addr, pmd);
>> +	/*
>> +	 * In case prot_numa, we are under down_read(mmap_sem). It's critical
>> +	 * to not clear pmd intermittently to avoid race with MADV_DONTNEED
>> +	 * which is also under down_read(mmap_sem):
>> +	 *
>> +	 *	CPU0:				CPU1:
>> +	 *				change_huge_pmd(prot_numa=1)
>> +	 *				 pmdp_huge_get_and_clear_notify()
>> +	 * madvise_dontneed()
>> +	 *  zap_pmd_range()
>> +	 *   pmd_trans_huge(*pmd) == 0 (without ptl)
>> +	 *   // skip the pmd
>> +	 *				 set_pmd_at();
>> +	 *				 // pmd is re-established
>> +	 *
>> +	 * The race makes MADV_DONTNEED miss the huge pmd and don't clear it
>> +	 * which may break userspace.
>> +	 *
>> +	 * pmdp_invalidate() is required to make sure we don't miss
>> +	 * dirty/young flags set by hardware.
>> +	 */
>> +	entry = *pmd;
>> +	pmdp_invalidate(vma, addr, pmd);
>> +
>> +	/*
>> +	 * Recover dirty/young flags.  It relies on pmdp_invalidate to not
>> +	 * corrupt them.
>> +	 */
> 
> pmdp_invalidate() does:
> 
>         pmd_t entry = *pmdp;
>         set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry));
> 
> so it's not atomic and if CPU sets dirty or accessed in the middle of
> this, they will be lost?
> 
> But I don't see how the other invalidate caller
> __split_huge_pmd_locked() deals with this either. Andrea, any idea?

Looks like we didn't resolve this and meanwhile the patch is in mainline
as ced108037c2aa. CC Andy who deals with TLB a lot these days.

> Vlastimil
> 
>> +	if (pmd_dirty(*pmd))
>> +		entry = pmd_mkdirty(entry);
>> +	if (pmd_young(*pmd))
>> +		entry = pmd_mkyoung(entry);
>> +
>>  	entry = pmd_modify(entry, newprot);
>>  	if (preserve_write)
>>  		entry = pmd_mk_savedwrite(entry);
>>
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
> 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 23/32] swiotlb: Add warnings for use of bounce buffers with SME
From: Borislav Petkov @ 2017-05-16 14:52 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170418212019.10190.24034.stgit@tlendack-t1.amdoffice.net>

On Tue, Apr 18, 2017 at 04:20:19PM -0500, Tom Lendacky wrote:
> Add warnings to let the user know when bounce buffers are being used for
> DMA when SME is active.  Since the bounce buffers are not in encrypted
> memory, these notifications are to allow the user to determine some
> appropriate action - if necessary.
> 
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>  arch/x86/include/asm/mem_encrypt.h |   11 +++++++++++
>  include/linux/dma-mapping.h        |   11 +++++++++++
>  include/linux/mem_encrypt.h        |    6 ++++++
>  lib/swiotlb.c                      |    3 +++
>  4 files changed, 31 insertions(+)
> 
> diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
> index 0637b4b..b406df2 100644
> --- a/arch/x86/include/asm/mem_encrypt.h
> +++ b/arch/x86/include/asm/mem_encrypt.h
> @@ -26,6 +26,11 @@ static inline bool sme_active(void)
>  	return !!sme_me_mask;
>  }
>  
> +static inline u64 sme_dma_mask(void)
> +{
> +	return ((u64)sme_me_mask << 1) - 1;
> +}
> +
>  void __init sme_early_encrypt(resource_size_t paddr,
>  			      unsigned long size);
>  void __init sme_early_decrypt(resource_size_t paddr,
> @@ -50,6 +55,12 @@ static inline bool sme_active(void)
>  {
>  	return false;
>  }
> +
> +static inline u64 sme_dma_mask(void)
> +{
> +	return 0ULL;
> +}
> +
>  #endif
>  
>  static inline void __init sme_early_encrypt(resource_size_t paddr,
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 0977317..f825870 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -10,6 +10,7 @@
>  #include <linux/scatterlist.h>
>  #include <linux/kmemcheck.h>
>  #include <linux/bug.h>
> +#include <linux/mem_encrypt.h>
>  
>  /**
>   * List of possible attributes associated with a DMA mapping. The semantics
> @@ -577,6 +578,11 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
>  
>  	if (!dev->dma_mask || !dma_supported(dev, mask))
>  		return -EIO;
> +
> +	if (sme_active() && (mask < sme_dma_mask()))
> +		dev_warn_ratelimited(dev,
> +				     "SME is active, device will require DMA bounce buffers\n");

Bah, no need to break that line - just let it stick out. Ditto for the
others.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 22/32] x86, swiotlb: DMA support for memory encryption
From: Borislav Petkov @ 2017-05-16 14:27 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170418212010.10190.78119.stgit@tlendack-t1.amdoffice.net>

On Tue, Apr 18, 2017 at 04:20:10PM -0500, Tom Lendacky wrote:
> Since DMA addresses will effectively look like 48-bit addresses when the
> memory encryption mask is set, SWIOTLB is needed if the DMA mask of the
> device performing the DMA does not support 48-bits. SWIOTLB will be
> initialized to create decrypted bounce buffers for use by these devices.

Use a verb in the subject:

Subject: x86, swiotlb: Add memory encryption support

or similar.

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v4] arm64: fix the overlap between the kernel image and vmalloc address
From: zhong jiang @ 2017-05-16 14:26 UTC (permalink / raw)
  To: zhongjiang
  Cc: catalin.marinas, labbott, mark.rutland, tanxiaojun,
	ard.biesheuvel, linux-arm-kernel, linux-mm
In-Reply-To: <1494944127-41737-1-git-send-email-zhongjiang@huawei.com>

Hi, catalin

you can pick up the patch.  Thanks

Thanks
zhongjiang
On 2017/5/16 22:15, zhongjiang wrote:
> Recently, xiaojun report the following issue.
>
> [ 4544.984139] Unable to handle kernel paging request at virtual address ffff804392800000
> [ 4544.991995] pgd = ffff80096745f000
> [ 4544.995369] [ffff804392800000] *pgd=0000000000000000
> [ 4545.000297] Internal error: Oops: 96000005 [#1] PREEMPT SMP
> [ 4545.005815] Modules linked in:
> [ 4545.008843] CPU: 1 PID: 8976 Comm: cat Not tainted 4.11.0-rc6 #1
> [ 4545.014790] Hardware name: ARM Juno development board (r1) (DT)
> [ 4545.020653] task: ffff8009753fdb00 task.stack: ffff80097533c000
> [ 4545.026520] PC is at __memcpy+0x100/0x180
> [ 4545.030491] LR is at vread+0x144/0x280
> [ 4545.034202] pc : [<ffff0000083a1000>] lr : [<ffff0000081c126c>] pstate: 20000145
> [ 4545.041530] sp : ffff80097533fcb0
> [ 4545.044811] x29: ffff80097533fcb0 x28: ffff800962d24000
> [ 4545.050074] x27: 0000000000001000 x26: ffff8009753fdb00
> [ 4545.055337] x25: ffff000008200000 x24: ffff800977801380
> [ 4545.060600] x23: ffff8009753fdb00 x22: ffff800962d24000
> [ 4545.065863] x21: 0000000000001000 x20: ffff000008200000
> [ 4545.071125] x19: 0000000000001000 x18: 0000ffffefa323c0
> [ 4545.076387] x17: 0000ffffa9c87440 x16: ffff0000081fdfd0
> [ 4545.081649] x15: 0000ffffa9d01588 x14: 72a77346b2407be7
> [ 4545.086911] x13: 5299400690000000 x12: b0000001f9001a79
> [ 4545.092173] x11: 97fc098d91042260 x10: 0000000000000000
> [ 4545.097435] x9 : 0000000000000000 x8 : 9110626091260021
> [ 4545.102698] x7 : 0000000000001000 x6 : ffff800962d24000
> [ 4545.107960] x5 : ffff8009778013b0 x4 : 0000000000000000
> [ 4545.113222] x3 : 0400000000000001 x2 : 0000000000000f80
> [ 4545.118484] x1 : ffff804392800000 x0 : ffff800962d24000
> [ 4545.123745]
> [ 4545.125220] Process cat (pid: 8976, stack limit = 0xffff80097533c000)
> [ 4545.131598] Stack: (0xffff80097533fcb0 to 0xffff800975340000)
> [ 4545.137289] fca0:                                   ffff80097533fd30 ffff000008270f64
> [ 4545.145049] fcc0: 000000000000e000 000000003956f000 ffff000008f950d0 ffff80097533feb8
> [ 4545.152809] fce0: 0000000000002000 ffff8009753fdb00 ffff800962d24000 ffff000008e8d3d8
> [ 4545.160568] fd00: 0000000000001000 ffff000008200000 0000000000001000 ffff800962d24000
> [ 4545.168327] fd20: 0000000000001000 ffff000008e884a0 ffff80097533fdb0 ffff00000826340c
> [ 4545.176086] fd40: ffff800976bf2800 fffffffffffffffb 000000003956d000 ffff80097533feb8
> [ 4545.183846] fd60: 0000000060000000 0000000000000015 0000000000000124 000000000000003f
> [ 4545.191605] fd80: ffff000008962000 ffff8009753fdb00 ffff8009753fdb00 ffff8009753fdb00
> [ 4545.199364] fda0: 0000000300000124 0000000000002000 ffff80097533fdd0 ffff0000081fb83c
> [ 4545.207123] fdc0: 0000000000010000 ffff80097514f900 ffff80097533fe50 ffff0000081fcb28
> [ 4545.214883] fde0: 0000000000010000 ffff80097514f900 0000000000000000 0000000000000000
> [ 4545.222642] fe00: ffff80097533fe30 ffff0000081fca1c ffff80097514f900 0000000000000000
> [ 4545.230401] fe20: 000000003956d000 ffff80097533feb8 ffff80097533fe50 ffff0000081fcb04
> [ 4545.238160] fe40: 0000000000010000 ffff80097514f900 ffff80097533fe80 ffff0000081fe014
> [ 4545.245919] fe60: ffff80097514f900 ffff80097514f900 000000003956d000 0000000000010000
> [ 4545.253678] fe80: 0000000000000000 ffff000008082f30 0000000000000000 0000800977146000
> [ 4545.261438] fea0: ffffffffffffffff 0000ffffa9c8745c 0000000000000124 0000000008202000
> [ 4545.269197] fec0: 0000000000000003 000000003956d000 0000000000010000 0000000000000000
> [ 4545.276956] fee0: 0000000000011011 0000000000000001 0000000000000011 0000000000000002
> [ 4545.284715] ff00: 000000000000003f 1f3c201f7372686b 00000000ffffffff 0000000000000030
> [ 4545.292474] ff20: 0000000000000038 0000000000000000 0000ffffa9bcca94 0000ffffa9d01588
> [ 4545.300233] ff40: 0000000000000000 0000ffffa9c87440 0000ffffefa323c0 0000000000010000
> [ 4545.307993] ff60: 000000000041a310 000000003956d000 0000000000000003 000000007fffe000
> [ 4545.315751] ff80: 00000000004088d0 0000000000010000 0000000000000000 0000000000000000
> [ 4545.323511] ffa0: 0000000000010000 0000ffffefa32690 0000000000404dcc 0000ffffefa32690
> [ 4545.331270] ffc0: 0000ffffa9c8745c 0000000060000000 0000000000000003 000000000000003f
> [ 4545.339029] ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> [ 4545.346786] Call trace:
> [ 4545.349207] Exception stack(0xffff80097533fae0 to 0xffff80097533fc10)
> [ 4545.355586] fae0: 0000000000001000 0001000000000000 ffff80097533fcb0 ffff0000083a1000
> [ 4545.363345] fb00: 000000003957c000 ffff80097533fc00 0000000020000145 0000000000000025
> [ 4545.371105] fb20: ffff800962d24000 ffff000008e8d3d8 0000000000001000 ffff8009753fdb00
> [ 4545.378864] fb40: 0000000000000000 0000000000000002 ffff80097533fd30 ffff000008082604
> [ 4545.386623] fb60: 0000000000001000 0001000000000000 ffff80097533fd30 ffff0000083a0a90
> [ 4545.394382] fb80: ffff800962d24000 ffff804392800000 0000000000000f80 0400000000000001
> [ 4545.402140] fba0: 0000000000000000 ffff8009778013b0 ffff800962d24000 0000000000001000
> [ 4545.409899] fbc0: 9110626091260021 0000000000000000 0000000000000000 97fc098d91042260
> [ 4545.417658] fbe0: b0000001f9001a79 5299400690000000 72a77346b2407be7 0000ffffa9d01588
> [ 4545.425416] fc00: ffff0000081fdfd0 0000ffffa9c87440
> [ 4545.430248] [<ffff0000083a1000>] __memcpy+0x100/0x180
> [ 4545.435253] [<ffff000008270f64>] read_kcore+0x21c/0x3b0
> [ 4545.440429] [<ffff00000826340c>] proc_reg_read+0x64/0x90
> [ 4545.445691] [<ffff0000081fb83c>] __vfs_read+0x1c/0x108
> [ 4545.450779] [<ffff0000081fcb28>] vfs_read+0x80/0x130
> [ 4545.455696] [<ffff0000081fe014>] SyS_read+0x44/0xa0
> [ 4545.460528] [<ffff000008082f30>] el0_svc_naked+0x24/0x28
> [ 4545.465790] Code: d503201f d503201f d503201f d503201f (a8c12027)
> [ 4545.471852] ---[ end trace 4d1897f94759f461 ]---
> [ 4545.476435] note: cat[8976] exited with preempt_count 2
>
> I find the issue is introduced when applying commit f9040773b7bb
> ("arm64: move kernel image to base of vmalloc area"). This patch
> make the kernel image overlap with vmalloc area. It will result in
> vmalloc area have the huge page table. but the vmalloc_to_page is
> not realize the change. and the function is public to any arch.
>
> I fix it by adding the another kernel image condition in vmalloc_to_page
> to make it keep the accordance with previous vmalloc mapping.
>
> Fixes: f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
> Reported-by: tan xiaojun <tanxiaojun@huawei.com>
> Signed-off-by: zhongjiang <zhongjiang@huawei.com>
> Reviewed-by: Laura Abbott <labbott@redhat.com>
> ---
>  arch/arm64/mm/mmu.c     |  2 +-
>  include/linux/vmalloc.h |  1 +
>  mm/vmalloc.c            | 34 +++++++++++++++++++++++++++-------
>  3 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 0c429ec..2265c39 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -509,7 +509,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
>  	vma->addr	= va_start;
>  	vma->phys_addr	= pa_start;
>  	vma->size	= size;
> -	vma->flags	= VM_MAP;
> +	vma->flags	= VM_KERNEL;
>  	vma->caller	= __builtin_return_address(0);
>  
>  	vm_area_add_early(vma);
> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> index 0328ce0..c9245af 100644
> --- a/include/linux/vmalloc.h
> +++ b/include/linux/vmalloc.h
> @@ -17,6 +17,7 @@
>  #define VM_ALLOC		0x00000002	/* vmalloc() */
>  #define VM_MAP			0x00000004	/* vmap()ed pages */
>  #define VM_USERMAP		0x00000008	/* suitable for remap_vmalloc_range */
> +#define VM_KERNEL		0x00000010	/* kernel pages */
>  #define VM_UNINITIALIZED	0x00000020	/* vm_struct is not fully initialized */
>  #define VM_NO_GUARD		0x00000040      /* don't add guard page */
>  #define VM_KASAN		0x00000080      /* has allocated kasan shadow memory */
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 1dda6d8..b456803 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1967,11 +1967,27 @@ void *vmalloc_32_user(unsigned long size)
>  EXPORT_SYMBOL(vmalloc_32_user);
>  
>  /*
> + * VM_KERNEL indicates an address is mapped linearly.The linear mapping may
> + * use larger pages which vmalloc_to_page cannot handle.
> + */
> +static inline struct page *aligned_get_page(char *addr, struct vm_struct *vm)
> +{
> +	struct page *p = NULL;
> +
> +	if (vm->flags & VM_KERNEL)
> +		p = virt_to_page(lm_alias(addr));
> +	else
> +		p = vmalloc_to_page(addr);
> +
> +	return p;
> +}
> +
> +/*
>   * small helper routine , copy contents to buf from addr.
>   * If the page is not present, fill zero.
>   */
> -
> -static int aligned_vread(char *buf, char *addr, unsigned long count)
> +static int aligned_vread(char *buf, char *addr, unsigned long count,
> +					struct vm_struct *vm)
>  {
>  	struct page *p;
>  	int copied = 0;
> @@ -1983,7 +1999,7 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>  		length = PAGE_SIZE - offset;
>  		if (length > count)
>  			length = count;
> -		p = vmalloc_to_page(addr);
> +		p = aligned_get_page(addr, vm);
>  		/*
>  		 * To do safe access to this _mapped_ area, we need
>  		 * lock. But adding lock here means that we need to add
> @@ -2010,7 +2026,8 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>  	return copied;
>  }
>  
> -static int aligned_vwrite(char *buf, char *addr, unsigned long count)
> +static int aligned_vwrite(char *buf, char *addr, unsigned long count,
> +					struct vm_struct *vm)
>  {
>  	struct page *p;
>  	int copied = 0;
> @@ -2022,7 +2039,7 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
>  		length = PAGE_SIZE - offset;
>  		if (length > count)
>  			length = count;
> -		p = vmalloc_to_page(addr);
> +		p = aligned_get_page(addr, vm);
>  		/*
>  		 * To do safe access to this _mapped_ area, we need
>  		 * lock. But adding lock here means that we need to add
> @@ -2109,7 +2126,7 @@ long vread(char *buf, char *addr, unsigned long count)
>  		if (n > count)
>  			n = count;
>  		if (!(vm->flags & VM_IOREMAP))
> -			aligned_vread(buf, addr, n);
> +			aligned_vread(buf, addr, n, vm);
>  		else /* IOREMAP area is treated as memory hole */
>  			memset(buf, 0, n);
>  		buf += n;
> @@ -2190,7 +2207,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
>  		if (n > count)
>  			n = count;
>  		if (!(vm->flags & VM_IOREMAP)) {
> -			aligned_vwrite(buf, addr, n);
> +			aligned_vwrite(buf, addr, n, vm);
>  			copied++;
>  		}
>  		buf += n;
> @@ -2710,6 +2727,9 @@ static int s_show(struct seq_file *m, void *p)
>  	if (v->flags & VM_USERMAP)
>  		seq_puts(m, " user");
>  
> +	if (v->flags & VM_KERNEL)
> +		seq_puts(m, " kernel");
> +
>  	if (is_vmalloc_addr(v->pages))
>  		seq_puts(m, " vpages");
>  


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH v4] arm64: fix the overlap between the kernel image and vmalloc address
From: zhongjiang @ 2017-05-16 14:15 UTC (permalink / raw)
  To: catalin.marinas
  Cc: labbott, mark.rutland, tanxiaojun, zhongjiang, ard.biesheuvel,
	linux-arm-kernel, linux-mm

Recently, xiaojun report the following issue.

[ 4544.984139] Unable to handle kernel paging request at virtual address ffff804392800000
[ 4544.991995] pgd = ffff80096745f000
[ 4544.995369] [ffff804392800000] *pgd=0000000000000000
[ 4545.000297] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 4545.005815] Modules linked in:
[ 4545.008843] CPU: 1 PID: 8976 Comm: cat Not tainted 4.11.0-rc6 #1
[ 4545.014790] Hardware name: ARM Juno development board (r1) (DT)
[ 4545.020653] task: ffff8009753fdb00 task.stack: ffff80097533c000
[ 4545.026520] PC is at __memcpy+0x100/0x180
[ 4545.030491] LR is at vread+0x144/0x280
[ 4545.034202] pc : [<ffff0000083a1000>] lr : [<ffff0000081c126c>] pstate: 20000145
[ 4545.041530] sp : ffff80097533fcb0
[ 4545.044811] x29: ffff80097533fcb0 x28: ffff800962d24000
[ 4545.050074] x27: 0000000000001000 x26: ffff8009753fdb00
[ 4545.055337] x25: ffff000008200000 x24: ffff800977801380
[ 4545.060600] x23: ffff8009753fdb00 x22: ffff800962d24000
[ 4545.065863] x21: 0000000000001000 x20: ffff000008200000
[ 4545.071125] x19: 0000000000001000 x18: 0000ffffefa323c0
[ 4545.076387] x17: 0000ffffa9c87440 x16: ffff0000081fdfd0
[ 4545.081649] x15: 0000ffffa9d01588 x14: 72a77346b2407be7
[ 4545.086911] x13: 5299400690000000 x12: b0000001f9001a79
[ 4545.092173] x11: 97fc098d91042260 x10: 0000000000000000
[ 4545.097435] x9 : 0000000000000000 x8 : 9110626091260021
[ 4545.102698] x7 : 0000000000001000 x6 : ffff800962d24000
[ 4545.107960] x5 : ffff8009778013b0 x4 : 0000000000000000
[ 4545.113222] x3 : 0400000000000001 x2 : 0000000000000f80
[ 4545.118484] x1 : ffff804392800000 x0 : ffff800962d24000
[ 4545.123745]
[ 4545.125220] Process cat (pid: 8976, stack limit = 0xffff80097533c000)
[ 4545.131598] Stack: (0xffff80097533fcb0 to 0xffff800975340000)
[ 4545.137289] fca0:                                   ffff80097533fd30 ffff000008270f64
[ 4545.145049] fcc0: 000000000000e000 000000003956f000 ffff000008f950d0 ffff80097533feb8
[ 4545.152809] fce0: 0000000000002000 ffff8009753fdb00 ffff800962d24000 ffff000008e8d3d8
[ 4545.160568] fd00: 0000000000001000 ffff000008200000 0000000000001000 ffff800962d24000
[ 4545.168327] fd20: 0000000000001000 ffff000008e884a0 ffff80097533fdb0 ffff00000826340c
[ 4545.176086] fd40: ffff800976bf2800 fffffffffffffffb 000000003956d000 ffff80097533feb8
[ 4545.183846] fd60: 0000000060000000 0000000000000015 0000000000000124 000000000000003f
[ 4545.191605] fd80: ffff000008962000 ffff8009753fdb00 ffff8009753fdb00 ffff8009753fdb00
[ 4545.199364] fda0: 0000000300000124 0000000000002000 ffff80097533fdd0 ffff0000081fb83c
[ 4545.207123] fdc0: 0000000000010000 ffff80097514f900 ffff80097533fe50 ffff0000081fcb28
[ 4545.214883] fde0: 0000000000010000 ffff80097514f900 0000000000000000 0000000000000000
[ 4545.222642] fe00: ffff80097533fe30 ffff0000081fca1c ffff80097514f900 0000000000000000
[ 4545.230401] fe20: 000000003956d000 ffff80097533feb8 ffff80097533fe50 ffff0000081fcb04
[ 4545.238160] fe40: 0000000000010000 ffff80097514f900 ffff80097533fe80 ffff0000081fe014
[ 4545.245919] fe60: ffff80097514f900 ffff80097514f900 000000003956d000 0000000000010000
[ 4545.253678] fe80: 0000000000000000 ffff000008082f30 0000000000000000 0000800977146000
[ 4545.261438] fea0: ffffffffffffffff 0000ffffa9c8745c 0000000000000124 0000000008202000
[ 4545.269197] fec0: 0000000000000003 000000003956d000 0000000000010000 0000000000000000
[ 4545.276956] fee0: 0000000000011011 0000000000000001 0000000000000011 0000000000000002
[ 4545.284715] ff00: 000000000000003f 1f3c201f7372686b 00000000ffffffff 0000000000000030
[ 4545.292474] ff20: 0000000000000038 0000000000000000 0000ffffa9bcca94 0000ffffa9d01588
[ 4545.300233] ff40: 0000000000000000 0000ffffa9c87440 0000ffffefa323c0 0000000000010000
[ 4545.307993] ff60: 000000000041a310 000000003956d000 0000000000000003 000000007fffe000
[ 4545.315751] ff80: 00000000004088d0 0000000000010000 0000000000000000 0000000000000000
[ 4545.323511] ffa0: 0000000000010000 0000ffffefa32690 0000000000404dcc 0000ffffefa32690
[ 4545.331270] ffc0: 0000ffffa9c8745c 0000000060000000 0000000000000003 000000000000003f
[ 4545.339029] ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 4545.346786] Call trace:
[ 4545.349207] Exception stack(0xffff80097533fae0 to 0xffff80097533fc10)
[ 4545.355586] fae0: 0000000000001000 0001000000000000 ffff80097533fcb0 ffff0000083a1000
[ 4545.363345] fb00: 000000003957c000 ffff80097533fc00 0000000020000145 0000000000000025
[ 4545.371105] fb20: ffff800962d24000 ffff000008e8d3d8 0000000000001000 ffff8009753fdb00
[ 4545.378864] fb40: 0000000000000000 0000000000000002 ffff80097533fd30 ffff000008082604
[ 4545.386623] fb60: 0000000000001000 0001000000000000 ffff80097533fd30 ffff0000083a0a90
[ 4545.394382] fb80: ffff800962d24000 ffff804392800000 0000000000000f80 0400000000000001
[ 4545.402140] fba0: 0000000000000000 ffff8009778013b0 ffff800962d24000 0000000000001000
[ 4545.409899] fbc0: 9110626091260021 0000000000000000 0000000000000000 97fc098d91042260
[ 4545.417658] fbe0: b0000001f9001a79 5299400690000000 72a77346b2407be7 0000ffffa9d01588
[ 4545.425416] fc00: ffff0000081fdfd0 0000ffffa9c87440
[ 4545.430248] [<ffff0000083a1000>] __memcpy+0x100/0x180
[ 4545.435253] [<ffff000008270f64>] read_kcore+0x21c/0x3b0
[ 4545.440429] [<ffff00000826340c>] proc_reg_read+0x64/0x90
[ 4545.445691] [<ffff0000081fb83c>] __vfs_read+0x1c/0x108
[ 4545.450779] [<ffff0000081fcb28>] vfs_read+0x80/0x130
[ 4545.455696] [<ffff0000081fe014>] SyS_read+0x44/0xa0
[ 4545.460528] [<ffff000008082f30>] el0_svc_naked+0x24/0x28
[ 4545.465790] Code: d503201f d503201f d503201f d503201f (a8c12027)
[ 4545.471852] ---[ end trace 4d1897f94759f461 ]---
[ 4545.476435] note: cat[8976] exited with preempt_count 2

I find the issue is introduced when applying commit f9040773b7bb
("arm64: move kernel image to base of vmalloc area"). This patch
make the kernel image overlap with vmalloc area. It will result in
vmalloc area have the huge page table. but the vmalloc_to_page is
not realize the change. and the function is public to any arch.

I fix it by adding the another kernel image condition in vmalloc_to_page
to make it keep the accordance with previous vmalloc mapping.

Fixes: f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
Reported-by: tan xiaojun <tanxiaojun@huawei.com>
Signed-off-by: zhongjiang <zhongjiang@huawei.com>
Reviewed-by: Laura Abbott <labbott@redhat.com>
---
 arch/arm64/mm/mmu.c     |  2 +-
 include/linux/vmalloc.h |  1 +
 mm/vmalloc.c            | 34 +++++++++++++++++++++++++++-------
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 0c429ec..2265c39 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -509,7 +509,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
 	vma->addr	= va_start;
 	vma->phys_addr	= pa_start;
 	vma->size	= size;
-	vma->flags	= VM_MAP;
+	vma->flags	= VM_KERNEL;
 	vma->caller	= __builtin_return_address(0);
 
 	vm_area_add_early(vma);
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 0328ce0..c9245af 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -17,6 +17,7 @@
 #define VM_ALLOC		0x00000002	/* vmalloc() */
 #define VM_MAP			0x00000004	/* vmap()ed pages */
 #define VM_USERMAP		0x00000008	/* suitable for remap_vmalloc_range */
+#define VM_KERNEL		0x00000010	/* kernel pages */
 #define VM_UNINITIALIZED	0x00000020	/* vm_struct is not fully initialized */
 #define VM_NO_GUARD		0x00000040      /* don't add guard page */
 #define VM_KASAN		0x00000080      /* has allocated kasan shadow memory */
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1dda6d8..b456803 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1967,11 +1967,27 @@ void *vmalloc_32_user(unsigned long size)
 EXPORT_SYMBOL(vmalloc_32_user);
 
 /*
+ * VM_KERNEL indicates an address is mapped linearly.The linear mapping may
+ * use larger pages which vmalloc_to_page cannot handle.
+ */
+static inline struct page *aligned_get_page(char *addr, struct vm_struct *vm)
+{
+	struct page *p = NULL;
+
+	if (vm->flags & VM_KERNEL)
+		p = virt_to_page(lm_alias(addr));
+	else
+		p = vmalloc_to_page(addr);
+
+	return p;
+}
+
+/*
  * small helper routine , copy contents to buf from addr.
  * If the page is not present, fill zero.
  */
-
-static int aligned_vread(char *buf, char *addr, unsigned long count)
+static int aligned_vread(char *buf, char *addr, unsigned long count,
+					struct vm_struct *vm)
 {
 	struct page *p;
 	int copied = 0;
@@ -1983,7 +1999,7 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
 		length = PAGE_SIZE - offset;
 		if (length > count)
 			length = count;
-		p = vmalloc_to_page(addr);
+		p = aligned_get_page(addr, vm);
 		/*
 		 * To do safe access to this _mapped_ area, we need
 		 * lock. But adding lock here means that we need to add
@@ -2010,7 +2026,8 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
 	return copied;
 }
 
-static int aligned_vwrite(char *buf, char *addr, unsigned long count)
+static int aligned_vwrite(char *buf, char *addr, unsigned long count,
+					struct vm_struct *vm)
 {
 	struct page *p;
 	int copied = 0;
@@ -2022,7 +2039,7 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
 		length = PAGE_SIZE - offset;
 		if (length > count)
 			length = count;
-		p = vmalloc_to_page(addr);
+		p = aligned_get_page(addr, vm);
 		/*
 		 * To do safe access to this _mapped_ area, we need
 		 * lock. But adding lock here means that we need to add
@@ -2109,7 +2126,7 @@ long vread(char *buf, char *addr, unsigned long count)
 		if (n > count)
 			n = count;
 		if (!(vm->flags & VM_IOREMAP))
-			aligned_vread(buf, addr, n);
+			aligned_vread(buf, addr, n, vm);
 		else /* IOREMAP area is treated as memory hole */
 			memset(buf, 0, n);
 		buf += n;
@@ -2190,7 +2207,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
 		if (n > count)
 			n = count;
 		if (!(vm->flags & VM_IOREMAP)) {
-			aligned_vwrite(buf, addr, n);
+			aligned_vwrite(buf, addr, n, vm);
 			copied++;
 		}
 		buf += n;
@@ -2710,6 +2727,9 @@ static int s_show(struct seq_file *m, void *p)
 	if (v->flags & VM_USERMAP)
 		seq_puts(m, " user");
 
+	if (v->flags & VM_KERNEL)
+		seq_puts(m, " kernel");
+
 	if (is_vmalloc_addr(v->pages))
 		seq_puts(m, " vpages");
 
-- 
1.7.12.4

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* Re: [PATCH v6 05/15] lockdep: Implement crossrelease feature
From: Peter Zijlstra @ 2017-05-16 14:18 UTC (permalink / raw)
  To: Byungchul Park
  Cc: mingo, tglx, walken, boqun.feng, kirill, linux-kernel, linux-mm,
	iamjoonsoo.kim, akpm, willy, npiggin, kernel-team
In-Reply-To: <20170425054044.GK21430@X58A-UD3R>

On Tue, Apr 25, 2017 at 02:40:44PM +0900, Byungchul Park wrote:
> On Mon, Apr 24, 2017 at 12:17:47PM +0200, Peter Zijlstra wrote:

> > My complaint is mostly about naming.. and "hist_gen_id" might be a
> > better name.
> 
> Ah, I also think the name, 'work_id', is not good... and frankly I am
> not sure if 'hist_gen_id' is good, either. What about to apply 'rollback',
> which I did for locks in irq, into works of workqueues? If you say yes,
> I will try to do it.

If the rollback thing works, that's fine too. If it gets ugly, stick
with something like 'hist_id'.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v3] arm64: fix the overlap between the kernel image and vmalloc address
From: zhong jiang @ 2017-05-16 14:06 UTC (permalink / raw)
  To: Laura Abbott
  Cc: Catalin Marinas, ard.biesheuvel, mark.rutland, linux-arm-kernel,
	tanxiaojun, linux-mm
In-Reply-To: <20c6ff45-d6d6-b8f1-72db-53b6e3167932@redhat.com>

On 2017/5/16 8:02, Laura Abbott wrote:
> On 05/10/2017 01:55 AM, Catalin Marinas wrote:
>> Given that there are a lot more mm changes than arm64, cc'ing linux-mm
>> as well.
>>
>> Patch below:
>>
>> On Wed, May 10, 2017 at 11:37:20AM +0800, zhongjiang wrote:
>>> Recently, xiaojun report the following issue.
>>>
>>> [ 4544.984139] Unable to handle kernel paging request at virtual address ffff804392800000
>>> [ 4544.991995] pgd = ffff80096745f000
>>> [ 4544.995369] [ffff804392800000] *pgd=0000000000000000
>>> [ 4545.000297] Internal error: Oops: 96000005 [#1] PREEMPT SMP
>>> [ 4545.005815] Modules linked in:
>>> [ 4545.008843] CPU: 1 PID: 8976 Comm: cat Not tainted 4.11.0-rc6 #1
>>> [ 4545.014790] Hardware name: ARM Juno development board (r1) (DT)
>>> [ 4545.020653] task: ffff8009753fdb00 task.stack: ffff80097533c000
>>> [ 4545.026520] PC is at __memcpy+0x100/0x180
>>> [ 4545.030491] LR is at vread+0x144/0x280
>>> [ 4545.034202] pc : [<ffff0000083a1000>] lr : [<ffff0000081c126c>] pstate: 20000145
>>> [ 4545.041530] sp : ffff80097533fcb0
>>> [ 4545.044811] x29: ffff80097533fcb0 x28: ffff800962d24000
>>> [ 4545.050074] x27: 0000000000001000 x26: ffff8009753fdb00
>>> [ 4545.055337] x25: ffff000008200000 x24: ffff800977801380
>>> [ 4545.060600] x23: ffff8009753fdb00 x22: ffff800962d24000
>>> [ 4545.065863] x21: 0000000000001000 x20: ffff000008200000
>>> [ 4545.071125] x19: 0000000000001000 x18: 0000ffffefa323c0
>>> [ 4545.076387] x17: 0000ffffa9c87440 x16: ffff0000081fdfd0
>>> [ 4545.081649] x15: 0000ffffa9d01588 x14: 72a77346b2407be7
>>> [ 4545.086911] x13: 5299400690000000 x12: b0000001f9001a79
>>> [ 4545.092173] x11: 97fc098d91042260 x10: 0000000000000000
>>> [ 4545.097435] x9 : 0000000000000000 x8 : 9110626091260021
>>> [ 4545.102698] x7 : 0000000000001000 x6 : ffff800962d24000
>>> [ 4545.107960] x5 : ffff8009778013b0 x4 : 0000000000000000
>>> [ 4545.113222] x3 : 0400000000000001 x2 : 0000000000000f80
>>> [ 4545.118484] x1 : ffff804392800000 x0 : ffff800962d24000
>>> [ 4545.123745]
>>> [ 4545.125220] Process cat (pid: 8976, stack limit = 0xffff80097533c000)
>>> [ 4545.131598] Stack: (0xffff80097533fcb0 to 0xffff800975340000)
>>> [ 4545.137289] fca0:                                   ffff80097533fd30 ffff000008270f64
>>> [ 4545.145049] fcc0: 000000000000e000 000000003956f000 ffff000008f950d0 ffff80097533feb8
>>> [ 4545.152809] fce0: 0000000000002000 ffff8009753fdb00 ffff800962d24000 ffff000008e8d3d8
>>> [ 4545.160568] fd00: 0000000000001000 ffff000008200000 0000000000001000 ffff800962d24000
>>> [ 4545.168327] fd20: 0000000000001000 ffff000008e884a0 ffff80097533fdb0 ffff00000826340c
>>> [ 4545.176086] fd40: ffff800976bf2800 fffffffffffffffb 000000003956d000 ffff80097533feb8
>>> [ 4545.183846] fd60: 0000000060000000 0000000000000015 0000000000000124 000000000000003f
>>> [ 4545.191605] fd80: ffff000008962000 ffff8009753fdb00 ffff8009753fdb00 ffff8009753fdb00
>>> [ 4545.199364] fda0: 0000000300000124 0000000000002000 ffff80097533fdd0 ffff0000081fb83c
>>> [ 4545.207123] fdc0: 0000000000010000 ffff80097514f900 ffff80097533fe50 ffff0000081fcb28
>>> [ 4545.214883] fde0: 0000000000010000 ffff80097514f900 0000000000000000 0000000000000000
>>> [ 4545.222642] fe00: ffff80097533fe30 ffff0000081fca1c ffff80097514f900 0000000000000000
>>> [ 4545.230401] fe20: 000000003956d000 ffff80097533feb8 ffff80097533fe50 ffff0000081fcb04
>>> [ 4545.238160] fe40: 0000000000010000 ffff80097514f900 ffff80097533fe80 ffff0000081fe014
>>> [ 4545.245919] fe60: ffff80097514f900 ffff80097514f900 000000003956d000 0000000000010000
>>> [ 4545.253678] fe80: 0000000000000000 ffff000008082f30 0000000000000000 0000800977146000
>>> [ 4545.261438] fea0: ffffffffffffffff 0000ffffa9c8745c 0000000000000124 0000000008202000
>>> [ 4545.269197] fec0: 0000000000000003 000000003956d000 0000000000010000 0000000000000000
>>> [ 4545.276956] fee0: 0000000000011011 0000000000000001 0000000000000011 0000000000000002
>>> [ 4545.284715] ff00: 000000000000003f 1f3c201f7372686b 00000000ffffffff 0000000000000030
>>> [ 4545.292474] ff20: 0000000000000038 0000000000000000 0000ffffa9bcca94 0000ffffa9d01588
>>> [ 4545.300233] ff40: 0000000000000000 0000ffffa9c87440 0000ffffefa323c0 0000000000010000
>>> [ 4545.307993] ff60: 000000000041a310 000000003956d000 0000000000000003 000000007fffe000
>>> [ 4545.315751] ff80: 00000000004088d0 0000000000010000 0000000000000000 0000000000000000
>>> [ 4545.323511] ffa0: 0000000000010000 0000ffffefa32690 0000000000404dcc 0000ffffefa32690
>>> [ 4545.331270] ffc0: 0000ffffa9c8745c 0000000060000000 0000000000000003 000000000000003f
>>> [ 4545.339029] ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>>> [ 4545.346786] Call trace:
>>> [ 4545.349207] Exception stack(0xffff80097533fae0 to 0xffff80097533fc10)
>>> [ 4545.355586] fae0: 0000000000001000 0001000000000000 ffff80097533fcb0 ffff0000083a1000
>>> [ 4545.363345] fb00: 000000003957c000 ffff80097533fc00 0000000020000145 0000000000000025
>>> [ 4545.371105] fb20: ffff800962d24000 ffff000008e8d3d8 0000000000001000 ffff8009753fdb00
>>> [ 4545.378864] fb40: 0000000000000000 0000000000000002 ffff80097533fd30 ffff000008082604
>>> [ 4545.386623] fb60: 0000000000001000 0001000000000000 ffff80097533fd30 ffff0000083a0a90
>>> [ 4545.394382] fb80: ffff800962d24000 ffff804392800000 0000000000000f80 0400000000000001
>>> [ 4545.402140] fba0: 0000000000000000 ffff8009778013b0 ffff800962d24000 0000000000001000
>>> [ 4545.409899] fbc0: 9110626091260021 0000000000000000 0000000000000000 97fc098d91042260
>>> [ 4545.417658] fbe0: b0000001f9001a79 5299400690000000 72a77346b2407be7 0000ffffa9d01588
>>> [ 4545.425416] fc00: ffff0000081fdfd0 0000ffffa9c87440
>>> [ 4545.430248] [<ffff0000083a1000>] __memcpy+0x100/0x180
>>> [ 4545.435253] [<ffff000008270f64>] read_kcore+0x21c/0x3b0
>>> [ 4545.440429] [<ffff00000826340c>] proc_reg_read+0x64/0x90
>>> [ 4545.445691] [<ffff0000081fb83c>] __vfs_read+0x1c/0x108
>>> [ 4545.450779] [<ffff0000081fcb28>] vfs_read+0x80/0x130
>>> [ 4545.455696] [<ffff0000081fe014>] SyS_read+0x44/0xa0
>>> [ 4545.460528] [<ffff000008082f30>] el0_svc_naked+0x24/0x28
>>> [ 4545.465790] Code: d503201f d503201f d503201f d503201f (a8c12027)
>>> [ 4545.471852] ---[ end trace 4d1897f94759f461 ]---
>>> [ 4545.476435] note: cat[8976] exited with preempt_count 2
>>>
>>> I find the issue is introduced when applying commit f9040773b7bb
>>> ("arm64: move kernel image to base of vmalloc area"). This patch
>>> make the kernel image overlap with vmalloc area. It will result in
>>> vmalloc area have the huge page table. but the vmalloc_to_page is
>>> not realize the change. and the function is public to any arch.
>>>
>>> I fix it by adding the another kernel image condition in vmalloc_to_page
>>> to make it keep the accordance with previous vmalloc mapping.
>>>
>>> Fixes: f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
>>> Reported-by: tan xiaojun <tanxiaojun@huawei.com>
>>> Signed-off-by: zhongjiang <zhongjiang@huawei.com>
>>> ---
>>>  arch/arm64/mm/mmu.c     |  2 +-
>>>  include/linux/vmalloc.h |  1 +
>>>  mm/vmalloc.c            | 35 ++++++++++++++++++++++++++++-------
>>>  3 files changed, 30 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>>> index 0c429ec..2265c39 100644
>>> --- a/arch/arm64/mm/mmu.c
>>> +++ b/arch/arm64/mm/mmu.c
>>> @@ -509,7 +509,7 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
>>>  	vma->addr	= va_start;
>>>  	vma->phys_addr	= pa_start;
>>>  	vma->size	= size;
>>> -	vma->flags	= VM_MAP;
>>> +	vma->flags	= VM_KERNEL;
>>>  	vma->caller	= __builtin_return_address(0);
>>>  
>>>  	vm_area_add_early(vma);
>>> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
>>> index 0328ce0..c9245af 100644
>>> --- a/include/linux/vmalloc.h
>>> +++ b/include/linux/vmalloc.h
>>> @@ -17,6 +17,7 @@
>>>  #define VM_ALLOC		0x00000002	/* vmalloc() */
>>>  #define VM_MAP			0x00000004	/* vmap()ed pages */
>>>  #define VM_USERMAP		0x00000008	/* suitable for remap_vmalloc_range */
>>> +#define VM_KERNEL		0x00000010	/* kernel pages */>>  #define VM_UNINITIALIZED	0x00000020	/* vm_struct is not fully initialized */
>>>  #define VM_NO_GUARD		0x00000040      /* don't add guard page */
>>>  #define VM_KASAN		0x00000080      /* has allocated kasan shadow memory */
>>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>>> index 1dda6d8..601d940 100644
>>> --- a/mm/vmalloc.c
>>> +++ b/mm/vmalloc.c
>>> @@ -1967,11 +1967,28 @@ void *vmalloc_32_user(unsigned long size)
>>>  EXPORT_SYMBOL(vmalloc_32_user);
>>>  
>>>  /*
>>> + * kernel image overlap with the valloc area in arm64,it
>>> + * will make the huge talbe page existence, if we walk the
>>> + * all page talbe, it may be result in the panic.
>>> + */
> I don't think we really need this comment. If you really want something here:
>
> /*
>  * VM_KERNEL indicates an address is mapped linearly. The linear mapping may
>  * use larger pages which vmalloc_to_page cannot handle.
>  */
 looks good. I will take this in next version.
>>> +static inline struct page *aligned_get_page(char *addr, struct vm_struct *vm)
>>> +{
>>> +	struct page *p = NULL;
>>> +
>>> +	if (vm->flags & VM_KERNEL)
>>> +		p = virt_to_page(lm_alias(addr));
>>> +	else
>>> +		p = vmalloc_to_page(addr);
>>> +
>>> +	return p;
>>> +}
>>> +
>>> +/*
>>>   * small helper routine , copy contents to buf from addr.
>>>   * If the page is not present, fill zero.
>>>   */
>>> -
>>> -static int aligned_vread(char *buf, char *addr, unsigned long count)
>>> +static int aligned_vread(char *buf, char *addr, unsigned long count,
>>> +					struct vm_struct *vm)
>>>  {
>>>  	struct page *p;
>>>  	int copied = 0;
>>> @@ -1983,7 +2000,7 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>>>  		length = PAGE_SIZE - offset;
>>>  		if (length > count)
>>>  			length = count;
>>> -		p = vmalloc_to_page(addr);
>>> +		p = aligned_get_page(addr, vm);
>>>  		/*
>>>  		 * To do safe access to this _mapped_ area, we need
>>>  		 * lock. But adding lock here means that we need to add
>>> @@ -2010,7 +2027,8 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
>>>  	return copied;
>>>  }
>>>  
>>> -static int aligned_vwrite(char *buf, char *addr, unsigned long count)
>>> +static int aligned_vwrite(char *buf, char *addr, unsigned long count,
>>> +					struct vm_struct *vm)
>>>  {
>>>  	struct page *p;
>>>  	int copied = 0;
>>> @@ -2022,7 +2040,7 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
>>>  		length = PAGE_SIZE - offset;
>>>  		if (length > count)
>>>  			length = count;
>>> -		p = vmalloc_to_page(addr);
>>> +		p = aligned_get_page(addr, vm);
>>>  		/*
>>>  		 * To do safe access to this _mapped_ area, we need
>>>  		 * lock. But adding lock here means that we need to add
>>> @@ -2109,7 +2127,7 @@ long vread(char *buf, char *addr, unsigned long count)
>>>  		if (n > count)
>>>  			n = count;
>>>  		if (!(vm->flags & VM_IOREMAP))
>>> -			aligned_vread(buf, addr, n);
>>> +			aligned_vread(buf, addr, n, vm);
>>>  		else /* IOREMAP area is treated as memory hole */
>>>  			memset(buf, 0, n);
>>>  		buf += n;
>>> @@ -2190,7 +2208,7 @@ long vwrite(char *buf, char *addr, unsigned long count)
>>>  		if (n > count)
>>>  			n = count;
>>>  		if (!(vm->flags & VM_IOREMAP)) {
>>> -			aligned_vwrite(buf, addr, n);
>>> +			aligned_vwrite(buf, addr, n, vm);
>>>  			copied++;
>>>  		}
>>>  		buf += n;
>>> @@ -2710,6 +2728,9 @@ static int s_show(struct seq_file *m, void *p)
>>>  	if (v->flags & VM_USERMAP)
>>>  		seq_puts(m, " user");
>>>  
>>> +	if (v->flags & VM_KERNEL)
>>> +		seq_puts(m, " kernel");
>>> +
>>>  	if (is_vmalloc_addr(v->pages))
>>>  		seq_puts(m, " vpages");
>>>  
> Marking the range as being kernel pages is certainly an improvement although
> I still have mixed feelings about is_vmalloc_addr returning true for a
> region where vmalloc_to_page will not return the correct address. I also
> don't have a better idea other than complicating is_vmalloc_addr so FWIW
 yes, it is unfortunate. but we still need to handle this.
> Reviewed-by: Laura Abbott <labbott@redhat.com>
 Thank a lot.

 Thanks
 zhongjiang
> Thanks,
> Laura
>
> .
>


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v5 19/32] x86/mm: Add support to access persistent memory in the clear
From: Borislav Petkov @ 2017-05-16 14:04 UTC (permalink / raw)
  To: Tom Lendacky
  Cc: linux-arch, linux-efi, kvm, linux-doc, x86, kexec, linux-kernel,
	kasan-dev, linux-mm, iommu, Rik van Riel,
	Radim Krčmář, Toshimitsu Kani, Arnd Bergmann,
	Jonathan Corbet, Matt Fleming, Michael S. Tsirkin, Joerg Roedel,
	Konrad Rzeszutek Wilk, Paolo Bonzini, Larry Woodman,
	Brijesh Singh, Ingo Molnar, Andy Lutomirski, H. Peter Anvin,
	Andrey Ryabinin, Alexander Potapenko, Dave Young, Thomas Gleixner,
	Dmitry Vyukov
In-Reply-To: <20170418211941.10190.19751.stgit@tlendack-t1.amdoffice.net>

On Tue, Apr 18, 2017 at 04:19:42PM -0500, Tom Lendacky wrote:
> Persistent memory is expected to persist across reboots. The encryption
> key used by SME will change across reboots which will result in corrupted
> persistent memory.  Persistent memory is handed out by block devices
> through memory remapping functions, so be sure not to map this memory as
> encrypted.
> 
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>  arch/x86/mm/ioremap.c |   31 ++++++++++++++++++++++++++++++-
>  1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index bce0604..55317ba 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -425,17 +425,46 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
>   * Examine the physical address to determine if it is an area of memory
>   * that should be mapped decrypted.  If the memory is not part of the
>   * kernel usable area it was accessed and created decrypted, so these
> - * areas should be mapped decrypted.
> + * areas should be mapped decrypted. And since the encryption key can
> + * change across reboots, persistent memory should also be mapped
> + * decrypted.
>   */
>  static bool memremap_should_map_decrypted(resource_size_t phys_addr,
>  					  unsigned long size)
>  {
> +	int is_pmem;
> +
> +	/*
> +	 * Check if the address is part of a persistent memory region.
> +	 * This check covers areas added by E820, EFI and ACPI.
> +	 */
> +	is_pmem = region_intersects(phys_addr, size, IORESOURCE_MEM,
> +				    IORES_DESC_PERSISTENT_MEMORY);
> +	if (is_pmem != REGION_DISJOINT)
> +		return true;
> +
> +	/*
> +	 * Check if the non-volatile attribute is set for an EFI
> +	 * reserved area.
> +	 */
> +	if (efi_enabled(EFI_BOOT)) {
> +		switch (efi_mem_type(phys_addr)) {
> +		case EFI_RESERVED_TYPE:
> +			if (efi_mem_attributes(phys_addr) & EFI_MEMORY_NV)
> +				return true;
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
>  	/* Check if the address is outside kernel usable area */
>  	switch (e820__get_entry_type(phys_addr, phys_addr + size - 1)) {
>  	case E820_TYPE_RESERVED:
>  	case E820_TYPE_ACPI:
>  	case E820_TYPE_NVS:
>  	case E820_TYPE_UNUSABLE:
> +	case E820_TYPE_PRAM:

Can't you simply add:

	case E820_TYPE_PMEM:

here too and thus get rid of the region_intersects() thing above?

Because, for example, e820_type_to_iores_desc() maps E820_TYPE_PMEM to
IORES_DESC_PERSISTENT_MEMORY so those should be equivalent...

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [patch 2/2] MM: allow per-cpu vmstat_threshold and vmstat_worker configuration
From: Christoph Lameter @ 2017-05-16 13:37 UTC (permalink / raw)
  To: Marcelo Tosatti
  Cc: Luiz Capitulino, linux-kernel, linux-mm, Rik van Riel,
	Linux RT Users, cmetcalf
In-Reply-To: <20170515191531.GA31483@amt.cnet>

On Mon, 15 May 2017, Marcelo Tosatti wrote:

> > NOHZ already does that. I wanted to know what your problem is that you
> > see. The latency issue has already been solved as far as I can tell .
> > Please tell me why the existing solutions are not sufficient for you.
>
> We don't want vmstat_worker to execute on a given CPU, even if the local
> CPU updates vm-statistics.

Instead of responding you repeat describing what you want.

> Because:
>
>     vmstat_worker increases latency of the application
>        (i can measure it if you want on a given CPU,
>         how many ns's the following takes:

That still is no use case. Just a measurement of vmstat_worker. Pointless.

If you move the latency from the vmstat worker into the code thats
updating the counters then you will require increased use of atomics
which will increase contention which in turn will significantly
increase the overall latency.

> Why the existing solutions are not sufficient:
>
> 1) task-isolation patchset seems too heavy for our usecase (we do
> want IPIs, signals, etc).

Ok then minor delays from remote random events are tolerable?
Then you can also have a vmstat update.

> So this seems a little heavy for our usecase.

Sorry all of this does not make sense to me. Maybe get some numbers of of
an app with intensive OS access running with atomics vs vmstat worker?

NOHZ currently disables the vmstat worker when no updates occur. This is
applicable to DPDK and will provide a quiet vmstat worker free environment
if no statistics activity is occurring.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox