Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v3 2/2] powerpc/mm/hugetlb: Add support for 1G huge pages
From: Aneesh Kumar K.V @ 2017-05-18  6:07 UTC (permalink / raw)
  To: Michael Ellerman, akpm, Anshuman Khandual
  Cc: linux-mm, linux-kernel, linuxppc-dev
In-Reply-To: <87fug2loze.fsf@concordia.ellerman.id.au>



On Thursday 18 May 2017 10:51 AM, Michael Ellerman wrote:
> "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
> 
>> POWER9 supports hugepages of size 2M and 1G in radix MMU mode. This patch
>> enables the usage of 1G page size for hugetlbfs. This also update the helper
>> such we can do 1G page allocation at runtime.
>>
>> We still don't enable 1G page size on DD1 version. This is to avoid doing
>> workaround mentioned in commit: 6d3a0379ebdc8 (powerpc/mm: Add
>> radix__tlb_flush_pte_p9_dd1()
>>
>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>> ---
>>   arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
>>   arch/powerpc/mm/hugetlbpage.c                |  7 +++++--
>>   arch/powerpc/platforms/Kconfig.cputype       |  1 +
>>   3 files changed, 16 insertions(+), 2 deletions(-)
> 
> I think this patch is OK, but it's very confusing because it doesn't
> mention that it's only talking about *generic* gigantic page support.


What you mean by generic gigantic page ? what is supported here is the 
gigantic page with size 1G alone ?

> 
> We have existing support for gigantic pages on powerpc, on several
> platforms. This patch appears to break that, but I think doesn't in
> practice?
> 

What is broken ?


> So can you make it a bit clearer in the commit message, and the code,
> that this is only about enabling the generic gigantic page support, and
> is unrelated to the arch-specific gigantic page support.
> 
> cheers
> 
>> diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
>> index 6666cd366596..5c28bd6f2ae1 100644
>> --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
>> +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
>> @@ -50,4 +50,14 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
>>   	else
>>   		return entry;
>>   }
>> +
>> +#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
>> +static inline bool gigantic_page_supported(void)
>> +{
>> +	if (radix_enabled())
>> +		return true;
>> +	return false;
>> +}
>> +#endif
>> +
>>   #endif
>> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
>> index a4f33de4008e..80f6d2ed551a 100644
>> --- a/arch/powerpc/mm/hugetlbpage.c
>> +++ b/arch/powerpc/mm/hugetlbpage.c
>> @@ -763,8 +763,11 @@ static int __init add_huge_page_size(unsigned long long size)
>>   	 * Hash: 16M and 16G
>>   	 */
>>   	if (radix_enabled()) {
>> -		if (mmu_psize != MMU_PAGE_2M)
>> -			return -EINVAL;
>> +		if (mmu_psize != MMU_PAGE_2M) {
>> +			if (cpu_has_feature(CPU_FTR_POWER9_DD1) ||
>> +			    (mmu_psize != MMU_PAGE_1G))
>> +				return -EINVAL;
>> +		}
>>   	} else {
>>   		if (mmu_psize != MMU_PAGE_16M && mmu_psize != MMU_PAGE_16G)
>>   			return -EINVAL;
>> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
>> index 684e886eaae4..b76ef6637016 100644
>> --- a/arch/powerpc/platforms/Kconfig.cputype
>> +++ b/arch/powerpc/platforms/Kconfig.cputype
>> @@ -344,6 +344,7 @@ config PPC_STD_MMU_64
>>   config PPC_RADIX_MMU
>>   	bool "Radix MMU Support"
>>   	depends on PPC_BOOK3S_64
>> +	select ARCH_HAS_GIGANTIC_PAGE if (MEMORY_ISOLATION && COMPACTION) || CMA
>>   	default y
>>   	help
>>   	  Enable support for the Power ISA 3.0 Radix style MMU. Currently this
>> -- 
>> 2.7.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

* Re: [PATCH v6 05/15] lockdep: Implement crossrelease feature
From: Byungchul Park @ 2017-05-18  6:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, tglx, walken, boqun.feng, kirill, linux-kernel, linux-mm,
	iamjoonsoo.kim, akpm, willy, npiggin, kernel-team
In-Reply-To: <20170516141846.GM4626@worktop.programming.kicks-ass.net>

On Tue, May 16, 2017 at 04:18:46PM +0200, Peter Zijlstra wrote:
> 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'.

I really want to implement it with rollback.. But it also needs to
introduce new fields to distinguish between works which are all normal
process contexts.

I will do this with renaming instead of applying rollback.

Thank you.

--
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 v1] mm: drop NULL return check of pte_offset_map_lock()
From: Naoya Horiguchi @ 2017-05-18  6:42 UTC (permalink / raw)
  To: linux-mm
  Cc: Mel Gorman, Johannes Weiner, Andrea Arcangeli, Rik van Riel,
	Andrew Morton, linux-kernel, Naoya Horiguchi

pte_offset_map_lock() finds and takes ptl, and returns pte.
But some callers return without unlocking the ptl when pte == NULL,
which seems weird.

