LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/5] powerpc/ftrace: Fix nop of modules on 64bit LE (ABIv2)
From: Michael Ellerman @ 2014-06-17  6:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Anton Blanchard, dcb314
In-Reply-To: <1402985736-32180-1-git-send-email-mpe@ellerman.id.au>

There is a bug in the handling of the function entry when we are nopping
out a branch from a module in ftrace.

We compare the result of module_trampoline_target() with the value of
ppc_function_entry(), and expect them to be true. But they never will
be.

module_trampoline_target() will always return the global entry point of
the function, whereas ppc_function_entry() will always return the local.

Fix it by using the newly added ppc_global_function_entry().

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/ftrace.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 8fc0c17..96efc66 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -105,7 +105,7 @@ __ftrace_make_nop(struct module *mod,
 		  struct dyn_ftrace *rec, unsigned long addr)
 {
 	unsigned int op;
-	unsigned long ptr;
+	unsigned long entry, ptr;
 	unsigned long ip = rec->ip;
 	void *tramp;
 
@@ -136,10 +136,11 @@ __ftrace_make_nop(struct module *mod,
 
 	pr_devel("trampoline target %lx", ptr);
 
+	entry = ppc_global_function_entry((void *)addr);
 	/* This should match what was called */
-	if (ptr != ppc_function_entry((void *)addr)) {
+	if (ptr != entry) {
 		printk(KERN_ERR "addr %lx does not match expected %lx\n",
-			ptr, ppc_function_entry((void *)addr));
+			ptr, entry);
 		return -EINVAL;
 	}
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/5] powerpc/ftrace: Fix inverted check of create_branch()
From: Michael Ellerman @ 2014-06-17  6:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Anton Blanchard, dcb314
In-Reply-To: <1402985736-32180-1-git-send-email-mpe@ellerman.id.au>

In commit 24a1bdc35, "Fix ABIv2 issues with __ftrace_make_call", Anton
changed the logic that creates and patches the branch, and added a
thinko in the check of create_branch(). create_branch() returns the
instruction that was generated, so if we get zero then it succeeded.

The result is we can't ftrace modules:

  Branch out of range
  WARNING: at ../kernel/trace/ftrace.c:1638
  ftrace failed to modify [<d000000004ba001c>] fuse_req_init_context+0x1c/0x90 [fuse]

We should probably fix patch_instruction() to do that check and make the
API saner, but that's a separate patch. For now just invert the test.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/ftrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index f5d1a34..8fc0c17 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -320,7 +320,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	}
 
 	/* Ensure branch is within 24 bits */
-	if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
+	if (!create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
 		printk(KERN_ERR "Branch out of range");
 		return -EINVAL;
 	}
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/5] powerpc/ftrace: Fix typo in mask of opcode
From: Michael Ellerman @ 2014-06-17  6:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Anton Blanchard, dcb314
In-Reply-To: <1402985736-32180-1-git-send-email-mpe@ellerman.id.au>

In commit 24a1bdc35, "Fix ABIv2 issues with __ftrace_make_call", Anton
changed the logic that checks for the expected code sequence when
patching a module.

We missed the typo in the mask, 0xffff00000 should be 0xffff0000, which
has the effect of making the test always true.

That makes it impossible to ftrace against modules, eg:

  Unexpected call sequence: 48000008 e8410018
  WARNING: at ../kernel/trace/ftrace.c:1638
  ftrace failed to modify [<d000000007cf001c>] rng_dev_open+0x1c/0x70 [rng_core]

Reported-by: David Binderman <dcb314@hotmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/ftrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index f202d07..f5d1a34 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -307,7 +307,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 	 * The load offset is different depending on the ABI. For simplicity
 	 * just mask it out when doing the compare.
 	 */
-	if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) {
+	if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) {
 		printk(KERN_ERR "Unexpected call sequence: %x %x\n",
 			op[0], op[1]);
 		return -EINVAL;
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/5] powerpc: Add ppc_global_function_entry()
From: Michael Ellerman @ 2014-06-17  6:15 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Anton Blanchard, dcb314

ABIv2 has the concept of a global and local entry point to a function.
In most cases we are interested in the local entry point, and so that is
what ppc_function_entry() returns.

However we have a case in the ftrace code where we want the global entry
point, and there may be other places we need it too. Rather than special
casing each, add an accessor.

For ABIv1 and 32-bit there is only a single entry point, so we return
that. That means it's safe for the caller to use this without also
checking the ABI version.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/code-patching.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 37991e1..840a550 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -88,4 +88,15 @@ static inline unsigned long ppc_function_entry(void *func)
 #endif
 }
 
+static inline unsigned long ppc_global_function_entry(void *func)
+{
+#if defined(CONFIG_PPC64) && defined(_CALL_ELF) && _CALL_ELF == 2
+	/* PPC64 ABIv2 the global entry point is at the address */
+	return (unsigned long)func;
+#else
+	/* All other cases there is no change vs ppc_function_entry() */
+	return ppc_function_entry(func);
+#endif
+}
+
 #endif /* _ASM_POWERPC_CODE_PATCHING_H */
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v1] fs2dt: Refine kdump device_tree sort
From: Yang,Wei @ 2014-06-17  6:01 UTC (permalink / raw)
  To: Wei.Yang, horms; +Cc: linuxppc-dev, linux-kernel, linux-arm-kernel
In-Reply-To: <1402550168-7826-1-git-send-email-Wei.Yang@windriver.com>

Hi Simon,

How about this patch?

Thanks
Wei
On 06/12/2014 01:16 PM, Wei.Yang@windriver.com wrote:
> From: Yang Wei <Wei.Yang@windriver.com>
>
> The commit b02d735bf was to rearrange the device-tree entries, and
> assumed that these entries are sorted in the ascending order. but
> acctually when I was validating kexec and kdump, the order of
> serial node still is changed. We should not only compare the length
> of directory name, but also compare the directory name, it would
> ensure that the order of device node is really in ascending order.
>
> Signed-off-by: Yang Wei <Wei.Yang@windriver.com>
> ---
>   kexec/fs2dt.c |   13 ++++++++++---
>   1 file changed, 10 insertions(+), 3 deletions(-)
>
> 		It is validated on Freescale t4240qds.
>
> diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c
> index 1e5f074..0bffaf5 100644
> --- a/kexec/fs2dt.c
> +++ b/kexec/fs2dt.c
> @@ -479,6 +479,9 @@ static int comparefunc(const struct dirent **dentry1,
>   {
>   	char *str1 = (*(struct dirent **)dentry1)->d_name;
>   	char *str2 = (*(struct dirent **)dentry2)->d_name;
> +	char* ptr1 = strchr(str1, '@');
> +	char* ptr2 = strchr(str2, '@');
> +	int len1, len2;
>   
>   	/*
>   	 * strcmp scans from left to right and fails to idetify for some
> @@ -486,9 +489,13 @@ static int comparefunc(const struct dirent **dentry1,
>   	 * Therefore, we get the wrong sorted order like memory@10000000 and
>   	 * memory@f000000.
>   	 */
> -	if (strchr(str1, '@') && strchr(str2, '@') &&
> -		(strlen(str1) > strlen(str2)))
> -		return 1;
> +	if (ptr1 && ptr2) {
> +		len1 = ptr1 - str1;
> +		len2 = ptr2 - str2;
> +		if (!strncmp(str1, str2, len1 >len2 ? len1: len2) &&
> +					(strlen(str1) > strlen(str2)))
> +				return 1;
> +	}
>   
>   	return strcmp(str1, str2);
>   }

^ permalink raw reply

* Re: [PATCH] powerpc: Fix build warning
From: Guenter Roeck @ 2014-06-17  2:02 UTC (permalink / raw)
  To: David Rientjes
  Cc: Vincent Guittot, Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <alpine.DEB.2.02.1406161824340.21018@chino.kir.corp.google.com>

On 06/16/2014 06:25 PM, David Rientjes wrote:
> On Fri, 13 Jun 2014, Guenter Roeck wrote:
>
>> If compiled with W=1, the following warning is seen in powerpc builds.
>>
>> arch/powerpc/kernel/smp.c:750:18: warning:
>> 	type qualifiers ignored on function return type
>> static const int powerpc_smt_flags(void)
>>                   ^
>>
>> This is caused by a function returning 'const int', which doesn't
>> make sense to gcc. Drop 'const' to fix the problem.
>>
>> Reported-by: Vincent Guittot <vincent.guittot@linaro.org>
>> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>
> Acked-by: David Rientjes <rientjes@google.com>
>
> Although it's strange you report this happening on line 750 in the
> changelog but the patch shows it differently.
>

In the latest kernel (v3.16-rc1) the function is at line 750.
It appears that I ran the build test on a later version than
the one I used to write the patch. Hope that is not a problem.

Guenter

^ permalink raw reply

* Re: [PATCH v3 -next 1/9] DMA, CMA: fix possible memory leak
From: Joonsoo Kim @ 2014-06-17  1:33 UTC (permalink / raw)
  To: Minchan Kim
  Cc: kvm-ppc, Russell King - ARM Linux, kvm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, Michal Nazarewicz,
	linux-kernel, linux-mm, Paul Mackerras, Aneesh Kumar K.V,
	Paolo Bonzini, Andrew Morton, Zhang Yanfei, linuxppc-dev,
	linux-arm-kernel, Marek Szyprowski
In-Reply-To: <20140616062719.GA18790@bbox>

On Mon, Jun 16, 2014 at 03:27:19PM +0900, Minchan Kim wrote:
> Hi, Joonsoo
> 
> On Mon, Jun 16, 2014 at 02:40:43PM +0900, Joonsoo Kim wrote:
> > We should free memory for bitmap when we find zone mis-match,
> > otherwise this memory will leak.
> > 
> > Additionally, I copy code comment from PPC KVM's CMA code to inform
> > why we need to check zone mis-match.
> > 
> > * Note
> > Minchan suggested to add a tag for the stable, but, I don't do it,
> > because I found this possibility during code-review and, IMO,
> > this patch isn't suitable for stable tree.
> 
> Nice idea to put the comment in here. Thanks Joonsoo.
> 
> It seems you obey "It must fix a real bug that bothers people"
> on Documentation/stable_kernel_rules.txt but it's a really obvious
> bug and hard to get a report from people because limited user and
> hard to detect small such small memory leak.
> 
> In my experince, Andrew perfered stable marking for such a obvious
> problem but simple fix like this but not sure so let's pass the decision
> to him and will learn a lesson from him and will follow the decision
> from now on.

Yes, I intended to pass the decision to others. :)

