Re: [PATCH v2 08/10] mm, cma: clean-up cma allocation error path

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@lge.com writes:

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

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com


 diff --git a/mm/cma.c b/mm/cma.c
 index 1e1b017..01a0713 100644
 --- a/mm/cma.c
 +++ b/mm/cma.c
 @@ -282,11 +282,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) {
 - clear_cma_bitmap(cma, pfn, count);
 - break;
   }
 +
   clear_cma_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

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 09/10] mm, cma: move output param to the end of param list

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@lge.com writes:

 Conventionally, we put output param to the end of param list.
 cma_declare_contiguous() doesn't look like that, so change it.

 Additionally, move down cma_areas reference code to the position
 where it is really needed.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com


 diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c 
 b/arch/powerpc/kvm/book3s_hv_builtin.c
 index 28ec226..97613ea 100644
 --- a/arch/powerpc/kvm/book3s_hv_builtin.c
 +++ b/arch/powerpc/kvm/book3s_hv_builtin.c
 @@ -184,7 +184,7 @@ void __init kvm_cma_reserve(void)

   align_size = max(kvm_rma_pages  PAGE_SHIFT, align_size);
   cma_declare_contiguous(selected_size, 0, 0, align_size,
 - KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, kvm_cma, false);
 + KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, kvm_cma);
   }
  }

 diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
 index f177f73..bfd4553 100644
 --- a/drivers/base/dma-contiguous.c
 +++ b/drivers/base/dma-contiguous.c
 @@ -149,7 +149,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
 phys_addr_t base,
  {
   int ret;

 - ret = cma_declare_contiguous(size, base, limit, 0, 0, res_cma, fixed);
 + ret = cma_declare_contiguous(size, base, limit, 0, 0, fixed, res_cma);
   if (ret)
   return ret;

 diff --git a/include/linux/cma.h b/include/linux/cma.h
 index e38efe9..e53eead 100644
 --- a/include/linux/cma.h
 +++ b/include/linux/cma.h
 @@ -6,7 +6,7 @@ struct cma;
  extern int __init cma_declare_contiguous(phys_addr_t size,
   phys_addr_t base, phys_addr_t limit,
   phys_addr_t alignment, int order_per_bit,
 - struct cma **res_cma, bool fixed);
 + bool fixed, struct cma **res_cma);
  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/mm/cma.c b/mm/cma.c
 index 01a0713..22a5b23 100644
 --- a/mm/cma.c
 +++ b/mm/cma.c
 @@ -142,8 +142,8 @@ core_initcall(cma_init_reserved_areas);
   * @limit: End address of the reserved memory (optional, 0 for any).
   * @alignment: Alignment for the contiguous memory area, should be power of 2
   * @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
 + * @res_cma: Pointer to store the created cma region.
   *
   * This function reserves memory from early allocator. It should be
   * called by arch specific code once the early allocator (memblock or 
 bootmem)
 @@ -156,9 +156,9 @@ core_initcall(cma_init_reserved_areas);
  int __init cma_declare_contiguous(phys_addr_t size,
   phys_addr_t base, phys_addr_t limit,
   phys_addr_t alignment, int order_per_bit,
 - struct cma **res_cma, bool fixed)
 + bool fixed, struct cma **res_cma)
  {
 - struct cma *cma = cma_areas[cma_area_count];
 + struct cma *cma;
   int ret = 0;

   pr_debug(%s(size %lx, base %08lx, limit %08lx alignment %08lx)\n,
 @@ -214,6 +214,7 @@ int __init cma_declare_contiguous(phys_addr_t size,
* Each reserved area must be initialised later, when more kernel
* subsystems (like slab allocator) are available.
*/
 + cma = cma_areas[cma_area_count];
   cma-base_pfn = PFN_DOWN(base);
   cma-count = size  PAGE_SHIFT;
   cma-order_per_bit = order_per_bit;
 -- 
 1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 00/10] CMA: generalize CMA reserved area management code

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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 ?

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 07/10] PPC, KVM, CMA: use general CMA reserved area management framework

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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 min...@mina86.com
 Acked-by: Paolo Bonzini pbonz...@redhat.com
 Signed-off-by: Joonsoo Kim iamjoonsoo@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

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 07/10] PPC, KVM, CMA: use general CMA reserved area management framework

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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 min...@mina86.com
 Acked-by: Paolo Bonzini pbonz...@redhat.com
 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

 diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c 
 b/arch/powerpc/kvm/book3s_hv_builtin.c
 index 7cde8a6..28ec226 100644
 --- a/arch/powerpc/kvm/book3s_hv_builtin.c
 +++ b/arch/powerpc/kvm/book3s_hv_builtin.c
 @@ -16,12 +16,14 @@
  #include linux/init.h
  #include linux/memblock.h
  #include linux/sizes.h
 +#include linux/cma.h

  #include asm/cputable.h
  #include asm/kvm_ppc.h
  #include asm/kvm_book3s.h

 -#include book3s_hv_cma.h
 +#define KVM_CMA_CHUNK_ORDER  18
 +
  /*
   * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
   * should be power of 2.
 @@ -43,6 +45,8 @@ static unsigned long kvm_cma_resv_ratio = 5;
  unsigned long kvm_rma_pages = (1  27)  PAGE_SHIFT;   /* 128MB */
  EXPORT_SYMBOL_GPL(kvm_rma_pages);

 +static struct cma *kvm_cma;
 +
  /* Work out RMLS (real mode limit selector) field value for a given RMA size.
 Assumes POWER7 or PPC970. */
  static inline int lpcr_rmls(unsigned long rma_size)
 @@ -97,7 +101,7 @@ struct kvm_rma_info *kvm_alloc_rma()
   ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL);
   if (!ri)
   return NULL;
 - page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages);
 + page = cma_alloc(kvm_cma, kvm_rma_pages, get_order(kvm_rma_pages));
   if (!page)
   goto err_out;
   atomic_set(ri-use_count, 1);
 @@ -112,7 +116,7 @@ EXPORT_SYMBOL_GPL(kvm_alloc_rma);
  void kvm_release_rma(struct kvm_rma_info *ri)
  {
   if (atomic_dec_and_test(ri-use_count)) {
 - kvm_release_cma(pfn_to_page(ri-base_pfn), kvm_rma_pages);
 + cma_release(kvm_cma, pfn_to_page(ri-base_pfn), kvm_rma_pages);
   kfree(ri);
   }
  }
 @@ -134,13 +138,13 @@ struct page *kvm_alloc_hpt(unsigned long nr_pages)
   /* 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));
  }
  EXPORT_SYMBOL_GPL(kvm_alloc_hpt);

  void kvm_release_hpt(struct page *page, unsigned long nr_pages)
  {
 - kvm_release_cma(page, nr_pages);
 + cma_release(kvm_cma, page, nr_pages);
  }
  EXPORT_SYMBOL_GPL(kvm_release_hpt);

 @@ -179,7 +183,8 @@ void __init kvm_cma_reserve(void)
   align_size = HPT_ALIGN_PAGES  PAGE_SHIFT;

   align_size = max(kvm_rma_pages  PAGE_SHIFT, align_size);
 - kvm_cma_declare_contiguous(selected_size, align_size);
 + cma_declare_contiguous(selected_size, 0, 0, align_size,
 + KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, kvm_cma, false);
   }
  }

 diff --git a/arch/powerpc/kvm/book3s_hv_cma.c 
 b/arch/powerpc/kvm/book3s_hv_cma.c
 deleted file mode 100644
 index d9d3d85..000
 --- a/arch/powerpc/kvm/book3s_hv_cma.c
 +++ /dev/null
 @@ -1,240 +0,0 @@
 -/*
 - * Contiguous Memory Allocator for ppc KVM hash pagetable  based on CMA
 - * for DMA mapping framework
 - *
 - * Copyright IBM Corporation, 2013
 - * Author Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.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) kvm_cma:  fmt
 -
 -#ifdef CONFIG_CMA_DEBUG
 -#ifndef DEBUG
 -#  define DEBUG
 -#endif
 -#endif
 -
 -#include linux/memblock.h
 -#include linux/mutex.h
 -#include linux/sizes.h
 -#include linux/slab.h
 -
 -#include book3s_hv_cma.h
 -
 -struct kvm_cma {
 - unsigned long   base_pfn;
 - unsigned long   count;
 - unsigned long   *bitmap;
 -};
 -
 -static DEFINE_MUTEX(kvm_cma_mutex);
 -static struct kvm_cma kvm_cma_area;
 -
 -/**
 - * kvm_cma_declare_contiguous() - reserve area for contiguous memory handling
 - * for kvm hash pagetable
 - * @size:  Size of the reserved memory.
 - * @alignment:  Alignment for the contiguous memory area
 - *
 - * This function reserves memory for kvm cma area. It should be
 - * called by arch code when early allocator (memblock or bootmem)
 - * is still activate.
 - */
 -long __init kvm_cma_declare_contiguous(phys_addr_t size, phys_addr_t 
 alignment)
 -{
 - long base_pfn;
 - phys_addr_t addr;
 - struct kvm_cma *cma = kvm_cma_area;
 -
 - pr_debug(%s(size %lx)\n, __func__, (unsigned long)size);
 -
 - if (!size)
 - return -EINVAL;
 - /*
 -  * Sanitise input arguments.
 -  * We should be pageblock aligned for CMA.
 -  */
 - 

Re: [PATCH v2 06/10] CMA: generalize CMA reserved area management functionality

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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.

 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.

 Acked-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com


 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 9bc9340..f177f73 100644
 --- a/drivers/base/dma-contiguous.c
 +++ b/drivers/base/dma-contiguous.c
 @@ -24,25 +24,10 @@

  #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;
 - int order_per_bit; /* Order of pages represented by one bit */
 - struct mutexlock;
 -};
 -
 -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 +35,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,199 +143,13 @@ 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 clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
 -{
 - unsigned long bitmapno, nr_bits;
 -
 - bitmapno = (pfn - cma-base_pfn)  cma-order_per_bit;
 - nr_bits = cma_bitmap_pages_to_bits(cma, count);
 -
 - mutex_lock(cma-lock);
 - bitmap_clear(cma-bitmap, bitmapno, nr_bits);
 - mutex_unlock(cma-lock);
 -}
 -
 -static int __init cma_activate_area(struct cma *cma)
 -{
 - int bitmap_maxno = cma_bitmap_maxno(cma);
 - int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long);
 - unsigned long base_pfn = cma-base_pfn, pfn = base_pfn;
 - unsigned i = cma-count  pageblock_order;
 - struct zone *zone;
 -
 - pr_debug(%s()\n, __func__);
 -
 - 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 