Git history said that !pte check in change_pte_range() was introduced in
commit 1ad9f620c3a2 ("mm: numa: recheck for transhuge pages under lock
during protection changes") and still remains after commit 175ad4f1e7a2
("mm: mprotect: use pmd_trans_unstable instead of taking the pmd_lock")
which partially reverts 1ad9f620c3a2. So I think that it's just dead code.

Many other caller of pte_offset_map_lock() never check NULL return, so
let's do likewise.

Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
---
 mm/memory.c   | 2 --
 mm/mprotect.c | 2 --
 2 files changed, 4 deletions(-)

diff --git v4.11-rc6-mmotm-2017-04-13-14-50/mm/memory.c v4.11-rc6-mmotm-2017-04-13-14-50_patched/mm/memory.c
index 8ae6700..c17fad1d 100644
--- v4.11-rc6-mmotm-2017-04-13-14-50/mm/memory.c
+++ v4.11-rc6-mmotm-2017-04-13-14-50_patched/mm/memory.c
@@ -4040,8 +4040,6 @@ static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address,
 		goto out;
 
 	ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
-	if (!ptep)
-		goto out;
 	if (!pte_present(*ptep))
 		goto unlock;
 	*ptepp = ptep;
diff --git v4.11-rc6-mmotm-2017-04-13-14-50/mm/mprotect.c v4.11-rc6-mmotm-2017-04-13-14-50_patched/mm/mprotect.c
index 8fd010f..d60a1ee 100644
--- v4.11-rc6-mmotm-2017-04-13-14-50/mm/mprotect.c
+++ v4.11-rc6-mmotm-2017-04-13-14-50_patched/mm/mprotect.c
@@ -58,8 +58,6 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 	 * reading.
 	 */
 	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
-	if (!pte)
-		return 0;
 
 	/* Get target node for single threaded private VMAs */
 	if (prot_numa && !(vma->vm_flags & VM_SHARED) &&
-- 
2.7.0

--
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 2/2] dax: Fix race between colliding PMD & PTE entries
From: Jan Kara @ 2017-05-18  7:50 UTC (permalink / raw)
  To: Ross Zwisler
  Cc: Andrew Morton, linux-kernel, Darrick J. Wong, Alexander Viro,
	Christoph Hellwig, Dan Williams, Dave Hansen, Jan Kara,
	Matthew Wilcox, linux-fsdevel, linux-mm, linux-nvdimm,
	Kirill A . Shutemov, Pawel Lebioda, Dave Jiang, Xiong Zhou,
	Eryu Guan, stable
In-Reply-To: <20170517171639.14501-2-ross.zwisler@linux.intel.com>

On Wed 17-05-17 11:16:39, Ross Zwisler wrote:
> We currently have two related PMD vs PTE races in the DAX code.  These can
> both be easily triggered by having two threads reading and writing
> simultaneously to the same private mapping, with the key being that private
> mapping reads can be handled with PMDs but private mapping writes are
> always handled with PTEs so that we can COW.
> 
> Here is the first race:
> 
> CPU 0					CPU 1
> 
> (private mapping write)
> __handle_mm_fault()
>   create_huge_pmd() - FALLBACK
>   handle_pte_fault()
>     passes check for pmd_devmap()
> 
> 					(private mapping read)
> 					__handle_mm_fault()
> 					  create_huge_pmd()
> 					    dax_iomap_pmd_fault() inserts PMD
> 
>     dax_iomap_pte_fault() does a PTE fault, but we already have a DAX PMD
>     			  installed in our page tables at this spot.
>
> 
> Here's the second race:
> 
> CPU 0					CPU 1
> 
> (private mapping write)
> __handle_mm_fault()
>   create_huge_pmd() - FALLBACK
> 					(private mapping read)
> 					__handle_mm_fault()
> 					  passes check for pmd_none()
> 					  create_huge_pmd()
> 
>   handle_pte_fault()
>     dax_iomap_pte_fault() inserts PTE
> 					    dax_iomap_pmd_fault() inserts PMD,
> 					       but we already have a PTE at
> 					       this spot.

So I don't see how this second scenario can happen. dax_iomap_pmd_fault()
will call grab_mapping_entry(). That will either find PTE entry in the
radix tree -> EEXIST and we retry the fault. Or we will not find PTE entry
-> try to insert PMD entry which collides with the PTE entry -> EEXIST and
we retry the fault. Am I missing something?

The first scenario seems to be possible. dax_iomap_pmd_fault() will create
PMD entry in the radix tree. Then dax_iomap_pte_fault() will come, do
grab_mapping_entry(), there it sees entry is PMD but we are doing PTE fault
so I'd think that pmd_downgrade = true... But actually the condition there
doesn't trigger in this case. And that's a catch that although we asked
grab_mapping_entry() for PTE, we've got PMD back and that screws us later.

Actually I'm not convinced your patch quite fixes this because
dax_load_hole() or dax_insert_mapping_entry() will modify the passed entry
with the assumption that it's PTE entry and so they will likely corrupt the
entry in the radix tree.

So I think to fix the first case we should rather modify
grab_mapping_entry() to properly go through the pmd_downgrade path once we
find PMD entry and we do PTE fault.

What do you think?

								Honza


> 
> The core of the issue is that while there is isolation between faults to
> the same range in the DAX fault handlers via our DAX entry locking, there
> is no isolation between faults in the code in mm/memory.c.  This means for
> instance that this code in __handle_mm_fault() can run:
> 
> 	if (pmd_none(*vmf.pmd) && transparent_hugepage_enabled(vma)) {
> 		ret = create_huge_pmd(&vmf);
> 
> But by the time we actually get to run the fault handler called by
> create_huge_pmd(), the PMD is no longer pmd_none() because a racing PTE
> fault has installed a normal PMD here as a parent.  This is the cause of
> the 2nd race.  The first race is similar - there is the following check in
> handle_pte_fault():
> 
> 	} else {
> 		/* See comment in pte_alloc_one_map() */
> 		if (pmd_devmap(*vmf->pmd) || pmd_trans_unstable(vmf->pmd))
> 			return 0;
> 
> So if a pmd_devmap() PMD (a DAX PMD) has been installed at vmf->pmd, we
> will bail and retry the fault.  This is correct, but there is nothing
> preventing the PMD from being installed after this check but before we
> actually get to the DAX PTE fault handlers.
> 
> In my testing these races result in the following types of errors:
> 
>  BUG: Bad rss-counter state mm:ffff8800a817d280 idx:1 val:1
>  BUG: non-zero nr_ptes on freeing mm: 15
> 
> Fix this issue by having the DAX fault handlers verify that it is safe to
> continue their fault after they have taken an entry lock to block other
> racing faults.
> 
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reported-by: Pawel Lebioda <pawel.lebioda@intel.com>
> Cc: stable@vger.kernel.org
> 
> ---
> 
> I've written a new xfstest for this race, which I will send in response to
> this patch series.  This series has also survived an xfstest run without
> any new issues.
> 
> ---
>  fs/dax.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/fs/dax.c b/fs/dax.c
> index c22eaf1..3cc02d1 100644
> --- a/fs/dax.c
> +++ b/fs/dax.c
> @@ -1155,6 +1155,15 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
>  	}
>  
>  	/*
> +	 * It is possible, particularly with mixed reads & writes to private
> +	 * mappings, that we have raced with a PMD fault that overlaps with
> +	 * the PTE we need to set up.  Now that we have a locked mapping entry
> +	 * we can safely unmap the huge PMD so that we can install our PTE in
> +	 * our page tables.
> +	 */
> +	split_huge_pmd(vmf->vma, vmf->pmd, vmf->address);
> +
> +	/*
>  	 * Note that we don't bother to use iomap_apply here: DAX required
>  	 * the file system block size to be equal the page size, which means
>  	 * that we never have to deal with more than a single extent here.
> @@ -1398,6 +1407,15 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf,
>  		goto fallback;
>  
>  	/*
> +	 * It is possible, particularly with mixed reads & writes to private
> +	 * mappings, that we have raced with a PTE fault that overlaps with
> +	 * the PMD we need to set up.  If so we just fall back to a PTE fault
> +	 * ourselves.
> +	 */
> +	if (!pmd_none(*vmf->pmd))
> +		goto unlock_entry;
> +
> +	/*
>  	 * Note that we don't use iomap_apply here.  We aren't doing I/O, only
>  	 * setting up a mapping, so really we're using iomap_begin() as a way
>  	 * to look up our filesystem block.
> -- 
> 2.9.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
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,oom: fix oom invocation issues
From: Michal Hocko @ 2017-05-18  8:01 UTC (permalink / raw)
  To: Roman Gushchin
  Cc: Tetsuo Handa, Johannes Weiner, Vladimir Davydov, kernel-team,
	linux-mm, linux-kernel
In-Reply-To: <20170517194316.GA30517@castle>

On Wed 17-05-17 20:43:16, Roman Gushchin wrote:
> On Wed, May 17, 2017 at 06:14:46PM +0200, Michal Hocko wrote:
> > On Wed 17-05-17 16:26:20, Roman Gushchin wrote:
[...]
> > > After some investigations I've found some issues:
> > > 
> > > 1) Prior to commit 1af8bb432695 ("mm, oom: fortify task_will_free_mem()"),
> > >    if a process with a pending SIGKILL was calling out_of_memory(),
> > >    it was always immediately selected as a victim.
> > 
> > Yes but this had its own issues. Mainly picking the same victim again
> > without making a further progress.
> 
> That is why I've added this check into the pagefault_out_of_memory(),
> rather than out_of_memory(), where it was earlier.

As I've said in my previous email, this alone makes some sense but I do
not think it is a bug fix but rather a short cut that should be safe to
do because we should check fatal signals on the way out of the #PF.

> > >    But now, after some changes, it's not always a case.
> > >    If a process has been reaped at the moment, MMF_SKIP_FLAG is set,
> > >    task_will_free_mem() will return false, and a new
> > >    victim selection logic will be started.
> > 
> > right. The point is that it doesn't make any sense to consider such a
> > task because it either cannot be reaped or it has been reaped and there
> > is not much left to consider. It would be interesting to see what
> > happened in your case.
> > 
> > >    This actually happens if a userspace pagefault causing an OOM.
> > >    pagefault_out_of_memory() is called in a context of a faulting
> > >    process after it has been selected as OOM victim (assuming, it
> > >    has), and killed. With some probability (there is a race with
> > >    oom_reaper thread) this process will be passed to the oom reaper
> > >    again, or an innocent victim will be selected and killed.
> > > 
> > > 2) We clear up the task->oom_reaper_list before setting
> > >    the MMF_OOM_SKIP flag, so there is a race.
> > 
> > I am not sure what you mean here. Why would a race matter?
> 
> oom_reaper_list pointer is zeroed before MMF_OOM_SKIP flag is set.
> Inbetween this process can be selected again and added to the
> oom reaper queue. It's not a big issue, still.

I still do not see why it would matter. Even if we queue this task again
then oom_lock would prevent from parallel reaping and even if we do not
race then it is not so harmfull to crawl over all mappings just to find
out that nothing is left to be reaped.

[...]
> > > 2) Set the MMF_OOM_SKIP bit in wake_oom_reaper() before adding a
> > >    process to the oom_reaper list. If it's already set, do nothing.
> > >    Do not rely on tsk->oom_reaper_list value.
> > 
> > This is wrong. The sole purpose of MMF_OOM_SKIP is to let the oom
> > selection logic know that this task is not interesting anymore. Setting
> > it in wake_oom_reaper means it would be set _before_ the oom_reaper had
> > any chance to free any memory from the task. So we would
> 
> But if have selected a task once, it has no way back.
> Anyway it will be reaped or will quit by itself soon. Right?

yes and we have to wait for one or the other...

> So, under no circumstances we should consider choosing them
> as an OOM victim again.

and that is exactly what we do right now. We just postpone a new task
selection. Put simply we just wait while there is a pending oom victim
and MMF_OOM_SKIP is a way to skip such a pending victim if we believe
there is no much hope to release some memory anymore.

> There are no reasons to calculate it's badness again, etc.

Yes that is true but oom_badness has to consider MMF_OOM_SKIP anyway
(mainly because it is called from more places).
 
> > > 3) Check the MMF_OOM_SKIP even if OOM is triggered by a sysrq.
> > 
> > The code is a bit messy here but we do check MMF_OOM_SKIP in that case.
> > We just do it in oom_badness(). So this is not needed, strictly
> > speaking.
> > 
> > That being said I would like to here more about the cause of the OOM and
> > the full dmesg would be interesting. The proposed setting of
> > MMF_OOM_SKIP before the task is reaped is a nogo, though.
> 
> If so, how you will prevent putting a process again into the reaper list,
> if it's already reaped?

We simply do not care all that much as already said.
 
> > 1) would be
> > acceptable I think but I would have to think about it some more.
> 
> Actually, the first problem is much more serious, as it leads
> to a killing of second process.

That sounds like a bug to me. I will investigate further.
 
> The second one can lead only to a unnecessary wake up of
> the oom reaper thread, which is not great, but acceptable.

yes.
-- 
Michal Hocko
SUSE Labs

--
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 -v2] drm: drop drm_[cm]alloc* helpers
From: Christian König @ 2017-05-18  8:16 UTC (permalink / raw)
  To: Michal Hocko, dri-devel; +Cc: linux-kernel, linux-mm, Daniel Vetter
In-Reply-To: <20170517122312.GK18247@dhcp22.suse.cz>

Am 17.05.2017 um 14:23 schrieb Michal Hocko:
> As it turned out my allyesconfig on x86_64 wasn't sufficient and 0day
> build machinery found a failure on arm architecture. It was clearly a
> typo. Now I have pushed this to my build battery with cross arch
> compilers and it passes so there shouldn't more surprises hopefully.
> Here is the v2.
> ---
>  From 4a00b3ade5ca4514f7affd8de6f7119c8d5c5a86 Mon Sep 17 00:00:00 2001
> From: Michal Hocko <mhocko@suse.com>
> Date: Tue, 16 May 2017 11:00:47 +0200
> Subject: [PATCH -v2] drm: drop drm_[cm]alloc* helpers
>
> Now that drm_[cm]alloc* helpers are simple one line wrappers around
> kvmalloc_array and drm_free_large is just kvfree alias we can drop
> them and replace by their native forms.
>
> This shouldn't introduce any functional change.
>
> Changes since v1
> - fix typo in drivers/gpu//drm/etnaviv/etnaviv_gem.c - noticed by 0day
>    build robot
>
> Suggested-by: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Michal Hocko <mhocko@suse.com>

Acked-by: Christian KA?nig <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c        | 16 +++----
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             | 19 ++++----
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |  7 +--
>   drivers/gpu/drm/drm_gem.c                          |  6 +--
>   drivers/gpu/drm/etnaviv/etnaviv_gem.c              | 12 ++---
>   drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c        |  4 +-
>   drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c       | 12 ++---
>   drivers/gpu/drm/exynos/exynos_drm_gem.c            | 11 +++--
>   drivers/gpu/drm/i915/i915_debugfs.c                |  4 +-
>   drivers/gpu/drm/i915/i915_gem.c                    |  4 +-
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c         | 34 +++++++-------
>   drivers/gpu/drm/i915/i915_gem_gtt.c                |  6 +--
>   drivers/gpu/drm/i915/i915_gem_userptr.c            |  8 ++--
>   drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c | 12 ++---
>   drivers/gpu/drm/msm/msm_gem.c                      | 10 ++--
>   drivers/gpu/drm/radeon/radeon_cs.c                 | 11 +++--
>   drivers/gpu/drm/radeon/radeon_gem.c                |  2 +-
>   drivers/gpu/drm/radeon/radeon_ring.c               |  4 +-
>   drivers/gpu/drm/radeon/radeon_vm.c                 |  4 +-
>   drivers/gpu/drm/ttm/ttm_tt.c                       | 13 +++---
>   drivers/gpu/drm/udl/udl_dmabuf.c                   |  2 +-
>   drivers/gpu/drm/udl/udl_gem.c                      |  2 +-
>   drivers/gpu/drm/vc4/vc4_gem.c                      | 15 +++---
>   drivers/gpu/drm/virtio/virtgpu_ioctl.c             | 27 +++++------
>   include/drm/drmP.h                                 |  1 -
>   include/drm/drm_mem_util.h                         | 53 ----------------------
>   26 files changed, 126 insertions(+), 173 deletions(-)
>   delete mode 100644 include/drm/drm_mem_util.h
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> index a6649874e6ce..9f0247cdda5e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
> @@ -96,7 +96,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>   	int r;
>   	unsigned long total_size = 0;
>   
> -	array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry));
> +	array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
>   	if (!array)
>   		return -ENOMEM;
>   	memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
> @@ -148,7 +148,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>   	for (i = 0; i < list->num_entries; ++i)
>   		amdgpu_bo_unref(&list->array[i].robj);
>   
> -	drm_free_large(list->array);
> +	kvfree(list->array);
>   
>   	list->gds_obj = gds_obj;
>   	list->gws_obj = gws_obj;
> @@ -163,7 +163,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
>   error_free:
>   	while (i--)
>   		amdgpu_bo_unref(&array[i].robj);
> -	drm_free_large(array);
> +	kvfree(array);
>   	return r;
>   }
>   
> @@ -224,7 +224,7 @@ void amdgpu_bo_list_free(struct amdgpu_bo_list *list)
>   		amdgpu_bo_unref(&list->array[i].robj);
>   
>   	mutex_destroy(&list->lock);
> -	drm_free_large(list->array);
> +	kvfree(list->array);
>   	kfree(list);
>   }
>   
> @@ -244,8 +244,8 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
>   
>   	int r;
>   
> -	info = drm_malloc_ab(args->in.bo_number,
> -			     sizeof(struct drm_amdgpu_bo_list_entry));
> +	info = kvmalloc_array(args->in.bo_number,
> +			     sizeof(struct drm_amdgpu_bo_list_entry), GFP_KERNEL);
>   	if (!info)
>   		return -ENOMEM;
>   
> @@ -311,11 +311,11 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
>   
>   	memset(args, 0, sizeof(*args));
>   	args->out.list_handle = handle;
> -	drm_free_large(info);
> +	kvfree(info);
>   
>   	return 0;
>   
>   error_free:
> -	drm_free_large(info);
> +	kvfree(info);
>   	return r;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index 4e6b9501ab0a..5b3e0f63a115 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -194,7 +194,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
>   		size = p->chunks[i].length_dw;
>   		cdata = (void __user *)(uintptr_t)user_chunk.chunk_data;
>   
> -		p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
> +		p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
>   		if (p->chunks[i].kdata == NULL) {
>   			ret = -ENOMEM;
>   			i--;
> @@ -247,7 +247,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
>   	i = p->nchunks - 1;
>   free_partial_kdata:
>   	for (; i >= 0; i--)
> -		drm_free_large(p->chunks[i].kdata);
> +		kvfree(p->chunks[i].kdata);
>   	kfree(p->chunks);
>   	p->chunks = NULL;
>   	p->nchunks = 0;
> @@ -505,7 +505,7 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
>   			return r;
>   
>   		if (binding_userptr) {
> -			drm_free_large(lobj->user_pages);
> +			kvfree(lobj->user_pages);
>   			lobj->user_pages = NULL;
>   		}
>   	}
> @@ -571,7 +571,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
>   				release_pages(e->user_pages,
>   					      e->robj->tbo.ttm->num_pages,
>   					      false);
> -				drm_free_large(e->user_pages);
> +				kvfree(e->user_pages);
>   				e->user_pages = NULL;
>   			}
>   
> @@ -601,8 +601,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
>   		list_for_each_entry(e, &need_pages, tv.head) {
>   			struct ttm_tt *ttm = e->robj->tbo.ttm;
>   
> -			e->user_pages = drm_calloc_large(ttm->num_pages,
> -							 sizeof(struct page*));
> +			e->user_pages = kvmalloc_array(ttm->num_pages,
> +							 sizeof(struct page*),
> +							 GFP_KERNEL | __GFP_ZERO);
>   			if (!e->user_pages) {
>   				r = -ENOMEM;
>   				DRM_ERROR("calloc failure in %s\n", __func__);
> @@ -612,7 +613,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
>   			r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages);
>   			if (r) {
>   				DRM_ERROR("amdgpu_ttm_tt_get_user_pages failed.\n");
> -				drm_free_large(e->user_pages);
> +				kvfree(e->user_pages);
>   				e->user_pages = NULL;
>   				goto error_free_pages;
>   			}
> @@ -708,7 +709,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
>   			release_pages(e->user_pages,
>   				      e->robj->tbo.ttm->num_pages,
>   				      false);
> -			drm_free_large(e->user_pages);
> +			kvfree(e->user_pages);
>   		}
>   	}
>   
> @@ -761,7 +762,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
>   		amdgpu_bo_list_put(parser->bo_list);
>   
>   	for (i = 0; i < parser->nchunks; i++)
> -		drm_free_large(parser->chunks[i].kdata);
> +		kvfree(parser->chunks[i].kdata);
>   	kfree(parser->chunks);
>   	if (parser->job)
>   		amdgpu_job_free(parser->job);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 07ff3b1514f1..749a6cde7985 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -279,8 +279,9 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
>   	if (!parent->entries) {
>   		unsigned num_entries = amdgpu_vm_num_entries(adev, level);
>   
> -		parent->entries = drm_calloc_large(num_entries,
> -						   sizeof(struct amdgpu_vm_pt));
> +		parent->entries = kvmalloc_array(num_entries,
> +						   sizeof(struct amdgpu_vm_pt),
> +						   GFP_KERNEL | __GFP_ZERO);
>   		if (!parent->entries)
>   			return -ENOMEM;
>   		memset(parent->entries, 0 , sizeof(struct amdgpu_vm_pt));
> @@ -2198,7 +2199,7 @@ static void amdgpu_vm_free_levels(struct amdgpu_vm_pt *level)
>   		for (i = 0; i <= level->last_entry_used; i++)
>   			amdgpu_vm_free_levels(&level->entries[i]);
>   
> -	drm_free_large(level->entries);
> +	kvfree(level->entries);
>   }
>   
>   /**
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index b1e28c944637..8dc11064253d 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -521,7 +521,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj)
>   
>   	npages = obj->size >> PAGE_SHIFT;
>   
> -	pages = drm_malloc_ab(npages, sizeof(struct page *));
> +	pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (pages == NULL)
>   		return ERR_PTR(-ENOMEM);
>   
> @@ -546,7 +546,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj)
>   	while (i--)
>   		put_page(pages[i]);
>   
> -	drm_free_large(pages);
> +	kvfree(pages);
>   	return ERR_CAST(p);
>   }
>   EXPORT_SYMBOL(drm_gem_get_pages);
> @@ -582,7 +582,7 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
>   		put_page(pages[i]);
>   	}
>   
> -	drm_free_large(pages);
> +	kvfree(pages);
>   }
>   EXPORT_SYMBOL(drm_gem_put_pages);
>   
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
> index fd56f92f3469..d6fb724fc3cc 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
> @@ -748,7 +748,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages(
>   	uintptr_t ptr;
>   	unsigned int flags = 0;
>   
> -	pvec = drm_malloc_ab(npages, sizeof(struct page *));
> +	pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (!pvec)
>   		return ERR_PTR(-ENOMEM);
>   
> @@ -772,7 +772,7 @@ static struct page **etnaviv_gem_userptr_do_get_pages(
>   
>   	if (ret < 0) {
>   		release_pages(pvec, pinned, 0);
> -		drm_free_large(pvec);
> +		kvfree(pvec);
>   		return ERR_PTR(ret);
>   	}
>   
> @@ -823,7 +823,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
>   	mm = get_task_mm(etnaviv_obj->userptr.task);
>   	pinned = 0;
>   	if (mm == current->mm) {
> -		pvec = drm_malloc_ab(npages, sizeof(struct page *));
> +		pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   		if (!pvec) {
>   			mmput(mm);
>   			return -ENOMEM;
> @@ -832,7 +832,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
>   		pinned = __get_user_pages_fast(etnaviv_obj->userptr.ptr, npages,
>   					       !etnaviv_obj->userptr.ro, pvec);
>   		if (pinned < 0) {
> -			drm_free_large(pvec);
> +			kvfree(pvec);
>   			mmput(mm);
>   			return pinned;
>   		}
> @@ -845,7 +845,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
>   	}
>   
>   	release_pages(pvec, pinned, 0);
> -	drm_free_large(pvec);
> +	kvfree(pvec);
>   
>   	work = kmalloc(sizeof(*work), GFP_KERNEL);
>   	if (!work) {
> @@ -879,7 +879,7 @@ static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj)
>   		int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
>   
>   		release_pages(etnaviv_obj->pages, npages, 0);
> -		drm_free_large(etnaviv_obj->pages);
> +		kvfree(etnaviv_obj->pages);
>   	}
>   	put_task_struct(etnaviv_obj->userptr.task);
>   }
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> index abed6f781281..e5da4f2300ba 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
> @@ -87,7 +87,7 @@ static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj)
>   	 * ours, just free the array we allocated:
>   	 */
>   	if (etnaviv_obj->pages)
> -		drm_free_large(etnaviv_obj->pages);
> +		kvfree(etnaviv_obj->pages);
>   
>   	drm_prime_gem_destroy(&etnaviv_obj->base, etnaviv_obj->sgt);
>   }
> @@ -128,7 +128,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
>   	npages = size / PAGE_SIZE;
>   
>   	etnaviv_obj->sgt = sgt;
> -	etnaviv_obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
> +	etnaviv_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (!etnaviv_obj->pages) {
>   		ret = -ENOMEM;
>   		goto fail;
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> index de80ee1b71df..ee7069e93eda 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
> @@ -345,9 +345,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
>   	 * Copy the command submission and bo array to kernel space in
>   	 * one go, and do this outside of any locks.
>   	 */
> -	bos = drm_malloc_ab(args->nr_bos, sizeof(*bos));
> -	relocs = drm_malloc_ab(args->nr_relocs, sizeof(*relocs));
> -	stream = drm_malloc_ab(1, args->stream_size);
> +	bos = kvmalloc_array(args->nr_bos, sizeof(*bos), GFP_KERNEL);
> +	relocs = kvmalloc_array(args->nr_relocs, sizeof(*relocs), GFP_KERNEL);
> +	stream = kvmalloc_array(1, args->stream_size, GFP_KERNEL);
>   	cmdbuf = etnaviv_cmdbuf_new(gpu->cmdbuf_suballoc,
>   				    ALIGN(args->stream_size, 8) + 8,
>   				    args->nr_bos);
> @@ -489,11 +489,11 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
>   	if (cmdbuf)
>   		etnaviv_cmdbuf_free(cmdbuf);
>   	if (stream)
> -		drm_free_large(stream);
> +		kvfree(stream);
>   	if (bos)
> -		drm_free_large(bos);
> +		kvfree(bos);
>   	if (relocs)
> -		drm_free_large(relocs);
> +		kvfree(relocs);
>   
>   	return ret;
>   }
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> index 55a1579d11b3..c23479be4850 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
> @@ -59,7 +59,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>   
>   	nr_pages = exynos_gem->size >> PAGE_SHIFT;
>   
> -	exynos_gem->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
> +	exynos_gem->pages = kvmalloc_array(nr_pages, sizeof(struct page *),
> +			GFP_KERNEL | __GFP_ZERO);
>   	if (!exynos_gem->pages) {
>   		DRM_ERROR("failed to allocate pages.\n");
>   		return -ENOMEM;
> @@ -101,7 +102,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
>   	dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie,
>   		       exynos_gem->dma_addr, exynos_gem->dma_attrs);
>   err_free:
> -	drm_free_large(exynos_gem->pages);
> +	kvfree(exynos_gem->pages);
>   
>   	return ret;
>   }
> @@ -122,7 +123,7 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem)
>   			(dma_addr_t)exynos_gem->dma_addr,
>   			exynos_gem->dma_attrs);
>   
> -	drm_free_large(exynos_gem->pages);
> +	kvfree(exynos_gem->pages);
>   }
>   
>   static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
> @@ -559,7 +560,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
>   	exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
>   
>   	npages = exynos_gem->size >> PAGE_SHIFT;
> -	exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
> +	exynos_gem->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (!exynos_gem->pages) {
>   		ret = -ENOMEM;
>   		goto err;
> @@ -588,7 +589,7 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
>   	return &exynos_gem->base;
>   
>   err_free_large:
> -	drm_free_large(exynos_gem->pages);
> +	kvfree(exynos_gem->pages);
>   err:
>   	drm_gem_object_release(&exynos_gem->base);
>   	kfree(exynos_gem);
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index bd9abef40c66..c8f3c0cc79fb 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -229,7 +229,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
>   	int ret;
>   
>   	total = READ_ONCE(dev_priv->mm.object_count);
> -	objects = drm_malloc_ab(total, sizeof(*objects));
> +	objects = kvmalloc_array(total, sizeof(*objects), GFP_KERNEL);
>   	if (!objects)
>   		return -ENOMEM;
>   
> @@ -274,7 +274,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
>   
>   	mutex_unlock(&dev->struct_mutex);
>   out:
> -	drm_free_large(objects);
> +	kvfree(objects);
>   	return ret;
>   }
>   
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 0c1cbe98c994..aa790a6d38e2 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2556,7 +2556,7 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
>   
>   	if (n_pages > ARRAY_SIZE(stack_pages)) {
>   		/* Too big for stack -- allocate temporary array instead */
> -		pages = drm_malloc_gfp(n_pages, sizeof(*pages), GFP_TEMPORARY);
> +		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_TEMPORARY);
>   		if (!pages)
>   			return NULL;
>   	}
> @@ -2578,7 +2578,7 @@ static void *i915_gem_object_map(const struct drm_i915_gem_object *obj,
>   	addr = vmap(pages, n_pages, 0, pgprot);
>   
>   	if (pages != stack_pages)
> -		drm_free_large(pages);
> +		kvfree(pages);
>   
>   	return addr;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index af1965774e7b..04211c970b9f 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1019,11 +1019,11 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
>   	for (i = 0; i < count; i++)
>   		total += exec[i].relocation_count;
>   
> -	reloc_offset = drm_malloc_ab(count, sizeof(*reloc_offset));
> -	reloc = drm_malloc_ab(total, sizeof(*reloc));
> +	reloc_offset = kvmalloc_array(count, sizeof(*reloc_offset), GFP_KERNEL);
> +	reloc = kvmalloc_array(total, sizeof(*reloc), GFP_KERNEL);
>   	if (reloc == NULL || reloc_offset == NULL) {
> -		drm_free_large(reloc);
> -		drm_free_large(reloc_offset);
> +		kvfree(reloc);
> +		kvfree(reloc_offset);
>   		mutex_lock(&dev->struct_mutex);
>   		return -ENOMEM;
>   	}
> @@ -1099,8 +1099,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
>   	 */
>   
>   err:
> -	drm_free_large(reloc);
> -	drm_free_large(reloc_offset);
> +	kvfree(reloc);
> +	kvfree(reloc_offset);
>   	return ret;
>   }
>   
> @@ -1871,13 +1871,13 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
>   	}
>   
>   	/* Copy in the exec list from userland */
> -	exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count);
> -	exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count);
> +	exec_list = kvmalloc_array(sizeof(*exec_list), args->buffer_count, GFP_KERNEL);
> +	exec2_list = kvmalloc_array(sizeof(*exec2_list), args->buffer_count, GFP_KERNEL);
>   	if (exec_list == NULL || exec2_list == NULL) {
>   		DRM_DEBUG("Failed to allocate exec list for %d buffers\n",
>   			  args->buffer_count);
> -		drm_free_large(exec_list);
> -		drm_free_large(exec2_list);
> +		kvfree(exec_list);
> +		kvfree(exec2_list);
>   		return -ENOMEM;
>   	}
>   	ret = copy_from_user(exec_list,
> @@ -1886,8 +1886,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
>   	if (ret != 0) {
>   		DRM_DEBUG("copy %d exec entries failed %d\n",
>   			  args->buffer_count, ret);
> -		drm_free_large(exec_list);
> -		drm_free_large(exec2_list);
> +		kvfree(exec_list);
> +		kvfree(exec2_list);
>   		return -EFAULT;
>   	}
>   
> @@ -1936,8 +1936,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
>   		}
>   	}
>   
> -	drm_free_large(exec_list);
> -	drm_free_large(exec2_list);
> +	kvfree(exec_list);
> +	kvfree(exec2_list);
>   	return ret;
>   }
>   
> @@ -1955,7 +1955,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
>   		return -EINVAL;
>   	}
>   
> -	exec2_list = drm_malloc_gfp(args->buffer_count,
> +	exec2_list = kvmalloc_array(args->buffer_count,
>   				    sizeof(*exec2_list),
>   				    GFP_TEMPORARY);
>   	if (exec2_list == NULL) {
> @@ -1969,7 +1969,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
>   	if (ret != 0) {
>   		DRM_DEBUG("copy %d exec entries failed %d\n",
>   			  args->buffer_count, ret);
> -		drm_free_large(exec2_list);
> +		kvfree(exec2_list);
>   		return -EFAULT;
>   	}
>   
> @@ -1996,6 +1996,6 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
>   		}
>   	}
>   
> -	drm_free_large(exec2_list);
> +	kvfree(exec2_list);
>   	return ret;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index bc3c63e92c16..899427863547 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3114,7 +3114,7 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>   	int ret = -ENOMEM;
>   
>   	/* Allocate a temporary list of source pages for random access. */
> -	page_addr_list = drm_malloc_gfp(n_pages,
> +	page_addr_list = kvmalloc_array(n_pages,
>   					sizeof(dma_addr_t),
>   					GFP_TEMPORARY);
>   	if (!page_addr_list)
> @@ -3147,14 +3147,14 @@ intel_rotate_pages(struct intel_rotation_info *rot_info,
>   	DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages)\n",
>   		      obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size);
>   
> -	drm_free_large(page_addr_list);
> +	kvfree(page_addr_list);
>   
>   	return st;
>   
>   err_sg_alloc:
>   	kfree(st);
>   err_st_alloc:
> -	drm_free_large(page_addr_list);
> +	kvfree(page_addr_list);
>   
>   	DRM_DEBUG_KMS("Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>   		      obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size);
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index 58ccf8b8ca1c..1a0ce1dc68f5 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
>   	ret = -ENOMEM;
>   	pinned = 0;
>   
> -	pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
> +	pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_TEMPORARY);
>   	if (pvec != NULL) {
>   		struct mm_struct *mm = obj->userptr.mm->mm;
>   		unsigned int flags = 0;
> @@ -555,7 +555,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
>   	mutex_unlock(&obj->mm.lock);
>   
>   	release_pages(pvec, pinned, 0);
> -	drm_free_large(pvec);
> +	kvfree(pvec);
>   
>   	i915_gem_object_put(obj);
>   	put_task_struct(work->task);
> @@ -642,7 +642,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
>   	pinned = 0;
>   
>   	if (mm == current->mm) {
> -		pvec = drm_malloc_gfp(num_pages, sizeof(struct page *),
> +		pvec = kvmalloc_array(num_pages, sizeof(struct page *),
>   				      GFP_TEMPORARY |
>   				      __GFP_NORETRY |
>   				      __GFP_NOWARN);
> @@ -669,7 +669,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
>   
>   	if (IS_ERR(pages))
>   		release_pages(pvec, pinned, 0);
> -	drm_free_large(pvec);
> +	kvfree(pvec);
>   
>   	return pages;
>   }
> diff --git a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
> index 19860a372d90..7276194c04f7 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c
> @@ -117,7 +117,7 @@ static int igt_random_insert_remove(void *arg)
>   
>   	mock_engine_reset(engine);
>   
> -	waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
> +	waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY);
>   	if (!waiters)
>   		goto out_engines;
>   
> @@ -169,7 +169,7 @@ static int igt_random_insert_remove(void *arg)
>   out_bitmap:
>   	kfree(bitmap);
>   out_waiters:
> -	drm_free_large(waiters);
> +	kvfree(waiters);
>   out_engines:
>   	mock_engine_flush(engine);
>   	return err;
> @@ -187,7 +187,7 @@ static int igt_insert_complete(void *arg)
>   
>   	mock_engine_reset(engine);
>   
> -	waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
> +	waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY);
>   	if (!waiters)
>   		goto out_engines;
>   
> @@ -254,7 +254,7 @@ static int igt_insert_complete(void *arg)
>   out_bitmap:
>   	kfree(bitmap);
>   out_waiters:
> -	drm_free_large(waiters);
> +	kvfree(waiters);
>   out_engines:
>   	mock_engine_flush(engine);
>   	return err;
> @@ -368,7 +368,7 @@ static int igt_wakeup(void *arg)
>   
>   	mock_engine_reset(engine);
>   
> -	waiters = drm_malloc_gfp(count, sizeof(*waiters), GFP_TEMPORARY);
> +	waiters = kvmalloc_array(count, sizeof(*waiters), GFP_TEMPORARY);
>   	if (!waiters)
>   		goto out_engines;
>   
> @@ -454,7 +454,7 @@ static int igt_wakeup(void *arg)
>   		put_task_struct(waiters[n].tsk);
>   	}
>   
> -	drm_free_large(waiters);
> +	kvfree(waiters);
>   out_engines:
>   	mock_engine_flush(engine);
>   	return err;
> diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
> index 68e509b3b9e4..465dab942afa 100644
> --- a/drivers/gpu/drm/msm/msm_gem.c
> +++ b/drivers/gpu/drm/msm/msm_gem.c
> @@ -50,13 +50,13 @@ static struct page **get_pages_vram(struct drm_gem_object *obj,
>   	struct page **p;
>   	int ret, i;
>   
> -	p = drm_malloc_ab(npages, sizeof(struct page *));
> +	p = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (!p)
>   		return ERR_PTR(-ENOMEM);
>   
>   	ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node, npages);
>   	if (ret) {
> -		drm_free_large(p);
> +		kvfree(p);
>   		return ERR_PTR(ret);
>   	}
>   
> @@ -127,7 +127,7 @@ static void put_pages(struct drm_gem_object *obj)
>   			drm_gem_put_pages(obj, msm_obj->pages, true, false);
>   		else {
>   			drm_mm_remove_node(msm_obj->vram_node);
> -			drm_free_large(msm_obj->pages);
> +			kvfree(msm_obj->pages);
>   		}
>   
>   		msm_obj->pages = NULL;
> @@ -707,7 +707,7 @@ void msm_gem_free_object(struct drm_gem_object *obj)
>   		 * ours, just free the array we allocated:
>   		 */
>   		if (msm_obj->pages)
> -			drm_free_large(msm_obj->pages);
> +			kvfree(msm_obj->pages);
>   
>   		drm_prime_gem_destroy(obj, msm_obj->sgt);
>   	} else {
> @@ -863,7 +863,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
>   
>   	msm_obj = to_msm_bo(obj);
>   	msm_obj->sgt = sgt;
> -	msm_obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
> +	msm_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (!msm_obj->pages) {
>   		ret = -ENOMEM;
>   		goto fail;
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
> index 3ac671f6c8e1..00b22af70f5c 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -87,7 +87,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
>   	p->dma_reloc_idx = 0;
>   	/* FIXME: we assume that each relocs use 4 dwords */
>   	p->nrelocs = chunk->length_dw / 4;
> -	p->relocs = drm_calloc_large(p->nrelocs, sizeof(struct radeon_bo_list));
> +	p->relocs = kvmalloc_array(p->nrelocs, sizeof(struct radeon_bo_list),
> +			GFP_KERNEL | __GFP_ZERO);
>   	if (p->relocs == NULL) {
>   		return -ENOMEM;
>   	}
> @@ -341,7 +342,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
>   				continue;
>   		}
>   
> -		p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t));
> +		p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
>   		size *= sizeof(uint32_t);
>   		if (p->chunks[i].kdata == NULL) {
>   			return -ENOMEM;
> @@ -440,10 +441,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
>   		}
>   	}
>   	kfree(parser->track);
> -	drm_free_large(parser->relocs);
> -	drm_free_large(parser->vm_bos);
> +	kvfree(parser->relocs);
> +	kvfree(parser->vm_bos);
>   	for (i = 0; i < parser->nchunks; i++)
> -		drm_free_large(parser->chunks[i].kdata);
> +		kvfree(parser->chunks[i].kdata);
>   	kfree(parser->chunks);
>   	kfree(parser->chunks_array);
>   	radeon_ib_free(parser->rdev, &parser->ib);
> diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
> index dddb372de2b9..574bf7e6b118 100644
> --- a/drivers/gpu/drm/radeon/radeon_gem.c
> +++ b/drivers/gpu/drm/radeon/radeon_gem.c
> @@ -587,7 +587,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
>   	ttm_eu_backoff_reservation(&ticket, &list);
>   
>   error_free:
> -	drm_free_large(vm_bos);
> +	kvfree(vm_bos);
>   
>   	if (r && r != -ERESTARTSYS)
>   		DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
> index 8c7872339c2a..84802b201bef 100644
> --- a/drivers/gpu/drm/radeon/radeon_ring.c
> +++ b/drivers/gpu/drm/radeon/radeon_ring.c
> @@ -314,7 +314,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring
>   	}
>   
>   	/* and then save the content of the ring */
> -	*data = drm_malloc_ab(size, sizeof(uint32_t));
> +	*data = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
>   	if (!*data) {
>   		mutex_unlock(&rdev->ring_lock);
>   		return 0;
> @@ -356,7 +356,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
>   	}
>   
>   	radeon_ring_unlock_commit(rdev, ring, false);
> -	drm_free_large(data);
> +	kvfree(data);
>   	return 0;
>   }
>   
> diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
> index a1358748cea5..5f68245579a3 100644
> --- a/drivers/gpu/drm/radeon/radeon_vm.c
> +++ b/drivers/gpu/drm/radeon/radeon_vm.c
> @@ -132,8 +132,8 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
>   	struct radeon_bo_list *list;
>   	unsigned i, idx;
>   
> -	list = drm_malloc_ab(vm->max_pde_used + 2,
> -			     sizeof(struct radeon_bo_list));
> +	list = kvmalloc_array(vm->max_pde_used + 2,
> +			     sizeof(struct radeon_bo_list), GFP_KERNEL);
>   	if (!list)
>   		return NULL;
>   
> diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
> index 5260179d788a..8ebc8d3560c3 100644
> --- a/drivers/gpu/drm/ttm/ttm_tt.c
> +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> @@ -39,7 +39,6 @@
>   #include <linux/slab.h>
>   #include <linux/export.h>
>   #include <drm/drm_cache.h>
> -#include <drm/drm_mem_util.h>
>   #include <drm/ttm/ttm_module.h>
>   #include <drm/ttm/ttm_bo_driver.h>
>   #include <drm/ttm/ttm_placement.h>
> @@ -53,14 +52,16 @@
>    */
>   static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
>   {
> -	ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(void*));
> +	ttm->pages = kvmalloc_array(ttm->num_pages, sizeof(void*),
> +			GFP_KERNEL | __GFP_ZERO);
>   }
>   
>   static void ttm_dma_tt_alloc_page_directory(struct ttm_dma_tt *ttm)
>   {
> -	ttm->ttm.pages = drm_calloc_large(ttm->ttm.num_pages,
> +	ttm->ttm.pages = kvmalloc_array(ttm->ttm.num_pages,
>   					  sizeof(*ttm->ttm.pages) +
> -					  sizeof(*ttm->dma_address));
> +					  sizeof(*ttm->dma_address),
> +					  GFP_KERNEL | __GFP_ZERO);
>   	ttm->dma_address = (void *) (ttm->ttm.pages + ttm->ttm.num_pages);
>   }
>   
> @@ -208,7 +209,7 @@ EXPORT_SYMBOL(ttm_tt_init);
>   
>   void ttm_tt_fini(struct ttm_tt *ttm)
>   {
> -	drm_free_large(ttm->pages);
> +	kvfree(ttm->pages);
>   	ttm->pages = NULL;
>   }
>   EXPORT_SYMBOL(ttm_tt_fini);
> @@ -243,7 +244,7 @@ void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma)
>   {
>   	struct ttm_tt *ttm = &ttm_dma->ttm;
>   
> -	drm_free_large(ttm->pages);
> +	kvfree(ttm->pages);
>   	ttm->pages = NULL;
>   	ttm_dma->dma_address = NULL;
>   }
> diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c
> index ed0e636243b2..2e031a894813 100644
> --- a/drivers/gpu/drm/udl/udl_dmabuf.c
> +++ b/drivers/gpu/drm/udl/udl_dmabuf.c
> @@ -228,7 +228,7 @@ static int udl_prime_create(struct drm_device *dev,
>   		return -ENOMEM;
>   
>   	obj->sg = sg;
> -	obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
> +	obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
>   	if (obj->pages == NULL) {
>   		DRM_ERROR("obj pages is NULL %d\n", npages);
>   		return -ENOMEM;
> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
> index 775c50e4f02c..db9ceceba30e 100644
> --- a/drivers/gpu/drm/udl/udl_gem.c
> +++ b/drivers/gpu/drm/udl/udl_gem.c
> @@ -146,7 +146,7 @@ int udl_gem_get_pages(struct udl_gem_object *obj)
>   void udl_gem_put_pages(struct udl_gem_object *obj)
>   {
>   	if (obj->base.import_attach) {
> -		drm_free_large(obj->pages);
> +		kvfree(obj->pages);
>   		obj->pages = NULL;
>   		return;
>   	}
> diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
> index e9c381c42139..bf466674ca9b 100644
> --- a/drivers/gpu/drm/vc4/vc4_gem.c
> +++ b/drivers/gpu/drm/vc4/vc4_gem.c
> @@ -545,14 +545,15 @@ vc4_cl_lookup_bos(struct drm_device *dev,
>   		return -EINVAL;
>   	}
>   
> -	exec->bo = drm_calloc_large(exec->bo_count,
> -				    sizeof(struct drm_gem_cma_object *));
> +	exec->bo = kvmalloc_array(exec->bo_count,
> +				    sizeof(struct drm_gem_cma_object *),
> +				    GFP_KERNEL | __GFP_ZERO);
>   	if (!exec->bo) {
>   		DRM_ERROR("Failed to allocate validated BO pointers\n");
>   		return -ENOMEM;
>   	}
>   
> -	handles = drm_malloc_ab(exec->bo_count, sizeof(uint32_t));
> +	handles = kvmalloc_array(exec->bo_count, sizeof(uint32_t), GFP_KERNEL);
>   	if (!handles) {
>   		ret = -ENOMEM;
>   		DRM_ERROR("Failed to allocate incoming GEM handles\n");
> @@ -584,7 +585,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
>   	spin_unlock(&file_priv->table_lock);
>   
>   fail:
> -	drm_free_large(handles);
> +	kvfree(handles);
>   	return ret;
>   }
>   
> @@ -622,7 +623,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
>   	 * read the contents back for validation, and I think the
>   	 * bo->vaddr is uncached access.
>   	 */
> -	temp = drm_malloc_ab(temp_size, 1);
> +	temp = kvmalloc_array(temp_size, 1, GFP_KERNEL);
>   	if (!temp) {
>   		DRM_ERROR("Failed to allocate storage for copying "
>   			  "in bin/render CLs.\n");
> @@ -697,7 +698,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
>   	ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true);
>   
>   fail:
> -	drm_free_large(temp);
> +	kvfree(temp);
>   	return ret;
>   }
>   
> @@ -710,7 +711,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
>   	if (exec->bo) {
>   		for (i = 0; i < exec->bo_count; i++)
>   			drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
> -		drm_free_large(exec->bo);
> +		kvfree(exec->bo);
>   	}
>   
>   	while (!list_empty(&exec->unref_list)) {
> diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> index 61f3a963af95..6ed4bfc9b82b 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
> @@ -119,13 +119,14 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>   	INIT_LIST_HEAD(&validate_list);
>   	if (exbuf->num_bo_handles) {
>   
> -		bo_handles = drm_malloc_ab(exbuf->num_bo_handles,
> -					   sizeof(uint32_t));
> -		buflist = drm_calloc_large(exbuf->num_bo_handles,
> -					   sizeof(struct ttm_validate_buffer));
> +		bo_handles = kvmalloc_array(exbuf->num_bo_handles,
> +					   sizeof(uint32_t), GFP_KERNEL);
> +		buflist = kvmalloc_array(exbuf->num_bo_handles,
> +					   sizeof(struct ttm_validate_buffer),
> +					   GFP_KERNEL | __GFP_ZERO);
>   		if (!bo_handles || !buflist) {
> -			drm_free_large(bo_handles);
> -			drm_free_large(buflist);
> +			kvfree(bo_handles);
> +			kvfree(buflist);
>   			return -ENOMEM;
>   		}
>   
> @@ -133,16 +134,16 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>   		if (copy_from_user(bo_handles, user_bo_handles,
>   				   exbuf->num_bo_handles * sizeof(uint32_t))) {
>   			ret = -EFAULT;
> -			drm_free_large(bo_handles);
> -			drm_free_large(buflist);
> +			kvfree(bo_handles);
> +			kvfree(buflist);
>   			return ret;
>   		}
>   
>   		for (i = 0; i < exbuf->num_bo_handles; i++) {
>   			gobj = drm_gem_object_lookup(drm_file, bo_handles[i]);
>   			if (!gobj) {
> -				drm_free_large(bo_handles);
> -				drm_free_large(buflist);
> +				kvfree(bo_handles);
> +				kvfree(buflist);
>   				return -ENOENT;
>   			}
>   
> @@ -151,7 +152,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>   
>   			list_add(&buflist[i].head, &validate_list);
>   		}
> -		drm_free_large(bo_handles);
> +		kvfree(bo_handles);
>   	}
>   
>   	ret = virtio_gpu_object_list_validate(&ticket, &validate_list);
> @@ -171,7 +172,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>   
>   	/* fence the command bo */
>   	virtio_gpu_unref_list(&validate_list);
> -	drm_free_large(buflist);
> +	kvfree(buflist);
>   	dma_fence_put(&fence->f);
>   	return 0;
>   
> @@ -179,7 +180,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
>   	ttm_eu_backoff_reservation(&ticket, &validate_list);
>   out_free:
>   	virtio_gpu_unref_list(&validate_list);
> -	drm_free_large(buflist);
> +	kvfree(buflist);
>   	return ret;
>   }
>   
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index e1daa4f343cd..59df08d14b89 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -70,7 +70,6 @@
>   #include <drm/drm_fourcc.h>
>   #include <drm/drm_global.h>
>   #include <drm/drm_hashtab.h>
> -#include <drm/drm_mem_util.h>
>   #include <drm/drm_mm.h>
>   #include <drm/drm_os_linux.h>
>   #include <drm/drm_sarea.h>
> diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h
> deleted file mode 100644
> index a1ddf55fda67..000000000000
> --- a/include/drm/drm_mem_util.h
> +++ /dev/null
> @@ -1,53 +0,0 @@
> -/*
> - * Copyright A(C) 2008 Intel Corporation
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice (including the next
> - * paragraph) shall be included in all copies or substantial portions of the
> - * Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> - * IN THE SOFTWARE.
> - *
> - * Authors:
> - *     Jesse Barnes <jbarnes@virtuousgeek.org>
> - *
> - */
> -#ifndef _DRM_MEM_UTIL_H_
> -#define _DRM_MEM_UTIL_H_
> -
> -#include <linux/vmalloc.h>
> -
> -static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
> -{
> -	return kvmalloc_array(nmemb, size, GFP_KERNEL | __GFP_ZERO);
> -}
> -
> -/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
> -static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
> -{
> -	return kvmalloc_array(nmemb, size, GFP_KERNEL);
> -}
> -
> -static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp)
> -{
> -	return kvmalloc_array(nmemb, size, gfp);
> -}
> -
> -static __inline void drm_free_large(void *ptr)
> -{
> -	kvfree(ptr);
> -}
> -
> -#endif


--
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 2/2] powerpc/mm/hugetlb: Add support for 1G huge pages
From: Michael Ellerman @ 2017-05-18  8:47 UTC (permalink / raw)
  To: Aneesh Kumar K.V, akpm, Anshuman Khandual
  Cc: linux-mm, linux-kernel, linuxppc-dev