> 
> Thanks.
> 
> Acked-by: Minchan Kim <minchan@kernel.org>

Thanks.

^ permalink raw reply

* Re: [PATCH] powerpc: Fix build warning
From: David Rientjes @ 2014-06-17  1:25 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: Vincent Guittot, Paul Mackerras, linuxppc-dev, linux-kernel
In-Reply-To: <1402677499-28289-1-git-send-email-linux@roeck-us.net>

On Fri, 13 Jun 2014, Guenter Roeck wrote:

> If compiled with W=1, the following warning is seen in powerpc builds.
> 
> arch/powerpc/kernel/smp.c:750:18: warning:
> 	type qualifiers ignored on function return type
> static const int powerpc_smt_flags(void)
>                  ^
> 
> This is caused by a function returning 'const int', which doesn't
> make sense to gcc. Drop 'const' to fix the problem.
> 
> Reported-by: Vincent Guittot <vincent.guittot@linaro.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>

Acked-by: David Rientjes <rientjes@google.com>

Although it's strange you report this happening on line 750 in the 
changelog but the patch shows it differently.

> ---
>  arch/powerpc/kernel/smp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index 10ffffe..49d5d4e 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -768,7 +768,7 @@ int setup_profiling_timer(unsigned int multiplier)
>  
>  #ifdef CONFIG_SCHED_SMT
>  /* cpumask of CPUs with asymetric SMT dependancy */
> -static const int powerpc_smt_flags(void)
> +static int powerpc_smt_flags(void)
>  {
>  	int flags = SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES;
>  

^ permalink raw reply

* Re: [PATCH v3 -next 0/9] CMA: generalize CMA reserved area management code
From: Joonsoo Kim @ 2014-06-17  1:25 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: kvm-ppc, Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, Michal Nazarewicz,
	linux-kernel, Minchan Kim, Paul Mackerras, Aneesh Kumar K.V,
	Paolo Bonzini, Andrew Morton, Zhang Yanfei, linuxppc-dev,
	linux-arm-kernel
In-Reply-To: <539EB4C7.3080106@samsung.com>

On Mon, Jun 16, 2014 at 11:11:35AM +0200, Marek Szyprowski wrote:
> Hello,
> 
> On 2014-06-16 07:40, Joonsoo Kim wrote:
> >Currently, there are two users on CMA functionality, one is the DMA
> >subsystem and the other is the KVM on powerpc. They have their own code
> >to manage CMA reserved area even if they looks really similar.
> >>From my guess, it is caused by some needs on bitmap management. Kvm side
> >wants to maintain bitmap not for 1 page, but for more size. Eventually it
> >use bitmap where one bit represents 64 pages.
> >
> >When I implement CMA related patches, I should change those two places
> >to apply my change and it seem to be painful to me. I want to change
> >this situation and reduce future code management overhead through
> >this patch.
> >
> >This change could also help developer who want to use CMA in their
> >new feature development, since they can use CMA easily without
> >copying & pasting this reserved area management code.
> >
> >v3:
> >   - Simplify old patch 1(log format fix) and move it to the end of patchset.
> >   - Patch 2: Pass aligned base and size to dma_contiguous_early_fixup()
> >   - Patch 5: Add some accessor functions to pass aligned base and size to
> >   dma_contiguous_early_fixup() function
> >   - Patch 5: Move MAX_CMA_AREAS definition to cma.h
> >   - Patch 6: Add CMA region zeroing to PPC KVM's CMA alloc function
> >   - Patch 8: put 'base' ahead of 'size' in cma_declare_contiguous()
> >   - Remaining minor fixes are noted in commit description of each one
> >
> >v2:
> >   - Although this patchset looks very different with v1, the end result,
> >   that is, mm/cma.c is same with v1's one. So I carry Ack to patch 6-7.
> >
> >This patchset is based on linux-next 20140610.
> 
> Thanks for taking care of this. I will test it with my setup and if
> everything goes well, I will take it to my -next tree. If any branch
> is required for anyone to continue his works on top of those patches,
> let me know, I will also prepare it.

Hello,

I'm glad to hear that. :)
But, there is one concern. As you already know, I am preparing further
patches (Aggressively allocate the pages on CMA reserved memory). It
may be highly related to MM branch and also slightly depends on this CMA
changes. In this case, what is the best strategy to merge this
patchset? IMHO, Anrew's tree is more appropriate branch. If there is
no issue in this case, I am willing to develope further patches based
on your tree.

Thanks.

^ permalink raw reply

* Re: [PATCH 23/38] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
From: Ulf Hansson @ 2014-06-16 16:10 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Barry Song, Anton Vorontsov, Stephen Warren, spear-devel,
	linux-mmc, Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra@vger.kernel.org, linuxppc-dev,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <CAPDyKFrp8JokqBbo3rg2i6WYykU1C9CuPF0FL7AOHh=Gcp5=hg@mail.gmail.com>

On 16 June 2014 14:17, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 16 June 2014 12:46, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:
>> On Wed, Apr 23, 2014 at 08:08:07PM +0100, Russell King wrote:
>>> @@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>>>                       host->ops->set_clock(host, host->clock);
>>>               }
>>>
>>> -             if (host->ops->set_uhs_signaling)
>>> -                     host->ops->set_uhs_signaling(host, ios->timing);
>>> -             else {
>>> -                     ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
>>> -                     /* Select Bus Speed Mode for host */
>>> -                     ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
>>> -                     if ((ios->timing == MMC_TIMING_MMC_HS200) ||
>>> -                         (ios->timing == MMC_TIMING_UHS_SDR104))
>>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
>>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR12)
>>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
>>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR25)
>>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
>>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR50)
>>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
>>> -                     else if (ios->timing == MMC_TIMING_UHS_DDR50)
>>> -                             ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
>>> -                     sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
>>> -             }
>>> +             host->ops->set_uhs_signaling(host, ios->timing);
>>>
>>>               if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
>>>                               ((ios->timing == MMC_TIMING_UHS_SDR12) ||
>>
>> Whoever decided to poorly pick these patches up against my will has
>> slightly messed this patch up - whereas my original patch left the
>> code correctly formatted, when whoever applied this patch did so, they
>> left an additional blank line in the above.
>

[snip]

> Please, feel free to send a patch to fixup my misstake. I will happily apply it.

I had a second look to fix it up myself, but I just can't find that
your patch was different than the one I applied (beside the conflict I
resolved).

If you do find any other issue regarding the patches in this patchset
- please let me know and I will try to help.

Kind regards
Uffe

^ permalink raw reply

* [PATCH tty-next 14/22] tty: Remove tty_wait_until_sent_from_close()
From: Peter Hurley @ 2014-06-16 13:17 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: One Thousand Gnomes, Karsten Keil, Peter Hurley, linux-kernel,
	linux-serial, linuxppc-dev
In-Reply-To: <1402924639-5164-1-git-send-email-peter@hurleysoftware.com>

tty_wait_until_sent_from_close() drops the tty lock while waiting
for the tty driver to finish sending previously accepted data (ie.,
data remaining in its write buffer and transmit fifo).

However, dropping the tty lock is a hold-over from when the tty
lock was system-wide; ie., one lock for all ttys.

Since commit 89c8d91e31f267703e365593f6bfebb9f6d2ad01,
'tty: localise the lock', dropping the tty lock has not been necessary.

CC: Karsten Keil <isdn@linux-pingi.de>
CC: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
 drivers/isdn/i4l/isdn_tty.c   |  2 +-
 drivers/tty/hvc/hvc_console.c |  2 +-
 drivers/tty/hvc/hvcs.c        |  2 +-
 drivers/tty/tty_port.c        | 11 ++---------
 include/linux/tty.h           | 18 ------------------
 5 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3c5f249..732f68a 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1587,7 +1587,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	 * line status register.
 	 */
 	if (port->flags & ASYNC_INITIALIZED) {
-		tty_wait_until_sent_from_close(tty, 3000);	/* 30 seconds timeout */
+		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 0ff7fda..2297dc7 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -417,7 +417,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 		 * there is no buffered data otherwise sleeps on a wait queue
 		 * waking periodically to check chars_in_buffer().
 		 */
-		tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT);
+		tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
 	} else {
 		if (hp->port.count < 0)
 			printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 81e939e..236302d 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1230,7 +1230,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		irq = hvcsd->vdev->irq;
 		spin_unlock_irqrestore(&hvcsd->lock, flags);
 
-		tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT);
+		tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
 
 		/*
 		 * This line is important because it tells hvcs_open that this
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 1b93357..6b6214b 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -464,10 +464,7 @@ static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
 	schedule_timeout_interruptible(timeout);
 }
 
-/* Caller holds tty lock.
- * NB: may drop and reacquire tty lock (in tty_wait_until_sent_from_close())
- * so tty and tty port may have changed state (but not hung up or reopened).
- */
+/* Caller holds tty lock. */
 int tty_port_close_start(struct tty_port *port,
 				struct tty_struct *tty, struct file *filp)
 {
@@ -505,7 +502,7 @@ int tty_port_close_start(struct tty_port *port,
 		if (tty->flow_stopped)
 			tty_driver_flush_buffer(tty);
 		if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-			tty_wait_until_sent_from_close(tty, port->closing_wait);
+			tty_wait_until_sent(tty, port->closing_wait);
 		if (port->drain_delay)
 			tty_port_drain_delay(port, tty);
 	}
@@ -545,10 +542,6 @@ EXPORT_SYMBOL(tty_port_close_end);
  * tty_port_close
  *
  * Caller holds tty lock
- *
- * NB: may drop and reacquire tty lock (in tty_port_close_start()->
- * tty_wait_until_sent_from_close()) so tty and tty_port may have changed
- * state (but not hung up or reopened).
  */
 void tty_port_close(struct tty_port *port, struct tty_struct *tty,
 							struct file *filp)
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1c3316a..f3eb70d 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -644,24 +644,6 @@ extern void __lockfunc tty_unlock_pair(struct tty_struct *tty,
 				struct tty_struct *tty2);
 
 /*
- * this shall be called only from where BTM is held (like close)
- *
- * We need this to ensure nobody waits for us to finish while we are waiting.
- * Without this we were encountering system stalls.
- *
- * This should be indeed removed with BTM removal later.
- *
- * Locking: BTM required. Nobody is allowed to hold port->mutex.
- */
-static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,
-		long timeout)
-{
-	tty_unlock(tty); /* tty->ops->close holds the BTM, drop it while waiting */
-	tty_wait_until_sent(tty, timeout);
-	tty_lock(tty);
-}
-
-/*
  * wait_event_interruptible_tty -- wait for a condition with the tty lock held
  *
  * The condition we are waiting for might take a long time to
-- 
2.0.0

^ permalink raw reply related

* Re: [PATCH 0/2] backlight: remove trivial get_brightness implementations
From: Lee Jones @ 2014-06-16 13:32 UTC (permalink / raw)
  To: Jingoo Han
  Cc: 'Milo Kim', 'open list:FRAMEBUFFER LAYER',
	'open list:X86 PLATFORM DRIVERS', 'Andrzej Hajda',
	'Thierry Reding', 'Laurent Pinchart',
	'Yijing Wang', 'Matthew Garrett',
	'Kukjin Kim', 'Sachin Kamat',
	'Tomi Valkeinen', 'Geert Uytterhoeven',
	'Daniel Vetter',
	'Jean-Christophe Plagniol-Villard',
	'Dan Carpenter', 'open list:PWM SUBSYSTEM',
	'Bryan Wu', 'moderated list:ARM/S5P EXYNOS AR...',
	'Mikulas Patocka',
	'moderated list:ARM/S5P EXYNOS AR...',
	'Randy Dunlap', 'open list', 'Rob Clark',
	'Jon Mason', 'Joe Perches',
	'open list:LINUX FOR POWER M...'
In-Reply-To: <000701cf895e$6a648f20$3f2dad60$%han@samsung.com>

On Mon, 16 Jun 2014, Jingoo Han wrote:

> On Friday, May 30, 2014 7:11 PM, Andrzej Hajda wrote:
> > 
> > This patchset makes get_brightness callback optional
> > and removes trivial implementations.
> > Driver changes are quite obvious so I have put them into single
> > patch.
> > 
> > The patchset is based on the current linux-next branch.
> > 
> > Regards
> > Andrzej
> > 
> > Andrzej Hajda (2):
> >   backlight: show brightness even if get_brightness is not implemented
> >   backlight: remove trivial get_brightness implementations
> 
> These patches look good!
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> 
> Lee Jones,
> Would you merge these patches into backlight git?

Yep, done.

NB: You don't have to ask.  I'll see that you've reviewed/acked the
patches and just apply them automatically (provided I'm on the CC list
of course).

> >  drivers/macintosh/via-pmu-backlight.c      | 6 ------
> >  drivers/platform/x86/samsung-q10.c         | 6 ------
> >  drivers/video/backlight/aat2870_bl.c       | 6 ------
> >  drivers/video/backlight/ams369fg06.c       | 6 ------
> >  drivers/video/backlight/backlight.c        | 2 ++
> >  drivers/video/backlight/bd6107.c           | 6 ------
> >  drivers/video/backlight/gpio_backlight.c   | 6 ------
> >  drivers/video/backlight/ld9040.c           | 6 ------
> >  drivers/video/backlight/lp855x_bl.c        | 6 ------
> >  drivers/video/backlight/lp8788_bl.c        | 6 ------
> >  drivers/video/backlight/lv5207lp.c         | 6 ------
> >  drivers/video/backlight/pandora_bl.c       | 6 ------
> >  drivers/video/backlight/pwm_bl.c           | 6 ------
> >  drivers/video/backlight/s6e63m0.c          | 6 ------
> >  drivers/video/backlight/tps65217_bl.c      | 6 ------
> >  drivers/video/fbdev/aty/aty128fb.c         | 6 ------
> >  drivers/video/fbdev/aty/atyfb_base.c       | 6 ------
> >  drivers/video/fbdev/aty/radeon_backlight.c | 6 ------
> >  drivers/video/fbdev/exynos/s6e8ax0.c       | 6 ------
> >  drivers/video/fbdev/nvidia/nv_backlight.c  | 6 ------
> >  drivers/video/fbdev/riva/fbdev.c           | 6 ------
> >  21 files changed, 2 insertions(+), 120 deletions(-)
> > 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH 0/2] backlight: remove trivial get_brightness implementations
From: Jingoo Han @ 2014-06-16 12:28 UTC (permalink / raw)
  To: 'Andrzej Hajda', 'Lee Jones', 'Bryan Wu'
  Cc: 'Milo Kim', 'open list:FRAMEBUFFER LAYER',
	'open list:X86 PLATFORM DRIVERS',
	'Thierry Reding', 'Laurent Pinchart',
	'Yijing Wang', 'Matthew Garrett',
	'Kukjin Kim', 'Sachin Kamat',
	'Jingoo Han', 'Tomi Valkeinen',
	'Geert Uytterhoeven', 'Daniel Vetter',
	'Jean-Christophe Plagniol-Villard',
	'Dan Carpenter', 'open list:PWM SUBSYSTEM',
	'moderated list:ARM/S5P EXYNOS AR...',
	'Mikulas Patocka',
	'moderated list:ARM/S5P EXYNOS AR...',
	'Randy Dunlap', 'open list', 'Rob Clark',
	'Jon Mason', 'Joe Perches',
	'open list:LINUX FOR POWER M...'
In-Reply-To: <1401444650-12267-1-git-send-email-a.hajda@samsung.com>

On Friday, May 30, 2014 7:11 PM, Andrzej Hajda wrote:
> 
> This patchset makes get_brightness callback optional
> and removes trivial implementations.
> Driver changes are quite obvious so I have put them into single
> patch.
> 
> The patchset is based on the current linux-next branch.
> 
> Regards
> Andrzej
> 
> Andrzej Hajda (2):
>   backlight: show brightness even if get_brightness is not implemented
>   backlight: remove trivial get_brightness implementations

These patches look good!
Acked-by: Jingoo Han <jg1.han@samsung.com>

Lee Jones,
Would you merge these patches into backlight git?

Best regards,
Jingoo Han

> 
>  drivers/macintosh/via-pmu-backlight.c      | 6 ------
>  drivers/platform/x86/samsung-q10.c         | 6 ------
>  drivers/video/backlight/aat2870_bl.c       | 6 ------
>  drivers/video/backlight/ams369fg06.c       | 6 ------
>  drivers/video/backlight/backlight.c        | 2 ++
>  drivers/video/backlight/bd6107.c           | 6 ------
>  drivers/video/backlight/gpio_backlight.c   | 6 ------
>  drivers/video/backlight/ld9040.c           | 6 ------
>  drivers/video/backlight/lp855x_bl.c        | 6 ------
>  drivers/video/backlight/lp8788_bl.c        | 6 ------
>  drivers/video/backlight/lv5207lp.c         | 6 ------
>  drivers/video/backlight/pandora_bl.c       | 6 ------
>  drivers/video/backlight/pwm_bl.c           | 6 ------
>  drivers/video/backlight/s6e63m0.c          | 6 ------
>  drivers/video/backlight/tps65217_bl.c      | 6 ------
>  drivers/video/fbdev/aty/aty128fb.c         | 6 ------
>  drivers/video/fbdev/aty/atyfb_base.c       | 6 ------
>  drivers/video/fbdev/aty/radeon_backlight.c | 6 ------
>  drivers/video/fbdev/exynos/s6e8ax0.c       | 6 ------
>  drivers/video/fbdev/nvidia/nv_backlight.c  | 6 ------
>  drivers/video/fbdev/riva/fbdev.c           | 6 ------
>  21 files changed, 2 insertions(+), 120 deletions(-)
> 
> --
> 1.9.1

^ permalink raw reply

* Re: [PATCH 23/38] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
From: Ulf Hansson @ 2014-06-16 12:17 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Barry Song, Anton Vorontsov, Stephen Warren, spear-devel,
	linux-mmc, Chris Ball, Michal Simek, Thierry Reding, Viresh Kumar,
	Ben Dooks, linux-tegra@vger.kernel.org, linuxppc-dev,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20140616104615.GA10701@n2100.arm.linux.org.uk>

On 16 June 2014 12:46, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:
> On Wed, Apr 23, 2014 at 08:08:07PM +0100, Russell King wrote:
>> @@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>>                       host->ops->set_clock(host, host->clock);
>>               }
>>
>> -             if (host->ops->set_uhs_signaling)
>> -                     host->ops->set_uhs_signaling(host, ios->timing);
>> -             else {
>> -                     ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
>> -                     /* Select Bus Speed Mode for host */
>> -                     ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
>> -                     if ((ios->timing == MMC_TIMING_MMC_HS200) ||
>> -                         (ios->timing == MMC_TIMING_UHS_SDR104))
>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR12)
>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR25)
>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
>> -                     else if (ios->timing == MMC_TIMING_UHS_SDR50)
>> -                             ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
>> -                     else if (ios->timing == MMC_TIMING_UHS_DDR50)
>> -                             ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
>> -                     sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
>> -             }
>> +             host->ops->set_uhs_signaling(host, ios->timing);
>>
>>               if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
>>                               ((ios->timing == MMC_TIMING_UHS_SDR12) ||
>
> Whoever decided to poorly pick these patches up against my will has
> slightly messed this patch up - whereas my original patch left the
> code correctly formatted, when whoever applied this patch did so, they
> left an additional blank line in the above.

Hi Russell,

We kindly pinged you several times asking for your state and for the
PR, but I suppose you were just too busy. Your PR were kind of
blocking patches for sdhci, if you remember.

Anyway, we did get some folks to test the patches and was thus fairly
confident that we could merge them. Chris asked me to try to collect
them in a PR for him, so I did. Sorry if I managed to screw some
things up, there were several conflicts and actual regressions, which
I tried to take care of.

The mmc people were also very helping in sending patches to fixup
related regressions, immediately after we merged your patchset. Thus
together I think we managed to pull it off.

>
> The other thing I'd ask is that the MMC people learn C precedence
> rules, and realise that it's not necessary (and actively harmful)
> to add additional parenthesis around simple if() conditions.  Testing
> for timing being one of two values does not need anything more than
> one set of parenthesis - it does not need if ((a == b) || (a == c)) -
> if (a == b || a == c) does just fine, and is less confusing when
> encountering more complex statements, such as:
>
>         if ((((a == b) || (a == c)) && ((d > a) || (d < c))) || (z == f))
>
> compared with:
>
>         if (((a == b || a == c) && (d > a || d < c)) || z == f)
>
> With the former "style", I normally end up having to pull the file into
> the editor, and rewrite the damned statement to work out what the
> grouping is, because the excessive use of parenthesis is detrimental to
> readability.  Don't do it.  Learn the C precedence rules and keep code
> readable.

Sure, we will adopt.

Please, feel free to send a patch to fixup my misstake. I will happily apply it.

Kind regards
Ulf Hansson

^ permalink raw reply

* Re: [PATCH 23/38] mmc: sdhci: convert sdhci_set_uhs_signaling() into a library function
From: Russell King - ARM Linux @ 2014-06-16 10:46 UTC (permalink / raw)
  To: Chris Ball, linux-mmc
  Cc: Barry Song, Anton Vorontsov, Stephen Warren, spear-devel,
	Michal Simek, Thierry Reding, Viresh Kumar, Ben Dooks,
	linux-tegra, Ulf Hansson, linuxppc-dev, linux-arm-kernel
In-Reply-To: <E1Wd2Wd-0003vp-S2@rmk-PC.arm.linux.org.uk>

On Wed, Apr 23, 2014 at 08:08:07PM +0100, Russell King wrote:
> @@ -1507,25 +1529,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>  			host->ops->set_clock(host, host->clock);
>  		}
>  
> -		if (host->ops->set_uhs_signaling)
> -			host->ops->set_uhs_signaling(host, ios->timing);
> -		else {
> -			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
> -			/* Select Bus Speed Mode for host */
> -			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
> -			if ((ios->timing == MMC_TIMING_MMC_HS200) ||
> -			    (ios->timing == MMC_TIMING_UHS_SDR104))
> -				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
> -			else if (ios->timing == MMC_TIMING_UHS_SDR12)
> -				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
> -			else if (ios->timing == MMC_TIMING_UHS_SDR25)
> -				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
> -			else if (ios->timing == MMC_TIMING_UHS_SDR50)
> -				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
> -			else if (ios->timing == MMC_TIMING_UHS_DDR50)
> -				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
> -			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
> -		}
> +		host->ops->set_uhs_signaling(host, ios->timing);
>  
>  		if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
>  				((ios->timing == MMC_TIMING_UHS_SDR12) ||

Whoever decided to poorly pick these patches up against my will has
slightly messed this patch up - whereas my original patch left the
code correctly formatted, when whoever applied this patch did so, they
left an additional blank line in the above.

The other thing I'd ask is that the MMC people learn C precedence
rules, and realise that it's not necessary (and actively harmful)
to add additional parenthesis around simple if() conditions.  Testing
for timing being one of two values does not need anything more than
one set of parenthesis - it does not need if ((a == b) || (a == c)) -
if (a == b || a == c) does just fine, and is less confusing when
encountering more complex statements, such as:

	if ((((a == b) || (a == c)) && ((d > a) || (d < c))) || (z == f))

compared with:

	if (((a == b || a == c) && (d > a || d < c)) || z == f)

With the former "style", I normally end up having to pull the file into
the editor, and rewrite the damned statement to work out what the
grouping is, because the excessive use of parenthesis is detrimental to
readability.  Don't do it.  Learn the C precedence rules and keep code
readable.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply

* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-06-16  9:48 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list

Hi Linus !

This is a single revert for a patch I should have never merged in the
first place had I reviewed things with a clear mind at the time :-(

Cheers,
Ben.

The following changes since commit
7171511eaec5bf23fb06078f59784a3a0626b38f:

  Linux 3.16-rc1 (2014-06-15 17:45:28 -1000)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git next

for you to fetch changes up to 68986c9f0f4552c34c248501eb0c690553866d6e:

  Revert "offb: Add palette hack for little endian" (2014-06-16 19:45:45
+1000)

----------------------------------------------------------------
Benjamin Herrenschmidt (1):
      Revert "offb: Add palette hack for little endian"

 drivers/video/fbdev/offb.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

^ permalink raw reply

* Re: [PATCH -next 26/26] sound: Use dma_zalloc_coherent
From: Takashi Iwai @ 2014-06-16  9:40 UTC (permalink / raw)
  To: Joe Perches
  Cc: Johannes Berg, linuxppc-dev, linux-kernel, alsa-devel,
	Jaroslav Kysela
In-Reply-To: <1ee1f44142267688ea2db19c11a83596b98c4f17.1402863905.git.joe@perches.com>

At Sun, 15 Jun 2014 13:37:55 -0700,
Joe Perches wrote:
> 
> Use the zeroing function instead of dma_alloc_coherent & memset(,0,)
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Applied, thanks.


Takashi

> ---
>  sound/aoa/soundbus/i2sbus/core.c | 12 ++++--------
>  sound/sparc/dbri.c               |  6 ++----
>  2 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
> index 4678360..a80d5ea 100644
> --- a/sound/aoa/soundbus/i2sbus/core.c
> +++ b/sound/aoa/soundbus/i2sbus/core.c
> @@ -47,15 +47,11 @@ static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
>  	/* We use the PCI APIs for now until the generic one gets fixed
>  	 * enough or until we get some macio-specific versions
>  	 */
> -	r->space = dma_alloc_coherent(
> -			&macio_get_pci_dev(i2sdev->macio)->dev,
> -			r->size,
> -			&r->bus_addr,
> -			GFP_KERNEL);
> +	r->space = dma_zalloc_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
> +				       r->size, &r->bus_addr, GFP_KERNEL);
> +	if (!r->space)
> +		return -ENOMEM;
>  
> -	if (!r->space) return -ENOMEM;
> -
> -	memset(r->space, 0, r->size);
>  	r->cmds = (void*)DBDMA_ALIGN(r->space);
>  	r->bus_cmd_start = r->bus_addr +
>  			   (dma_addr_t)((char*)r->cmds - (char*)r->space);
> diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
> index be1b1aa..b2c3d0d 100644
> --- a/sound/sparc/dbri.c
> +++ b/sound/sparc/dbri.c
> @@ -2534,12 +2534,10 @@ static int snd_dbri_create(struct snd_card *card,
>  	dbri->op = op;
>  	dbri->irq = irq;
>  
> -	dbri->dma = dma_alloc_coherent(&op->dev,
> -				       sizeof(struct dbri_dma),
> -				       &dbri->dma_dvma, GFP_ATOMIC);
> +	dbri->dma = dma_zalloc_coherent(&op->dev, sizeof(struct dbri_dma),
> +					&dbri->dma_dvma, GFP_ATOMIC);
>  	if (!dbri->dma)
>  		return -ENOMEM;
> -	memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
>  
>  	dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
>  		dbri->dma, dbri->dma_dvma);
> -- 
> 1.8.1.2.459.gbcd45b4.dirty
> 

^ permalink raw reply

* Re: [PATCH v3 -next 0/9] CMA: generalize CMA reserved area management code
From: Marek Szyprowski @ 2014-06-16  9:11 UTC (permalink / raw)
  To: Joonsoo Kim, Andrew Morton, Aneesh Kumar K.V, Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Zhang Yanfei,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1402897251-23639-1-git-send-email-iamjoonsoo.kim@lge.com>

Hello,

On 2014-06-16 07:40, Joonsoo Kim wrote:
> Currently, there are two users on CMA functionality, one is the DMA
> subsystem and the other is the KVM on powerpc. They have their own code
> to manage CMA reserved area even if they looks really similar.
> >From my guess, it is caused by some needs on bitmap management. Kvm side
> wants to maintain bitmap not for 1 page, but for more size. Eventually it
> use bitmap where one bit represents 64 pages.
>
> When I implement CMA related patches, I should change those two places
> to apply my change and it seem to be painful to me. I want to change
> this situation and reduce future code management overhead through
> this patch.
>
> This change could also help developer who want to use CMA in their
> new feature development, since they can use CMA easily without
> copying & pasting this reserved area management code.
>
> v3:
>    - Simplify old patch 1(log format fix) and move it to the end of patchset.
>    - Patch 2: Pass aligned base and size to dma_contiguous_early_fixup()
>    - Patch 5: Add some accessor functions to pass aligned base and size to
>    dma_contiguous_early_fixup() function
>    - Patch 5: Move MAX_CMA_AREAS definition to cma.h
>    - Patch 6: Add CMA region zeroing to PPC KVM's CMA alloc function
>    - Patch 8: put 'base' ahead of 'size' in cma_declare_contiguous()
>    - Remaining minor fixes are noted in commit description of each one
>
> v2:
>    - Although this patchset looks very different with v1, the end result,
>    that is, mm/cma.c is same with v1's one. So I carry Ack to patch 6-7.
>
> This patchset is based on linux-next 20140610.

Thanks for taking care of this. I will test it with my setup and if
everything goes well, I will take it to my -next tree. If any branch
is required for anyone to continue his works on top of those patches,
let me know, I will also prepare it.

> Patch 1-4 prepare some features to cover PPC KVM's requirements.
> Patch 5-6 generalize CMA reserved area management code and change users
> to use it.
> Patch 7-9 clean-up minor things.
>
> Joonsoo Kim (9):
>    DMA, CMA: fix possible memory leak
>    DMA, CMA: separate core CMA management codes from DMA APIs
>    DMA, CMA: support alignment constraint on CMA region
>    DMA, CMA: support arbitrary bitmap granularity
>    CMA: generalize CMA reserved area management functionality
>    PPC, KVM, CMA: use general CMA reserved area management framework
>    mm, CMA: clean-up CMA allocation error path
>    mm, CMA: change cma_declare_contiguous() to obey coding convention
>    mm, CMA: clean-up log message
>
>   arch/arm/mm/dma-mapping.c            |    1 +
>   arch/powerpc/kvm/book3s_64_mmu_hv.c  |    4 +-
>   arch/powerpc/kvm/book3s_hv_builtin.c |   19 +-
>   arch/powerpc/kvm/book3s_hv_cma.c     |  240 ------------------------
>   arch/powerpc/kvm/book3s_hv_cma.h     |   27 ---
>   drivers/base/Kconfig                 |   10 -
>   drivers/base/dma-contiguous.c        |  210 ++-------------------
>   include/linux/cma.h                  |   21 +++
>   include/linux/dma-contiguous.h       |   11 +-
>   mm/Kconfig                           |   11 ++
>   mm/Makefile                          |    1 +
>   mm/cma.c                             |  335 ++++++++++++++++++++++++++++++++++
>   12 files changed, 397 insertions(+), 493 deletions(-)
>   delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.c
>   delete mode 100644 arch/powerpc/kvm/book3s_hv_cma.h
>   create mode 100644 include/linux/cma.h
>   create mode 100644 mm/cma.c
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* Re: [PATCH v2 00/10] CMA: generalize CMA reserved area management code
From: Aneesh Kumar K.V @ 2014-06-16  7:04 UTC (permalink / raw)
  To: Joonsoo Kim
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, Michal Nazarewicz,
	linux-kernel, Minchan Kim, Paul Mackerras, kvm-ppc, Paolo Bonzini,
	Andrew Morton, linuxppc-dev, linux-arm-kernel, Marek Szyprowski
In-Reply-To: <20140616053209.GG23210@js1304-P5Q-DELUXE>

Joonsoo Kim <iamjoonsoo.kim@lge.com> writes:

> On Sat, Jun 14, 2014 at 12:55:39PM +0530, Aneesh Kumar K.V wrote:
>> Joonsoo Kim <iamjoonsoo.kim@lge.com> writes:
>> 
>> > Currently, there are two users on CMA functionality, one is the DMA
>> > subsystem and the other is the kvm on powerpc. They have their own code
>> > to manage CMA reserved area even if they looks really similar.
>> > From my guess, it is caused by some needs on bitmap management. Kvm side
>> > wants to maintain bitmap not for 1 page, but for more size. Eventually it
>> > use bitmap where one bit represents 64 pages.
>> >
>> > When I implement CMA related patches, I should change those two places
>> > to apply my change and it seem to be painful to me. I want to change
>> > this situation and reduce future code management overhead through
>> > this patch.
>> >
>> > This change could also help developer who want to use CMA in their
>> > new feature development, since they can use CMA easily without
>> > copying & pasting this reserved area management code.
>> >
>> > v2:
>> >   Although this patchset looks very different with v1, the end result,
>> >   that is, mm/cma.c is same with v1's one. So I carry Ack to patch 6-7.
>> >
>> > Patch 1-5 prepare some features to cover ppc kvm's requirements.
>> > Patch 6-7 generalize CMA reserved area management code and change users
>> > to use it.
>> > Patch 8-10 clean-up minor things.
>> 
>> 
>> I wanted to test the ppc changes and found that the patch series doesn't apply
>> against v3.15 . Do you have a kernel tree which I can clone to test this
>> series ?
>
> This is based on linux-next -next-20140610.
> And my tree is on following link.
>
> https://github.com/JoonsooKim/linux/tree/cma-general-v2.0-next-20140610
>
> But, I think I'm late, because you have already added a Tested-by tag.

linux-next kexec is broken on ppc64, hence I hand picked few of
dependent patches for dma CMA on top of 3.15 and used that for testing.

-aneesh

^ permalink raw reply

* Re: [PATCH v2 07/10] PPC, KVM, CMA: use general CMA reserved area management framework
From: Aneesh Kumar K.V @ 2014-06-16  7:02 UTC (permalink / raw)
  To: Joonsoo Kim
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, Michal Nazarewicz,
	linux-kernel, Minchan Kim, Paul Mackerras, kvm-ppc, Paolo Bonzini,
	Andrew Morton, linuxppc-dev, linux-arm-kernel, Marek Szyprowski
In-Reply-To: <20140616053408.GH23210@js1304-P5Q-DELUXE>

Joonsoo Kim <iamjoonsoo.kim@lge.com> writes:

> On Sat, Jun 14, 2014 at 02:23:59PM +0530, Aneesh Kumar K.V wrote:
>> Joonsoo Kim <iamjoonsoo.kim@lge.com> writes:
>> 
>> > Now, we have general CMA reserved area management framework,
>> > so use it for future maintainabilty. There is no functional change.
>> >
>> > Acked-by: Michal Nazarewicz <mina86@mina86.com>
>> > Acked-by: Paolo Bonzini <pbonzini@redhat.com>
>> > Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
>> 
>> Need this. We may want to keep the VM_BUG_ON by moving
>> KVM_CMA_CHUNK_ORDER around.
>> 
>> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
>> index 8056107..1932e0e 100644
>> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
>> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
>> @@ -37,8 +37,6 @@
>>  #include <asm/ppc-opcode.h>
>>  #include <asm/cputable.h>
>>  
>> -#include "book3s_hv_cma.h"
>> -
>>  /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */
>>  #define MAX_LPID_970   63
>>  
>> @@ -64,7 +62,6 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
>>         }
>>  
>>         kvm->arch.hpt_cma_alloc = 0;
>> -       VM_BUG_ON(order < KVM_CMA_CHUNK_ORDER);
>>         page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT));
>>         if (page) {
>>                 hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
>> 
>> 
>> 
>> -aneesh
>
> Okay.
> So do you also want this?
>
> @@ -131,16 +135,18 @@ struct page *kvm_alloc_hpt(unsigned long nr_pages)
>  {
>         unsigned long align_pages = HPT_ALIGN_PAGES;
>
> +       VM_BUG_ON(get_order(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);
> +
>         /* Old CPUs require HPT aligned on a multiple of its size */
>         if (!cpu_has_feature(CPU_FTR_ARCH_206))
>                 align_pages = nr_pages;
> -       return kvm_alloc_cma(nr_pages, align_pages);
> +       return cma_alloc(kvm_cma, nr_pages, get_order(align_pages));
>  }

That would also work.

Thanks
-aneesh

^ permalink raw reply

* Re: [PATCH v3 -next 1/9] DMA, CMA: fix possible memory leak
From: Minchan Kim @ 2014-06-16  6:27 UTC (permalink / raw)
  To: Joonsoo Kim
  Cc: kvm-ppc, Russell King - ARM Linux, kvm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, Michal Nazarewicz,
	linux-kernel, linux-mm, Paul Mackerras, Aneesh Kumar K.V,
	Paolo Bonzini, Andrew Morton, Zhang Yanfei, linuxppc-dev,
	linux-arm-kernel, Marek Szyprowski
In-Reply-To: <1402897251-23639-2-git-send-email-iamjoonsoo.kim@lge.com>

Hi, Joonsoo

On Mon, Jun 16, 2014 at 02:40:43PM +0900, Joonsoo Kim wrote:
> We should free memory for bitmap when we find zone mis-match,
> otherwise this memory will leak.
> 
> Additionally, I copy code comment from PPC KVM's CMA code to inform
> why we need to check zone mis-match.
> 
> * Note
> Minchan suggested to add a tag for the stable, but, I don't do it,
> because I found this possibility during code-review and, IMO,
> this patch isn't suitable for stable tree.

Nice idea to put the comment in here. Thanks Joonsoo.

It seems you obey "It must fix a real bug that bothers people"
on Documentation/stable_kernel_rules.txt but it's a really obvious
bug and hard to get a report from people because limited user and
hard to detect small such small memory leak.

In my experince, Andrew perfered stable marking for such a obvious
problem but simple fix like this but not sure so let's pass the decision
to him and will learn a lesson from him and will follow the decision
from now on.

Thanks.

Acked-by: Minchan Kim <minchan@kernel.org>

> 
> Acked-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
> Reviewed-by: Michal Nazarewicz <mina86@mina86.com>
> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> 
> diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
> index 83969f8..6467c91 100644
> --- a/drivers/base/dma-contiguous.c
> +++ b/drivers/base/dma-contiguous.c
> @@ -176,14 +176,24 @@ static int __init cma_activate_area(struct cma *cma)
>  		base_pfn = pfn;
>  		for (j = pageblock_nr_pages; j; --j, pfn++) {
>  			WARN_ON_ONCE(!pfn_valid(pfn));
> +			/*
> +			 * alloc_contig_range requires the pfn range
> +			 * specified to be in the same zone. Make this
> +			 * simple by forcing the entire CMA resv range
> +			 * to be in the same zone.
> +			 */
>  			if (page_zone(pfn_to_page(pfn)) != zone)
> -				return -EINVAL;
> +				goto err;
>  		}
>  		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
>  	} while (--i);
>  
>  	mutex_init(&cma->lock);
>  	return 0;
> +
> +err:
> +	kfree(cma->bitmap);
> +	return -EINVAL;
>  }
>  
>  static struct cma cma_areas[MAX_CMA_AREAS];
> -- 
> 1.7.9.5
> 
> --
> 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>