Re: [PATCH v2 06/10] CMA: generalize CMA reserved area management functionality

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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.

 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.

 Acked-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com


 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 9bc9340..f177f73 100644
 --- a/drivers/base/dma-contiguous.c
 +++ b/drivers/base/dma-contiguous.c
 @@ -24,25 +24,10 @@

  #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;
 - int order_per_bit; /* Order of pages represented by one bit */
 - struct mutexlock;
 -};
 -
 -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 +35,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,199 +143,13 @@ 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 clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
 -{
 - unsigned long bitmapno, nr_bits;
 -
 - bitmapno = (pfn - cma-base_pfn)  cma-order_per_bit;
 - nr_bits = cma_bitmap_pages_to_bits(cma, count);
 -
 - mutex_lock(cma-lock);
 - bitmap_clear(cma-bitmap, bitmapno, nr_bits);
 - mutex_unlock(cma-lock);
 -}
 -
 -static int __init cma_activate_area(struct cma *cma)
 -{
 - int bitmap_maxno = cma_bitmap_maxno(cma);
 - int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long);
 - unsigned long base_pfn = cma-base_pfn, pfn = base_pfn;
 - unsigned i = cma-count  pageblock_order;
 - struct zone *zone;
 -
 - pr_debug(%s()\n, __func__);
 -
 - 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 

Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@lge.com writes:

 ppc kvm's cma region management requires arbitrary bitmap granularity,
 since they want to reserve very large memory and manage this region
 with bitmap that one bit for several pages to reduce management overheads.
 So support arbitrary bitmap granularity for following generalization.

 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com

Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com


 diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
 index bc4c171..9bc9340 100644
 --- a/drivers/base/dma-contiguous.c
 +++ b/drivers/base/dma-contiguous.c
 @@ -38,6 +38,7 @@ struct cma {
   unsigned long   base_pfn;
   unsigned long   count;
   unsigned long   *bitmap;
 + int order_per_bit; /* Order of pages represented by one bit */
   struct mutexlock;
  };

 @@ -157,9 +158,38 @@ 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 clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
 +{
 + unsigned long bitmapno, nr_bits;
 +
 + bitmapno = (pfn - cma-base_pfn)  cma-order_per_bit;
 + nr_bits = cma_bitmap_pages_to_bits(cma, count);
 +
 + mutex_lock(cma-lock);
 + bitmap_clear(cma-bitmap, bitmapno, nr_bits);
 + mutex_unlock(cma-lock);
 +}
 +
  static int __init cma_activate_area(struct cma *cma)
  {
 - int bitmap_size = BITS_TO_LONGS(cma-count) * sizeof(long);
 + int bitmap_maxno = cma_bitmap_maxno(cma);
 + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long);
   unsigned long base_pfn = cma-base_pfn, pfn = base_pfn;
   unsigned i = cma-count  pageblock_order;
   struct zone *zone;
 @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas);
   * @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 contiguous memory area, should be power of 2
 + * @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
   *
 @@ -235,7 +266,7 @@ 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,
 + phys_addr_t alignment, int order_per_bit,
   struct cma **res_cma, bool fixed)
  {
   struct cma *cma = cma_areas[cma_area_count];
 @@ -269,6 +300,8 @@ static int __init 
 __dma_contiguous_reserve_area(phys_addr_t size,
   base = ALIGN(base, alignment);
   size = ALIGN(size, alignment);
   limit = ~(alignment - 1);
 + /* size should be aligned with order_per_bit */
 + BUG_ON(!IS_ALIGNED(size  PAGE_SHIFT, 1  order_per_bit));

   /* Reserve memory */
   if (base  fixed) {
 @@ -294,6 +327,7 @@ static int __init 
 __dma_contiguous_reserve_area(phys_addr_t size,
*/
   cma-base_pfn = PFN_DOWN(base);
   cma-count = size  PAGE_SHIFT;
 + cma-order_per_bit = order_per_bit;
   *res_cma = cma;
   cma_area_count++;

 @@ -313,7 +347,7 @@ 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,
 + ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0,
   res_cma, fixed);
   if (ret)
   return ret;
 @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, 
 phys_addr_t base,
   return 0;
  }

 -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
 -{
 - mutex_lock(cma-lock);
 - bitmap_clear(cma-bitmap, pfn - cma-base_pfn, count);
 - mutex_unlock(cma-lock);
 -}
 -
  /**
   * dma_alloc_from_contiguous() - allocate pages from contiguous area
   * @dev:   Pointer to device for which the allocation is performed.
 @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned 
 long pfn, int count)
  static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count,
  unsigned int align)
  {
 - unsigned long mask, pfn, pageno, start = 0;
 + unsigned long mask, pfn, start = 0;
 + unsigned long bitmap_maxno, bitmapno, nr_bits;
   struct page *page = 

Re: [PATCH v2 06/10] CMA: generalize CMA reserved area management functionality

2014-06-14 Thread Aneesh Kumar K.V
Joonsoo Kim iamjoonsoo@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.

 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.

 Acked-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Joonsoo Kim iamjoonsoo@lge.com


.

 +
 + mask = cma_bitmap_aligned_mask(cma, align);
 + bitmap_maxno = cma_bitmap_maxno(cma);
 + nr_bits = cma_bitmap_pages_to_bits(cma, count);
 +
 + for (;;) {
 + mutex_lock(cma-lock);
 + bitmapno = bitmap_find_next_zero_area(cma-bitmap,
 + bitmap_maxno, start, nr_bits, mask);
 + if (bitmapno = bitmap_maxno) {
 + mutex_unlock(cma-lock);
 + break;
 + }
 + bitmap_set(cma-bitmap, bitmapno, nr_bits);
 + /*
 +  * 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 + (bitmapno  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) {
 + clear_cma_bitmap(cma, pfn, count);
 + break;
 + }
 + 


For setting bit map we do
bitmap_set(cma-bitmap, bitmapno, nr_bits);
alloc_contig()..
if (error)
clear_cma_bitmap(cma, pfn, count);

Why ?

why not bitmap_clear() ?

-aneesh

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] powerpc/kvm: support to handle sw breakpoint

2014-06-14 Thread Madhavan Srinivasan
This patch adds kernel side support for software breakpoint.
Design is that, by using an illegal instruction, we trap to hypervisor
via Emulation Assistance interrupt, where we check for the illegal instruction
and accordingly we return to Host or Guest. Patch mandates use of abs 
instruction
(primary opcode 31 and extended opcode 360) as sw breakpoint instruction.
Based on PowerISA v2.01, ABS instruction has been dropped from the architecture
and treated an illegal instruction.

Signed-off-by: Madhavan Srinivasan ma...@linux.vnet.ibm.com
---
 arch/powerpc/kvm/book3s.c|  3 ++-
 arch/powerpc/kvm/book3s_hv.c | 23 +++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index c254c27..b40fe5d 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -789,7 +789,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
 {
-   return -EINVAL;
+   vcpu-guest_debug = dbg-control;
+   return 0;
 }
 
 void kvmppc_decrementer_func(unsigned long data)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 7a12edb..688421d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -67,6 +67,14 @@
 /* Used as a null value for timebase values */
 #define TB_NIL (~(u64)0)
 
+/*
+ * SW_BRK_DBG_INT is debug Instruction for supporting Software Breakpoint.
+ * Instruction mnemonic is ABS, primary opcode is 31 and extended opcode is 
360.
+ * Based on PowerISA v2.01, ABS instruction has been dropped from the 
architecture
+ * and treated an illegal instruction.
+ */
+#define SW_BRK_DBG_INT 0x7c0002d0
+
 static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
 static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
 
@@ -721,12 +729,19 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, 
struct kvm_vcpu *vcpu,
break;
/*
 * This occurs if the guest executes an illegal instruction.
-* We just generate a program interrupt to the guest, since
-* we don't emulate any guest instructions at this stage.
+* To support software breakpoint, we check for the sw breakpoint
+* instruction to return back to host, if not we just generate a
+* program interrupt to the guest.
 */
case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
-   kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
-   r = RESUME_GUEST;
+   if (vcpu-arch.last_inst == SW_BRK_DBG_INT) {
+   run-exit_reason = KVM_EXIT_DEBUG;
+   run-debug.arch.address = vcpu-arch.pc;
+   r = RESUME_HOST;
+   } else {
+   kvmppc_core_queue_program(vcpu, 0x8);
+   r = RESUME_GUEST;
+   }
break;
/*
 * This occurs if the guest (kernel or userspace), does something that
-- 
1.8.3.1

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html