In-Reply-To: <852b601c-a044-0445-e97d-d17d76ec1154@linux.vnet.ibm.com>

"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:

> On Thursday 18 May 2017 10:51 AM, Michael Ellerman wrote:
>> "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
>> 
>>> POWER9 supports hugepages of size 2M and 1G in radix MMU mode. This patch
>>> enables the usage of 1G page size for hugetlbfs. This also update the helper
>>> such we can do 1G page allocation at runtime.
>>>
>>> We still don't enable 1G page size on DD1 version. This is to avoid doing
>>> workaround mentioned in commit: 6d3a0379ebdc8 (powerpc/mm: Add
>>> radix__tlb_flush_pte_p9_dd1()
>>>
>>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>>> ---
>>>   arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
>>>   arch/powerpc/mm/hugetlbpage.c                |  7 +++++--
>>>   arch/powerpc/platforms/Kconfig.cputype       |  1 +
>>>   3 files changed, 16 insertions(+), 2 deletions(-)
>> 
>> I think this patch is OK, but it's very confusing because it doesn't
>> mention that it's only talking about *generic* gigantic page support.
>
> What you mean by generic gigantic page ? what is supported here is the 
> gigantic page with size 1G alone ?

What about 16G pages on pseries.

And all the other gigantic page sizes that Book3E supports?

cheers

--
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,oom: fix oom invocation issues
From: Michal Hocko @ 2017-05-18  8:47 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: guro, hannes, vdavydov.dev, kernel-team, linux-mm, linux-kernel
In-Reply-To: <201705180703.JGH95344.SOHJtFFMOQFLOV@I-love.SAKURA.ne.jp>

On Thu 18-05-17 07:03:36, Tetsuo Handa wrote:
> Roman Gushchin wrote:
> > On Wed, May 17, 2017 at 06:14:46PM +0200, Michal Hocko wrote:
> > > On Wed 17-05-17 16:26:20, Roman Gushchin wrote:
> > > [...]
> > > > [   25.781882] Out of memory: Kill process 492 (allocate) score 899 or sacrifice child
> > > > [   25.783874] Killed process 492 (allocate) total-vm:2052368kB, anon-rss:1894576kB, file-rss:4kB, shmem-rss:0kB
> > > 
> > > Are there any oom_reaper messages? Could you provide the full kernel log
> > > please?
> > 
> > Sure. Sorry, it was too bulky, so I've cut the line about oom_reaper by mistake.
> > Here it is:
> > --------------------------------------------------------------------------------
> > [   25.721494] allocate invoked oom-killer: gfp_mask=0x14280ca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null),  order=0, oom_score_adj=0
> > [   25.725658] allocate cpuset=/ mems_allowed=0
> 
> > [   25.759892] Node 0 DMA32 free:44700kB min:44704kB low:55880kB high:67056kB active_anon:1944216kB inactive_anon:204kB active_file:592kB inactive_file:0kB unevictable:0kB writepending:304kB present:2080640kB managed:2031972kB mlocked:0kB slab_reclaimable:11336kB slab_unreclaimable:9784kB kernel_stack:1776kB pagetables:6932kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
> 
> > [   25.781882] Out of memory: Kill process 492 (allocate) score 899 or sacrifice child
> > [   25.783874] Killed process 492 (allocate) total-vm:2052368kB, anon-rss:1894576kB, file-rss:4kB, shmem-rss:0kB
> 
> > [   25.785680] allocate: page allocation failure: order:0, mode:0x14280ca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null)
> > [   25.786797] allocate cpuset=/ mems_allowed=0
> 
> This is a side effect of commit 9a67f6488eca926f ("mm: consolidate GFP_NOFAIL
> checks in the allocator slowpath") which I noticed at
> http://lkml.kernel.org/r/e7f932bf-313a-917d-6304-81528aca5994@I-love.SAKURA.ne.jp .

Hmm, I guess you are right. I haven't realized that pagefault_out_of_memory
can race and pick up another victim. For some reason I thought that the
page fault would break out on fatal signal pending but we don't do that (we
used to in the past). Now that I think about that more we should
probably remove out_of_memory out of pagefault_out_of_memory completely.
It is racy and it basically doesn't have any allocation context so we
might kill a task from a different domain. So can we do this instead?
There is a slight risk that somebody might have returned VM_FAULT_OOM
without doing an allocation but from my quick look nobody does that
currently.
---