-- 
Kind regards,
Minchan Kim

^ permalink raw reply

* [PATCH v3 -next 5/9] CMA: generalize CMA reserved area management functionality
From: Joonsoo Kim @ 2014-06-16  5:40 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	Zhang Yanfei, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1402897251-23639-1-git-send-email-iamjoonsoo.kim@lge.com>

Currently, there are two users on CMA functionality, one is the DMA
subsystem and the other is the KVM on powerpc. They have their own code
to manage CMA reserved area even if they looks really similar.
>From my guess, it is caused by some needs on bitmap management. KVM side
wants to maintain bitmap not for 1 page, but for more size. Eventually it
use bitmap where one bit represents 64 pages.

When I implement CMA related patches, I should change those two places
to apply my change and it seem to be painful to me. I want to change
this situation and reduce future code management overhead through
this patch.

This change could also help developer who want to use CMA in their
new feature development, since they can use CMA easily without
copying & pasting this reserved area management code.

In previous patches, we have prepared some features to generalize
CMA reserved area management and now it's time to do it. This patch
moves core functions to mm/cma.c and change DMA APIs to use
these functions.

There is no functional change in DMA APIs.

v2: There is no big change from v1 in mm/cma.c. Mostly renaming.
v3: remove log2.h in dma-contiguous.c (Minchan)
    add some accessor functions to pass aligned base and size to
    dma_contiguous_early_fixup() function
    move MAX_CMA_AREAS to cma.h

Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Acked-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4c88935..3116880 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/vmalloc.h>
 #include <linux/sizes.h>
+#include <linux/cma.h>
 
 #include <asm/memory.h>
 #include <asm/highmem.h>
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 00e13ce..4eac559 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -283,16 +283,6 @@ config CMA_ALIGNMENT
 
 	  If unsure, leave the default value "8".
 
-config CMA_AREAS
-	int "Maximum count of the CMA device-private areas"
-	default 7
-	help
-	  CMA allows to create CMA areas for particular devices. This parameter
-	  sets the maximum number of such device private CMA areas in the
-	  system.
-
-	  If unsure, leave the default value "7".
-
 endif
 
 endmenu
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index c6eeb2c..0411c1c 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -24,25 +24,9 @@
 
 #include <linux/memblock.h>
 #include <linux/err.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/page-isolation.h>
 #include <linux/sizes.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/mm_types.h>
 #include <linux/dma-contiguous.h>
-#include <linux/log2.h>
-
-struct cma {
-	unsigned long	base_pfn;
-	unsigned long	count;
-	unsigned long	*bitmap;
-	unsigned int order_per_bit; /* Order of pages represented by one bit */
-	struct mutex	lock;
-};
-
-struct cma *dma_contiguous_default_area;
+#include <linux/cma.h>
 
 #ifdef CONFIG_CMA_SIZE_MBYTES
 #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