^ permalink raw reply

* Re: [PATCH v3 2/2] powerpc/mm/hugetlb: Add support for 1G huge pages
From: Aneesh Kumar K.V @ 2017-05-18  8:50 UTC (permalink / raw)
  To: Michael Ellerman, akpm, Anshuman Khandual
  Cc: linux-mm, linux-kernel, linuxppc-dev
In-Reply-To: <877f1elfga.fsf@concordia.ellerman.id.au>



On Thursday 18 May 2017 02:17 PM, Michael Ellerman wrote:
> "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
> 
>> On Thursday 18 May 2017 10:51 AM, Michael Ellerman wrote:
>>> "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:
>>>
>>>> POWER9 supports hugepages of size 2M and 1G in radix MMU mode. This patch
>>>> enables the usage of 1G page size for hugetlbfs. This also update the helper
>>>> such we can do 1G page allocation at runtime.
>>>>
>>>> We still don't enable 1G page size on DD1 version. This is to avoid doing
>>>> workaround mentioned in commit: 6d3a0379ebdc8 (powerpc/mm: Add
>>>> radix__tlb_flush_pte_p9_dd1()
>>>>
>>>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>>>> ---
>>>>    arch/powerpc/include/asm/book3s/64/hugetlb.h | 10 ++++++++++
>>>>    arch/powerpc/mm/hugetlbpage.c                |  7 +++++--
>>>>    arch/powerpc/platforms/Kconfig.cputype       |  1 +
>>>>    3 files changed, 16 insertions(+), 2 deletions(-)
>>>
>>> I think this patch is OK, but it's very confusing because it doesn't
>>> mention that it's only talking about *generic* gigantic page support.
>>
>> What you mean by generic gigantic page ? what is supported here is the
>> gigantic page with size 1G alone ?
> 
> What about 16G pages on pseries.
> 
> And all the other gigantic page sizes that Book3E supports?
> 

None of that is supported w.r.t runtime allocation of hugepages. ie, we 
cannot echo nr_hugepages w.r.t them.  For 16GB i am not sure it make 
sense, because we will rarely get such large contiguous region. W.r.t 
page size supported for Book3E, may be we can. But I don't have a 
facility to test those. Hence didn't include that.

-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] mm,oom: fix oom invocation issues
From: Michal Hocko @ 2017-05-18  9:00 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: guro, hannes, vdavydov.dev, kernel-team, linux-mm, linux-kernel
In-Reply-To: <20170518084729.GB25462@dhcp22.suse.cz>