@@ -50,6 +34,8 @@ struct cma *dma_contiguous_default_area;
 #define CMA_SIZE_MBYTES 0
 #endif
 
+struct cma *dma_contiguous_default_area;
+
 /*
  * Default global CMA area size can be defined in kernel's .config.
  * This is useful mainly for distro maintainers to create a kernel
@@ -156,169 +142,6 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
 	}
 }
 
-static DEFINE_MUTEX(cma_mutex);
-
-static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order)
-{
-	return (1 << (align_order >> cma->order_per_bit)) - 1;
-}
-
-static unsigned long cma_bitmap_maxno(struct cma *cma)
-{
-	return cma->count >> cma->order_per_bit;
-}
-
-static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
-						unsigned long pages)
-{
-	return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit;
-}
-
-static void cma_clear_bitmap(struct cma *cma, unsigned long pfn, int count)
-{
-	unsigned long bitmap_no, bitmap_count;
-
-	bitmap_no = (pfn - cma->base_pfn) >> cma->order_per_bit;
-	bitmap_count = cma_bitmap_pages_to_bits(cma, count);
-
-	mutex_lock(&cma->lock);
-	bitmap_clear(cma->bitmap, bitmap_no, bitmap_count);
-	mutex_unlock(&cma->lock);
-}
-
-static int __init cma_activate_area(struct cma *cma)
-{
-	int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
-	unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
-	unsigned i = cma->count >> pageblock_order;
-	struct zone *zone;
-
-	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-
-	if (!cma->bitmap)
-		return -ENOMEM;
-
-	WARN_ON_ONCE(!pfn_valid(pfn));
-	zone = page_zone(pfn_to_page(pfn));
-
-	do {
-		unsigned j;
-		base_pfn = pfn;
-		for (j = pageblock_nr_pages; j; --j, pfn++) {
-			WARN_ON_ONCE(!pfn_valid(pfn));
-			/*
-			 * alloc_contig_range requires the pfn range
-			 * specified to be in the same zone. Make this
-			 * simple by forcing the entire CMA resv range
-			 * to be in the same zone.
-			 */
-			if (page_zone(pfn_to_page(pfn)) != zone)
-				goto err;
-		}
-		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
-	} while (--i);
-
-	mutex_init(&cma->lock);
-	return 0;
-
-err:
-	kfree(cma->bitmap);
-	return -EINVAL;
-}
-
-static struct cma cma_areas[MAX_CMA_AREAS];
-static unsigned cma_area_count;
-
-static int __init cma_init_reserved_areas(void)
-{
-	int i;
-
-	for (i = 0; i < cma_area_count; i++) {
-		int ret = cma_activate_area(&cma_areas[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-core_initcall(cma_init_reserved_areas);
-
-static int __init __dma_contiguous_reserve_area(phys_addr_t size,
-			phys_addr_t base, phys_addr_t limit,
-			phys_addr_t alignment, unsigned int order_per_bit,
-			struct cma **res_cma, bool fixed)
-{
-	struct cma *cma = &cma_areas[cma_area_count];
-	int ret = 0;
-
-	pr_debug("%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n",
-		__func__, (unsigned long)size, (unsigned long)base,
-		(unsigned long)limit, (unsigned long)alignment);
-
-	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
-		pr_err("Not enough slots for CMA reserved regions!\n");
-		return -ENOSPC;
-	}
-
-	if (!size)
-		return -EINVAL;
-
-	if (alignment && !is_power_of_2(alignment))
-		return -EINVAL;
-
-	/*
-	 * Sanitise input arguments.
-	 * Pages both ends in CMA area could be merged into adjacent unmovable
-	 * migratetype page by page allocator's buddy algorithm. In the case,
-	 * you couldn't get a contiguous memory, which is not what we want.
-	 */
-	alignment = max(alignment,
-		(phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order));
-	base = ALIGN(base, alignment);
-	size = ALIGN(size, alignment);
-	limit &= ~(alignment - 1);
-
-	/* size should be aligned with order_per_bit */
-	if (!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit))
-		return -EINVAL;
-
-	/* Reserve memory */
-	if (base && fixed) {
-		if (memblock_is_region_reserved(base, size) ||
-		    memblock_reserve(base, size) < 0) {
-			ret = -EBUSY;
-			goto err;
-		}
-	} else {
-		phys_addr_t addr = memblock_alloc_range(size, alignment, base,
-							limit);
-		if (!addr) {
-			ret = -ENOMEM;
-			goto err;
-		} else {
-			base = addr;
-		}
-	}
-
-	/*
-	 * Each reserved area must be initialised later, when more kernel
-	 * subsystems (like slab allocator) are available.
-	 */
-	cma->base_pfn = PFN_DOWN(base);
-	cma->count = size >> PAGE_SHIFT;
-	cma->order_per_bit = order_per_bit;
-	*res_cma = cma;
-	cma_area_count++;
-
-	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
-		(unsigned long)base);
-	return 0;
-
-err:
-	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
-	return ret;
-}
-
 /**
  * dma_contiguous_reserve_area() - reserve custom contiguous area
  * @size: Size of the reserved area (in bytes),
@@ -342,77 +165,17 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
 {
 	int ret;
 
-	ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0,
-						res_cma, fixed);
+	ret = cma_declare_contiguous(size, base, limit, 0, 0, res_cma, fixed);
 	if (ret)
 		return ret;
 
 	/* Architecture specific contiguous memory fixup. */
-	dma_contiguous_early_fixup(PFN_PHYS((*res_cma)->base_pfn),
-				(*res_cma)->count << PAGE_SHIFT);
+	dma_contiguous_early_fixup(cma_get_base(*res_cma),
+				cma_get_size(*res_cma));
 
 	return 0;
 }
 
-static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count,
-				       unsigned int align)
-{
-	unsigned long mask, pfn, start = 0;
-	unsigned long bitmap_maxno, bitmap_no, bitmap_count;
-	struct page *page = NULL;
-	int ret;
-
-	if (!cma || !cma->count)
-		return NULL;
-
-	pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
-		 count, align);
-
-	if (!count)
-		return NULL;
-
-	mask = cma_bitmap_aligned_mask(cma, align);
-	bitmap_maxno = cma_bitmap_maxno(cma);
-	bitmap_count = cma_bitmap_pages_to_bits(cma, count);
-
-	for (;;) {
-		mutex_lock(&cma->lock);
-		bitmap_no = bitmap_find_next_zero_area(cma->bitmap,
-				bitmap_maxno, start, bitmap_count, mask);
-		if (bitmap_no >= bitmap_maxno) {
-			mutex_unlock(&cma->lock);
-			break;
-		}
-		bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
-		/*
-		 * It's safe to drop the lock here. We've marked this region for
-		 * our exclusive use. If the migration fails we will take the
-		 * lock again and unmark it.
-		 */
-		mutex_unlock(&cma->lock);
-
-		pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
-		mutex_lock(&cma_mutex);
-		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
-		mutex_unlock(&cma_mutex);
-		if (ret == 0) {
-			page = pfn_to_page(pfn);
-			break;
-		} else if (ret != -EBUSY) {
-			cma_clear_bitmap(cma, pfn, count);
-			break;
-		}
-		cma_clear_bitmap(cma, pfn, count);
-		pr_debug("%s(): memory range at %p is busy, retrying\n",
-			 __func__, pfn_to_page(pfn));
-		/* try again with a bit different memory target */
-		start = bitmap_no + mask + 1;
-	}
-
-	pr_debug("%s(): returned %p\n", __func__, page);
-	return page;
-}
-
 /**
  * dma_alloc_from_contiguous() - allocate pages from contiguous area
  * @dev:   Pointer to device for which the allocation is performed.
@@ -427,35 +190,10 @@ static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count,
 struct page *dma_alloc_from_contiguous(struct device *dev, int count,
 				       unsigned int align)
 {
-	struct cma *cma = dev_get_cma_area(dev);
-
 	if (align > CONFIG_CMA_ALIGNMENT)
 		align = CONFIG_CMA_ALIGNMENT;
 
-	return __dma_alloc_from_contiguous(cma, count, align);
-}
-
-static bool __dma_release_from_contiguous(struct cma *cma, struct page *pages,
-				 int count)
-{
-	unsigned long pfn;
-
-	if (!cma || !pages)
-		return false;
-
-	pr_debug("%s(page %p)\n", __func__, (void *)pages);
-
-	pfn = page_to_pfn(pages);
-
-	if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
-		return false;
-
-	VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
-
-	free_contig_range(pfn, count);
-	cma_clear_bitmap(cma, pfn, count);
-
-	return true;
+	return cma_alloc(dev_get_cma_area(dev), count, align);
 }
 
 /**
@@ -471,7 +209,5 @@ static bool __dma_release_from_contiguous(struct cma *cma, struct page *pages,
 bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 				 int count)
 {
-	struct cma *cma = dev_get_cma_area(dev);
-
-	return __dma_release_from_contiguous(cma, pages, count);
+	return cma_release(dev_get_cma_area(dev), pages, count);
 }
diff --git a/include/linux/cma.h b/include/linux/cma.h
new file mode 100644
index 0000000..69d3726
--- /dev/null
+++ b/include/linux/cma.h
@@ -0,0 +1,21 @@
+#ifndef __CMA_H__
+#define __CMA_H__
+
+/*
+ * There is always at least global CMA area and a few optional
+ * areas configured in kernel .config.
+ */
+#define MAX_CMA_AREAS	(1 + CONFIG_CMA_AREAS)
+
+struct cma;
+
+extern phys_addr_t cma_get_base(struct cma *cma);
+extern unsigned long cma_get_size(struct cma *cma);
+
+extern int __init cma_declare_contiguous(phys_addr_t size,
+			phys_addr_t base, phys_addr_t limit,
+			phys_addr_t alignment, unsigned int order_per_bit,
+			struct cma **res_cma, bool fixed);
+extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align);
+extern bool cma_release(struct cma *cma, struct page *pages, int count);
+#endif
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 772eab5..569bbd0 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -53,18 +53,13 @@
 
 #ifdef __KERNEL__
 