On Thu 18-05-17 10:47:29, Michal Hocko wrote:
> On Thu 18-05-17 07:03:36, Tetsuo Handa wrote:
> > Roman Gushchin wrote:
> > > On Wed, May 17, 2017 at 06:14:46PM +0200, Michal Hocko wrote:
> > > > On Wed 17-05-17 16:26:20, Roman Gushchin wrote:
> > > > [...]
> > > > > [   25.781882] Out of memory: Kill process 492 (allocate) score 899 or sacrifice child
> > > > > [   25.783874] Killed process 492 (allocate) total-vm:2052368kB, anon-rss:1894576kB, file-rss:4kB, shmem-rss:0kB
> > > > 
> > > > Are there any oom_reaper messages? Could you provide the full kernel log
> > > > please?
> > > 
> > > Sure. Sorry, it was too bulky, so I've cut the line about oom_reaper by mistake.
> > > Here it is:
> > > --------------------------------------------------------------------------------
> > > [   25.721494] allocate invoked oom-killer: gfp_mask=0x14280ca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null),  order=0, oom_score_adj=0
> > > [   25.725658] allocate cpuset=/ mems_allowed=0
> > 
> > > [   25.759892] Node 0 DMA32 free:44700kB min:44704kB low:55880kB high:67056kB active_anon:1944216kB inactive_anon:204kB active_file:592kB inactive_file:0kB unevictable:0kB writepending:304kB present:2080640kB managed:2031972kB mlocked:0kB slab_reclaimable:11336kB slab_unreclaimable:9784kB kernel_stack:1776kB pagetables:6932kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
> > 
> > > [   25.781882] Out of memory: Kill process 492 (allocate) score 899 or sacrifice child
> > > [   25.783874] Killed process 492 (allocate) total-vm:2052368kB, anon-rss:1894576kB, file-rss:4kB, shmem-rss:0kB
> > 
> > > [   25.785680] allocate: page allocation failure: order:0, mode:0x14280ca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO), nodemask=(null)
> > > [   25.786797] allocate cpuset=/ mems_allowed=0
> > 
> > This is a side effect of commit 9a67f6488eca926f ("mm: consolidate GFP_NOFAIL
> > checks in the allocator slowpath") which I noticed at
> > http://lkml.kernel.org/r/e7f932bf-313a-917d-6304-81528aca5994@I-love.SAKURA.ne.jp .
> 
> Hmm, I guess you are right. I haven't realized that pagefault_out_of_memory
> can race and pick up another victim. For some reason I thought that the
> page fault would break out on fatal signal pending but we don't do that (we
> used to in the past). Now that I think about that more we should
> probably remove out_of_memory out of pagefault_out_of_memory completely.
> It is racy and it basically doesn't have any allocation context so we
> might kill a task from a different domain. So can we do this instead?
> There is a slight risk that somebody might have returned VM_FAULT_OOM
> without doing an allocation but from my quick look nobody does that
> currently.

If this is considered too risky then we can do what Roman was proposing
and check tsk_is_oom_victim in pagefault_out_of_memory and bail out.
-- 
Michal Hocko
SUSE Labs

--
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 17/32] x86/mm: Add support to access boot related data in the clear
From: Borislav Petkov @ 2017-05-18  9:02 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: <4845df29-bae7-9b78-0428-ff96dbef2128@amd.com>

On Wed, May 17, 2017 at 01:54:39PM -0500, Tom Lendacky wrote:
> I was worried what the compiler might do when CONFIG_EFI is not set,
> but it appears to take care of it. I'll double check though.

There's a efi_enabled() !CONFIG_EFI version too, so should be fine.

> I may introduce a length variable to capture data->len right after
> paddr_next is set and then have just a single memunmap() call before
> the if check.

Yap.

> I tried that, but calling an "__init" function (early_memremap()) from
> a non "__init" function generated warnings. I suppose I can pass in a
> function for the map and unmap but that looks worse to me (also the
> unmap functions take different arguments).

No, the other way around: the __init function should call the non-init
one and you need the non-init one anyway for memremap_is_setup_data().

> This is like the chicken and the egg scenario. In order to determine if
> an address is setup data I have to explicitly map the setup data chain
> as decrypted. In order to do that I have to supply a flag to explicitly
> map the data decrypted otherwise I wind up back in the
> memremap_is_setup_data() function again and again and again...

Oh, fun.

-- 
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 18/32] x86, mpparse: Use memremap to map the mpf and mpc data
From: Borislav Petkov @ 2017-05-18  9:03 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: <6e155b8f-b691-2ee0-8977-969aaab6199a@amd.com>

On Wed, May 17, 2017 at 03:26:58PM -0500, Tom Lendacky wrote:
> > Also, simplify that test:
> > 
> > 	if (mpf->feature1)
> > 		...
> 
> Ok, I can do that but I hope no one says anything about it being
> unrelated to the patch. :)

Bah, that's minor.

-- 
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 0/6] refine and rename slub sysfs
From: Michal Hocko @ 2017-05-18  9:06 UTC (permalink / raw)
  To: Wei Yang; +Cc: cl, penberg, rientjes, akpm, linux-mm, linux-kernel
In-Reply-To: <20170517141146.11063-1-richard.weiyang@gmail.com>

On Wed 17-05-17 22:11:40, Wei Yang wrote:
> This patch serial could be divided into two parts.
> 
> First three patches refine and adds slab sysfs.
> Second three patches rename slab sysfs.
> 
> 1. Refine slab sysfs
> 
> There are four level slabs:
> 
>     CPU
>     CPU_PARTIAL
>     PARTIAL
>     FULL
> 
> And in sysfs, it use show_slab_objects() and cpu_partial_slabs_show() to
> reflect the statistics.
> 
> In patch 2, it splits some function in show_slab_objects() which makes sure
> only cpu_partial_slabs_show() covers statistics for CPU_PARTIAL slabs.
> 
> After doing so, it would be more clear that show_slab_objects() has totally 9
> statistic combinations for three level of slabs. Each slab has three cases
> statistic.
> 
>     slabs
>     objects
>     total_objects
> 
> And when we look at current implementation, some of them are missing. So patch
> 2 & 3 add them up.
> 
> 2. Rename sysfs
> 
> The slab statistics in sysfs are
> 
>     slabs
>     objects
>     total_objects
>     cpu_slabs
>     partial
>     partial_objects
>     cpu_partial_slabs
> 
> which is a little bit hard for users to understand. The second three patches
> rename sysfs file in this pattern.
> 
>     xxx_slabs[[_total]_objects]
> 
> Finally it looks Like
> 
>     slabs
>     slabs_objects
>     slabs_total_objects
>     cpu_slabs
>     cpu_slabs_objects
>     cpu_slabs_total_objects
>     partial_slabs
>     partial_slabs_objects
>     partial_slabs_total_objects
>     cpu_partial_slabs

_Why_ do we need all this?
-- 
Michal Hocko
SUSE Labs

--
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 1/6] mm, page_alloc: fix more premature OOM due to race with cpuset update
From: Michal Hocko @ 2017-05-18  9:08 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Vlastimil Babka, linux-mm, linux-kernel, cgroups, Li Zefan,
	Mel Gorman, David Rientjes, Hugh Dickins, Andrea Arcangeli,
	Anshuman Khandual, Kirill A. Shutemov, linux-api
In-Reply-To: <alpine.DEB.2.20.1705171021570.9487@east.gentwo.org>

On Wed 17-05-17 10:25:09, Cristopher Lameter wrote:
> On Wed, 17 May 2017, Michal Hocko wrote:
> 
> > > If you have screwy things like static mbinds in there then you are
> > > hopelessly lost anyways. You may have moved the process to another set
> > > of nodes but the static bindings may refer to a node no longer
> > > available. Thus the OOM is legitimate.
> >
> > The point is that you do _not_ want such a process to trigger the OOM
> > because it can cause other processes being killed.
> 
> Nope. The OOM in a cpuset gets the process doing the alloc killed. Or what
> that changed?
> 
> At this point you have messed up royally and nothing is going to rescue
> you anyways. OOM or not does not matter anymore. The app will fail.

Not really. If you can trick the system to _think_ that the intersection
between mempolicy and the cpuset is empty then the OOM killer might
trigger an innocent task rather than the one which tricked it into that
situation.
-- 
Michal Hocko
SUSE Labs

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

* mm, something wring in page_lock_anon_vma_read()?
From: Xishi Qiu @ 2017-05-18  9:46 UTC (permalink / raw)
  To: Andrew Morton, Tejun Heo, Michal Hocko, Johannes Weiner,
	Mel Gorman, Michal Hocko, Vlastimil Babka, Minchan Kim,
	David Rientjes, Joonsoo Kim, aarcange, sumeet.keswani,
	Rik van Riel, Hugh Dickins
  Cc: Linux MM, LKML, zhong jiang

Hi, my system triggers this bug, and the vmcore shows the anon_vma seems be freed.
The kernel is RHEL 7.2, and the bug is hard to reproduce, so I don't know if it
exists in mainline, any reply is welcome!

[35030.332666] general protection fault: 0000 [#1] SMP
[35030.333016] Modules linked in: veth ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 xt_addrtype iptable_filter xt_conntrack nf_nat nf_conntrack bridge stp llc dm_thin_pool dm_persistent_data dm_bio_prison dm_bufio libcrc32c rtos_kbox_panic(OE) ipmi_devintf ipmi_si ipmi_msghandler signo_catch(O) cirrus syscopyarea sysfillrect sysimgblt ttm crc32_pclmul ghash_clmulni_intel drm_kms_helper aesni_intel ppdev drm lrw gf128mul parport_pc glue_helper ablk_helper serio_raw cryptd i2c_piix4 parport pcspkr sg floppy i2c_core dm_mod sha512_generic ip_tables sd_mod crc_t10dif crct10dif_generic sr_mod cdrom virtio_console virtio_scsi virtio_net ata_generic pata_acpi crct10dif_pclmul crct10dif_common crc32c_intel virtio_pci virtio_ring virtio ata_piix libata ext4 mbcache
[35030.333016]  jbd2
[35030.333016] CPU: 3 PID: 48 Comm: kswapd0 Tainted: G           OE  ---- -------   3.10.0-327.36.58.4.x86_64 #1
[35030.333016] Hardware name: OpenStack Foundation OpenStack Nova, BIOS rel-1.8.1-0-g4adadbd-20160826_044443-hghoulaslx112 04/01/2014
[35030.333016] task: ffff8801b2d20000 ti: ffff8801b4c38000 task.ti: ffff8801b4c38000
[35030.333016] RIP: 0010:[<ffffffff810acac5>]  [<ffffffff810acac5>] down_read_trylock+0x5/0x50
[35030.333016] RSP: 0000:ffff8801b4c3ba90  EFLAGS: 00010282
[35030.333016] RAX: 0000000000000000 RBX: ffff8801b3e2a100 RCX: 0000000000000000
[35030.333016] RDX: 0000000000000000 RSI: 0000000000000000 RDI: deb604d497705c5d
[35030.333016] RBP: ffff8801b4c3bab8 R08: ffffea0002c34460 R09: ffff8801b3d7e8a0
[35030.333016] R10: 0000000000000004 R11: fff00000fe000000 R12: ffff8801b3e2a101
[35030.333016] R13: ffffea0002c34440 R14: deb604d497705c5d R15: ffffea0002c34440
[35030.333016] FS:  0000000000000000(0000) GS:ffff8801bed80000(0000) knlGS:0000000000000000
[35030.333016] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[35030.333016] CR2: 000000c422011080 CR3: 0000000001976000 CR4: 00000000001407e0
[35030.333016] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[35030.333016] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[35030.333016] Stack:
[35030.333016]  ffffffff811b2795 ffffea0002c34440 0000000000000000 000000000000000f
[35030.333016]  0000000000000001 ffff8801b4c3bb30 ffffffff811b2a17 ffff8800a712d640
[35030.333016]  000000000c4229e2 ffff8801b4c3bb80 0000000100000000 000000000c41fe38
[35030.333016] Call Trace:
[35030.333016]  [<ffffffff811b2795>] ? page_lock_anon_vma_read+0x55/0x110
[35030.333016]  [<ffffffff811b2a17>] page_referenced+0x1c7/0x350
[35030.333016]  [<ffffffff8118d9b4>] shrink_active_list+0x1e4/0x400
[35030.333016]  [<ffffffff8118e08d>] shrink_lruvec+0x4bd/0x770
[35030.333016]  [<ffffffff8118e3b6>] shrink_zone+0x76/0x1a0
[35030.333016]  [<ffffffff8118f6cc>] balance_pgdat+0x49c/0x610
[35030.333016]  [<ffffffff8118f9b3>] kswapd+0x173/0x450
[35030.333016]  [<ffffffff810a8a00>] ? wake_up_atomic_t+0x30/0x30
[35030.333016]  [<ffffffff8118f840>] ? balance_pgdat+0x610/0x610
[35030.333016]  [<ffffffff810a79bf>] kthread+0xcf/0xe0
[35030.333016]  [<ffffffff810a78f0>] ? kthread_create_on_node+0x120/0x120
[35030.333016]  [<ffffffff81665bd8>] ret_from_fork+0x58/0x90
[35030.333016]  [<ffffffff810a78f0>] ? kthread_create_on_node+0x120/0x120
[35030.333016] Code: 00 ba ff ff ff ff 48 89 d8 f0 48 0f c1 10 79 05 e8 31 06 27 00 5b 5d c3 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 <48> 8b 07 48 89 c2 48 83 c2 01 7e 07 f0 48 0f b1 17 75 f0 48 f7
[35030.333016] RIP  [<ffffffff810acac5>] down_read_trylock+0x5/0x50
[35030.333016]  RSP <ffff8801b4c3ba90>
[35030.333016] ------------[ cut here ]------------

struct page {
  flags = 9007194960298056,
  mapping = 0xffff8801b3e2a101,
  {
    {
      index = 34324593617,
      freelist = 0x7fde7bbd1,
      pfmemalloc = 209,
      thp_mmu_gather = {
        counter = -35144751
      },
      pmd_huge_pte = 0x7fde7bbd1
    },
    {
      counters = 8589934592,
      {
        {
          _mapcount = {
            counter = 0
          },
          {
            inuse = 0,
            objects = 0,
            frozen = 0
          },
          units = 0
        },
        _count = {
          counter = 2
        }
      }
    }
  },
  {
    lru = {
      next = 0xdead000000100100,
      prev = 0xdead000000200200
    },
    {
      next = 0xdead000000100100,
      pages = 2097664,
      pobjects = -559087616
    },
    list = {
      next = 0xdead000000100100,
      prev = 0xdead000000200200
    },
    slab_page = 0xdead000000100100
  },
  {
    private = 0,
    ptl = {
      {
        rlock = {
          raw_lock = {
            {
              head_tail = 0,
              tickets = {
                head = 0,
                tail = 0
              }
            }
          }
        }
      }
    },
    slab_cache = 0x0,
    first_page = 0x0
  }
}



crash> struct anon_vma 0xffff8801b3e2a100
struct anon_vma {
  root = 0xdeb604d497705c55,
  rwsem = {
    count = -8192007903225070328,
    wait_lock = {
      raw_lock = {
        {
          head_tail = 2955503940,
          tickets = {
            head = 26948,
            tail = 45097
          }
        }
      }
    },
    wait_list = {
      next = 0x559f9107c1b47439,
      prev = 0x3de13f709bfa043b
    }
  },
  refcount = {
    counter = -13243516
  },
  rb_root = {
    rb_node = 0x11dd18f9ce0bb2e9
  }
}

This address 0xffff8801b3e2a100 can not find in "kmem -S anon_vma"

The page flags is
crash> kmem -g 0x1FFFFF00080048
FLAGS: 1fffff00080048
  PAGE-FLAG        BIT  VALUE
  PG_uptodate        3  0000008
  PG_active          6  0000040
  PG_swapbacked     19  0080000

--
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 1/6] mm, page_alloc: fix more premature OOM due to race with cpuset update
From: Vlastimil Babka @ 2017-05-18 10:03 UTC (permalink / raw)
  To: Christoph Lameter, Michal Hocko
  Cc: linux-mm, linux-kernel, cgroups, Li Zefan, Mel Gorman,
	David Rientjes, Hugh Dickins, Andrea Arcangeli, Anshuman Khandual,
	Kirill A. Shutemov, linux-api
In-Reply-To: <alpine.DEB.2.20.1705170943090.8714@east.gentwo.org>

On 05/17/2017 04:48 PM, Christoph Lameter wrote:
> On Wed, 17 May 2017, Michal Hocko wrote:
> 
>>>> So how are you going to distinguish VM_FAULT_OOM from an empty mempolicy
>>>> case in a raceless way?
>>>
>>> You dont have to do that if you do not create an empty mempolicy in the
>>> first place. The current kernel code avoids that by first allowing access
>>> to the new set of nodes and removing the old ones from the set when done.
>>
>> which is racy and as Vlastimil pointed out. If we simply fail such an
>> allocation the failure will go up the call chain until we hit the OOM
>> killer due to VM_FAULT_OOM. How would you want to handle that?
> 
> The race is where? If you expand the node set during the move of the
> application then you are safe in terms of the legacy apps that did not
> include static bindings.

No, that expand/shrink by itself doesn't work against parallel
get_page_from_freelist going through a zonelist. Moving from node 0 to
1, with zonelist containing nodes 1 and 0 in that order:

- mempolicy mask is 0
- zonelist iteration checks node 1, it's not allowed, skip
- mempolicy mask is 0,1 (expand)
- mempolicy mask is 1 (shrink)
- zonelist iteration checks node 0, it's not allowed, skip
- OOM