+#include <linux/device.h>
+
 struct cma;
 struct page;
-struct device;
 
 #ifdef CONFIG_DMA_CMA
 
-/*
- * There is always at least global CMA area and a few optional device
- * private areas configured in kernel .config.
- */
-#define MAX_CMA_AREAS	(1 + CONFIG_CMA_AREAS)
-
 extern struct cma *dma_contiguous_default_area;
 
 static inline struct cma *dev_get_cma_area(struct device *dev)
@@ -123,8 +118,6 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 
 #else
 
-#define MAX_CMA_AREAS	(0)
-
 static inline struct cma *dev_get_cma_area(struct device *dev)
 {
 	return NULL;
diff --git a/mm/Kconfig b/mm/Kconfig
index 3e9977a..f4899ec 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -508,6 +508,17 @@ config CMA_DEBUG
 	  processing calls such as dma_alloc_from_contiguous().
 	  This option does not affect warning and error messages.
 
+config CMA_AREAS
+	int "Maximum count of the CMA areas"
+	depends on CMA
+	default 7
+	help
+	  CMA allows to create CMA areas for particular purpose, mainly,
+	  used as device private area. This parameter sets the maximum
+	  number of CMA area in the system.
+
+	  If unsure, leave the default value "7".
+
 config ZBUD
 	tristate
 	default n
diff --git a/mm/Makefile b/mm/Makefile
index 1eaa70b..bc0422b 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -62,3 +62,4 @@ obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
 obj-$(CONFIG_ZBUD)	+= zbud.o
 obj-$(CONFIG_ZSMALLOC)	+= zsmalloc.o
 obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
+obj-$(CONFIG_CMA)	+= cma.o
diff --git a/mm/cma.c b/mm/cma.c
new file mode 100644
index 0000000..0cf50da
--- /dev/null
+++ b/mm/cma.c
@@ -0,0 +1,333 @@
+/*
+ * Contiguous Memory Allocator
+ *
+ * Copyright (c) 2010-2011 by Samsung Electronics.
+ * Copyright IBM Corporation, 2013
+ * Copyright LG Electronics Inc., 2014
+ * Written by:
+ *	Marek Szyprowski <m.szyprowski@samsung.com>
+ *	Michal Nazarewicz <mina86@mina86.com>
+ *	Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *	Joonsoo Kim <iamjoonsoo.kim@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+
+#define pr_fmt(fmt) "cma: " fmt
+
+#ifdef CONFIG_CMA_DEBUG
+#ifndef DEBUG
+#  define DEBUG
+#endif
+#endif
+
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/log2.h>
+#include <linux/cma.h>
+
+struct cma {
+	unsigned long	base_pfn;
+	unsigned long	count;
+	unsigned long	*bitmap;
+	unsigned int order_per_bit; /* Order of pages represented by one bit */
+	struct mutex	lock;
+};
+
+static struct cma cma_areas[MAX_CMA_AREAS];
+static unsigned cma_area_count;
+static DEFINE_MUTEX(cma_mutex);
+
+phys_addr_t cma_get_base(struct cma *cma)
+{
+	return PFN_PHYS(cma->base_pfn);
+}
+
+unsigned long cma_get_size(struct cma *cma)
+{
+	return cma->count << PAGE_SHIFT;
+}
+
+static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order)
+{
+	return (1 << (align_order >> cma->order_per_bit)) - 1;
+}
+
+static unsigned long cma_bitmap_maxno(struct cma *cma)
+{
+	return cma->count >> cma->order_per_bit;
+}
+
+static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
+						unsigned long pages)
+{
+	return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit;
+}
+
+static void cma_clear_bitmap(struct cma *cma, unsigned long pfn, int count)
+{
+	unsigned long bitmap_no, bitmap_count;
+
+	bitmap_no = (pfn - cma->base_pfn) >> cma->order_per_bit;
+	bitmap_count = cma_bitmap_pages_to_bits(cma, count);
+
+	mutex_lock(&cma->lock);
+	bitmap_clear(cma->bitmap, bitmap_no, bitmap_count);
+	mutex_unlock(&cma->lock);
+}
+
+static int __init cma_activate_area(struct cma *cma)
+{
+	int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long);
+	unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
+	unsigned i = cma->count >> pageblock_order;
+	struct zone *zone;
+
+	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+
+	if (!cma->bitmap)
+		return -ENOMEM;
+
+	WARN_ON_ONCE(!pfn_valid(pfn));
+	zone = page_zone(pfn_to_page(pfn));
+
+	do {
+		unsigned j;
+
+		base_pfn = pfn;
+		for (j = pageblock_nr_pages; j; --j, pfn++) {
+			WARN_ON_ONCE(!pfn_valid(pfn));
+			/*
+			 * alloc_contig_range requires the pfn range
+			 * specified to be in the same zone. Make this
+			 * simple by forcing the entire CMA resv range
+			 * to be in the same zone.
+			 */
+			if (page_zone(pfn_to_page(pfn)) != zone)
+				goto err;
+		}
+		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
+	} while (--i);
+
+	mutex_init(&cma->lock);
+	return 0;
+
+err:
+	kfree(cma->bitmap);
+	return -EINVAL;
+}
+
+static int __init cma_init_reserved_areas(void)
+{
+	int i;
+
+	for (i = 0; i < cma_area_count; i++) {
+		int ret = cma_activate_area(&cma_areas[i]);
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+core_initcall(cma_init_reserved_areas);
+
+/**
+ * cma_declare_contiguous() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ * @alignment: Alignment for the CMA area, should be power of 2 or zero
+ * @order_per_bit: Order of pages represented by one bit on bitmap.
+ * @res_cma: Pointer to store the created cma region.
+ * @fixed: hint about where to place the reserved area
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas.
+ *
+ * If @fixed is true, reserve contiguous area at exactly @base.  If false,
+ * reserve in range from @base to @limit.
+ */
+int __init cma_declare_contiguous(phys_addr_t size,
+			phys_addr_t base, phys_addr_t limit,
+			phys_addr_t alignment, unsigned int order_per_bit,
+			struct cma **res_cma, bool fixed)
+{
+	struct cma *cma = &cma_areas[cma_area_count];
+	int ret = 0;
+
+	pr_debug("%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n",
+		__func__, (unsigned long)size, (unsigned long)base,
+		(unsigned long)limit, (unsigned long)alignment);
+
+	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
+		pr_err("Not enough slots for CMA reserved regions!\n");
+		return -ENOSPC;
+	}
+
+	if (!size)
+		return -EINVAL;
+
+	if (alignment && !is_power_of_2(alignment))
+		return -EINVAL;
+
+	/*
+	 * Sanitise input arguments.
+	 * Pages both ends in CMA area could be merged into adjacent unmovable
+	 * migratetype page by page allocator's buddy algorithm. In the case,
+	 * you couldn't get a contiguous memory, which is not what we want.
+	 */
+	alignment = max(alignment,
+		(phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order));
+	base = ALIGN(base, alignment);
+	size = ALIGN(size, alignment);
+	limit &= ~(alignment - 1);
+
+	/* size should be aligned with order_per_bit */
+	if (!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit))
+		return -EINVAL;
+
+	/* Reserve memory */
+	if (base && fixed) {
+		if (memblock_is_region_reserved(base, size) ||
+		    memblock_reserve(base, size) < 0) {
+			ret = -EBUSY;
+			goto err;
+		}
+	} else {
+		phys_addr_t addr = memblock_alloc_range(size, alignment, base,
+							limit);
+		if (!addr) {
+			ret = -ENOMEM;
+			goto err;
+		} else {
+			base = addr;
+		}
+	}
+
+	/*
+	 * Each reserved area must be initialised later, when more kernel
+	 * subsystems (like slab allocator) are available.
+	 */
+	cma->base_pfn = PFN_DOWN(base);
+	cma->count = size >> PAGE_SHIFT;
+	cma->order_per_bit = order_per_bit;
+	*res_cma = cma;
+	cma_area_count++;
+
+	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
+		(unsigned long)base);
+	return 0;
+
+err:
+	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
+	return ret;
+}
+
+/**
+ * cma_alloc() - allocate pages from contiguous area
+ * @cma:   Contiguous memory region for which the allocation is performed.
+ * @count: Requested number of pages.
+ * @align: Requested alignment of pages (in PAGE_SIZE order).
+ *
+ * This function allocates part of contiguous memory on specific
+ * contiguous memory area.
+ */
+struct page *cma_alloc(struct cma *cma, int count, unsigned int align)
+{
+	unsigned long mask, pfn, start = 0;
+	unsigned long bitmap_maxno, bitmap_no, bitmap_count;
+	struct page *page = NULL;
+	int ret;
+
+	if (!cma || !cma->count)
+		return NULL;
+
+	pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
+		 count, align);
+
+	if (!count)
+		return NULL;
+
+	mask = cma_bitmap_aligned_mask(cma, align);
+	bitmap_maxno = cma_bitmap_maxno(cma);
+	bitmap_count = cma_bitmap_pages_to_bits(cma, count);
+
+	for (;;) {
+		mutex_lock(&cma->lock);
+		bitmap_no = bitmap_find_next_zero_area(cma->bitmap,
+				bitmap_maxno, start, bitmap_count, mask);
+		if (bitmap_no >= bitmap_maxno) {
+			mutex_unlock(&cma->lock);
+			break;
+		}
+		bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
+		/*
+		 * It's safe to drop the lock here. We've marked this region for
+		 * our exclusive use. If the migration fails we will take the
+		 * lock again and unmark it.
+		 */
+		mutex_unlock(&cma->lock);
+
+		pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
+		mutex_lock(&cma_mutex);
+		ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+		mutex_unlock(&cma_mutex);
+		if (ret == 0) {
+			page = pfn_to_page(pfn);
+			break;
+		} else if (ret != -EBUSY) {
+			cma_clear_bitmap(cma, pfn, count);
+			break;
+		}
+		cma_clear_bitmap(cma, pfn, count);
+		pr_debug("%s(): memory range at %p is busy, retrying\n",
+			 __func__, pfn_to_page(pfn));
+		/* try again with a bit different memory target */
+		start = bitmap_no + mask + 1;
+	}
+
+	pr_debug("%s(): returned %p\n", __func__, page);
+	return page;
+}
+
+/**
+ * cma_release() - release allocated pages
+ * @cma:   Contiguous memory region for which the allocation is performed.
+ * @pages: Allocated pages.
+ * @count: Number of allocated pages.
+ *
+ * This function releases memory allocated by alloc_cma().
+ * It returns false when provided pages do not belong to contiguous area and
+ * true otherwise.
+ */
+bool cma_release(struct cma *cma, struct page *pages, int count)
+{
+	unsigned long pfn;
+
+	if (!cma || !pages)
+		return false;
+
+	pr_debug("%s(page %p)\n", __func__, (void *)pages);
+
+	pfn = page_to_pfn(pages);
+
+	if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
+		return false;
+
+	VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
+
+	free_contig_range(pfn, count);
+	cma_clear_bitmap(cma, pfn, count);
+
+	return true;
+}
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 -next 7/9] mm, CMA: clean-up CMA allocation error path
From: Joonsoo Kim @ 2014-06-16  5:40 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	Zhang Yanfei, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1402897251-23639-1-git-send-email-iamjoonsoo.kim@lge.com>