--
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] Patch for remapping pages around the fault page
From: Kirill A. Shutemov @ 2017-05-18 10:09 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Sarunya Pumma, akpm, kirill.shutemov, jack, ross.zwisler, mhocko,
	aneesh.kumar, lstoakes, dave.jiang, linux-mm
In-Reply-To: <20170518055333.GC24445@rapoport-lnx>

On Thu, May 18, 2017 at 08:53:33AM +0300, Mike Rapoport wrote:
> Hello,
> 
> On Tue, May 16, 2017 at 12:16:00PM -0400, Sarunya Pumma wrote:
> > 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.
> 
> [...] 
>  
> > 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(+)
> 
> The patch is completely unreadable :(
> Please use a mail client that does not break whitespace, e.g 'git
> send-email'

And I would like to see performance numbers, please.

-- 
 Kirill A. Shutemov

--
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 v2 3/6] mm, page_alloc: pass preferred nid instead of zonelist to allocator
From: Vlastimil Babka @ 2017-05-18 10:25 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: Andrew Morton, linux-mm, linux-api, linux-kernel, cgroups,
	Li Zefan, Michal Hocko, Mel Gorman, David Rientjes, Hugh Dickins,
	Andrea Arcangeli, Anshuman Khandual, Kirill A. Shutemov,
	Dimitri Sivanich
In-Reply-To: <alpine.DEB.2.20.1705171009340.8714@east.gentwo.org>

On 05/17/2017 05:19 PM, Christoph Lameter wrote:
> On Wed, 17 May 2017, Vlastimil Babka wrote:
> 
>>  struct page *
>> -__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
>> -		       struct zonelist *zonelist, nodemask_t *nodemask);
>> +__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
>> +							nodemask_t *nodemask);
>>
>>  static inline struct page *
>> -__alloc_pages(gfp_t gfp_mask, unsigned int order,
>> -		struct zonelist *zonelist)
>> +__alloc_pages(gfp_t gfp_mask, unsigned int order, int preferred_nid)
>>  {
>> -	return __alloc_pages_nodemask(gfp_mask, order, zonelist, NULL);
>> +	return __alloc_pages_nodemask(gfp_mask, order, preferred_nid, NULL);
>>  }
> 
> Maybe use nid instead of preferred_nid like in __alloc_pages? Otherwise
> there may be confusion with the MPOL_PREFER policy.

I'll think about that.

>> @@ -1963,8 +1960,8 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
>>  {
>>  	struct mempolicy *pol;
>>  	struct page *page;
>> +	int preferred_nid;
>>  	unsigned int cpuset_mems_cookie;
>> -	struct zonelist *zl;
>>  	nodemask_t *nmask;
> 
> Same here.
> 
>> @@ -4012,8 +4012,8 @@ static inline void finalise_ac(gfp_t gfp_mask,
>>   * This is the 'heart' of the zoned buddy allocator.
>>   */
>>  struct page *
>> -__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
>> -			struct zonelist *zonelist, nodemask_t *nodemask)
>> +__alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
>> +							nodemask_t *nodemask)
>>  {
> 
> and here
> 
> This looks clean to me. Still feel a bit uneasy about this since I do
> remember that we had a reason to use zonelists instead of nodes back then
> but cannot remember what that reason was....

My history digging showed me that mempolicies used to have a custom
zonelist attached, not nodemask. So I supposed that's why.

> CCing Dimitri at SGI. This may break a lot of legacy SGIapps. If you read
> this Dimitri then please review this patchset and the discussions around
> it.

Break how? This shouldn't break any apps AFAICS, just out-of-tree kernel
patches/modules as usual when APIs change.

> Reviewed-by: Christoph Lameter <cl@linux.com>

Thanks!

--
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: [PATCHv5, REBASED 9/9] x86/mm: Allow to have userspace mappings above 47-bits
From: Michal Hocko @ 2017-05-18 11:43 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: x86, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andi Kleen,
	Dave Hansen, Andy Lutomirski, Dan Williams, linux-mm,
	linux-kernel, linux-api
In-Reply-To: <20170515121218.27610-10-kirill.shutemov@linux.intel.com>

On Mon 15-05-17 15:12:18, Kirill A. Shutemov wrote:
[...]
> @@ -195,6 +207,16 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
>  	info.length = len;
>  	info.low_limit = PAGE_SIZE;
>  	info.high_limit = get_mmap_base(0);
> +
> +	/*
> +	 * If hint address is above DEFAULT_MAP_WINDOW, look for unmapped area
> +	 * in the full address space.
> +	 *
> +	 * !in_compat_syscall() check to avoid high addresses for x32.
> +	 */
> +	if (addr > DEFAULT_MAP_WINDOW && !in_compat_syscall())
> +		info.high_limit += TASK_SIZE_MAX - DEFAULT_MAP_WINDOW;
> +
>  	info.align_mask = 0;
>  	info.align_offset = pgoff << PAGE_SHIFT;
>  	if (filp) {

I have two questions/concerns here. The above assumes that any address above
1<<47 will use the _whole_ address space. Is this what we want? What
if somebody does mmap(1<<52, ...) because he wants to (ab)use 53+ bits
for some other purpose? Shouldn't we cap the high_limit by the given
address?

Another thing would be that 
	/* requesting a specific address */
	if (addr) {
		addr = PAGE_ALIGN(addr);
		vma = find_vma(mm, addr);
		if (TASK_SIZE - len >= addr &&
				(!vma || addr + len <= vma->vm_start))
			return addr;
	}

would fail for mmap(-1UL, ...) which is good because we do want to
fallback to vm_unmapped_area and have randomized address which is
ensured by your info.high_limit += ... but that wouldn't work for
mmap(1<<N, ...) where N>47. So the first such mapping won't be
randomized while others will be. This is quite unexpected I would say.
So it should be documented at least or maybe we want to skip the above
shortcut for addr > DEFAULT_MAP_WINDOW altogether.

The patch looks sensible other than that.
-- 
Michal Hocko
SUSE Labs

--
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 29/32] x86/mm: Add support to encrypt the kernel in-place
From: Borislav Petkov @ 2017-05-18 12:46 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: <20170418212149.10190.70894.stgit@tlendack-t1.amdoffice.net>

On Tue, Apr 18, 2017 at 04:21:49PM -0500, Tom Lendacky wrote:
> Add the support to encrypt the kernel in-place. This is done by creating
> new page mappings for the kernel - a decrypted write-protected mapping
> and an encrypted mapping. The kernel is encrypted by copying it through
> a temporary buffer.
> 
> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
> ---
>  arch/x86/include/asm/mem_encrypt.h |    6 +
>  arch/x86/mm/Makefile               |    2 
>  arch/x86/mm/mem_encrypt.c          |  262 ++++++++++++++++++++++++++++++++++++
>  arch/x86/mm/mem_encrypt_boot.S     |  151 +++++++++++++++++++++
>  4 files changed, 421 insertions(+)
>  create mode 100644 arch/x86/mm/mem_encrypt_boot.S
> 
> diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
> index b406df2..8f6f9b4 100644
> --- a/arch/x86/include/asm/mem_encrypt.h
> +++ b/arch/x86/include/asm/mem_encrypt.h
> @@ -31,6 +31,12 @@ static inline u64 sme_dma_mask(void)
>  	return ((u64)sme_me_mask << 1) - 1;
>  }
>  
> +void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr,
> +			 unsigned long decrypted_kernel_vaddr,
> +			 unsigned long kernel_len,
> +			 unsigned long encryption_wa,
> +			 unsigned long encryption_pgd);
> +
>  void __init sme_early_encrypt(resource_size_t paddr,
>  			      unsigned long size);
>  void __init sme_early_decrypt(resource_size_t paddr,
> diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
> index 9e13841..0633142 100644
> --- a/arch/x86/mm/Makefile
> +++ b/arch/x86/mm/Makefile
> @@ -38,3 +38,5 @@ obj-$(CONFIG_NUMA_EMU)		+= numa_emulation.o
>  obj-$(CONFIG_X86_INTEL_MPX)	+= mpx.o
>  obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
>  obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
> +
> +obj-$(CONFIG_AMD_MEM_ENCRYPT)	+= mem_encrypt_boot.o
> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
> index 30b07a3..0ff41a4 100644
> --- a/arch/x86/mm/mem_encrypt.c
> +++ b/arch/x86/mm/mem_encrypt.c
> @@ -24,6 +24,7 @@
>  #include <asm/setup.h>
>  #include <asm/bootparam.h>
>  #include <asm/cacheflush.h>
> +#include <asm/sections.h>
>  
>  /*
>   * Since SME related variables are set early in the boot process they must
> @@ -216,8 +217,269 @@ void swiotlb_set_mem_attributes(void *vaddr, unsigned long size)
>  	set_memory_decrypted((unsigned long)vaddr, size >> PAGE_SHIFT);
>  }
>  
> +void __init sme_clear_pgd(pgd_t *pgd_base, unsigned long start,

static

> +			  unsigned long end)
> +{
> +	unsigned long addr = start;
> +	pgdval_t *pgd_p;
> +
> +	while (addr < end) {
> +		unsigned long pgd_end;
> +
> +		pgd_end = (addr & PGDIR_MASK) + PGDIR_SIZE;
> +		if (pgd_end > end)
> +			pgd_end = end;
> +
> +		pgd_p = (pgdval_t *)pgd_base + pgd_index(addr);
> +		*pgd_p = 0;

Hmm, so this is a contiguous range from [start:end] which translates to
8-byte PGD pointers in the PGD page so you can simply memset that range,
no?

Instead of iterating over each one?

> +
> +		addr = pgd_end;
> +	}
> +}
> +
> +#define PGD_FLAGS	_KERNPG_TABLE_NOENC
> +#define PUD_FLAGS	_KERNPG_TABLE_NOENC
> +#define PMD_FLAGS	(__PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL)
> +
> +static void __init *sme_populate_pgd(pgd_t *pgd_base, void *pgtable_area,
> +				     unsigned long vaddr, pmdval_t pmd_val)
> +{
> +	pgdval_t pgd, *pgd_p;
> +	pudval_t pud, *pud_p;
> +	pmdval_t pmd, *pmd_p;

You should use the enclosing type, not the underlying one. I.e.,

	pgd_t *pgd;
	pud_t *pud;
	...

and then the macros native_p*d_val(), p*d_offset() and so on. I say
native_* because we don't want to have any paravirt nastyness here.
I believe your previous version was using the proper interfaces.

And the kernel has gotten 5-level pagetables support in
the meantime, so this'll need to start at p4d AFAICT.
arch/x86/mm/fault.c::dump_pagetable() looks like a good example to stare
at.

> +	pgd_p = (pgdval_t *)pgd_base + pgd_index(vaddr);
> +	pgd = *pgd_p;
> +	if (pgd) {
> +		pud_p = (pudval_t *)(pgd & ~PTE_FLAGS_MASK);
> +	} else {
> +		pud_p = pgtable_area;
> +		memset(pud_p, 0, sizeof(*pud_p) * PTRS_PER_PUD);
> +		pgtable_area += sizeof(*pud_p) * PTRS_PER_PUD;
> +
> +		*pgd_p = (pgdval_t)pud_p + PGD_FLAGS;
> +	}
> +
> +	pud_p += pud_index(vaddr);
> +	pud = *pud_p;
> +	if (pud) {
> +		if (pud & _PAGE_PSE)
> +			goto out;
> +
> +		pmd_p = (pmdval_t *)(pud & ~PTE_FLAGS_MASK);
> +	} else {
> +		pmd_p = pgtable_area;
> +		memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD);
> +		pgtable_area += sizeof(*pmd_p) * PTRS_PER_PMD;
> +
> +		*pud_p = (pudval_t)pmd_p + PUD_FLAGS;
> +	}
> +
> +	pmd_p += pmd_index(vaddr);
> +	pmd = *pmd_p;
> +	if (!pmd || !(pmd & _PAGE_PSE))
> +		*pmd_p = pmd_val;
> +
> +out:
> +	return pgtable_area;
> +}
> +
> +static unsigned long __init sme_pgtable_calc(unsigned long len)
> +{
> +	unsigned long pud_tables, pmd_tables;
> +	unsigned long total = 0;
> +
> +	/*
> +	 * Perform a relatively simplistic calculation of the pagetable
> +	 * entries that are needed. That mappings will be covered by 2MB
> +	 * PMD entries so we can conservatively calculate the required
> +	 * number of PUD and PMD structures needed to perform the mappings.
> +	 * Incrementing the count for each covers the case where the
> +	 * addresses cross entries.
> +	 */
> +	pud_tables = ALIGN(len, PGDIR_SIZE) / PGDIR_SIZE;
> +	pud_tables++;
> +	pmd_tables = ALIGN(len, PUD_SIZE) / PUD_SIZE;
> +	pmd_tables++;
> +
> +	total += pud_tables * sizeof(pud_t) * PTRS_PER_PUD;
> +	total += pmd_tables * sizeof(pmd_t) * PTRS_PER_PMD;
> +
> +	/*
> +	 * Now calculate the added pagetable structures needed to populate
> +	 * the new pagetables.
> +	 */

Nice commenting, helps following what's going on.

> +	pud_tables = ALIGN(total, PGDIR_SIZE) / PGDIR_SIZE;
> +	pmd_tables = ALIGN(total, PUD_SIZE) / PUD_SIZE;
> +
> +	total += pud_tables * sizeof(pud_t) * PTRS_PER_PUD;
> +	total += pmd_tables * sizeof(pmd_t) * PTRS_PER_PMD;
> +
> +	return total;
> +}
> +
>  void __init sme_encrypt_kernel(void)
>  {
> +	pgd_t *pgd;
> +	void *pgtable_area;
> +	unsigned long kernel_start, kernel_end, kernel_len;
> +	unsigned long workarea_start, workarea_end, workarea_len;
> +	unsigned long execute_start, execute_end, execute_len;
> +	unsigned long pgtable_area_len;
> +	unsigned long decrypted_base;
> +	unsigned long paddr, pmd_flags;


Please sort function local variables declaration in a reverse christmas
tree order:

	<type> longest_variable_name;
	<type> shorter_var_name;
	<type> even_shorter;
	<type> i;

> +
> +	if (!sme_active())
> +		return;

...

> diff --git a/arch/x86/mm/mem_encrypt_boot.S b/arch/x86/mm/mem_encrypt_boot.S
> new file mode 100644
> index 0000000..fb58f9f
> --- /dev/null
> +++ b/arch/x86/mm/mem_encrypt_boot.S
> @@ -0,0 +1,151 @@
> +/*
> + * AMD Memory Encryption Support
> + *
> + * Copyright (C) 2016 Advanced Micro Devices, Inc.
> + *
> + * Author: Tom Lendacky <thomas.lendacky@amd.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/pgtable.h>
> +#include <asm/page.h>
> +#include <asm/processor-flags.h>
> +#include <asm/msr-index.h>
> +
> +	.text
> +	.code64
> +ENTRY(sme_encrypt_execute)
> +
> +	/*
> +	 * Entry parameters:
> +	 *   RDI - virtual address for the encrypted kernel mapping
> +	 *   RSI - virtual address for the decrypted kernel mapping
> +	 *   RDX - length of kernel
> +	 *   RCX - virtual address of the encryption workarea, including:
> +	 *     - stack page (PAGE_SIZE)
> +	 *     - encryption routine page (PAGE_SIZE)
> +	 *     - intermediate copy buffer (PMD_PAGE_SIZE)
> +	 *    R8 - physcial address of the pagetables to use for encryption
> +	 */
> +
> +	push	%rbp
> +	push	%r12
> +
> +	/* Set up a one page stack in the non-encrypted memory area */
> +	movq	%rsp, %rbp		/* Save current stack pointer */
> +	movq	%rcx, %rax		/* Workarea stack page */
> +	movq	%rax, %rsp		/* Set new stack pointer */
> +	addq	$PAGE_SIZE, %rsp	/* Stack grows from the bottom */
> +	addq	$PAGE_SIZE, %rax	/* Workarea encryption routine */
> +
> +	movq	%rdi, %r10		/* Encrypted kernel */
> +	movq	%rsi, %r11		/* Decrypted kernel */
> +	movq	%rdx, %r12		/* Kernel length */
> +
> +	/* Copy encryption routine into the workarea */
> +	movq	%rax, %rdi		/* Workarea encryption routine */
> +	leaq	.Lenc_start(%rip), %rsi	/* Encryption routine */
> +	movq	$(.Lenc_stop - .Lenc_start), %rcx	/* Encryption routine length */
> +	rep	movsb
> +
> +	/* Setup registers for call */
> +	movq	%r10, %rdi		/* Encrypted kernel */
> +	movq	%r11, %rsi		/* Decrypted kernel */
> +	movq	%r8, %rdx		/* Pagetables used for encryption */
> +	movq	%r12, %rcx		/* Kernel length */
> +	movq	%rax, %r8		/* Workarea encryption routine */
> +	addq	$PAGE_SIZE, %r8		/* Workarea intermediate copy buffer */
> +
> +	call	*%rax			/* Call the encryption routine */
> +
> +	movq	%rbp, %rsp		/* Restore original stack pointer */
> +
> +	pop	%r12
> +	pop	%rbp
> +
> +	ret
> +ENDPROC(sme_encrypt_execute)
> +
> +.Lenc_start:
> +ENTRY(sme_enc_routine)

A function called a "routine"? Why do we need the global symbol?
Nothing's referencing it AFAICT.

> +/*
> + * Routine used to encrypt kernel.
> + *   This routine must be run outside of the kernel proper since
> + *   the kernel will be encrypted during the process. So this
> + *   routine is defined here and then copied to an area outside
> + *   of the kernel where it will remain and run decrypted
> + *   during execution.
> + *
> + *   On entry the registers must be:
> + *     RDI - virtual address for the encrypted kernel mapping
> + *     RSI - virtual address for the decrypted kernel mapping
> + *     RDX - address of the pagetables to use for encryption
> + *     RCX - length of kernel
> + *      R8 - intermediate copy buffer
> + *
> + *     RAX - points to this routine
> + *
> + * The kernel will be encrypted by copying from the non-encrypted
> + * kernel space to an intermediate buffer and then copying from the
> + * intermediate buffer back to the encrypted kernel space. The physical
> + * addresses of the two kernel space mappings are the same which
> + * results in the kernel being encrypted "in place".
> + */
> +	/* Enable the new page tables */
> +	mov	%rdx, %cr3
> +
> +	/* Flush any global TLBs */
> +	mov	%cr4, %rdx
> +	andq	$~X86_CR4_PGE, %rdx
> +	mov	%rdx, %cr4
> +	orq	$X86_CR4_PGE, %rdx
> +	mov	%rdx, %cr4
> +
> +	/* Set the PAT register PA5 entry to write-protect */
> +	push	%rcx
> +	movl	$MSR_IA32_CR_PAT, %ecx
> +	rdmsr
> +	push	%rdx			/* Save original PAT value */
> +	andl	$0xffff00ff, %edx	/* Clear PA5 */
> +	orl	$0x00000500, %edx	/* Set PA5 to WP */

Maybe check first whether PA5 is already set correctly and avoid the
WRMSR and the restoring below too?

> +	wrmsr
> +	pop	%rdx			/* RDX contains original PAT value */
> +	pop	%rcx
> +
> +	movq	%rcx, %r9		/* Save kernel length */
> +	movq	%rdi, %r10		/* Save encrypted kernel address */
> +	movq	%rsi, %r11		/* Save decrypted kernel address */
> +
> +	wbinvd				/* Invalidate any cache entries */
> +
> +	/* Copy/encrypt 2MB at a time */
> +1:
> +	movq	%r11, %rsi		/* Source - decrypted kernel */
> +	movq	%r8, %rdi		/* Dest   - intermediate copy buffer */
> +	movq	$PMD_PAGE_SIZE, %rcx	/* 2MB length */
> +	rep	movsb

not movsQ?

> +	movq	%r8, %rsi		/* Source - intermediate copy buffer */
> +	movq	%r10, %rdi		/* Dest   - encrypted kernel */
> +	movq	$PMD_PAGE_SIZE, %rcx	/* 2MB length */
> +	rep	movsb
> +
> +	addq	$PMD_PAGE_SIZE, %r11
> +	addq	$PMD_PAGE_SIZE, %r10
> +	subq	$PMD_PAGE_SIZE, %r9	/* Kernel length decrement */
> +	jnz	1b			/* Kernel length not zero? */
> +
> +	/* Restore PAT register */
> +	push	%rdx			/* Save original PAT value */
> +	movl	$MSR_IA32_CR_PAT, %ecx
> +	rdmsr
> +	pop	%rdx			/* Restore original PAT value */
> +	wrmsr
> +
> +	ret
> +ENDPROC(sme_enc_routine)
> +.Lenc_stop:
> 

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

* [PATCH] mm/swapfile.c: fix a minor coding style issue
From: Harish Jenny K N @ 2017-05-18 13:04 UTC (permalink / raw)
  To: linux-mm

This commit fixes a minor coding style issue in swapfile.c
adding an underscore in procswaps_init call.

Signed-off-by: Harish Jenny K N <harish_kandiga@mentor.com>
---
 mm/swapfile.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index 4f6cba1..9a6004c 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2426,12 +2426,12 @@ static int swaps_open(struct inode *inode, struct file *file)
 	.poll		= swaps_poll,
 };

-static int __init procswaps_init(void)
+static int __init proc_swaps_init(void)
 {
 	proc_create("swaps", 0, NULL, &proc_swaps_operations);
 	return 0;
 }
-__initcall(procswaps_init);
+__initcall(proc_swaps_init);
 #endif /* CONFIG_PROC_FS */

 #ifdef MAX_SWAPFILES_CHECK
--
1.9.1


--
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] mm,oom: fix oom invocation issues
From: Roman Gushchin @ 2017-05-18 13:20 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Tetsuo Handa, hannes, vdavydov.dev, kernel-team, linux-mm,
	linux-kernel
In-Reply-To: <20170518090039.GC25462@dhcp22.suse.cz>

On Thu, May 18, 2017 at 11:00:39AM +0200, Michal Hocko wrote:
> On Thu 18-05-17 10:47:29, Michal Hocko wrote:
> > 
> > Hmm, I guess you are right. I haven't realized that pagefault_out_of_memory
> > can race and pick up another victim. For some reason I thought that the
> > page fault would break out on fatal signal pending but we don't do that (we
> > used to in the past). Now that I think about that more we should
> > probably remove out_of_memory out of pagefault_out_of_memory completely.
> > It is racy and it basically doesn't have any allocation context so we
> > might kill a task from a different domain. So can we do this instead?
> > There is a slight risk that somebody might have returned VM_FAULT_OOM
> > without doing an allocation but from my quick look nobody does that
> > currently.
> 
> If this is considered too risky then we can do what Roman was proposing
> and check tsk_is_oom_victim in pagefault_out_of_memory and bail out.

Hi, Michal!

If we consider this approach, I've prepared a separate patch for this problem
(stripped all oom reaper list stuff).

Thanks!

^ permalink raw reply

* Strange condition in invalidate_mapping_pages()
From: Jan Kara @ 2017-05-18 13:28 UTC (permalink / raw)
  To: Kirill A. Shutemov; +Cc: linux-mm

Hi Kirill,

in commit fc127da085c26 "truncate: handle file thp" you've added the
following to invalidate_mapping_pages():

          /* Middle of THP: skip */
          if (PageTransTail(page)) {
                  unlock_page(page);
                  continue;
          } else if (PageTransHuge(page)) {
                  index += HPAGE_PMD_NR - 1;
                  i += HPAGE_PMD_NR - 1;
                  /* 'end' is in the middle of THP */
                  if (index ==  round_down(end, HPAGE_PMD_NR))
                          continue;
          }

Now how can ever condition "if (index ==  round_down(end,
HPAGE_PMD_NR))" be true? We have just added HPAGE_PMD_NR - 1 to 'index'
so it will not be a multiple of HPAGE_PMD_NR. Presumably you wanted to
check whether the current THP is the one containing 'end' here which would
be something like 'round_down(index, HPAGE_PMD_NR) == round_down(end,
HPAGE_PMD_NR)' but then I still miss why you'd like to avoid invalidating
the partial THP at the end of file... Can you please enlighten me? Thanks!

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
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,oom: fix oom invocation issues
From: Tetsuo Handa @ 2017-05-18 13:57 UTC (permalink / raw)
  To: mhocko; +Cc: guro, hannes, vdavydov.dev, kernel-team, linux-mm, linux-kernel
In-Reply-To: <20170518090039.GC25462@dhcp22.suse.cz>

Michal Hocko wrote:
> It is racy and it basically doesn't have any allocation context so we
> might kill a task from a different domain. So can we do this instead?
> There is a slight risk that somebody might have returned VM_FAULT_OOM
> without doing an allocation but from my quick look nobody does that
> currently.

I can't tell whether it is safe to remove out_of_memory() from pagefault_out_of_memory().
There are VM_FAULT_OOM users in fs/ directory. What happens if pagefault_out_of_memory()
was called as a result of e.g. GFP_NOFS allocation failure? Is it guaranteed that all
memory allocations that might occur from page fault event (or any action that might return
VM_FAULT_OOM) are allowed to call oom_kill_process() from out_of_memory() before
reaching pagefault_out_of_memory() ?

Anyway, I want

	/* Avoid allocations with no watermarks from looping endlessly */
-	if (test_thread_flag(TIF_MEMDIE))
+	if (alloc_flags == ALLOC_NO_WATERMARKS && test_thread_flag(TIF_MEMDIE))
		goto nopage;

so that we won't see similar backtraces and memory information from both
out_of_memory() and warn_alloc().

--
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: clarify why we want kmalloc before falling backto vmallock
From: Vlastimil Babka @ 2017-05-18 14:08 UTC (permalink / raw)
  To: Michal Hocko, Andrew Morton; +Cc: Chris Wilson, linux-mm, LKML, Michal Hocko
In-Reply-To: <20170517080932.21423-1-mhocko@kernel.org>

On 05/17/2017 10:09 AM, Michal Hocko wrote:
> From: Michal Hocko <mhocko@suse.com>
> 
> While converting drm_[cm]alloc* helpers to kvmalloc* variants Chris
> Wilson has wondered why we want to try kmalloc before vmalloc fallback
> even for larger allocations requests. Let's clarify that one larger
> physically contiguous block is less likely to fragment memory than many
> scattered pages which can prevent more large blocks from being created.
> 
> Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Michal Hocko <mhocko@suse.com>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

> ---
>  mm/util.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/util.c b/mm/util.c
> index 464df3489903..87499f8119f2 100644
> --- a/mm/util.c
> +++ b/mm/util.c
> @@ -357,7 +357,10 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
>  	WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL);
>  
>  	/*
> -	 * Make sure that larger requests are not too disruptive - no OOM
> +	 * We want to attempt a large physically contiguous block first because
> +	 * it is less likely to fragment multiple larger blocks and therefore
> +	 * contribute to a long term fragmentation less than vmalloc fallback.
> +	 * However make sure that larger requests are not too disruptive - no OOM
>  	 * killer and no allocation failure warnings as we have a fallback
>  	 */
>  	if (size > PAGE_SIZE) {
> 

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