We can remove one call sites for clear_cma_bitmap() if we first
call it before checking error number.

Acked-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: Michal Nazarewicz <mina86@mina86.com>
Reviewed-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/mm/cma.c b/mm/cma.c
index 0cf50da..b442a13 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -285,11 +285,12 @@ struct page *cma_alloc(struct cma *cma, int count, unsigned int align)
 		if (ret == 0) {
 			page = pfn_to_page(pfn);
 			break;
-		} else if (ret != -EBUSY) {
-			cma_clear_bitmap(cma, pfn, count);
-			break;
 		}
+
 		cma_clear_bitmap(cma, pfn, count);
+		if (ret != -EBUSY)
+			break;
+
 		pr_debug("%s(): memory range at %p is busy, retrying\n",
 			 __func__, pfn_to_page(pfn));
 		/* try again with a bit different memory target */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 -next 1/9] DMA, CMA: fix possible memory leak
From: Joonsoo Kim @ 2014-06-16  5:40 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	Zhang Yanfei, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1402897251-23639-1-git-send-email-iamjoonsoo.kim@lge.com>

We should free memory for bitmap when we find zone mis-match,
otherwise this memory will leak.

Additionally, I copy code comment from PPC KVM's CMA code to inform
why we need to check zone mis-match.

* Note
Minchan suggested to add a tag for the stable, but, I don't do it,
because I found this possibility during code-review and, IMO,
this patch isn't suitable for stable tree.

Acked-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Reviewed-by: Michal Nazarewicz <mina86@mina86.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 83969f8..6467c91 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -176,14 +176,24 @@ static int __init cma_activate_area(struct cma *cma)
 		base_pfn = pfn;
 		for (j = pageblock_nr_pages; j; --j, pfn++) {
 			WARN_ON_ONCE(!pfn_valid(pfn));
+			/*
+			 * alloc_contig_range requires the pfn range
+			 * specified to be in the same zone. Make this
+			 * simple by forcing the entire CMA resv range
+			 * to be in the same zone.
+			 */
 			if (page_zone(pfn_to_page(pfn)) != zone)
-				return -EINVAL;
+				goto err;
 		}
 		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
 	} while (--i);
 
 	mutex_init(&cma->lock);
 	return 0;
+
+err:
+	kfree(cma->bitmap);
+	return -EINVAL;
 }
 
 static struct cma cma_areas[MAX_CMA_AREAS];
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 -next 9/9] mm, CMA: clean-up log message
From: Joonsoo Kim @ 2014-06-16  5:40 UTC (permalink / raw)
  To: Andrew Morton, Aneesh Kumar K.V, Marek Szyprowski,
	Michal Nazarewicz
  Cc: Russell King - ARM Linux, kvm, linux-mm, Gleb Natapov,
	Greg Kroah-Hartman, Alexander Graf, kvm-ppc, linux-kernel,
	Minchan Kim, Paul Mackerras, Paolo Bonzini, Joonsoo Kim,
	Zhang Yanfei, linuxppc-dev, linux-arm-kernel
In-Reply-To: <1402897251-23639-1-git-send-email-iamjoonsoo.kim@lge.com>

We don't need explicit 'CMA:' prefix, since we already define prefix
'cma:' in pr_fmt. So remove it.

Acked-by: Michal Nazarewicz <mina86@mina86.com>
Reviewed-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

diff --git a/mm/cma.c b/mm/cma.c
index 9961120..4b251b0 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -225,12 +225,12 @@ int __init cma_declare_contiguous(phys_addr_t base,
 	*res_cma = cma;
 	cma_area_count++;
 
-	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
+	pr_info("Reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
 		(unsigned long)base);
 	return 0;
 
 err:
-	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
+	pr_err("Failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
 	return ret;
 }
 
-- 
1.7.9.5

^ permalink raw reply related


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