All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] The Contiguous Memory Allocator
@ 2010-07-20 15:51 ` Michal Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz

Hello everyone,

The following patchset implement a Contiguous Memory Allocator.  Here
is an excerpt from the documentation which describes what it is and
why is it needed:

   The Contiguous Memory Allocator (CMA) is a framework, which allows
   setting up a machine-specific configuration for physically-contiguous
   memory management. Memory for devices is then allocated according
   to that configuration.

   The main role of the framework is not to allocate memory, but to
   parse and manage memory configurations, as well as to act as an
   in-between between device drivers and pluggable allocators. It is
   thus not tied to any memory allocation method or strategy.

** Why is it needed?

    Various devices on embedded systems have no scatter-getter and/or
    IO map support and as such require contiguous blocks of memory to
    operate.  They include devices such as cameras, hardware video
    decoders and encoders, etc.

    Such devices often require big memory buffers (a full HD frame is,
    for instance, more then 2 mega pixels large, i.e. more than 6 MB
    of memory), which makes mechanisms such as kmalloc() ineffective.

    Some embedded devices impose additional requirements on the
    buffers, e.g. they can operate only on buffers allocated in
    particular location/memory bank (if system has more than one
    memory bank) or buffers aligned to a particular memory boundary.

    Development of embedded devices have seen a big rise recently
    (especially in the V4L area) and many such drivers include their
    own memory allocation code. Most of them use bootmem-based methods.
    CMA framework is an attempt to unify contiguous memory allocation
    mechanisms and provide a simple API for device drivers, while
    staying as customisable and modular as possible.

** Design

    The main design goal for the CMA was to provide a customisable and
    modular framework, which could be configured to suit the needs of
    individual systems.  Configuration specifies a list of memory
    regions, which then are assigned to devices.  Memory regions can
    be shared among many device drivers or assigned exclusively to
    one.  This has been achieved in the following ways:

    1. The core of the CMA does not handle allocation of memory and
       management of free space.  Dedicated allocators are used for
       that purpose.

       This way, if the provided solution does not match demands
       imposed on a given system, one can develop a new algorithm and
       easily plug it into the CMA framework.

       The presented solution includes an implementation of a best-fit
       algorithm.

    2. CMA allows a run-time configuration of the memory regions it
       will use to allocate chunks of memory from.  The set of memory
       regions is given on command line so it can be easily changed
       without the need for recompiling the kernel.

       Each region has it's own size, alignment demand, a start
       address (physical address where it should be placed) and an
       allocator algorithm assigned to the region.

       This means that there can be different algorithms running at
       the same time, if different devices on the platform have
       distinct memory usage characteristics and different algorithm
       match those the best way.

    3. When requesting memory, devices have to introduce themselves.
       This way CMA knows who the memory is allocated for.  This
       allows for the system architect to specify which memory regions
       each device should use.

       3a. Devices can also specify a "kind" of memory they want.
           This makes it possible to configure the system in such
           a way, that a single device may get memory from different
           memory regions, depending on the "kind" of memory it
           requested.  For example, a video codec driver might want to
           allocate some shared buffers from the first memory bank and
           the other from the second to get the highest possible
           memory throughput.

For more information please refer to the second patch from the
patchset which contains the documentation.


The patches in the patchset include:

Michal Nazarewicz (4):
  lib: rbtree: rb_root_init() function added

    The rb_root_init() function initialises an RB tree with a single
    node placed in the root.  This is more convenient then
    initialising an empty tree and then adding an element.

  mm: cma: Contiguous Memory Allocator added

    This patch is the main patchset that implements the CMA framework
    including the best-fit allocator.  It also adds a documentation.

  mm: cma: Test device and application added

    This patch adds a misc device that works as a proxy to the CMA
    framework and a simple testing application.  This lets one test
    the whole framework from user space as well as reply an recorded
    allocate/free sequence.

  arm: Added CMA to Aquila and Goni

    This patch adds the CMA platform initialisation code to two ARM
    platforms.  It serves as an example of how this is achieved.

 Documentation/cma.txt               |  435 +++++++++++++++++++
 Documentation/kernel-parameters.txt |    7 +
 arch/arm/Kconfig                    |    1 +
 arch/arm/mach-s5pv210/Kconfig       |    1 +
 arch/arm/mach-s5pv210/mach-aquila.c |    7 +
 arch/arm/mach-s5pv210/mach-goni.c   |    7 +
 drivers/misc/Kconfig                |    8 +
 drivers/misc/Makefile               |    1 +
 drivers/misc/cma-dev.c              |  183 ++++++++
 include/linux/cma-int.h             |  183 ++++++++
 include/linux/cma.h                 |  122 ++++++
 include/linux/rbtree.h              |   11 +
 mm/Kconfig                          |   41 ++
 mm/Makefile                         |    3 +
 mm/cma-allocators.h                 |   42 ++
 mm/cma-best-fit.c                   |  360 ++++++++++++++++
 mm/cma.c                            |  778 +++++++++++++++++++++++++++++++++++
 tools/cma/cma-test.c                |  373 +++++++++++++++++
 18 files changed, 2563 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/cma.txt
 create mode 100644 drivers/misc/cma-dev.c
 create mode 100644 include/linux/cma-int.h
 create mode 100644 include/linux/cma.h
 create mode 100644 mm/cma-allocators.h
 create mode 100644 mm/cma-best-fit.c
 create mode 100644 mm/cma.c
 create mode 100644 tools/cma/cma-test.c


^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH 0/4] The Contiguous Memory Allocator
@ 2010-07-20 15:51 ` Michal Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz

Hello everyone,

The following patchset implement a Contiguous Memory Allocator.  Here
is an excerpt from the documentation which describes what it is and
why is it needed:

   The Contiguous Memory Allocator (CMA) is a framework, which allows
   setting up a machine-specific configuration for physically-contiguous
   memory management. Memory for devices is then allocated according
   to that configuration.

   The main role of the framework is not to allocate memory, but to
   parse and manage memory configurations, as well as to act as an
   in-between between device drivers and pluggable allocators. It is
   thus not tied to any memory allocation method or strategy.

** Why is it needed?

    Various devices on embedded systems have no scatter-getter and/or
    IO map support and as such require contiguous blocks of memory to
    operate.  They include devices such as cameras, hardware video
    decoders and encoders, etc.

    Such devices often require big memory buffers (a full HD frame is,
    for instance, more then 2 mega pixels large, i.e. more than 6 MB
    of memory), which makes mechanisms such as kmalloc() ineffective.

    Some embedded devices impose additional requirements on the
    buffers, e.g. they can operate only on buffers allocated in
    particular location/memory bank (if system has more than one
    memory bank) or buffers aligned to a particular memory boundary.

    Development of embedded devices have seen a big rise recently
    (especially in the V4L area) and many such drivers include their
    own memory allocation code. Most of them use bootmem-based methods.
    CMA framework is an attempt to unify contiguous memory allocation
    mechanisms and provide a simple API for device drivers, while
    staying as customisable and modular as possible.

** Design

    The main design goal for the CMA was to provide a customisable and
    modular framework, which could be configured to suit the needs of
    individual systems.  Configuration specifies a list of memory
    regions, which then are assigned to devices.  Memory regions can
    be shared among many device drivers or assigned exclusively to
    one.  This has been achieved in the following ways:

    1. The core of the CMA does not handle allocation of memory and
       management of free space.  Dedicated allocators are used for
       that purpose.

       This way, if the provided solution does not match demands
       imposed on a given system, one can develop a new algorithm and
       easily plug it into the CMA framework.

       The presented solution includes an implementation of a best-fit
       algorithm.

    2. CMA allows a run-time configuration of the memory regions it
       will use to allocate chunks of memory from.  The set of memory
       regions is given on command line so it can be easily changed
       without the need for recompiling the kernel.

       Each region has it's own size, alignment demand, a start
       address (physical address where it should be placed) and an
       allocator algorithm assigned to the region.

       This means that there can be different algorithms running at
       the same time, if different devices on the platform have
       distinct memory usage characteristics and different algorithm
       match those the best way.

    3. When requesting memory, devices have to introduce themselves.
       This way CMA knows who the memory is allocated for.  This
       allows for the system architect to specify which memory regions
       each device should use.

       3a. Devices can also specify a "kind" of memory they want.
           This makes it possible to configure the system in such
           a way, that a single device may get memory from different
           memory regions, depending on the "kind" of memory it
           requested.  For example, a video codec driver might want to
           allocate some shared buffers from the first memory bank and
           the other from the second to get the highest possible
           memory throughput.

For more information please refer to the second patch from the
patchset which contains the documentation.


The patches in the patchset include:

Michal Nazarewicz (4):
  lib: rbtree: rb_root_init() function added

    The rb_root_init() function initialises an RB tree with a single
    node placed in the root.  This is more convenient then
    initialising an empty tree and then adding an element.

  mm: cma: Contiguous Memory Allocator added

    This patch is the main patchset that implements the CMA framework
    including the best-fit allocator.  It also adds a documentation.

  mm: cma: Test device and application added

    This patch adds a misc device that works as a proxy to the CMA
    framework and a simple testing application.  This lets one test
    the whole framework from user space as well as reply an recorded
    allocate/free sequence.

  arm: Added CMA to Aquila and Goni

    This patch adds the CMA platform initialisation code to two ARM
    platforms.  It serves as an example of how this is achieved.

 Documentation/cma.txt               |  435 +++++++++++++++++++
 Documentation/kernel-parameters.txt |    7 +
 arch/arm/Kconfig                    |    1 +
 arch/arm/mach-s5pv210/Kconfig       |    1 +
 arch/arm/mach-s5pv210/mach-aquila.c |    7 +
 arch/arm/mach-s5pv210/mach-goni.c   |    7 +
 drivers/misc/Kconfig                |    8 +
 drivers/misc/Makefile               |    1 +
 drivers/misc/cma-dev.c              |  183 ++++++++
 include/linux/cma-int.h             |  183 ++++++++
 include/linux/cma.h                 |  122 ++++++
 include/linux/rbtree.h              |   11 +
 mm/Kconfig                          |   41 ++
 mm/Makefile                         |    3 +
 mm/cma-allocators.h                 |   42 ++
 mm/cma-best-fit.c                   |  360 ++++++++++++++++
 mm/cma.c                            |  778 +++++++++++++++++++++++++++++++++++
 tools/cma/cma-test.c                |  373 +++++++++++++++++
 18 files changed, 2563 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/cma.txt
 create mode 100644 drivers/misc/cma-dev.c
 create mode 100644 include/linux/cma-int.h
 create mode 100644 include/linux/cma.h
 create mode 100644 mm/cma-allocators.h
 create mode 100644 mm/cma-best-fit.c
 create mode 100644 mm/cma.c
 create mode 100644 tools/cma/cma-test.c

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH 1/4] lib: rbtree: rb_root_init() function added
  2010-07-20 15:51 ` Michal Nazarewicz
  (?)
@ 2010-07-20 15:51 ` Michal Nazarewicz
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
  -1 siblings, 1 reply; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz,
	Kyungmin Park

Added a rb_root_init() function which initialises a rb_root
structure as a red-black tree with at most one element.  The
rationale is that using rb_root_init(root, node) is more
straightforward and cleaner then first initialising and
empty tree followed by an insert operation.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 include/linux/rbtree.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 7066acb..5b6dc66 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -130,6 +130,17 @@ static inline void rb_set_color(struct rb_node *rb, int color)
 }
 
 #define RB_ROOT	(struct rb_root) { NULL, }
+
+static inline void rb_root_init(struct rb_root *root, struct rb_node *node)
+{
+	root->rb_node = node;
+	if (node) {
+		node->rb_parent_color = RB_BLACK; /* black, no parent */
+		node->rb_left  = NULL;
+		node->rb_right = NULL;
+	}
+}
+
 #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 15:51 ` [PATCH 1/4] lib: rbtree: rb_root_init() function added Michal Nazarewicz
@ 2010-07-20 15:51   ` Michal Nazarewicz
  2010-07-20 15:51     ` [PATCH 3/4] mm: cma: Test device and application added Michal Nazarewicz
                       ` (4 more replies)
  0 siblings, 5 replies; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz,
	Kyungmin Park

The Contiguous Memory Allocator framework is a set of APIs for
allocating physically contiguous chunks of memory.

Various chips require contiguous blocks of memory to operate.  Those
chips include devices such as cameras, hardware video decoders and
encoders, etc.

The code is highly modular and customisable to suit the needs of
various users.  Set of regions reserved for CMA can be configured on
run-time and it is easy to add custom allocator algorithms if one
has such need.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
---
 Documentation/cma.txt               |  435 +++++++++++++++++++
 Documentation/kernel-parameters.txt |    7 +
 include/linux/cma-int.h             |  183 ++++++++
 include/linux/cma.h                 |   92 ++++
 mm/Kconfig                          |   41 ++
 mm/Makefile                         |    3 +
 mm/cma-allocators.h                 |   42 ++
 mm/cma-best-fit.c                   |  360 ++++++++++++++++
 mm/cma.c                            |  778 +++++++++++++++++++++++++++++++++++
 9 files changed, 1941 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/cma.txt
 create mode 100644 include/linux/cma-int.h
 create mode 100644 include/linux/cma.h
 create mode 100644 mm/cma-allocators.h
 create mode 100644 mm/cma-best-fit.c
 create mode 100644 mm/cma.c

diff --git a/Documentation/cma.txt b/Documentation/cma.txt
new file mode 100644
index 0000000..7edc20a
--- /dev/null
+++ b/Documentation/cma.txt
@@ -0,0 +1,435 @@
+                                                             -*- org -*-
+
+* Contiguous Memory Allocator
+
+   The Contiguous Memory Allocator (CMA) is a framework, which allows
+   setting up a machine-specific configuration for physically-contiguous
+   memory management. Memory for devices is then allocated according
+   to that configuration.
+
+   The main role of the framework is not to allocate memory, but to
+   parse and manage memory configurations, as well as to act as an
+   in-between between device drivers and pluggable allocators. It is
+   thus not tied to any memory allocation method or strategy.
+
+** Why is it needed?
+
+    Various devices on embedded systems have no scatter-getter and/or
+    IO map support and as such require contiguous blocks of memory to
+    operate.  They include devices such as cameras, hardware video
+    decoders and encoders, etc.
+
+    Such devices often require big memory buffers (a full HD frame is,
+    for instance, more then 2 mega pixels large, i.e. more than 6 MB
+    of memory), which makes mechanisms such as kmalloc() ineffective.
+
+    Some embedded devices impose additional requirements on the
+    buffers, e.g. they can operate only on buffers allocated in
+    particular location/memory bank (if system has more than one
+    memory bank) or buffers aligned to a particular memory boundary.
+
+    Development of embedded devices have seen a big rise recently
+    (especially in the V4L area) and many such drivers include their
+    own memory allocation code. Most of them use bootmem-based methods.
+    CMA framework is an attempt to unify contiguous memory allocation
+    mechanisms and provide a simple API for device drivers, while
+    staying as customisable and modular as possible.
+
+** Design
+
+    The main design goal for the CMA was to provide a customisable and
+    modular framework, which could be configured to suit the needs of
+    individual systems.  Configuration specifies a list of memory
+    regions, which then are assigned to devices.  Memory regions can
+    be shared among many device drivers or assigned exclusively to
+    one.  This has been achieved in the following ways:
+
+    1. The core of the CMA does not handle allocation of memory and
+       management of free space.  Dedicated allocators are used for
+       that purpose.
+
+       This way, if the provided solution does not match demands
+       imposed on a given system, one can develop a new algorithm and
+       easily plug it into the CMA framework.
+
+       The presented solution includes an implementation of a best-fit
+       algorithm.
+
+    2. CMA allows a run-time configuration of the memory regions it
+       will use to allocate chunks of memory from.  The set of memory
+       regions is given on command line so it can be easily changed
+       without the need for recompiling the kernel.
+
+       Each region has it's own size, alignment demand, a start
+       address (physical address where it should be placed) and an
+       allocator algorithm assigned to the region.
+
+       This means that there can be different algorithms running at
+       the same time, if different devices on the platform have
+       distinct memory usage characteristics and different algorithm
+       match those the best way.
+
+    3. When requesting memory, devices have to introduce themselves.
+       This way CMA knows who the memory is allocated for.  This
+       allows for the system architect to specify which memory regions
+       each device should use.
+
+       3a. Devices can also specify a "kind" of memory they want.
+           This makes it possible to configure the system in such
+           a way, that a single device may get memory from different
+           memory regions, depending on the "kind" of memory it
+           requested.  For example, a video codec driver might want to
+           allocate some shared buffers from the first memory bank and
+           the other from the second to get the highest possible
+           memory throughput.
+
+** Use cases
+
+    Lets analyse some imaginary system that uses the CMA to see how
+    the framework can be used and configured.
+
+
+    We have a platform with a hardware video decoder and a camera each
+    needing 20 MiB of memory in worst case.  Our system is written in
+    such a way though that the two devices are never used at the same
+    time and memory for them may be shared.  In such a system the
+    following two command line arguments would be used:
+
+        cma=r=20M cma_map=video,camera=r
+
+    The first instructs CMA to allocate a region of 20 MiB and use the
+    first available memory allocator on it.  The second, that drivers
+    named "video" and "camera" are to be granted memory from the
+    previously defined region.
+
+    We can see, that because the devices share the same region of
+    memory, we save 20 MiB of memory, compared to the situation when
+    each of the devices would reserve 20 MiB of memory for itself.
+
+
+    However, after some development of the system, it can now run
+    video decoder and camera at the same time.  The 20 MiB region is
+    no longer enough for the two to share.  A quick fix can be made to
+    grant each of those devices separate regions:
+
+        cma=v=20M,c=20M cma_map=video=v;camera=c
+
+    This solution also shows how with CMA you can assign private pools
+    of memory to each device if that is required.
+
+    Allocation mechanisms can be replaced dynamically in a similar
+    manner as well. Let's say that during testing, it has been
+    discovered that, for a given shared region of 40 MiB,
+    fragmentation has become a problem.  It has been observed that,
+    after some time, it becomes impossible to allocate buffers of the
+    required sizes. So to satisfy our requirements, we would have to
+    reserve a larger shared region beforehand.
+
+    But fortunately, you have also managed to develop a new allocation
+    algorithm -- Neat Allocation Algorithm or "na" for short -- which
+    satisfies the needs for both devices even on a 30 MiB region.  The
+    configuration can be then quickly changed to:
+
+        cma=r=30M:na cma_map=video,camera=r
+
+    This shows how you can develop your own allocation algorithms if
+    the ones provided with CMA do not suit your needs and easily
+    replace them, without the need to modify CMA core or even
+    recompiling the kernel.
+
+** Technical Details
+
+*** The command line parameters
+
+    As shown above, CMA is configured from command line via two
+    arguments: "cma" and "cma_map".  The first one specifies regions
+    that are to be reserved for CMA.  The second one specifies what
+    regions each device is assigned to.
+
+    The format of the "cma" parameter is as follows:
+
+        cma          ::=  "cma=" regions [ ';' ]
+        regions      ::= region [ ';' regions ]
+
+        region       ::= reg-name
+                           '=' size
+                         [ '@' start ]
+                         [ '/' alignment ]
+                         [ ':' [ alloc-name ] [ '(' alloc-params ')' ] ]
+
+        reg-name     ::= a sequence of letters and digits
+                                   // name of the region
+
+        size         ::= memsize   // size of the region
+        start        ::= memsize   // desired start address of
+                                   // the region
+        alignment    ::= memsize   // alignment of the start
+                                   // address of the region
+
+        alloc-name   ::= a non-empty sequence of letters and digits
+                     // name of an allocator that will be used
+                     // with the region
+        alloc-params ::= a sequence of chars other then ')' and ';'
+                     // optional parameters for the allocator
+
+        memsize      ::= whatever memparse() accepts
+
+    The format of the "cma_map" parameter is as follows:
+
+        cma-map      ::=  "cma_map=" rules [ ';' ]
+        rules        ::= rule [ ';' rules ]
+        rule         ::= patterns '=' regions
+        patterns     ::= pattern [ ',' patterns ]
+
+        regions      ::= reg-name [ ',' regions ]
+                     // list of regions to try to allocate memory
+                     // from for devices that match pattern
+
+        pattern      ::= dev-pattern [ '/' kind-pattern ]
+                       | '/' kind-pattern
+                     // pattern request must match for this rule to
+                     // apply to it; the first rule that matches is
+                     // applied; if dev-pattern part is omitted
+                     // value identical to the one used in previous
+                     // pattern is assumed
+
+        dev-pattern  ::= pattern-str
+                     // pattern that device name must match for the
+                     // rule to apply.
+        kind-pattern ::= pattern-str
+                     // pattern that "kind" of memory (provided by
+                     // device) must match for the rule to apply.
+
+        pattern-str  ::= a non-empty sequence of characters with '?'
+                         meaning any character and possible '*' at
+                         the end meaning to match the rest of the
+                         string
+
+    Some examples (whitespace added for better readability):
+
+        cma = r1 = 64M       // 64M region
+                   @512M       // starting at address 512M
+                               // (or at least as near as possible)
+                   /1M         // make sure it's aligned to 1M
+                   :foo(bar);  // uses allocator "foo" with "bar"
+                               // as parameters for it
+              r2 = 64M       // 64M region
+                   /1M;        // make sure it's aligned to 1M
+                               // uses the first available allocator
+              r3 = 64M       // 64M region
+                   @512M       // starting at address 512M
+                   :foo;       // uses allocator "foo" with no parameters
+
+        cma_map = foo = r1;
+                      // device foo with kind==NULL uses region r1
+
+                  foo/quaz = r2;  // OR:
+                  /quaz = r2;
+                      // device foo with kind == "quaz" uses region r2
+
+                  foo/* = r3;     // OR:
+                  /* = r3;
+                      // device foo with any other kind uses region r3
+
+                  bar/* = r1,r2;
+                      // device bar with any kind uses region r1 or r2
+
+                  baz?/a* , baz?/b* = r3;
+                      // devices named baz? where ? is any character
+                      // with kind being a string starting with "a" or
+                      // "b" use r3
+
+
+*** The device and kind of memory
+
+    The name of the device is taken form the device structure.  It is
+    not possible to use CMA if driver does not register a device
+    (actually this can be overcome if a fake device structure is
+    provided with at least the name set).
+
+    The kind of memory is an optional argument provided by the device
+    whenever it requests memory chunk.  In many cases this can be
+    ignored but sometimes it may be required for some devices.
+
+    For instance, let say that there are two memory banks and for
+    performance reasons a device uses buffers in both of them.  In
+    such case, the device driver would define two kinds and use it for
+    different buffers.  Command line arguments could look as follows:
+
+            cma=a=32M@0,b=32M@512M cma_map=foo/a=a;foo/b=b
+
+    And whenever the driver allocated the memory it would specify the
+    kind of memory:
+
+            buffer1 = cma_alloc(dev, 1 << 20, 0, "a");
+            buffer2 = cma_alloc(dev, 1 << 20, 0, "b");
+
+    If it was needed to try to allocate from the other bank as well if
+    the dedicated one is full command line arguments could be changed
+    to:
+
+            cma=a=32M@0,b=32M@512M cma_map=foo/a=a,b;foo/b=b,a
+
+    On the other hand, if the same driver was used on a system with
+    only one bank, the command line could be changed to:
+
+            cma=r=64M cma_map=foo/*=r
+
+    without the need to change the driver at all.
+
+*** API
+
+    There are four calls provided by the CMA framework to devices.  To
+    allocate a chunk of memory cma_alloc() function needs to be used:
+
+            unsigned long cma_alloc(const struct device *dev,
+                                    const char *kind,
+                                    unsigned long size,
+                                    unsigned long alignment);
+
+    If required, device may specify alignment that the chunk need to
+    satisfy.  It have to be a power of two or zero.  The chunks are
+    always aligned at least to a page.
+
+    The kind specifies the kind of memory as described to in the
+    previous subsection.  If device driver does not use notion of
+    memory kinds it's safe to pass NULL as the kind.
+
+    The basic usage of the function is just a:
+
+            addr = cma_alloc(dev, NULL, size, 0);
+
+    The function returns physical address of allocated chunk or
+    a value that evaluated true if checked with IS_ERR_VALUE(), so the
+    correct way for checking for errors is:
+
+            unsigned long addr = cma_alloc(dev, size);
+            if (IS_ERR_VALUE(addr))
+                    return (int)addr;
+            /* Allocated */
+
+    (Make sure to include <linux/err.h> which contains the definition
+    of the IS_ERR_VALUE() macro.)
+
+
+    Allocated chunk is freed via a cma_put() function:
+
+            int cma_put(unsigned long addr);
+
+    It takes physical address of the chunk as an argument and
+    decreases it's reference counter.  If the counter reaches zero the
+    chunk is freed.  Most of the time users do not need to think about
+    reference counter and simply use the cma_put() as a free call.
+
+    If one, however, were to share a chunk with others built in
+    reference counter may turn out to be handy.  To increment it, one
+    needs to use cma_get() function:
+
+            int cma_put(unsigned long addr);
+
+
+    The last function is the cma_info() which returns information
+    about regions assigned to given (dev, kind) pair.  Its syntax is:
+
+            int cma_info(struct cma_info *info,
+                         const struct device *dev,
+                         const char *kind);
+
+    On successful exit it fills the info structure with lower and
+    upper bound of regions, total size and number of regions assigned
+    to given (dev, kind) pair.
+
+*** Allocator operations
+
+    Creating an allocator for CMA needs four functions to be
+    implemented.
+
+
+    The first two are used to initialise an allocator far given driver
+    and clean up afterwards:
+
+            int  cma_foo_init(struct cma_region *reg);
+            void cma_foo_done(struct cma_region *reg);
+
+    The first is called during platform initialisation.  The
+    cma_region structure has saved starting address of the region as
+    well as its size.  It has also alloc_params field with optional
+    parameters passed via command line (allocator is free to interpret
+    those in any way it pleases).  Any data that allocate associated
+    with the region can be saved in private_data field.
+
+    The second call cleans up and frees all resources the allocator
+    has allocated for the region.  The function can assume that all
+    chunks allocated form this region have been freed thus the whole
+    region is free.
+
+
+    The two other calls are used for allocating and freeing chunks.
+    They are:
+
+            struct cma_chunk *cma_foo_alloc(struct cma_region *reg,
+                                            unsigned long size,
+                                            unsigned long alignment);
+            void cma_foo_free(struct cma_chunk *chunk);
+
+    As names imply the first allocates a chunk and the other frees
+    a chunk of memory.  It also manages a cma_chunk object
+    representing the chunk in physical memory.
+
+    Either of those function can assume that they are the only thread
+    accessing the region.  Therefore, allocator does not need to worry
+    about concurrency.
+
+
+    When allocator is ready, all that is left is register it by adding
+    a line to "mm/cma-allocators.h" file:
+
+            CMA_ALLOCATOR("foo", foo)
+
+    The first "foo" is a named that will be available to use with
+    command line argument.  The second is the part used in function
+    names.
+
+*** Integration with platform
+
+    There is one function that needs to be called form platform
+    initialisation code.  That is the cma_regions_allocate() function:
+
+            void cma_regions_allocate(int (*alloc)(struct cma_region *reg));
+
+    It traverses list of all of the regions given on command line and
+    reserves memory for them.  The only argument is a callback
+    function used to reserve the region.  Passing NULL as the argument
+    makes the function use cma_region_alloc() function which uses
+    bootmem for allocating.
+
+    Alternatively, platform code could traverse the cma_regions array
+    by itself but this should not be necessary.
+
+    The If cma_region_alloc() allocator is used, the
+    cma_regions_allocate() function needs to be allocated when bootmem
+    is active.
+
+
+    Platform has also a way of providing default cma and cma_map
+    parameters.  cma_defaults() function is used for that purpose:
+
+            int cma_defaults(const char *cma, const char *cma_map)
+
+    It needs to be called after early params have been parsed but
+    prior to allocating regions.  Arguments of this function are used
+    only if they are not-NULL and respective command line argument was
+    not provided.
+
+** Future work
+
+    In the future, implementation of mechanisms that would allow the
+    free space inside the regions to be used as page cache, filesystem
+    buffers or swap devices is planned.  With such mechanisms, the
+    memory would not be wasted when not used.
+
+    Because all allocations and freeing of chunks pass the CMA
+    framework it can follow what parts of the reserved memory are
+    freed and what parts are allocated.  Tracking the unused memory
+    would let CMA use it for other purposes such as page cache, I/O
+    buffers, swap, etc.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a6a3fcb..de1a522 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -43,6 +43,7 @@ parameter is applicable:
 	AVR32	AVR32 architecture is enabled.
 	AX25	Appropriate AX.25 support is enabled.
 	BLACKFIN Blackfin architecture is enabled.
+	CMA	Contiguous Memory Allocator is enabled.
 	DRM	Direct Rendering Management support is enabled.
 	EDD	BIOS Enhanced Disk Drive Services (EDD) is enabled
 	EFI	EFI Partitioning (GPT) is enabled
@@ -476,6 +477,12 @@ and is between 256 and 4096 characters. It is defined in the file
 			Also note the kernel might malfunction if you disable
 			some critical bits.
 
+	cma=		[CMA] List of CMA regions.
+			See Documentation/cma.txt for details.
+
+	cma_map=	[CMA] List of CMA mapping rules.
+			See Documentation/cma.txt for details.
+
 	cmo_free_hint=	[PPC] Format: { yes | no }
 			Specify whether pages are marked as being inactive
 			when they are freed.  This is used in CMO environments
diff --git a/include/linux/cma-int.h b/include/linux/cma-int.h
new file mode 100644
index 0000000..b588e9b
--- /dev/null
+++ b/include/linux/cma-int.h
@@ -0,0 +1,183 @@
+#ifndef __LINUX_CMA_INT_H
+#define __LINUX_CMA_INT_H
+
+#ifdef CONFIG_CMA
+
+/*
+ * Contiguous Memory Allocator framework: internal header
+ * Copyright (c) 2010 by Samsung Electronics.
+ * Written by Michal Nazarewicz (m.nazarewicz@samsung.com)
+ */
+
+/*
+ * See Documentation/cma.txt for documentation.
+ */
+
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/rbtree.h>
+
+struct cma_allocator;
+
+/**
+ * struct cma_region - a region reserved for CMA allocations.
+ * @name:	Unique name of the region.  Passed with cmdline.  Read only.
+ * @start:	Physical starting address of the region in bytes.  Always
+ * 		aligned to the value specified by @alignment.  Initialised
+ * 		from value read from cmdline.  Read only for allocators.
+ * 		Read write for platform-specific region allocation code.
+ * @size:	Physical size of the region in bytes.  At least page
+ * 		aligned.  Initialised with value read from cmdline.  Read
+ * 		only for allocators.  Read write for platform-specific region
+ * 		allocation code.
+ * @alignment:	Desired alignment of the region.  A power of two, greater or\
+ * 		equal PAGE_SIZE.  Initialised from value read from cmdline.
+ * 		Read only.
+ * @alloc:	Allocator used with this region.  NULL means region is not
+ * 		allocated.  Read only.
+ * @alloc_name:	Allocator name read from cmdline.  Private.
+ * @alloc_params:	Allocator-specific parameters read from cmdline.
+ * 			Read only for allocator.
+ * @private_data:	Allocator's private data.
+ * @users:	Number of chunks allocated in this region.
+ * @mutex:	Guarantees that only one allocation/deallocation on given
+ * 		region is performed.
+ */
+struct cma_region {
+	const char *name;
+	unsigned long start;
+	unsigned long size, free_space;
+	unsigned long alignment;
+
+	struct cma_allocator *alloc;
+	const char *alloc_name;
+	const char *alloc_params;
+	void *private_data;
+
+	unsigned users;
+	/*
+	 * Protects the "users" and "free_space" fields and any calls
+	 * to allocator on this region thus guarantees only one call
+	 * to allocator will operate on this region..
+	 */
+	struct mutex mutex;
+};
+
+/**
+ * struct cma_chunk - an allocated contiguous chunk of memory.
+ * @start:	Physical address in bytes.
+ * @size:	Size in bytes.
+ * @free_space:	Free space in region in bytes.  Read only.
+ * @reg:	Region this chunk belongs to.
+ * @kref:	Number of references.  Private.
+ * @by_start:	A node in an red-black tree with all chunks sorted by
+ * 		start address.
+ *
+ * The cma_allocator::alloc() operation need to set only the @start
+ * and @size fields.  The rest is handled by the caller (ie. CMA
+ * glue).
+ */
+struct cma_chunk {
+	unsigned long start;
+	unsigned long size;
+
+	struct cma_region *reg;
+	struct kref ref;
+	struct rb_node by_start;
+};
+
+
+/**
+ * struct cma_allocator - a CMA allocator.
+ * @name:	Allocator's unique name
+ * @init:	Initialises a allocator on given region.  May not sleep.
+ * @cleanup:	Cleans up after init.  May assume that there are no chunks
+ * 		allocated in given region.  May not sleep.
+ * @alloc:	Allocates a chunk of memory of given size in bytes and
+ * 		with given alignment.  Alignment is a power of
+ * 		two (thus non-zero) and callback does not need to check it.
+ * 		May also assume that it is the only call that uses given
+ * 		region (ie. access to the region is synchronised with
+ * 		a mutex).  This has to allocate the chunk object (it may be
+ * 		contained in a bigger structure with allocator-specific data.
+ * 		May sleep.
+ * @free:	Frees allocated chunk.  May also assume that it is the only
+ * 		call that uses given region.  This has to kfree() the chunk
+ * 		object as well.  May sleep.
+ */
+struct cma_allocator {
+	const char *name;
+	int (*init)(struct cma_region *reg);
+	void (*cleanup)(struct cma_region *reg);
+	struct cma_chunk *(*alloc)(struct cma_region *reg, unsigned long size,
+				   unsigned long alignment);
+	void (*free)(struct cma_chunk *chunk);
+};
+
+
+/**
+ * cma_region - a list of regions filled when parameters are parsed.
+ *
+ * This is terminated by an zero-sized entry (ie. an entry which size
+ * field is zero).  Platform needs to allocate space for each of the
+ * region before initcalls are executed.
+ */
+extern struct cma_region cma_regions[];
+
+
+/**
+ * cma_defaults() - specifies default command line parameters.
+ * @cma:	Default cma parameter if one was not specified via command
+ * 		line.
+ * @cma_map:	Default cma_map parameter if one was not specified via
+ * 		command line.
+ *
+ * This function should be called prior to cma_regions_allocate() and
+ * after early parameters have been parsed.  The @cma argument is only
+ * used if there was no cma argument passed on command line.  The same
+ * goes for @cma_map which is used only if cma_map was not passed on
+ * command line.
+ *
+ * Either of the argument may be NULL.
+ *
+ * Returns negative error code if there was an error parsing either of
+ * the parameters or zero.
+ */
+int __init cma_defaults(const char *cma, const char *cma_map);
+
+
+/**
+ * cma_region_alloc() - allocates a physically contiguous memory region.
+ * @reg:	Region to allocate memory for.
+ *
+ * If platform supports bootmem this is the first allocator this
+ * function tries to use.  If that failes (or bootmem is not
+ * supported) function tries to use memblec if it is available.
+ *
+ * Returns zero or negative error.
+ */
+int __init cma_region_alloc(struct cma_region *reg);
+
+/**
+ * cma_regions_allocate() - helper function for allocating regions.
+ * @alloc:	Region allocator.  Needs to return non-negative if
+ * 		allocation succeeded, negative error otherwise.  NULL
+ * 		means cma_region_alloc() should be used.
+ *
+ * This function traverses the cma_regions array and tries to reserve
+ * memory for each region.  It uses the @alloc callback function for
+ * that purpose.  If allocation failes for a given region, it is
+ * removed from the array (by shifting all the elements after it).
+ *
+ * Returns number of reserved regions.
+ */
+int __init cma_regions_allocate(int (*alloc)(struct cma_region *reg));
+
+#else
+
+#define cma_regions_allocate(alloc) ((int)0)
+
+#endif
+
+
+#endif
diff --git a/include/linux/cma.h b/include/linux/cma.h
new file mode 100644
index 0000000..aef8347
--- /dev/null
+++ b/include/linux/cma.h
@@ -0,0 +1,92 @@
+#ifndef __LINUX_CMA_H
+#define __LINUX_CMA_H
+
+/*
+ * Contiguous Memory Allocator framework
+ * Copyright (c) 2010 by Samsung Electronics.
+ * Written by Michal Nazarewicz (m.nazarewicz@samsung.com)
+ */
+
+/*
+ * See Documentation/cma.txt for documentation.
+ */
+
+#ifdef __KERNEL__
+
+struct device;
+
+/**
+ * cma_alloc() - allocates contiguous chunk of memory.
+ * @dev:	The device to perform allocation for.
+ * @kind:	A kind of memory to allocate.  A device may use several
+ * 		different kinds of memory which are configured
+ * 		separately.  Usually it's safe to pass NULL here.
+ * @size:	Size of the memory to allocate in bytes.
+ * @alignment:	Desired alignment.  Must be a power of two or zero.  If
+ * 		alignment is less then a page size it will be set to
+ * 		page size. If unsure, pass zero here.
+ *
+ * On error returns a negative error cast to unsigned long.  Use
+ * IS_ERR_VALUE() to check if returned value is indeed an error.
+ * Otherwise physical address of the chunk is returned.
+ */
+unsigned long __must_check
+cma_alloc(const struct device *dev, const char *kind,
+	  unsigned long size, unsigned long alignment);
+
+
+/**
+ * struct cma_info - information about regions returned by cma_info().
+ * @lower_bound:	The smallest address that is possible to be
+ * 			allocated for given (dev, kind) pair.
+ * @upper_bound:	The one byte after the biggest address that is
+ * 			possible to be allocated for given (dev, kind)
+ * 			pair.
+ * @total_size:	Total size of regions mapped to (dev, kind) pair.
+ * @count:	Number of regions mapped to (dev, kind) pair.
+ */
+struct cma_info {
+	unsigned long lower_bound, upper_bound;
+	unsigned long total_size;
+	unsigned count;
+};
+
+/**
+ * cma_info() - queries information about regions.
+ * @info:	Pointer to a structure where to save the information.
+ * @dev:	The device to query information for.
+ * @kind:	A kind of memory to query information for.
+ * 		If unsure, pass NULL here.
+ *
+ * On error returns a negative error, zero otherwise.
+ */
+int __must_check
+cma_info(struct cma_info *info, const struct device *dev, const char *kind);
+
+
+/**
+ * cma_get() - increases reference counter of a chunk.
+ * @addr:	Beginning of the chunk.
+ *
+ * Returns zero on success or -ENOENT if there is no chunk at given
+ * location.  In the latter case issues a warning and a stacktrace.
+ */
+int cma_get(unsigned long addr);
+
+/**
+ * cma_put() - decreases reference counter of a chunk.
+ * @addr:	Beginning of the chunk.
+ *
+ * Returns one if the chunk has been freed, zero if it hasn't, and
+ * -ENOENT if there is no chunk at given location.  In the latter case
+ * issues a warning and a stacktrace.
+ *
+ * If this function returns zero, you still can not count on the area
+ * remaining in memory.  Only use the return value if you want to see
+ * if the area is now gone, not present.
+ */
+int cma_put(unsigned long addr);
+
+#endif
+
+#endif
diff --git a/mm/Kconfig b/mm/Kconfig
index f4e516e..7841f77 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -301,3 +301,44 @@ config NOMMU_INITIAL_TRIM_EXCESS
 	  of 1 says that all excess pages should be trimmed.
 
 	  See Documentation/nommu-mmap.txt for more information.
+
+
+config ARCH_CMA_POSSIBLE
+	bool
+
+config ARCH_NEED_CMA_REGION_ALLOC
+	bool
+
+config CMA
+	bool "Contiguous Memory Allocator framework"
+	depends on ARCH_CMA_POSSIBLE
+	# Currently there is only one allocator so force it on
+	select CMA_BEST_FIT
+	help
+	  This enables the Contiguous Memory Allocator framework which
+	  allows drivers to allocate big physically-contiguous blocks of
+	  memory for use with hardware components that do not support I/O
+	  map nor scatter-gather.
+
+	  If you select this option you will also have to select at least
+	  one allocator algorithm below.
+
+	  To make use of CMA you need to specify the regions and
+	  driver->region mapping on command line when booting the kernel.
+
+config CMA_DEBUG
+	bool "CMA debug messages"
+	depends on CMA
+	help
+	  Enable debug messages in CMA code.
+
+config CMA_BEST_FIT
+	bool "CMA best-fit allocator"
+	depends on CMA
+	default y
+	help
+	  This is a best-fit algorithm running in O(n log n) time where
+	  n is the number of existing holes (which is never greater then
+	  the number of allocated regions and usually much smaller).  It
+	  allocates area from the smallest hole that is big enough for
+	  allocation in question.
diff --git a/mm/Makefile b/mm/Makefile
index 34b2546..54b0e99 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -47,3 +47,6 @@ obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
 obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
 obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
 obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
+
+obj-$(CONFIG_CMA) += cma.o
+obj-$(CONFIG_CMA_BEST_FIT) += cma-best-fit.o
diff --git a/mm/cma-allocators.h b/mm/cma-allocators.h
new file mode 100644
index 0000000..564f705
--- /dev/null
+++ b/mm/cma-allocators.h
@@ -0,0 +1,42 @@
+#ifdef __CMA_ALLOCATORS_H
+
+/* List all existing allocators here using CMA_ALLOCATOR macro. */
+
+#ifdef CONFIG_CMA_BEST_FIT
+CMA_ALLOCATOR("bf", bf)
+#endif
+
+
+#  undef CMA_ALLOCATOR
+#else
+#  define __CMA_ALLOCATORS_H
+
+/* Function prototypes */
+#  ifndef __LINUX_CMA_ALLOCATORS_H
+#    define __LINUX_CMA_ALLOCATORS_H
+#    define CMA_ALLOCATOR(name, infix)					\
+	extern int cma_ ## infix ## _init(struct cma_region *);		\
+	extern void cma_ ## infix ## _cleanup(struct cma_region *);	\
+	extern struct cma_chunk *					\
+	cma_ ## infix ## _alloc(struct cma_region *,			\
+			      unsigned long, unsigned long);		\
+	extern void cma_ ## infix ## _free(struct cma_chunk *);
+#    include "cma-allocators.h"
+#  endif
+
+/* The cma_allocators array */
+#  ifdef CMA_ALLOCATORS_LIST
+#    define CMA_ALLOCATOR(_name, infix) {		\
+		.name    = _name,			\
+		.init    = cma_ ## infix ## _init,	\
+		.cleanup = cma_ ## infix ## _cleanup,	\
+		.alloc   = cma_ ## infix ## _alloc,	\
+		.free    = cma_ ## infix ## _free,	\
+	},
+static struct cma_allocator cma_allocators[] = {
+#    include "cma-allocators.h"
+};
+#    undef CMA_ALLOCATOR_LIST
+#  endif
+#  undef __CMA_ALLOCATORS_H
+#endif
diff --git a/mm/cma-best-fit.c b/mm/cma-best-fit.c
new file mode 100644
index 0000000..0862a8d
--- /dev/null
+++ b/mm/cma-best-fit.c
@@ -0,0 +1,360 @@
+/*
+ * Contiguous Memory Allocator framework: Best Fit allocator
+ * Copyright (c) 2010 by Samsung Electronics.
+ * Written by Michal Nazarewicz (m.nazarewicz@samsung.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: bf: " fmt
+
+#ifdef CONFIG_CMA_DEBUG
+#  define DEBUG
+#endif
+
+#include <linux/errno.h>       /* Error numbers */
+#include <linux/slab.h>        /* kmalloc() */
+
+#include <linux/cma-int.h>     /* CMA structures */
+
+#include "cma-allocators.h"    /* Prototypes */
+
+
+/************************* Data Types *************************/
+
+struct cma_bf_item {
+	struct cma_chunk ch;
+	struct rb_node by_size;
+};
+
+struct cma_bf_private {
+	struct rb_root by_start_root;
+	struct rb_root by_size_root;
+};
+
+
+/************************* Prototypes *************************/
+
+/*
+ * Those are only for holes.  They must be called whenever hole's
+ * properties change but also whenever chunk becomes a hole or hole
+ * becames a chunk.
+ */
+static void __cma_bf_hole_insert_by_size(struct cma_bf_item *item);
+static void __cma_bf_hole_erase_by_size(struct cma_bf_item *item);
+static void __cma_bf_hole_insert_by_start(struct cma_bf_item *item);
+static void __cma_bf_hole_erase_by_start(struct cma_bf_item *item);
+
+/**
+ * __cma_bf_hole_take() - takes a chunk of memory out of a hole.
+ * @hole:	hole to take chunk from
+ * @size	chunk's size
+ * @alignment:	chunk's starting address alignment (must be power of two)
+ *
+ * Takes a @size bytes large chunk from hole @hole which must be able
+ * to hold the chunk.  The "must be able" includes also alignment
+ * constraint.
+ *
+ * Returns allocated item or NULL on error (if kmalloc() failed).
+ */
+static struct cma_bf_item *__must_check
+__cma_bf_hole_take(struct cma_bf_item *hole, size_t size, size_t alignment);
+
+/**
+ * __cma_bf_hole_merge_maybe() - tries to merge hole with neighbours.
+ *
+ * @item hole to try and merge
+ *
+ * Which items are preserved is undefined so you may not rely on it.
+ */
+static void __cma_bf_hole_merge_maybe(struct cma_bf_item *item);
+
+
+/************************* Device API *************************/
+
+int cma_bf_init(struct cma_region *reg)
+{
+	struct cma_bf_private *prv;
+	struct cma_bf_item *item;
+
+	prv = kzalloc(sizeof *prv, GFP_NOWAIT);
+	if (unlikely(!prv))
+		return -ENOMEM;
+
+	item = kzalloc(sizeof *item, GFP_NOWAIT);
+	if (unlikely(!item)) {
+		kfree(prv);
+		return -ENOMEM;
+	}
+
+	item->ch.start = reg->start;
+	item->ch.size  = reg->size;
+	item->ch.reg   = reg;
+
+	rb_root_init(&prv->by_start_root, &item->ch.by_start);
+	rb_root_init(&prv->by_size_root, &item->by_size);
+
+	reg->private_data = prv;
+	return 0;
+}
+
+void cma_bf_cleanup(struct cma_region *reg)
+{
+	struct cma_bf_private *prv = reg->private_data;
+	struct cma_bf_item *item =
+		rb_entry(prv->by_size_root.rb_node,
+			 struct cma_bf_item, by_size);
+
+	/* We can assume there is only a single hole in the tree. */
+	WARN_ON(item->by_size.rb_left || item->by_size.rb_right ||
+		item->ch.by_start.rb_left || item->ch.by_start.rb_right);
+
+	kfree(item);
+	kfree(prv);
+}
+
+struct cma_chunk *cma_bf_alloc(struct cma_region *reg,
+			       unsigned long size, unsigned long alignment)
+{
+	struct cma_bf_private *prv = reg->private_data;
+	struct rb_node *node = prv->by_size_root.rb_node;
+	struct cma_bf_item *item = NULL;
+	unsigned long start, end;
+
+	/* First first item that is large enough */
+	while (node) {
+		struct cma_bf_item *i =
+			rb_entry(node, struct cma_bf_item, by_size);
+
+		if (i->ch.size < size) {
+			node = node->rb_right;
+		} else if (i->ch.size >= size) {
+			node = node->rb_left;
+			item = i;
+		}
+	}
+	if (unlikely(!item))
+		return NULL;
+
+	/* Now look for items which can satisfy alignment requirements */
+	for (;;) {
+		start = ALIGN(item->ch.start, alignment);
+		end   = item->ch.start + item->ch.size;
+		if (start < end && end - start >= size) {
+			item = __cma_bf_hole_take(item, size, alignment);
+			return likely(item) ? &item->ch : NULL;
+		}
+
+		node = rb_next(node);
+		if (!node)
+			return NULL;
+
+		item  = rb_entry(node, struct cma_bf_item, by_size);
+	}
+}
+
+void cma_bf_free(struct cma_chunk *chunk)
+{
+	struct cma_bf_item *item = container_of(chunk, struct cma_bf_item, ch);
+
+	/* Add new hole */
+	__cma_bf_hole_insert_by_size(item);
+	__cma_bf_hole_insert_by_start(item);
+
+	/* Merge with prev and next sibling */
+	__cma_bf_hole_merge_maybe(item);
+}
+
+
+/************************* Basic Tree Manipulation *************************/
+
+#define __CMA_BF_HOLE_INSERT(root, node, field) ({			\
+	bool equal = false;						\
+	struct rb_node **link = &(root).rb_node, *parent = NULL;	\
+	const unsigned long value = item->field;			\
+	while (*link) {							\
+		struct cma_bf_item *i;					\
+		parent = *link;						\
+		i = rb_entry(parent, struct cma_bf_item, node);		\
+		link = value <= i->field				\
+			? &parent->rb_left				\
+			: &parent->rb_right;				\
+		equal = equal || value == i->field;			\
+	}								\
+	rb_link_node(&item->node, parent, link);			\
+	rb_insert_color(&item->node, &root);				\
+	equal;								\
+})
+
+static void __cma_bf_hole_insert_by_size(struct cma_bf_item *item)
+{
+	struct cma_bf_private *prv = item->ch.reg->private_data;
+	(void)__CMA_BF_HOLE_INSERT(prv->by_size_root, by_size, ch.size);
+}
+
+static void __cma_bf_hole_erase_by_size(struct cma_bf_item *item)
+{
+	struct cma_bf_private *prv = item->ch.reg->private_data;
+	rb_erase(&item->by_size, &prv->by_size_root);
+}
+
+static void __cma_bf_hole_insert_by_start(struct cma_bf_item *item)
+{
+	struct cma_bf_private *prv = item->ch.reg->private_data;
+	/*
+	 * __CMA_BF_HOLE_INSERT returns true if there was another node
+	 * with the same value encountered.  This should never happen
+	 * for start address and so we produce a warning.
+	 *
+	 * It's really some kind of bug if we got to such situation
+	 * and things may start working incorrectly.  Nonetheless,
+	 * there is not much we can do other then screaming as loud as
+	 * we can hoping someone will notice the bug and fix it.
+	 */
+	WARN_ON(__CMA_BF_HOLE_INSERT(prv->by_start_root, ch.by_start,
+				     ch.start));
+}
+
+static void __cma_bf_hole_erase_by_start(struct cma_bf_item *item)
+{
+	struct cma_bf_private *prv = item->ch.reg->private_data;
+	rb_erase(&item->ch.by_start, &prv->by_start_root);
+}
+
+
+/************************* More Tree Manipulation *************************/
+
+static struct cma_bf_item *__must_check
+__cma_bf_hole_take(struct cma_bf_item *hole, size_t size, size_t alignment)
+{
+	struct cma_bf_item *item;
+
+	/*
+	 * There are three cases:
+	 * 1. the chunk takes the whole hole,
+	 * 2. the chunk is at the beginning or at the end of the hole, or
+	 * 3. the chunk is in the middle of the hole.
+	 */
+
+
+	/* Case 1, the whole hole */
+	if (size == hole->ch.size) {
+		__cma_bf_hole_erase_by_size(hole);
+		__cma_bf_hole_erase_by_start(hole);
+		return hole;
+	}
+
+
+	/* Allocate */
+	item = kmalloc(sizeof *item, GFP_KERNEL);
+	if (unlikely(!item))
+		return NULL;
+
+	item->ch.start = ALIGN(hole->ch.start, alignment);
+	item->ch.size  = size;
+
+	/* Case 3, in the middle */
+	if (item->ch.start != hole->ch.start
+	 && item->ch.start + item->ch.size !=
+	    hole->ch.start + hole->ch.size) {
+		struct cma_bf_item *next;
+
+		/*
+		 * Space between the end of the chunk and the end of
+		 * the region, ie. space left after the end of the
+		 * chunk.  If this is dividable by alignment we can
+		 * move the chunk to the end of the hole.
+		 */
+		unsigned long left =
+			hole->ch.start + hole->ch.size -
+			(item->ch.start + item->ch.size);
+		if (left % alignment == 0) {
+			item->ch.start += left;
+			goto case_2;
+		}
+
+		/*
+		 * We are going to add a hole at the end.  This way,
+		 * we will reduce the problem to case 2 -- the chunk
+		 * will be at the end of the hole.
+		 */
+		next = kmalloc(sizeof *next, GFP_KERNEL);
+
+		if (unlikely(!next)) {
+			kfree(item);
+			return NULL;
+		}
+
+		next->ch.start = item->ch.start + item->ch.size;
+		next->ch.size  =
+			hole->ch.start + hole->ch.size - next->ch.start;
+		next->ch.reg   = hole->ch.reg;
+
+		__cma_bf_hole_insert_by_size(next);
+		__cma_bf_hole_insert_by_start(next);
+
+		hole->ch.size = next->ch.start - hole->ch.start;
+		/* Go to case 2 */
+	}
+
+
+	/* Case 2, at the beginning or at the end */
+case_2:
+	/* No need to update the tree; order preserved. */
+	if (item->ch.start == hole->ch.start)
+		hole->ch.start += item->ch.size;
+
+	/* Alter hole's size */
+	hole->ch.size -= size;
+	__cma_bf_hole_erase_by_size(hole);
+	__cma_bf_hole_insert_by_size(hole);
+
+	return item;
+}
+
+
+static void __cma_bf_hole_merge_maybe(struct cma_bf_item *item)
+{
+	struct cma_bf_item *prev;
+	struct rb_node *node;
+	int twice = 2;
+
+	node = rb_prev(&item->ch.by_start);
+	if (unlikely(!node))
+		goto next;
+	prev = rb_entry(node, struct cma_bf_item, ch.by_start);
+
+	for (;;) {
+		if (prev->ch.start + prev->ch.size == item->ch.start) {
+			/* Remove previous hole from trees */
+			__cma_bf_hole_erase_by_size(prev);
+			__cma_bf_hole_erase_by_start(prev);
+
+			/* Alter this hole */
+			item->ch.size += prev->ch.size;
+			item->ch.start = prev->ch.start;
+			__cma_bf_hole_erase_by_size(item);
+			__cma_bf_hole_insert_by_size(item);
+			/*
+			 * No need to update by start trees as we do
+			 * not break sequence order
+			 */
+
+			/* Free prev hole */
+			kfree(prev);
+		}
+
+next:
+		if (!--twice)
+			break;
+
+		node = rb_next(&item->ch.by_start);
+		if (unlikely(!node))
+			break;
+		prev = item;
+		item = rb_entry(node, struct cma_bf_item, ch.by_start);
+	}
+}
diff --git a/mm/cma.c b/mm/cma.c
new file mode 100644
index 0000000..6a0942f
--- /dev/null
+++ b/mm/cma.c
@@ -0,0 +1,778 @@
+/*
+ * Contiguous Memory Allocator framework
+ * Copyright (c) 2010 by Samsung Electronics.
+ * Written by Michal Nazarewicz (m.nazarewicz@samsung.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.
+ */
+
+/*
+ * See Documentation/cma.txt for documentation.
+ */
+
+#define pr_fmt(fmt) "cma: " fmt
+
+#ifdef CONFIG_CMA_DEBUG
+#  define DEBUG
+#endif
+
+#ifndef CONFIG_NO_BOOTMEM
+#  include <linux/bootmem.h>   /* alloc_bootmem_pages_nopanic() */
+#endif
+#ifdef CONFIG_HAVE_MEMBLOCK
+#  include <linux/memblock.h>  /* memblock*() */
+#endif
+#include <linux/device.h>      /* struct device, dev_name() */
+#include <linux/errno.h>       /* Error numbers */
+#include <linux/err.h>         /* IS_ERR, PTR_ERR, etc. */
+#include <linux/mm.h>          /* PAGE_ALIGN() */
+#include <linux/module.h>      /* EXPORT_SYMBOL_GPL() */
+#include <linux/slab.h>        /* kmalloc() */
+#include <linux/string.h>      /* str*() */
+
+#include <linux/cma-int.h>     /* CMA structures */
+#include <linux/cma.h>         /* CMA Device API */
+
+
+#define CMA_MAX_REGIONS      16
+#define CMA_MAX_MAPPINGS     64
+#define CMA_MAX_PARAM_LEN   512
+
+
+/************************* Parse region list *************************/
+
+struct cma_region cma_regions[CMA_MAX_REGIONS + 1 /* 1 for zero-sized */];
+
+static char *__must_check __init
+cma_param_parse_entry(char *param, struct cma_region *reg)
+{
+	const char *name, *alloc = NULL, *alloc_params = NULL, *ch;
+	unsigned long long size, start = 0, alignment = 0;
+
+	/* Parse */
+	name = param;
+	param = strchr(param, '=');
+	if (!param) {
+		pr_err("param: expecting '=' near %s\n", name);
+		return NULL;
+	} else if (param == name) {
+		pr_err("param: empty region name near %s\n", name);
+		return NULL;
+	}
+	*param = '\0';
+	++param;
+
+	ch = param;
+	size = memparse(param, &param);
+	if (unlikely(!size || size > ULONG_MAX)) {
+		pr_err("param: invalid size near %s\n", ch);
+		return NULL;
+	}
+
+
+	if (*param == '@') {
+		ch = param;
+		start = memparse(param + 1, &param);
+		if (unlikely(start > ULONG_MAX)) {
+			pr_err("param: invalid start near %s\n", ch);
+			return NULL;
+		}
+	}
+
+	if (*param == '/') {
+		ch = param;
+		alignment = memparse(param + 1, &param);
+		if (unlikely(alignment > ULONG_MAX ||
+			     (alignment & (alignment - 1)))) {
+			pr_err("param: invalid alignment near %s\n", ch);
+			return NULL;
+		}
+	}
+
+	if (*param == ':') {
+		alloc = ++param;
+		while (*param && *param != '(' && *param != ';')
+			++param;
+
+		if (*param == '(') {
+			*param = '\0';
+			alloc_params = ++param;
+			param = strchr(param, ')');
+			if (!param) {
+				pr_err("param: expecting ')' near %s\n", param);
+				return NULL;
+			}
+			*param++ = '\0';
+		}
+	}
+
+	if (*param == ';') {
+		*param = '\0';
+		++param;
+	} else if (*param) {
+		pr_err("param: expecting ';' or end of parameter near %s\n",
+		       param);
+		return NULL;
+	}
+
+	/* Save */
+	alignment         = alignment ? PAGE_ALIGN(alignment) : PAGE_SIZE;
+	start             = ALIGN(start, alignment);
+	size              = PAGE_ALIGN(size);
+	reg->name         = name;
+	reg->start        = start;
+	reg->size         = size;
+	reg->free_space   = size;
+	reg->alignment    = alignment;
+	reg->alloc_name   = alloc && *alloc ? alloc : NULL;
+	reg->alloc_params = alloc_params;
+
+	return param;
+}
+
+/*
+ * cma          ::=  "cma=" regions [ ';' ]
+ * regions      ::= region [ ';' regions ]
+ *
+ * region       ::= reg-name
+ *                    '=' size
+ *                  [ '@' start ]
+ *                  [ '/' alignment ]
+ *                  [ ':' [ alloc-name ] [ '(' alloc-params ')' ] ]
+ *
+ * See Documentation/cma.txt for details.
+ *
+ * Example:
+ * cma=reg1=64M:bf;reg2=32M@0x100000:bf;reg3=64M/1M:bf
+ *
+ * If allocator is ommited the first available allocater will be used.
+ */
+
+static int __init cma_param_parse(char *param)
+{
+	static char buffer[CMA_MAX_PARAM_LEN];
+
+	unsigned left = ARRAY_SIZE(cma_regions);
+	struct cma_region *reg = cma_regions;
+
+	pr_debug("param: %s\n", param);
+
+	strlcpy(buffer, param, sizeof buffer);
+	for (param = buffer; *param; ++reg) {
+		if (unlikely(!--left)) {
+			pr_err("param: too many regions\n");
+			return -ENOSPC;
+		}
+
+		param = cma_param_parse_entry(param, reg);
+		if (unlikely(!param))
+			return -EINVAL;
+
+		pr_debug("param: adding region %s (%p@%p)\n",
+			 reg->name, (void *)reg->size, (void *)reg->start);
+	}
+	return 0;
+}
+early_param("cma", cma_param_parse);
+
+
+/************************* Parse dev->regions map *************************/
+
+static const char *cma_map[CMA_MAX_MAPPINGS + 1 /* 1 for NULL */];
+
+/*
+ * cma-map      ::=  "cma_map=" rules [ ';' ]
+ * rules        ::= rule [ ';' rules ]
+ * rule         ::= patterns '=' regions
+ * patterns     ::= pattern [ ',' patterns ]
+ *
+ * regions      ::= reg-name [ ',' regions ]
+ *              // list of regions to try to allocate memory
+ *              // from for devices that match pattern
+ *
+ * pattern      ::= dev-pattern [ '/' kind-pattern ]
+ *                | '/' kind-pattern
+ *              // pattern request must match for this rule to
+ *              // apply to it; the first rule that matches is
+ *              // applied; if dev-pattern part is omitted
+ *              // value identical to the one used in previous
+ *              // rule is assumed
+ *
+ * See Documentation/cma.txt for details.
+ *
+ * Example (white space added for convenience, forbidden in real string):
+ * cma_map = foo-dev = reg1;             -- foo-dev with no kind
+ *           bar-dev / firmware = reg3;  -- bar-dev's firmware
+ *           / * = reg2;                 -- bar-dev's all other kinds
+ *           baz-dev / * = reg1,reg2;    -- any kind of baz-dev
+ *           * / * = reg2,reg1;          -- any other allocations
+ */
+static int __init cma_map_param_parse(char *param)
+{
+	static char buffer[CMA_MAX_PARAM_LEN];
+
+	unsigned left = ARRAY_SIZE(cma_map) - 1;
+	const char **spec = cma_map;
+
+	pr_debug("map: %s\n", param);
+
+	strlcpy(buffer, param, sizeof buffer);
+	for (param = buffer; *param; ++spec) {
+		char *eq, *e;
+
+		if (!left--) {
+			pr_err("map: too many mappings\n");
+			return -ENOSPC;
+		}
+
+		e = strchr(param, ';');
+		if (e)
+			*e = '\0';
+
+		eq = strchr(param, '=');
+		if (unlikely(!eq)) {
+			pr_err("map: expecting '='\n");
+			cma_map[0] = NULL;
+			return -EINVAL;
+		}
+
+		*eq = '\0';
+		*spec = param;
+
+		pr_debug("map: adding: '%s' -> '%s'\n", param, eq + 1);
+
+		if (!e)
+			break;
+		param = e + 1;
+	}
+
+	return 0;
+}
+early_param("cma_map", cma_map_param_parse);
+
+
+/************************* Initialise CMA *************************/
+
+#define CMA_ALLOCATORS_LIST
+#include "cma-allocators.h"
+
+static struct cma_allocator *__must_check __init
+__cma_allocator_find(const char *name)
+{
+	size_t i = ARRAY_SIZE(cma_allocators);
+
+	if (i) {
+		struct cma_allocator *alloc = cma_allocators;
+
+		if (!name)
+			return alloc;
+
+		do {
+			if (!strcmp(alloc->name, name))
+				return alloc;
+			++alloc;
+		} while (--i);
+	}
+
+	return NULL;
+}
+
+
+int __init cma_defaults(const char *cma_str, const char *cma_map_str)
+{
+	int ret;
+
+	if (cma_str && !cma_regions->size) {
+		ret = cma_param_parse((char *)cma_str);
+		if (unlikely(ret))
+			return ret;
+	}
+
+	if (cma_map_str && !*cma_map) {
+		ret = cma_map_param_parse((char *)cma_map_str);
+		if (unlikely(ret))
+			return ret;
+	}
+
+	return 0;
+}
+
+
+int __init cma_region_alloc(struct cma_region *reg)
+{
+
+#ifndef CONFIG_NO_BOOTMEM
+
+	void *ptr;
+
+	ptr = __alloc_bootmem_nopanic(reg->size, reg->alignment, reg->start);
+	if (likely(ptr)) {
+		reg->start = virt_to_phys(ptr);
+		return 0;
+	}
+
+#endif
+
+#ifdef CONFIG_HAVE_MEMBLOCK
+
+	if (reg->start) {
+		if (memblock_is_region_reserved(reg->start, reg->size) < 0 &&
+		    memblock_reserve(reg->start, reg->size) >= 0)
+			return 0;
+	} else {
+		/*
+		 * Use __memblock_alloc_base() since
+		 * memblock_alloc_base() panic()s.
+		 */
+		u64 ret = __memblock_alloc_base(reg->size, reg->alignment, 0);
+		if (ret && ret < ULONG_MAX && ret + reg->size < ULONG_MAX) {
+			reg->start = ret;
+			return 0;
+		}
+
+		if (ret)
+			memblock_free(ret, reg->size);
+	}
+
+#endif
+
+	return -ENOMEM;
+}
+
+int __init cma_regions_allocate(int (*alloc)(struct cma_region *reg))
+{
+	struct cma_region *reg = cma_regions, *out = cma_regions;
+
+	pr_debug("allocating\n");
+
+	if (!alloc)
+		alloc = cma_region_alloc;
+
+	for (; reg->size; ++reg) {
+		if (likely(alloc(reg) >= 0)) {
+			pr_debug("init: %s: allocated %p@%p\n",
+				 reg->name,
+				 (void *)reg->size, (void *)reg->start);
+			if (out != reg)
+				memcpy(out, reg, sizeof *out);
+			++out;
+		} else {
+			pr_warn("init: %s: unable to allocate %p@%p\n",
+				reg->name,
+				(void *)reg->size, (void *)reg->start);
+		}
+	}
+	out->size = 0; /* Zero size termination */
+
+	return cma_regions - out;
+}
+
+static int __init cma_init(void)
+{
+	struct cma_allocator *alloc;
+	struct cma_region *reg;
+
+	pr_debug("initialising\n");
+
+	for (reg = cma_regions; reg->size; ++reg) {
+		mutex_init(&reg->mutex);
+
+		alloc = __cma_allocator_find(reg->alloc_name);
+		if (unlikely(!alloc)) {
+			pr_warn("init: %s: %s: no such allocator\n",
+				reg->name, reg->alloc_name ?: "(default)");
+			continue;
+		}
+
+		if (unlikely(alloc->init(reg))) {
+			pr_err("init: %s: %s: unable to initialise allocator\n",
+			       reg->name, alloc->name);
+			continue;
+		}
+
+		reg->alloc      = alloc;
+		reg->alloc_name = alloc->name; /* it may have been NULL */
+		pr_debug("init: %s: %s: initialised allocator\n",
+			 reg->name, reg->alloc_name);
+	}
+
+	return 0;
+}
+subsys_initcall(cma_init);
+
+
+/************************* Various prototypes *************************/
+
+static struct cma_chunk *__must_check __cma_chunk_find(unsigned long addr);
+static int __must_check __cma_chunk_insert(struct cma_chunk *chunk);
+static void __cma_chunk_release(struct kref *ref);
+
+static struct cma_region *__must_check
+__cma_region_find(const char *name, unsigned n);
+
+static const char *__must_check
+__cma_where_from(const struct device *dev, const char *kind);
+static struct cma_chunk *__must_check
+__cma_alloc_do(const char *from, unsigned long size, unsigned long alignment);
+
+
+
+/************************* The Device API *************************/
+
+unsigned long __must_check
+cma_alloc(const struct device *dev, const char *kind,
+	  unsigned long size, unsigned long alignment)
+{
+	struct cma_chunk *chunk;
+	const char *from;
+
+	pr_debug("allocate %p/%p for %s/%s\n",
+		 (void *)size, (void *)alignment, dev_name(dev), kind ?: "");
+
+	if (unlikely(alignment & (alignment - 1) || !size))
+		return -EINVAL;
+
+	from = __cma_where_from(dev, kind);
+	if (unlikely(IS_ERR(from)))
+		return PTR_ERR(from);
+
+	chunk = __cma_alloc_do(from, size, alignment ?: 1);
+	if (chunk)
+		pr_debug("allocated at %p\n", (void *)chunk->start);
+	else
+		pr_debug("not enough memory\n");
+
+	return chunk ? chunk->start : -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(cma_alloc);
+
+
+int __must_check
+cma_info(struct cma_info *info, const struct device *dev, const char *kind)
+{
+	struct cma_info ret = { ~0, 0, 0, 0 };
+	const char *from;
+
+	if (unlikely(!info))
+		return -EINVAL;
+
+	from = __cma_where_from(dev, kind);
+	if (unlikely(IS_ERR(from)))
+		return PTR_ERR(from);
+
+	while (*from) {
+		const char *end = strchr(from, ',');
+		struct cma_region *reg =
+			__cma_region_find(from, end ? end - from : strlen(from));
+		if (reg) {
+			ret.total_size += reg->size;
+			if (ret.lower_bound > reg->start)
+				ret.lower_bound = reg->start;
+			if (ret.upper_bound < reg->start + reg->size)
+				ret.upper_bound = reg->start + reg->size;
+			++ret.count;
+		}
+		if (!end)
+			break;
+		from = end + 1;
+	}
+
+	memcpy(info, &ret, sizeof ret);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cma_info);
+
+
+int cma_get(unsigned long addr)
+{
+	struct cma_chunk *c = __cma_chunk_find(addr);
+
+	pr_debug("get(%p): %sfound\n", (void *)addr, c ? "" : "not ");
+
+	if (unlikely(!c))
+		return -ENOENT;
+	kref_get(&c->ref);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cma_get);
+
+int cma_put(unsigned long addr)
+{
+	struct cma_chunk *c = __cma_chunk_find(addr);
+	int ret;
+
+	pr_debug("put(%p): %sfound\n", (void *)addr, c ? "" : "not ");
+
+	if (unlikely(!c))
+		return -ENOENT;
+
+	ret = kref_put(&c->ref, __cma_chunk_release);
+	if (ret)
+		pr_debug("put(%p): destroyed\n", (void *)addr);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cma_put);
+
+
+/************************* Implementation *************************/
+
+static struct rb_root cma_chunks_by_start;;
+static DEFINE_MUTEX(cma_chunks_mutex);
+
+static struct cma_chunk *__must_check __cma_chunk_find(unsigned long addr)
+{
+	struct cma_chunk *chunk;
+	struct rb_node *n;
+
+	mutex_lock(&cma_chunks_mutex);
+
+	for (n = cma_chunks_by_start.rb_node; n; ) {
+		chunk = rb_entry(n, struct cma_chunk, by_start);
+		if (addr < chunk->start)
+			n = n->rb_left;
+		else if (addr > chunk->start)
+			n = n->rb_right;
+		else
+			goto found;
+	}
+	WARN("no chunk starting at %p\n", (void *)addr);
+	chunk = NULL;
+
+found:
+	mutex_unlock(&cma_chunks_mutex);
+
+	return chunk;
+}
+
+static int __must_check __cma_chunk_insert(struct cma_chunk *chunk)
+{
+	struct rb_node **new, *parent = NULL;
+	unsigned long addr = chunk->start;
+
+	mutex_lock(&cma_chunks_mutex);
+
+	for (new = &cma_chunks_by_start.rb_node; *new; ) {
+		struct cma_chunk *c =
+			container_of(*new, struct cma_chunk, by_start);
+
+		parent = *new;
+		if (addr < c->start) {
+			new = &(*new)->rb_left;
+		} else if (addr > c->start) {
+			new = &(*new)->rb_right;
+		} else {
+			/*
+			 * We should never be here.  If we are it
+			 * means allocator gave us an invalid chunk
+			 * (one that has already been allocated) so we
+			 * refuse to accept it.  Our caller will
+			 * recover by freeing the chunk.
+			 */
+			WARN_ON(1);
+			return -EBUSY;
+		}
+	}
+
+	rb_link_node(&chunk->by_start, parent, new);
+	rb_insert_color(&chunk->by_start, &cma_chunks_by_start);
+
+	mutex_unlock(&cma_chunks_mutex);
+
+	return 0;
+}
+
+static void __cma_chunk_release(struct kref *ref)
+{
+	struct cma_chunk *chunk = container_of(ref, struct cma_chunk, ref);
+
+	mutex_lock(&cma_chunks_mutex);
+	rb_erase(&chunk->by_start, &cma_chunks_by_start);
+	mutex_unlock(&cma_chunks_mutex);
+
+	mutex_lock(&chunk->reg->mutex);
+	chunk->reg->alloc->free(chunk);
+	--chunk->reg->users;
+	chunk->reg->free_space += chunk->size;
+	mutex_unlock(&chunk->reg->mutex);
+}
+
+
+static struct cma_region *__must_check
+__cma_region_find(const char *name, unsigned n)
+{
+	struct cma_region *reg = cma_regions;
+
+	for (; reg->start; ++reg) {
+		if (!strncmp(name, reg->name, n) && !reg->name[n])
+			return reg;
+	}
+
+	return NULL;
+}
+
+
+static const char *__must_check
+__cma_where_from(const struct device *dev, const char *kind)
+{
+	/*
+	 * This function matches the pattern given at command line
+	 * parameter agains given device name and kind.  Kind may be
+	 * of course NULL or an emtpy string.
+	 */
+
+	const char **spec, *name;
+	int name_matched = 0;
+
+	/* Make sure dev was given and has name */
+	if (unlikely(!dev))
+		return ERR_PTR(-EINVAL);
+
+	name = dev_name(dev);
+	if (WARN_ON(!name || !*name))
+		return ERR_PTR(-EINVAL);
+
+	/* kind == NULL is just like an empty kind */
+	if (!kind)
+		kind = "";
+
+	/*
+	 * Now we go throught the cma_map array.  It is an array of
+	 * pointers to chars (ie. array of strings) so in each
+	 * iteration we take each of the string.  The strings is
+	 * basically what user provided at the command line separated
+	 * by semicolons.
+	 */
+	for (spec = cma_map; *spec; ++spec) {
+		/*
+		 * This macro tries to match pattern pointed by s to
+		 * @what.  If, while reading the spec, we ecnounter
+		 * comma it means that the pattern does not match and
+		 * we need to start over with another spec.  If there
+		 * is a character that does not match, we neet to try
+		 * again looking if there is another spec.
+		 */
+#define TRY_MATCH(what) do {				\
+		const char *c = what;			\
+		for (; *s != '*' && *c; ++c, ++s)	\
+			if (*s == ',')			\
+				goto again;		\
+			else if (*s != '?' && *c != *s)	\
+				goto again_maybe;	\
+		if (*s == '*')				\
+			++s;				\
+	} while (0)
+
+		const char *s = *spec - 1;
+again:
+		++s;
+
+		/*
+		 * If the pattern is spec starts with a slash, this
+		 * means that the device part of the pattern matches
+		 * if it matched previously.
+		 */
+		if (*s == '/') {
+			if (!name_matched)
+				goto again_maybe;
+			goto kind;
+		}
+
+		/*
+		 * We are now trying to match the device name.  This
+		 * also updates the name_matched variable.  If the
+		 * name does not match we will jump to again or
+		 * again_maybe out of the TRY_MATCH() macro.
+		 */
+		name_matched = 0;
+		TRY_MATCH(name);
+		name_matched = 1;
+
+		/*
+		 * Now we need to match the kind part of the pattern.
+		 * If the pattern is missing it we match only if kind
+		 * points to an empty string.  Otherwise wy try to
+		 * match it just like name.
+		 */
+		if (*s != '/') {
+			if (*kind)
+				goto again_maybe;
+		} else {
+kind:
+			++s;
+			TRY_MATCH(kind);
+		}
+
+		/*
+		 * Patterns end either when the string ends or on
+		 * a comma.  Returned value is the part of the rule
+		 * with list of region names.  This works because when
+		 * we parse the cma_map parameter the equel sign in
+		 * rules is replaced by a NUL byte.
+		 */
+		if (!*s || *s == ',')
+			return s + strlen(s) + 1;
+
+again_maybe:
+		s = strchr(s, ',');
+		if (s)
+			goto again;
+
+#undef TRY_MATCH
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+
+static struct cma_chunk *__must_check
+__cma_alloc_do(const char *from, unsigned long size, unsigned long alignment)
+{
+	struct cma_chunk *chunk;
+	struct cma_region *reg;
+
+	pr_debug("alloc_do(%p/%p from %s)\n",
+		 (void *)size, (void *)alignment, from);
+
+	while (*from) {
+		const char *end = strchr(from, ',');
+		reg = __cma_region_find(from, end ? end - from : strlen(from));
+		if (unlikely(!reg || !reg->alloc))
+			goto skip;
+
+		if (reg->free_space < size)
+			goto skip;
+
+		mutex_lock(&reg->mutex);
+		chunk = reg->alloc->alloc(reg, size, alignment);
+		if (chunk) {
+			++reg->users;
+			reg->free_space -= chunk->size;
+		}
+		mutex_unlock(&reg->mutex);
+		if (chunk)
+			goto got;
+
+skip:
+		if (!end)
+			break;
+		from = end + 1;
+	}
+	return NULL;
+
+got:
+	chunk->reg = reg;
+	kref_init(&chunk->ref);
+
+	if (likely(!__cma_chunk_insert(chunk)))
+		return chunk;
+
+	mutex_lock(&reg->mutex);
+	--reg->users;
+	reg->free_space += chunk->size;
+	chunk->reg->alloc->free(chunk);
+	mutex_unlock(&reg->mutex);
+	return NULL;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 3/4] mm: cma: Test device and application added
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
@ 2010-07-20 15:51     ` Michal Nazarewicz
  2010-07-20 15:51       ` [PATCH 4/4] arm: Added CMA to Aquila and Goni Michal Nazarewicz
  2010-07-20 18:15       ` Daniel Walker
                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz,
	Kyungmin Park

This patch adds a "cma" misc device which lets user space use the
CMA API.  This device is meant for testing.  A testing application
is also provided.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/misc/Kconfig   |    8 +
 drivers/misc/Makefile  |    1 +
 drivers/misc/cma-dev.c |  183 +++++++++++++++++++++++
 include/linux/cma.h    |   30 ++++
 tools/cma/cma-test.c   |  373 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 595 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/cma-dev.c
 create mode 100644 tools/cma/cma-test.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 26386a9..2db9d46 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -358,4 +358,12 @@ source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/iwmc3200top/Kconfig"
 
+config CMA_DEVICE
+	tristate "CMA misc device (DEVELOPEMENT)"
+	depends on CMA
+	help
+	  The CMA misc device allows allocating contiguous memory areas
+	  from user space.  This is mostly for testing of the CMA
+	  framework.
+
 endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6ed06a1..6d0ef2b 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y				+= eeprom/
 obj-y				+= cb710/
 obj-$(CONFIG_VMWARE_BALLOON)	+= vmware_balloon.o
+obj-$(CONFIG_CMA_DEVICE)	+= cma-dev.o
diff --git a/drivers/misc/cma-dev.c b/drivers/misc/cma-dev.c
new file mode 100644
index 0000000..c5247a7
--- /dev/null
+++ b/drivers/misc/cma-dev.c
@@ -0,0 +1,183 @@
+/*
+ * Contiguous Memory Allocator userspace driver
+ * Copyright (c) 2010 by Samsung Electronics.
+ * Written by Michal Nazarewicz (m.nazarewicz@samsung.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
+#  define DEBUG
+#endif
+
+#include <linux/errno.h>       /* Error numbers */
+#include <linux/err.h>         /* IS_ERR_VALUE() */
+#include <linux/fs.h>          /* struct file */
+#include <linux/mm.h>          /* Memory stuff */
+#include <linux/mman.h>
+#include <linux/slab.h>
+#include <linux/module.h>      /* Standard module stuff */
+#include <linux/device.h>      /* struct device, dev_dbg() */
+#include <linux/types.h>       /* Just to be safe ;) */
+#include <linux/uaccess.h>     /* __copy_{to,from}_user */
+#include <linux/miscdevice.h>  /* misc_register() and company */
+
+#include <linux/cma.h>
+
+static int  cma_file_open(struct inode *inode, struct file *file);
+static int  cma_file_release(struct inode *inode, struct file *file);
+static long cma_file_ioctl(struct file *file, unsigned cmd, unsigned long arg);
+static int  cma_file_mmap(struct file *file, struct vm_area_struct *vma);
+
+
+static struct miscdevice cma_miscdev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name  = "cma",
+	.fops  = &(const struct file_operations) {
+		.owner          = THIS_MODULE,
+		.open           = cma_file_open,
+		.release        = cma_file_release,
+		.unlocked_ioctl = cma_file_ioctl,
+		.mmap           = cma_file_mmap,
+	},
+};
+#define cma_dev (cma_miscdev.this_device)
+
+
+#define cma_file_start(file) (((unsigned long *)(file)->private_data)[0])
+#define cma_file_size(file) (((unsigned long *)(file)->private_data)[1])
+
+
+static int  cma_file_open(struct inode *inode, struct file *file)
+{
+	dev_dbg(cma_dev, "%s(%p)\n", __func__, (void *)file);
+
+	file->private_data = NULL;
+
+	return 0;
+}
+
+
+static int  cma_file_release(struct inode *inode, struct file *file)
+{
+	dev_dbg(cma_dev, "%s(%p)\n", __func__, (void *)file);
+
+	if (file->private_data) {
+		cma_put(cma_file_start(file));
+		kfree(file->private_data);
+	}
+
+	return 0;
+}
+
+
+static long cma_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+{
+	struct cma_alloc_request req;
+	struct device fake_device;
+	unsigned long addr;
+	long ret;
+
+	dev_dbg(cma_dev, "%s(%p)\n", __func__, (void *)file);
+
+	if (cmd != IOCTL_CMA_ALLOC)
+		return -ENOTTY;
+
+	if (!arg)
+		return -EINVAL;
+
+	if (file->private_data) /* Already allocated */
+		return -EBADFD;
+
+	if (copy_from_user(&req, (void *)arg, sizeof req))
+		return -EFAULT;
+
+	if (req.magic != CMA_MAGIC)
+		return -ENOTTY;
+
+	/* May happen on 32 bit system. */
+	if (req.size > ULONG_MAX || req.alignment > ULONG_MAX)
+		return -EINVAL;
+
+	if (strnlen(req.name, sizeof req.name) >= sizeof req.name
+	 || strnlen(req.kind, sizeof req.kind) >= sizeof req.kind)
+		return -EINVAL;
+
+	file->private_data = kmalloc(2 * sizeof(unsigned long), GFP_KERNEL);
+	if (!file->private_data)
+		return -ENOMEM;
+
+	fake_device.init_name = req.name;
+	fake_device.kobj.name = req.name;
+	addr = cma_alloc(&fake_device, req.kind, req.size, req.alignment);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto error_priv;
+	}
+
+	if (put_user(addr, (typeof(req.start) *)(arg + offsetof(typeof(req), start)))) {
+		ret = -EFAULT;
+		goto error_put;
+	}
+
+	cma_file_start(file) = addr;
+	cma_file_size(file) = req.size;
+
+	dev_dbg(cma_dev, "allocated %p@%p\n",
+		(void *)(unsigned long) req.size, (void *)addr);
+
+	return 0;
+
+error_put:
+	cma_put(addr);
+error_priv:
+	kfree(file->private_data);
+	file->private_data = NULL;
+	return ret;
+}
+
+
+static int  cma_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	unsigned long pgoff, offset, length;
+
+	dev_dbg(cma_dev, "%s(%p)\n", __func__, (void *)file);
+
+	if (!file->private_data)
+		return -EBADFD;
+
+	pgoff  = vma->vm_pgoff;
+	offset = pgoff << PAGE_SHIFT;
+	length = vma->vm_end - vma->vm_start;
+
+	if (offset          >= cma_file_size(file)
+	 || length          >  cma_file_size(file)
+	 || offset + length >  cma_file_size(file))
+		return -ENOSPC;
+
+	return remap_pfn_range(vma, vma->vm_start,
+			       __phys_to_pfn(cma_file_start(file) + offset),
+			       length, vma->vm_page_prot);
+}
+
+
+
+static int __init cma_dev_init(void)
+{
+	int ret = misc_register(&cma_miscdev);
+	pr_debug("miscdev: register returned: %d\n", ret);
+	return ret;
+}
+module_init(cma_dev_init);
+
+static void __exit cma_dev_exit(void)
+{
+	dev_dbg(cma_dev, "deregisterring\n");
+	misc_deregister(&cma_miscdev);
+}
+module_exit(cma_dev_exit);
diff --git a/include/linux/cma.h b/include/linux/cma.h
index aef8347..1bfffb2 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -11,6 +11,36 @@
  * See Documentation/cma.txt for documentation.
  */
 
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+
+#define CMA_MAGIC (('c' << 24) | ('M' << 16) | ('a' << 8) | 0x42)
+
+/**
+ * An information about area exportable to user space.
+ * @magic: must always be CMA_MAGIC.
+ * @name:  name of the device to allocate as.
+ * @kind:  kind of the memory.
+ * @_pad:  reserved.
+ * @size:  size of the chunk to allocate.
+ * @alignment: desired alignment of the chunk (must be power of two or zero).
+ * @start: when ioctl() finishes this stores physical address of the chunk.
+ */
+struct cma_alloc_request {
+	__u32 magic;
+	char  name[17];
+	char  kind[17];
+	__u16 pad;
+	/* __u64 to be compatible accross 32 and 64 bit systems. */
+	__u64 size;
+	__u64 alignment;
+	__u64 start;
+};
+
+#define IOCTL_CMA_ALLOC    _IOWR('p', 0, struct cma_alloc_request)
+
+
 #ifdef __KERNEL__
 
 struct device;
diff --git a/tools/cma/cma-test.c b/tools/cma/cma-test.c
new file mode 100644
index 0000000..567c57b
--- /dev/null
+++ b/tools/cma/cma-test.c
@@ -0,0 +1,373 @@
+/*
+ * cma-test.c -- CMA testing application
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *                    Author: Michal Nazarewicz <m.nazarewicz@samsung.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 option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* $(CROSS_COMPILE)gcc -Wall -Wextra -g -o cma-test cma-test.c  */
+
+#include <linux/cma.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static void handle_command(char *line);
+
+int main(void)
+{
+	unsigned no = 1;
+	char line[1024];
+	int skip = 0;
+
+	fputs("commands:\n"
+	      " l or list                                list allocated chunks\n"
+	      " a or alloc  <name> <size>[/<alignment>]  allocate chunk\n"
+	      " f or free   [<num>]                      free an chunk\n"
+	      " # ...                                    comment\n"
+	      " <empty line>                             repeat previous\n"
+	      "\n", stderr);
+
+	while (fgets(line, sizeof line, stdin)) {
+		char *nl = strchr(line, '\n');
+		if (nl) {
+			if (skip) {
+				fprintf(stderr, "cma: %d: line too long\n", no);
+				skip = 0;
+			} else {
+				*nl = '\0';
+				handle_command(line);
+			}
+			++no;
+		} else {
+			skip = 1;
+		}
+	}
+
+	if (skip)
+		fprintf(stderr, "cma: %d: no new line at EOF\n", no);
+	return 0;
+}
+
+
+
+static void cmd_list(char *name, char *line);
+static void cmd_alloc(char *name, char *line);
+static void cmd_free(char *name, char *line);
+
+static const struct command {
+	const char name[8];
+	void (*handle)(char *name, char *line);
+} commands[] = {
+	{ "list",  cmd_list  },
+	{ "l",     cmd_list  },
+	{ "alloc", cmd_alloc },
+	{ "a",     cmd_alloc },
+	{ "free",  cmd_free  },
+	{ "f",     cmd_free  },
+	{ "",      NULL      }
+};
+
+
+#define SKIP_SPACE(ch) do while (isspace(*(ch))) ++(ch); while (0)
+
+
+static void handle_command(char *line)
+{
+	static char last_line[1024];
+
+	const struct command *cmd;
+	char *name;
+
+	SKIP_SPACE(line);
+	if (*line == '#')
+		return;
+
+	if (!*line)
+		strcpy(line, last_line);
+	else
+		strcpy(last_line, line);
+
+	name = line;
+	while (*line && !isspace(*line))
+		++line;
+
+	if (*line) {
+		*line = '\0';
+		++line;
+	}
+
+	for (cmd = commands; *(cmd->name); ++cmd)
+		if (!strcmp(name, cmd->name)) {
+			cmd->handle(name, line);
+			return;
+		}
+
+	fprintf(stderr, "%s: unknown command\n", name);
+}
+
+
+
+struct chunk {
+	struct chunk *next, *prev;
+	int fd;
+	unsigned long size;
+	unsigned long start;
+};
+
+static struct chunk root = {
+	.next = &root,
+	.prev = &root,
+};
+
+#define for_each(a) for (a = root.next; a != &root; a = a->next)
+
+static struct chunk *chunk_create(const char *prefix);
+static void chunk_destroy(struct chunk *chunk);
+static void chunk_add(struct chunk *chunk);
+
+static int memparse(char *ptr, char **retptr, unsigned long *ret);
+
+
+static void cmd_list(char *name, char *line)
+{
+	struct chunk *chunk;
+
+	(void)name; (void)line;
+
+	for_each(chunk)
+		printf("%3d: %p@%p\n", chunk->fd,
+		       (void *)chunk->size, (void *)chunk->start);
+}
+
+
+static void cmd_alloc(char *name, char *line)
+{
+	unsigned long size, alignment = 0;
+	struct cma_alloc_request req;
+	char *dev, *kind = NULL;
+	struct chunk *chunk;
+	int ret;
+
+	SKIP_SPACE(line);
+	if (!*line) {
+		fprintf(stderr, "%s: expecting name\n", name);
+		return;
+	}
+
+	for (dev = line; *line && !isspace(*line); ++line)
+		if (*line == '/')
+			kind = line;
+
+	if (!*line) {
+		fprintf(stderr, "%s: expecting size after name\n", name);
+		return;
+	}
+
+	if (kind)
+		*kind++ = '\0';
+	*line++ = '\0';
+
+	if (( kind && (size_t)(kind - dev ) > sizeof req.name)
+	 || (!kind && (size_t)(line - dev ) > sizeof req.name)
+	 || ( kind && (size_t)(line - kind) > sizeof req.kind)) {
+		fprintf(stderr, "%s: name or kind too long\n", name);
+		return;
+	}
+
+
+	if (memparse(line, &line, &size) < 0 || !size) {
+		fprintf(stderr, "%s: invalid size\n", name);
+		return;
+	}
+
+	if (*line == '/')
+		if (memparse(line, &line, &alignment) < 0) {
+			fprintf(stderr, "%s: invalid alignment\n", name);
+			return;
+		}
+
+	SKIP_SPACE(line);
+	if (*line) {
+		fprintf(stderr, "%s: unknown arguments at the end: %s\n",
+			name, line);
+		return;
+	}
+
+
+	chunk = chunk_create(name);
+	if (!chunk)
+		return;
+
+	fprintf(stderr, "%s: allocating %p/%p\n", name,
+		(void *)size, (void *)alignment);
+
+	req.magic     = CMA_MAGIC;
+	req.size      = size;
+	req.alignment = alignment;
+
+	strcpy(req.name, dev);
+	if (kind)
+		strcpy(req.kind, kind);
+	else
+		req.kind[0] = '\0';
+
+
+	ret = ioctl(chunk->fd, IOCTL_CMA_ALLOC, &req);
+	if (ret < 0) {
+		fprintf(stderr, "%s: cma_alloc: %s\n", name, strerror(errno));
+		chunk_destroy(chunk);
+	} else {
+		chunk_add(chunk);
+		chunk->size  = req.size;
+		chunk->start = req.start;
+
+		printf("%3d: %p@%p\n", chunk->fd,
+		       (void *)chunk->size, (void *)chunk->start);
+	}
+}
+
+
+static void cmd_free(char *name, char *line)
+{
+	struct chunk *chunk;
+
+	SKIP_SPACE(line);
+
+	if (*line) {
+		unsigned long num;
+
+		errno = 0;
+		num = strtoul(line, &line, 10);
+
+		if (errno || num > INT_MAX) {
+			fprintf(stderr, "%s: invalid number\n", name);
+			return;
+		}
+
+		SKIP_SPACE(line);
+		if (*line) {
+			fprintf(stderr, "%s: unknown arguments at the end: %s\n",
+				name, line);
+			return;
+		}
+
+		for_each(chunk)
+			if (chunk->fd == (int)num)
+				goto ok;
+		fprintf(stderr, "%s: no chunk %3lu\n", name, num);
+		return;
+
+	} else {
+		chunk = root.prev;
+		if (chunk == &root) {
+			fprintf(stderr, "%s: no chunks\n", name);
+			return;
+		}
+	}
+
+ok:
+	fprintf(stderr, "%s: freeing %p@%p\n", name,
+		(void *)chunk->size, (void *)chunk->start);
+	chunk_destroy(chunk);
+}
+
+
+static struct chunk *chunk_create(const char *prefix)
+{
+	struct chunk *chunk;
+	int fd;
+
+	chunk = malloc(sizeof *chunk);
+	if (!chunk) {
+		fprintf(stderr, "%s: %s\n", prefix, strerror(errno));
+		return NULL;
+	}
+
+	fd = open("/dev/cma", O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "%s: /dev/cma: %s\n", prefix, strerror(errno));
+		return NULL;
+	}
+
+	chunk->prev = chunk;
+	chunk->next = chunk;
+	chunk->fd   = fd;
+	return chunk;
+}
+
+static void chunk_destroy(struct chunk *chunk)
+{
+	chunk->prev->next = chunk->next;
+	chunk->next->prev = chunk->prev;
+	close(chunk->fd);
+}
+
+static void chunk_add(struct chunk *chunk)
+{
+	chunk->next = &root;
+	chunk->prev = root.prev;
+	root.prev->next = chunk;
+	root.prev = chunk;
+}
+
+
+
+static int memparse(char *ptr, char **retptr, unsigned long *ret)
+{
+	unsigned long val;
+
+	SKIP_SPACE(ptr);
+
+	errno = 0;
+	val = strtoul(ptr, &ptr, 0);
+	if (errno)
+		return -1;
+
+	switch (*ptr) {
+	case 'G':
+	case 'g':
+		val <<= 10;
+	case 'M':
+	case 'm':
+		val <<= 10;
+	case 'K':
+	case 'k':
+		val <<= 10;
+		++ptr;
+	}
+
+	if (retptr) {
+		SKIP_SPACE(ptr);
+		*retptr = ptr;
+	}
+
+	*ret = val;
+	return 0;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 4/4] arm: Added CMA to Aquila and Goni
  2010-07-20 15:51     ` [PATCH 3/4] mm: cma: Test device and application added Michal Nazarewicz
@ 2010-07-20 15:51       ` Michal Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michal Nazarewicz @ 2010-07-20 15:51 UTC (permalink / raw)
  To: linux-mm
  Cc: Marek Szyprowski, Pawel Osciak, Xiaolin Zhang, Hiremath Vaibhav,
	Robert Fekete, Marcus Lorentzon, linux-kernel, Michal Nazarewicz,
	Kyungmin Park

Added the CMA initialisation code to two Samsung platforms.

Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/Kconfig                    |    1 +
 arch/arm/mach-s5pv210/Kconfig       |    1 +
 arch/arm/mach-s5pv210/mach-aquila.c |    7 +++++++
 arch/arm/mach-s5pv210/mach-goni.c   |    7 +++++++
 4 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2e5b0f3..40c7380 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -691,6 +691,7 @@ config ARCH_S5PC100
 	select CPU_V7
 	select ARM_L1_CACHE_SHIFT_6
 	select ARCH_USES_GETTIMEOFFSET
+	select ARCH_CMA_POSSIBLE
 	help
 	  Samsung S5PC100 series based systems
 
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index e65825f..5fa1378 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -14,6 +14,7 @@ config CPU_S5PV210
 	select PLAT_S5P
 	select S3C_PL330_DMA
 	select S5P_EXT_INT
+	select ARCH_CMA_POSSIBLE
 	help
 	  Enable S5PV210 CPU support
 
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 0992618..4044233 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -19,6 +19,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
+#include <linux/cma-int.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -454,6 +455,11 @@ static void __init aquila_map_io(void)
 	s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
 }
 
+static void __init aquila_reserve(void)
+{
+	cma_regions_allocate(NULL);
+}
+
 static void __init aquila_machine_init(void)
 {
 	/* PMIC */
@@ -478,4 +484,5 @@ MACHINE_START(AQUILA, "Aquila")
 	.map_io		= aquila_map_io,
 	.init_machine	= aquila_machine_init,
 	.timer		= &s3c24xx_timer,
+	.reserve	= aquila_reserve,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 7b18505..8ab0751 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -19,6 +19,7 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
+#include <linux/cma-int.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -435,6 +436,11 @@ static void __init goni_map_io(void)
 	s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
 }
 
+static void __init goni_reserve(void)
+{
+	cma_regions_allocate(NULL);
+}
+
 static void __init goni_machine_init(void)
 {
 	/* PMIC */
@@ -456,4 +462,5 @@ MACHINE_START(GONI, "GONI")
 	.map_io		= goni_map_io,
 	.init_machine	= goni_machine_init,
 	.timer		= &s3c24xx_timer,
+	.reserve	= goni_reserve,
 MACHINE_END
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
@ 2010-07-20 18:15       ` Daniel Walker
  2010-07-20 18:15       ` Daniel Walker
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-20 18:15 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
> +** Use cases
> +
> +    Lets analyse some imaginary system that uses the CMA to see how
> +    the framework can be used and configured.
> +
> +
> +    We have a platform with a hardware video decoder and a camera
> each
> +    needing 20 MiB of memory in worst case.  Our system is written in
> +    such a way though that the two devices are never used at the same
> +    time and memory for them may be shared.  In such a system the
> +    following two command line arguments would be used:
> +
> +        cma=r=20M cma_map=video,camera=r 

This seems inelegant to me.. It seems like these should be connected
with the drivers themselves vs. doing it on the command like for
everything. You could have the video driver declare it needs 20megs, and
the the camera does the same but both indicate it's shared ..

If you have this disconnected from the drivers it will just cause
confusion, since few will know what these parameters should be for a
given driver set. It needs to be embedded in the kernel.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-20 18:15       ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-20 18:15 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
> +** Use cases
> +
> +    Lets analyse some imaginary system that uses the CMA to see how
> +    the framework can be used and configured.
> +
> +
> +    We have a platform with a hardware video decoder and a camera
> each
> +    needing 20 MiB of memory in worst case.  Our system is written in
> +    such a way though that the two devices are never used at the same
> +    time and memory for them may be shared.  In such a system the
> +    following two command line arguments would be used:
> +
> +        cma=r=20M cma_map=video,camera=r 

This seems inelegant to me.. It seems like these should be connected
with the drivers themselves vs. doing it on the command like for
everything. You could have the video driver declare it needs 20megs, and
the the camera does the same but both indicate it's shared ..

If you have this disconnected from the drivers it will just cause
confusion, since few will know what these parameters should be for a
given driver set. It needs to be embedded in the kernel.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 18:15       ` Daniel Walker
@ 2010-07-20 19:14         ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-20 19:14 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
>> +** Use cases
>> +
>> +    Lets analyse some imaginary system that uses the CMA to see how
>> +    the framework can be used and configured.
>> +
>> +
>> +    We have a platform with a hardware video decoder and a camera
>> each
>> +    needing 20 MiB of memory in worst case.  Our system is written in
>> +    such a way though that the two devices are never used at the same
>> +    time and memory for them may be shared.  In such a system the
>> +    following two command line arguments would be used:
>> +
>> +        cma=r=20M cma_map=video,camera=r
>
> This seems inelegant to me.. It seems like these should be connected
> with the drivers themselves vs. doing it on the command like for
> everything. You could have the video driver declare it needs 20megs, and
> the the camera does the same but both indicate it's shared ..
>
> If you have this disconnected from the drivers it will just cause
> confusion, since few will know what these parameters should be for a
> given driver set. It needs to be embedded in the kernel.

I see your point but the problem is that devices drivers don't know the
rest of the system neither they know what kind of use cases the system
should support.


Lets say, we have a camera, a JPEG encoder, a video decoder and
scaler (ie. devices that scales raw image).  We want to support the
following 3 use cases:

1. Camera's output is scaled and displayed in real-time.
2. Single frame is taken from camera and saved as JPEG image.
3. A video file is decoded, scaled and displayed.

What is apparent is that camera and video decoder are never running
at the same time.  The same situation is with JPEG encoder and scaler.
 From this knowledge we can construct the following:

   cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b

This may be a silly example but it shows that the configuration of
memory regions and device->regions mapping should be done after
some investigation rather then from devices which may have not enough
knowledge.


One of the purposes of the CMA framework is to make it let device
drivers completely forget about the memory management and enjoy
a simple API.


CMA core has a cma_defaults() function which can be called from
platform initialisation code.  It makes it easy to provide default
values for the cma and cma_map parameters.  This makes it possible
to provide a default which will work in many/most cases even if
user does not provide custom cma and/or cma_map parameters.


Having said that, some way of letting device drivers request
a region if one has not been defined for them may be a good idea.
I'll have to think about it...

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-20 19:14         ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-20 19:14 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
>> +** Use cases
>> +
>> +    Lets analyse some imaginary system that uses the CMA to see how
>> +    the framework can be used and configured.
>> +
>> +
>> +    We have a platform with a hardware video decoder and a camera
>> each
>> +    needing 20 MiB of memory in worst case.  Our system is written in
>> +    such a way though that the two devices are never used at the same
>> +    time and memory for them may be shared.  In such a system the
>> +    following two command line arguments would be used:
>> +
>> +        cma=r=20M cma_map=video,camera=r
>
> This seems inelegant to me.. It seems like these should be connected
> with the drivers themselves vs. doing it on the command like for
> everything. You could have the video driver declare it needs 20megs, and
> the the camera does the same but both indicate it's shared ..
>
> If you have this disconnected from the drivers it will just cause
> confusion, since few will know what these parameters should be for a
> given driver set. It needs to be embedded in the kernel.

I see your point but the problem is that devices drivers don't know the
rest of the system neither they know what kind of use cases the system
should support.


Lets say, we have a camera, a JPEG encoder, a video decoder and
scaler (ie. devices that scales raw image).  We want to support the
following 3 use cases:

1. Camera's output is scaled and displayed in real-time.
2. Single frame is taken from camera and saved as JPEG image.
3. A video file is decoded, scaled and displayed.

What is apparent is that camera and video decoder are never running
at the same time.  The same situation is with JPEG encoder and scaler.
 From this knowledge we can construct the following:

   cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b

This may be a silly example but it shows that the configuration of
memory regions and device->regions mapping should be done after
some investigation rather then from devices which may have not enough
knowledge.


One of the purposes of the CMA framework is to make it let device
drivers completely forget about the memory management and enjoy
a simple API.


CMA core has a cma_defaults() function which can be called from
platform initialisation code.  It makes it easy to provide default
values for the cma and cma_map parameters.  This makes it possible
to provide a default which will work in many/most cases even if
user does not provide custom cma and/or cma_map parameters.


Having said that, some way of letting device drivers request
a region if one has not been defined for them may be a good idea.
I'll have to think about it...

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 19:14         ` Michał Nazarewicz
@ 2010-07-20 19:38           ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-20 19:38 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 2010-07-20 at 21:14 +0200, Michał Nazarewicz wrote:
> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
> >> +** Use cases
> >> +
> >> +    Lets analyse some imaginary system that uses the CMA to see how
> >> +    the framework can be used and configured.
> >> +
> >> +
> >> +    We have a platform with a hardware video decoder and a camera
> >> each
> >> +    needing 20 MiB of memory in worst case.  Our system is written in
> >> +    such a way though that the two devices are never used at the same
> >> +    time and memory for them may be shared.  In such a system the
> >> +    following two command line arguments would be used:
> >> +
> >> +        cma=r=20M cma_map=video,camera=r
> >
> > This seems inelegant to me.. It seems like these should be connected
> > with the drivers themselves vs. doing it on the command like for
> > everything. You could have the video driver declare it needs 20megs, and
> > the the camera does the same but both indicate it's shared ..
> >
> > If you have this disconnected from the drivers it will just cause
> > confusion, since few will know what these parameters should be for a
> > given driver set. It needs to be embedded in the kernel.
> 
> I see your point but the problem is that devices drivers don't know the
> rest of the system neither they know what kind of use cases the system
> should support.
> 
> 
> Lets say, we have a camera, a JPEG encoder, a video decoder and
> scaler (ie. devices that scales raw image).  We want to support the
> following 3 use cases:
> 
> 1. Camera's output is scaled and displayed in real-time.
> 2. Single frame is taken from camera and saved as JPEG image.
> 3. A video file is decoded, scaled and displayed.
> 
> What is apparent is that camera and video decoder are never running
> at the same time.  The same situation is with JPEG encoder and scaler.
>  From this knowledge we can construct the following:
> 
>    cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b

It should be implicit tho. If the video driver isn't using the memory
then it should tell your framework that the memory is not used. That way
something else can use it.

(btw, these strings your creating yikes, talk about confusing ..)

> One of the purposes of the CMA framework is to make it let device
> drivers completely forget about the memory management and enjoy
> a simple API.

The driver, and it's maintainer, are really the best people to know how
much memory they need and when it's used/unused. You don't really want
to architect them out.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-20 19:38           ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-20 19:38 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 2010-07-20 at 21:14 +0200, MichaA? Nazarewicz wrote:
> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
> >> +** Use cases
> >> +
> >> +    Lets analyse some imaginary system that uses the CMA to see how
> >> +    the framework can be used and configured.
> >> +
> >> +
> >> +    We have a platform with a hardware video decoder and a camera
> >> each
> >> +    needing 20 MiB of memory in worst case.  Our system is written in
> >> +    such a way though that the two devices are never used at the same
> >> +    time and memory for them may be shared.  In such a system the
> >> +    following two command line arguments would be used:
> >> +
> >> +        cma=r=20M cma_map=video,camera=r
> >
> > This seems inelegant to me.. It seems like these should be connected
> > with the drivers themselves vs. doing it on the command like for
> > everything. You could have the video driver declare it needs 20megs, and
> > the the camera does the same but both indicate it's shared ..
> >
> > If you have this disconnected from the drivers it will just cause
> > confusion, since few will know what these parameters should be for a
> > given driver set. It needs to be embedded in the kernel.
> 
> I see your point but the problem is that devices drivers don't know the
> rest of the system neither they know what kind of use cases the system
> should support.
> 
> 
> Lets say, we have a camera, a JPEG encoder, a video decoder and
> scaler (ie. devices that scales raw image).  We want to support the
> following 3 use cases:
> 
> 1. Camera's output is scaled and displayed in real-time.
> 2. Single frame is taken from camera and saved as JPEG image.
> 3. A video file is decoded, scaled and displayed.
> 
> What is apparent is that camera and video decoder are never running
> at the same time.  The same situation is with JPEG encoder and scaler.
>  From this knowledge we can construct the following:
> 
>    cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b

It should be implicit tho. If the video driver isn't using the memory
then it should tell your framework that the memory is not used. That way
something else can use it.

(btw, these strings your creating yikes, talk about confusing ..)

> One of the purposes of the CMA framework is to make it let device
> drivers completely forget about the memory management and enjoy
> a simple API.

The driver, and it's maintainer, are really the best people to know how
much memory they need and when it's used/unused. You don't really want
to architect them out.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
@ 2010-07-20 20:52       ` Jonathan Corbet
  2010-07-20 18:15       ` Daniel Walker
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Jonathan Corbet @ 2010-07-20 20:52 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

On Tue, 20 Jul 2010 17:51:25 +0200
Michal Nazarewicz <m.nazarewicz@samsung.com> wrote:

> The Contiguous Memory Allocator framework is a set of APIs for
> allocating physically contiguous chunks of memory.
> 
> Various chips require contiguous blocks of memory to operate.  Those
> chips include devices such as cameras, hardware video decoders and
> encoders, etc.

Certainly this is something that many of us have run into; a general
solution would make life easier. I do wonder if this implementation
isn't a bit more complex than is really needed, though.

> diff --git a/Documentation/cma.txt b/Documentation/cma.txt

"cma.txt" is not a name that will say much to people browsing the
directory, especially since you didn't add a 00-INDEX entry for it.  Maybe
something like contiguous-memory.txt would be better?

[...]

> +    For instance, let say that there are two memory banks and for
> +    performance reasons a device uses buffers in both of them.  In
> +    such case, the device driver would define two kinds and use it for
> +    different buffers.  Command line arguments could look as follows:
> +
> +            cma=a=32M@0,b=32M@512M cma_map=foo/a=a;foo/b=b

About the time I get here I really have to wonder if we *really* need all
of this.  A rather large portion of the entire patch is parsing code.  Are
there real-world use cases for this kind of functionality?

> +    And whenever the driver allocated the memory it would specify the
> +    kind of memory:
> +
> +            buffer1 = cma_alloc(dev, 1 << 20, 0, "a");
> +            buffer2 = cma_alloc(dev, 1 << 20, 0, "b");

This example, above, is not consistent with:

> +
> +    There are four calls provided by the CMA framework to devices.  To
> +    allocate a chunk of memory cma_alloc() function needs to be used:
> +
> +            unsigned long cma_alloc(const struct device *dev,
> +                                    const char *kind,
> +                                    unsigned long size,
> +                                    unsigned long alignment);

It looks like the API changed and the example didn't get updated?

> +
> +    If required, device may specify alignment that the chunk need to
> +    satisfy.  It have to be a power of two or zero.  The chunks are
> +    always aligned at least to a page.

So is the alignment specified in bytes or pages?

> +    Allocated chunk is freed via a cma_put() function:
> +
> +            int cma_put(unsigned long addr);
> +
> +    It takes physical address of the chunk as an argument and
> +    decreases it's reference counter.  If the counter reaches zero the
> +    chunk is freed.  Most of the time users do not need to think about
> +    reference counter and simply use the cma_put() as a free call.

A return value from a put() function is mildly different; when would that
value be useful?

> +    If one, however, were to share a chunk with others built in
> +    reference counter may turn out to be handy.  To increment it, one
> +    needs to use cma_get() function:
> +
> +            int cma_put(unsigned long addr);

Somebody's been cut-n-pasting a little too quickly...:)

> +    Creating an allocator for CMA needs four functions to be
> +    implemented.
> +
> +
> +    The first two are used to initialise an allocator far given driver
> +    and clean up afterwards:
> +
> +            int  cma_foo_init(struct cma_region *reg);
> +            void cma_foo_done(struct cma_region *reg);
> +
> +    The first is called during platform initialisation.  The
> +    cma_region structure has saved starting address of the region as
> +    well as its size.  It has also alloc_params field with optional
> +    parameters passed via command line (allocator is free to interpret
> +    those in any way it pleases).  Any data that allocate associated
> +    with the region can be saved in private_data field.
> +
> +    The second call cleans up and frees all resources the allocator
> +    has allocated for the region.  The function can assume that all
> +    chunks allocated form this region have been freed thus the whole
> +    region is free.
> +
> +
> +    The two other calls are used for allocating and freeing chunks.
> +    They are:
> +
> +            struct cma_chunk *cma_foo_alloc(struct cma_region *reg,
> +                                            unsigned long size,
> +                                            unsigned long alignment);
> +            void cma_foo_free(struct cma_chunk *chunk);
> +
> +    As names imply the first allocates a chunk and the other frees
> +    a chunk of memory.  It also manages a cma_chunk object
> +    representing the chunk in physical memory.
> +
> +    Either of those function can assume that they are the only thread
> +    accessing the region.  Therefore, allocator does not need to worry
> +    about concurrency.
> +
> +
> +    When allocator is ready, all that is left is register it by adding
> +    a line to "mm/cma-allocators.h" file:
> +
> +            CMA_ALLOCATOR("foo", foo)
> +
> +    The first "foo" is a named that will be available to use with
> +    command line argument.  The second is the part used in function
> +    names.

This is a bit of an awkward way to register new allocators.  Why not just
have new allocators fill in an operations structure can call something like
cma_allocator_register() at initialization time?  That would let people
write allocators as modules and would eliminate the need to add allocators
to a central include file.  It would also get rid of some ugly and (IMHO)
unnecessary preprocessor hackery.

[...]

> +** Future work
> +
> +    In the future, implementation of mechanisms that would allow the
> +    free space inside the regions to be used as page cache, filesystem
> +    buffers or swap devices is planned.  With such mechanisms, the
> +    memory would not be wasted when not used.

Ouch.  You'd need to be able to evacuate that space again when it's needed,
or the whole point of CMA has been lost.  Once again, is it worth the
complexity?


[...]
> diff --git a/include/linux/cma-int.h b/include/linux/cma-int.h
> new file mode 100644
> index 0000000..b588e9b
> --- /dev/null
> +++ b/include/linux/cma-int.h

> +struct cma_region {
> +	const char *name;
> +	unsigned long start;
> +	unsigned long size, free_space;
> +	unsigned long alignment;
> +
> +	struct cma_allocator *alloc;
> +	const char *alloc_name;
> +	const char *alloc_params;
> +	void *private_data;
> +
> +	unsigned users;
> +	/*
> +	 * Protects the "users" and "free_space" fields and any calls
> +	 * to allocator on this region thus guarantees only one call
> +	 * to allocator will operate on this region..
> +	 */
> +	struct mutex mutex;
> +};

The use of mutexes means that allocation/free functions cannot be called
from atomic context.  Perhaps that will never be a problem, but it might
also be possible to use spinlocks instead?

[...]

> diff --git a/mm/cma-allocators.h b/mm/cma-allocators.h
> new file mode 100644
> index 0000000..564f705
> --- /dev/null
> +++ b/mm/cma-allocators.h
> @@ -0,0 +1,42 @@
> +#ifdef __CMA_ALLOCATORS_H
> +
> +/* List all existing allocators here using CMA_ALLOCATOR macro. */
> +
> +#ifdef CONFIG_CMA_BEST_FIT
> +CMA_ALLOCATOR("bf", bf)
> +#endif

This is the kind of thing I think it would be nice to avoid; is there any
real reason why allocators need to be put into this central file?

This is some weird ifdef stuff as well; it processes the CMA_ALLOCATOR()
invocations if it's included twice?

> +
> +#  undef CMA_ALLOCATOR
> +#else
> +#  define __CMA_ALLOCATORS_H
> +
> +/* Function prototypes */
> +#  ifndef __LINUX_CMA_ALLOCATORS_H
> +#    define __LINUX_CMA_ALLOCATORS_H
> +#    define CMA_ALLOCATOR(name, infix)				\
> +	extern int cma_ ## infix ## _init(struct cma_region *);		\
> +	extern void cma_ ## infix ## _cleanup(struct cma_region *);	\
> +	extern struct cma_chunk *					\
> +	cma_ ## infix ## _alloc(struct cma_region *,			\
> +			      unsigned long, unsigned long);		\
> +	extern void cma_ ## infix ## _free(struct cma_chunk *);
> +#    include "cma-allocators.h"
> +#  endif
> +
> +/* The cma_allocators array */
> +#  ifdef CMA_ALLOCATORS_LIST
> +#    define CMA_ALLOCATOR(_name, infix) {		\
> +		.name    = _name,			\
> +		.init    = cma_ ## infix ## _init,	\
> +		.cleanup = cma_ ## infix ## _cleanup,	\
> +		.alloc   = cma_ ## infix ## _alloc,	\
> +		.free    = cma_ ## infix ## _free,	\
> +	},

Different implementations of the macro in different places in the same
kernel can cause confusion.  To what end?  As I said before, a simple
registration function called by the allocators would eliminate the need for
this kind of stuff.

> diff --git a/mm/cma-best-fit.c b/mm/cma-best-fit.c

[...]

> +int cma_bf_init(struct cma_region *reg)
> +{
> +	struct cma_bf_private *prv;
> +	struct cma_bf_item *item;
> +
> +	prv = kzalloc(sizeof *prv, GFP_NOWAIT);
> +	if (unlikely(!prv))
> +		return -ENOMEM;

I'll say this once, but the comment applies all over this code: I hate it
when people go nuts with likely/unlikely().  This is an initialization
function, we don't actually care if the branch prediction gets it wrong.
Classic premature optimization.  The truth of the matter is that
*programmers* often get this wrong.  Have you profiled all these
ocurrences?  Maybe it would be better to take them out?

[...]

> +struct cma_chunk *cma_bf_alloc(struct cma_region *reg,
> +			       unsigned long size, unsigned long alignment)
> +{
> +	struct cma_bf_private *prv = reg->private_data;
> +	struct rb_node *node = prv->by_size_root.rb_node;
> +	struct cma_bf_item *item = NULL;
> +	unsigned long start, end;
> +
> +	/* First first item that is large enough */
> +	while (node) {
> +		struct cma_bf_item *i =
> +			rb_entry(node, struct cma_bf_item, by_size);

This is about where I start to wonder about locking.  I take it that the
allocator code is relying upon locking at the CMA level to prevent
concurrent calls?  If so, it would be good to document what guarantees the
CMA level provides.

> +/************************* Basic Tree Manipulation *************************/
> +
> +#define __CMA_BF_HOLE_INSERT(root, node, field) ({			\
> +	bool equal = false;						\
> +	struct rb_node **link = &(root).rb_node, *parent = NULL;	\
> +	const unsigned long value = item->field;			\
> +	while (*link) {							\
> +		struct cma_bf_item *i;					\
> +		parent = *link;						\
> +		i = rb_entry(parent, struct cma_bf_item, node);		\
> +		link = value <= i->field				\
> +			? &parent->rb_left				\
> +			: &parent->rb_right;				\
> +		equal = equal || value == i->field;			\
> +	}								\
> +	rb_link_node(&item->node, parent, link);			\
> +	rb_insert_color(&item->node, &root);				\
> +	equal;								\
> +})

Is there a reason why this is a macro?  The code might be more readable if
you just wrote out the two versions that you need.

[...]

> diff --git a/mm/cma.c b/mm/cma.c
> new file mode 100644
> index 0000000..6a0942f
> --- /dev/null
> +++ b/mm/cma.c

[...]

> +static const char *__must_check
> +__cma_where_from(const struct device *dev, const char *kind)
> +{
> +	/*
> +	 * This function matches the pattern given at command line
> +	 * parameter agains given device name and kind.  Kind may be
> +	 * of course NULL or an emtpy string.
> +	 */
> +
> +	const char **spec, *name;
> +	int name_matched = 0;
> +
> +	/* Make sure dev was given and has name */
> +	if (unlikely(!dev))
> +		return ERR_PTR(-EINVAL);
> +
> +	name = dev_name(dev);
> +	if (WARN_ON(!name || !*name))
> +		return ERR_PTR(-EINVAL);
> +
> +	/* kind == NULL is just like an empty kind */
> +	if (!kind)
> +		kind = "";
> +
> +	/*
> +	 * Now we go throught the cma_map array.  It is an array of
> +	 * pointers to chars (ie. array of strings) so in each
> +	 * iteration we take each of the string.  The strings is
> +	 * basically what user provided at the command line separated
> +	 * by semicolons.
> +	 */
> +	for (spec = cma_map; *spec; ++spec) {
> +		/*
> +		 * This macro tries to match pattern pointed by s to
> +		 * @what.  If, while reading the spec, we ecnounter
> +		 * comma it means that the pattern does not match and
> +		 * we need to start over with another spec.  If there
> +		 * is a character that does not match, we neet to try
> +		 * again looking if there is another spec.
> +		 */
> +#define TRY_MATCH(what) do {				\
> +		const char *c = what;			\
> +		for (; *s != '*' && *c; ++c, ++s)	\
> +			if (*s == ',')			\
> +				goto again;		\
> +			else if (*s != '?' && *c != *s)	\
> +				goto again_maybe;	\
> +		if (*s == '*')				\
> +			++s;				\
> +	} while (0)

This kind of thing rarely contributes to the readability or maintainability
of the code.  Is it really necessary?  Or (as asked before) is all this
functionality really necessary?

[...]

One other comment: it might be nice if drivers could provide allocation
regions of their own.  The viafb driver, for example, really needs an
allocator to hand out chunks of framebuffer memory - including large chunks
for things like video frames.  If that driver could hand responsibility
for that over to CMA, it could eliminate the need for yet another
driver-quality memory manager.

jon

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-20 20:52       ` Jonathan Corbet
  0 siblings, 0 replies; 98+ messages in thread
From: Jonathan Corbet @ 2010-07-20 20:52 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

On Tue, 20 Jul 2010 17:51:25 +0200
Michal Nazarewicz <m.nazarewicz@samsung.com> wrote:

> The Contiguous Memory Allocator framework is a set of APIs for
> allocating physically contiguous chunks of memory.
> 
> Various chips require contiguous blocks of memory to operate.  Those
> chips include devices such as cameras, hardware video decoders and
> encoders, etc.

Certainly this is something that many of us have run into; a general
solution would make life easier. I do wonder if this implementation
isn't a bit more complex than is really needed, though.

> diff --git a/Documentation/cma.txt b/Documentation/cma.txt

"cma.txt" is not a name that will say much to people browsing the
directory, especially since you didn't add a 00-INDEX entry for it.  Maybe
something like contiguous-memory.txt would be better?

[...]

> +    For instance, let say that there are two memory banks and for
> +    performance reasons a device uses buffers in both of them.  In
> +    such case, the device driver would define two kinds and use it for
> +    different buffers.  Command line arguments could look as follows:
> +
> +            cma=a=32M@0,b=32M@512M cma_map=foo/a=a;foo/b=b

About the time I get here I really have to wonder if we *really* need all
of this.  A rather large portion of the entire patch is parsing code.  Are
there real-world use cases for this kind of functionality?

> +    And whenever the driver allocated the memory it would specify the
> +    kind of memory:
> +
> +            buffer1 = cma_alloc(dev, 1 << 20, 0, "a");
> +            buffer2 = cma_alloc(dev, 1 << 20, 0, "b");

This example, above, is not consistent with:

> +
> +    There are four calls provided by the CMA framework to devices.  To
> +    allocate a chunk of memory cma_alloc() function needs to be used:
> +
> +            unsigned long cma_alloc(const struct device *dev,
> +                                    const char *kind,
> +                                    unsigned long size,
> +                                    unsigned long alignment);

It looks like the API changed and the example didn't get updated?

> +
> +    If required, device may specify alignment that the chunk need to
> +    satisfy.  It have to be a power of two or zero.  The chunks are
> +    always aligned at least to a page.

So is the alignment specified in bytes or pages?

> +    Allocated chunk is freed via a cma_put() function:
> +
> +            int cma_put(unsigned long addr);
> +
> +    It takes physical address of the chunk as an argument and
> +    decreases it's reference counter.  If the counter reaches zero the
> +    chunk is freed.  Most of the time users do not need to think about
> +    reference counter and simply use the cma_put() as a free call.

A return value from a put() function is mildly different; when would that
value be useful?

> +    If one, however, were to share a chunk with others built in
> +    reference counter may turn out to be handy.  To increment it, one
> +    needs to use cma_get() function:
> +
> +            int cma_put(unsigned long addr);

Somebody's been cut-n-pasting a little too quickly...:)

> +    Creating an allocator for CMA needs four functions to be
> +    implemented.
> +
> +
> +    The first two are used to initialise an allocator far given driver
> +    and clean up afterwards:
> +
> +            int  cma_foo_init(struct cma_region *reg);
> +            void cma_foo_done(struct cma_region *reg);
> +
> +    The first is called during platform initialisation.  The
> +    cma_region structure has saved starting address of the region as
> +    well as its size.  It has also alloc_params field with optional
> +    parameters passed via command line (allocator is free to interpret
> +    those in any way it pleases).  Any data that allocate associated
> +    with the region can be saved in private_data field.
> +
> +    The second call cleans up and frees all resources the allocator
> +    has allocated for the region.  The function can assume that all
> +    chunks allocated form this region have been freed thus the whole
> +    region is free.
> +
> +
> +    The two other calls are used for allocating and freeing chunks.
> +    They are:
> +
> +            struct cma_chunk *cma_foo_alloc(struct cma_region *reg,
> +                                            unsigned long size,
> +                                            unsigned long alignment);
> +            void cma_foo_free(struct cma_chunk *chunk);
> +
> +    As names imply the first allocates a chunk and the other frees
> +    a chunk of memory.  It also manages a cma_chunk object
> +    representing the chunk in physical memory.
> +
> +    Either of those function can assume that they are the only thread
> +    accessing the region.  Therefore, allocator does not need to worry
> +    about concurrency.
> +
> +
> +    When allocator is ready, all that is left is register it by adding
> +    a line to "mm/cma-allocators.h" file:
> +
> +            CMA_ALLOCATOR("foo", foo)
> +
> +    The first "foo" is a named that will be available to use with
> +    command line argument.  The second is the part used in function
> +    names.

This is a bit of an awkward way to register new allocators.  Why not just
have new allocators fill in an operations structure can call something like
cma_allocator_register() at initialization time?  That would let people
write allocators as modules and would eliminate the need to add allocators
to a central include file.  It would also get rid of some ugly and (IMHO)
unnecessary preprocessor hackery.

[...]

> +** Future work
> +
> +    In the future, implementation of mechanisms that would allow the
> +    free space inside the regions to be used as page cache, filesystem
> +    buffers or swap devices is planned.  With such mechanisms, the
> +    memory would not be wasted when not used.

Ouch.  You'd need to be able to evacuate that space again when it's needed,
or the whole point of CMA has been lost.  Once again, is it worth the
complexity?


[...]
> diff --git a/include/linux/cma-int.h b/include/linux/cma-int.h
> new file mode 100644
> index 0000000..b588e9b
> --- /dev/null
> +++ b/include/linux/cma-int.h

> +struct cma_region {
> +	const char *name;
> +	unsigned long start;
> +	unsigned long size, free_space;
> +	unsigned long alignment;
> +
> +	struct cma_allocator *alloc;
> +	const char *alloc_name;
> +	const char *alloc_params;
> +	void *private_data;
> +
> +	unsigned users;
> +	/*
> +	 * Protects the "users" and "free_space" fields and any calls
> +	 * to allocator on this region thus guarantees only one call
> +	 * to allocator will operate on this region..
> +	 */
> +	struct mutex mutex;
> +};

The use of mutexes means that allocation/free functions cannot be called
from atomic context.  Perhaps that will never be a problem, but it might
also be possible to use spinlocks instead?

[...]

> diff --git a/mm/cma-allocators.h b/mm/cma-allocators.h
> new file mode 100644
> index 0000000..564f705
> --- /dev/null
> +++ b/mm/cma-allocators.h
> @@ -0,0 +1,42 @@
> +#ifdef __CMA_ALLOCATORS_H
> +
> +/* List all existing allocators here using CMA_ALLOCATOR macro. */
> +
> +#ifdef CONFIG_CMA_BEST_FIT
> +CMA_ALLOCATOR("bf", bf)
> +#endif

This is the kind of thing I think it would be nice to avoid; is there any
real reason why allocators need to be put into this central file?

This is some weird ifdef stuff as well; it processes the CMA_ALLOCATOR()
invocations if it's included twice?

> +
> +#  undef CMA_ALLOCATOR
> +#else
> +#  define __CMA_ALLOCATORS_H
> +
> +/* Function prototypes */
> +#  ifndef __LINUX_CMA_ALLOCATORS_H
> +#    define __LINUX_CMA_ALLOCATORS_H
> +#    define CMA_ALLOCATOR(name, infix)				\
> +	extern int cma_ ## infix ## _init(struct cma_region *);		\
> +	extern void cma_ ## infix ## _cleanup(struct cma_region *);	\
> +	extern struct cma_chunk *					\
> +	cma_ ## infix ## _alloc(struct cma_region *,			\
> +			      unsigned long, unsigned long);		\
> +	extern void cma_ ## infix ## _free(struct cma_chunk *);
> +#    include "cma-allocators.h"
> +#  endif
> +
> +/* The cma_allocators array */
> +#  ifdef CMA_ALLOCATORS_LIST
> +#    define CMA_ALLOCATOR(_name, infix) {		\
> +		.name    = _name,			\
> +		.init    = cma_ ## infix ## _init,	\
> +		.cleanup = cma_ ## infix ## _cleanup,	\
> +		.alloc   = cma_ ## infix ## _alloc,	\
> +		.free    = cma_ ## infix ## _free,	\
> +	},

Different implementations of the macro in different places in the same
kernel can cause confusion.  To what end?  As I said before, a simple
registration function called by the allocators would eliminate the need for
this kind of stuff.

> diff --git a/mm/cma-best-fit.c b/mm/cma-best-fit.c

[...]

> +int cma_bf_init(struct cma_region *reg)
> +{
> +	struct cma_bf_private *prv;
> +	struct cma_bf_item *item;
> +
> +	prv = kzalloc(sizeof *prv, GFP_NOWAIT);
> +	if (unlikely(!prv))
> +		return -ENOMEM;

I'll say this once, but the comment applies all over this code: I hate it
when people go nuts with likely/unlikely().  This is an initialization
function, we don't actually care if the branch prediction gets it wrong.
Classic premature optimization.  The truth of the matter is that
*programmers* often get this wrong.  Have you profiled all these
ocurrences?  Maybe it would be better to take them out?

[...]

> +struct cma_chunk *cma_bf_alloc(struct cma_region *reg,
> +			       unsigned long size, unsigned long alignment)
> +{
> +	struct cma_bf_private *prv = reg->private_data;
> +	struct rb_node *node = prv->by_size_root.rb_node;
> +	struct cma_bf_item *item = NULL;
> +	unsigned long start, end;
> +
> +	/* First first item that is large enough */
> +	while (node) {
> +		struct cma_bf_item *i =
> +			rb_entry(node, struct cma_bf_item, by_size);

This is about where I start to wonder about locking.  I take it that the
allocator code is relying upon locking at the CMA level to prevent
concurrent calls?  If so, it would be good to document what guarantees the
CMA level provides.

> +/************************* Basic Tree Manipulation *************************/
> +
> +#define __CMA_BF_HOLE_INSERT(root, node, field) ({			\
> +	bool equal = false;						\
> +	struct rb_node **link = &(root).rb_node, *parent = NULL;	\
> +	const unsigned long value = item->field;			\
> +	while (*link) {							\
> +		struct cma_bf_item *i;					\
> +		parent = *link;						\
> +		i = rb_entry(parent, struct cma_bf_item, node);		\
> +		link = value <= i->field				\
> +			? &parent->rb_left				\
> +			: &parent->rb_right;				\
> +		equal = equal || value == i->field;			\
> +	}								\
> +	rb_link_node(&item->node, parent, link);			\
> +	rb_insert_color(&item->node, &root);				\
> +	equal;								\
> +})

Is there a reason why this is a macro?  The code might be more readable if
you just wrote out the two versions that you need.

[...]

> diff --git a/mm/cma.c b/mm/cma.c
> new file mode 100644
> index 0000000..6a0942f
> --- /dev/null
> +++ b/mm/cma.c

[...]

> +static const char *__must_check
> +__cma_where_from(const struct device *dev, const char *kind)
> +{
> +	/*
> +	 * This function matches the pattern given at command line
> +	 * parameter agains given device name and kind.  Kind may be
> +	 * of course NULL or an emtpy string.
> +	 */
> +
> +	const char **spec, *name;
> +	int name_matched = 0;
> +
> +	/* Make sure dev was given and has name */
> +	if (unlikely(!dev))
> +		return ERR_PTR(-EINVAL);
> +
> +	name = dev_name(dev);
> +	if (WARN_ON(!name || !*name))
> +		return ERR_PTR(-EINVAL);
> +
> +	/* kind == NULL is just like an empty kind */
> +	if (!kind)
> +		kind = "";
> +
> +	/*
> +	 * Now we go throught the cma_map array.  It is an array of
> +	 * pointers to chars (ie. array of strings) so in each
> +	 * iteration we take each of the string.  The strings is
> +	 * basically what user provided at the command line separated
> +	 * by semicolons.
> +	 */
> +	for (spec = cma_map; *spec; ++spec) {
> +		/*
> +		 * This macro tries to match pattern pointed by s to
> +		 * @what.  If, while reading the spec, we ecnounter
> +		 * comma it means that the pattern does not match and
> +		 * we need to start over with another spec.  If there
> +		 * is a character that does not match, we neet to try
> +		 * again looking if there is another spec.
> +		 */
> +#define TRY_MATCH(what) do {				\
> +		const char *c = what;			\
> +		for (; *s != '*' && *c; ++c, ++s)	\
> +			if (*s == ',')			\
> +				goto again;		\
> +			else if (*s != '?' && *c != *s)	\
> +				goto again_maybe;	\
> +		if (*s == '*')				\
> +			++s;				\
> +	} while (0)

This kind of thing rarely contributes to the readability or maintainability
of the code.  Is it really necessary?  Or (as asked before) is all this
functionality really necessary?

[...]

One other comment: it might be nice if drivers could provide allocation
regions of their own.  The viafb driver, for example, really needs an
allocator to hand out chunks of framebuffer memory - including large chunks
for things like video frames.  If that driver could hand responsibility
for that over to CMA, it could eliminate the need for yet another
driver-quality memory manager.

jon

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
@ 2010-07-21  0:12       ` Jonathan Corbet
  2010-07-20 18:15       ` Daniel Walker
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Jonathan Corbet @ 2010-07-21  0:12 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

One other thing occurred to me as I was thinking about this...

> +    There are four calls provided by the CMA framework to devices.  To
> +    allocate a chunk of memory cma_alloc() function needs to be used:
> +
> +            unsigned long cma_alloc(const struct device *dev,
> +                                    const char *kind,
> +                                    unsigned long size,
> +                                    unsigned long alignment);

The purpose behind this interface, I believe, is pretty much always
going to be to allocate memory for DMA buffers.  Given that, might it
make more sense to integrate the API with the current DMA mapping API?
Then the allocation function could stop messing around with long values
and, instead, just hand back a void * kernel-space pointer and a
dma_addr_t to hand to the device.  That would make life a little easier
in driverland...

jon

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21  0:12       ` Jonathan Corbet
  0 siblings, 0 replies; 98+ messages in thread
From: Jonathan Corbet @ 2010-07-21  0:12 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

One other thing occurred to me as I was thinking about this...

> +    There are four calls provided by the CMA framework to devices.  To
> +    allocate a chunk of memory cma_alloc() function needs to be used:
> +
> +            unsigned long cma_alloc(const struct device *dev,
> +                                    const char *kind,
> +                                    unsigned long size,
> +                                    unsigned long alignment);

The purpose behind this interface, I believe, is pretty much always
going to be to allocate memory for DMA buffers.  Given that, might it
make more sense to integrate the API with the current DMA mapping API?
Then the allocation function could stop messing around with long values
and, instead, just hand back a void * kernel-space pointer and a
dma_addr_t to hand to the device.  That would make life a little easier
in driverland...

jon

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 20:52       ` Jonathan Corbet
@ 2010-07-21 10:16         ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 10:16 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

Hello Jonathan,

Thank you for review and comments!

> On Tue, 20 Jul 2010 17:51:25 +0200 Michal Nazarewicz wrote:
>> The Contiguous Memory Allocator framework is a set of APIs for
>> allocating physically contiguous chunks of memory.
>>
>> Various chips require contiguous blocks of memory to operate.  Those
>> chips include devices such as cameras, hardware video decoders and
>> encoders, etc.

On Tue, 20 Jul 2010 22:52:38 +0200, Jonathan Corbet <corbet@lwn.net> wrote:
> Certainly this is something that many of us have run into; a general
> solution would make life easier. I do wonder if this implementation
> isn't a bit more complex than is really needed, though.
>
>> diff --git a/Documentation/cma.txt b/Documentation/cma.txt
>
> "cma.txt" is not a name that will say much to people browsing the
> directory, especially since you didn't add a 00-INDEX entry for it.  Maybe
> something like contiguous-memory.txt would be better?

Will fix.

>> +    For instance, let say that there are two memory banks and for
>> +    performance reasons a device uses buffers in both of them.  In
>> +    such case, the device driver would define two kinds and use it for
>> +    different buffers.  Command line arguments could look as follows:
>> +
>> +            cma=a=32M@0,b=32M@512M cma_map=foo/a=a;foo/b=b

> About the time I get here I really have to wonder if we *really* need all
> of this.  A rather large portion of the entire patch is parsing code.  Are
> there real-world use cases for this kind of functionality?

As of "cma" parameter: we encountered a system where all of the information
(expect for allocator) that it is possible to specify is needed.

1. The size is needed from obvious reasons.
2. Our platform have two banks of memory and one of the devices needs
     some buffers to be allocated in one bank and other buffers in the
     other bank.  The start address that can be specified let us
     specify regions in both banks.
3. At least one of our drivers needs a buffer for firmware that is aligned
     to 128K (if recall correctly).  Due to other, unrelated reasons it needs
     to be in a region on its own so we need to reserve a region aligned
     at least to 128K.
4. As of allocator, we use only best-fit but I believe that letting user
     specify desired allocator is desirable.

As of "cma_map" parameter: It is needed because different devices are
assigned to different regions.  Also, at least one of our drivers uses
three kinds of memory (bank 1, bank 2 and firmware) and hence we also
need the optional kind.

The remaining question is whether we need the pattern matching (like '?'
and '*').  I agree that the matching code may be not the most beautiful
piece of software but I believe it may be useful.  In particular letting
user write something like the following may be nice:

    cma_map=foo-dev=foo-region;*/*=bar-region

This lets one say that foo-dev should use its own region and all other
devices should share the other region.  Similarly, if at one point the driver
I described above (that uses 3 kinds) were to receive a firmware upgrade or
be installed on different platform and regions in two banks would no longer
be necessary the command line could be set to:

    cma_map=baz-dev/firmware=baz-firmware;baz-dev/*=baz-region

and everything would start working fine without the need to change the
driver itself -- it would be completely unaware of the change.

Generally I see that the asterisk may be quite useful.

>> +    And whenever the driver allocated the memory it would specify the
>> +    kind of memory:
>> +
>> +            buffer1 = cma_alloc(dev, 1 << 20, 0, "a");
>> +            buffer2 = cma_alloc(dev, 1 << 20, 0, "b");

> This example, above, is not consistent with:

>> +
>> +    There are four calls provided by the CMA framework to devices.  To
>> +    allocate a chunk of memory cma_alloc() function needs to be used:
>> +
>> +            unsigned long cma_alloc(const struct device *dev,
>> +                                    const char *kind,
>> +                                    unsigned long size,
>> +                                    unsigned long alignment);

> It looks like the API changed and the example didn't get updated?

Yep, will fix.

>> +
>> +    If required, device may specify alignment that the chunk need to
>> +    satisfy.  It have to be a power of two or zero.  The chunks are
>> +    always aligned at least to a page.
>
> So is the alignment specified in bytes or pages?

In bytes, will fix.

>> +    Allocated chunk is freed via a cma_put() function:
>> +
>> +            int cma_put(unsigned long addr);
>> +
>> +    It takes physical address of the chunk as an argument and
>> +    decreases it's reference counter.  If the counter reaches zero the
>> +    chunk is freed.  Most of the time users do not need to think about
>> +    reference counter and simply use the cma_put() as a free call.
>
> A return value from a put() function is mildly different;

Not sure what you mean.  cma_put() returns either -ENOENT if there is no
chunk with given address or whatever kref_put() returned.

> when would that value be useful?

I dunno.  I'm just returning what kref_put() returns.

>
>> +    If one, however, were to share a chunk with others built in
>> +    reference counter may turn out to be handy.  To increment it, one
>> +    needs to use cma_get() function:
>> +
>> +            int cma_put(unsigned long addr);
>
> Somebody's been cut-n-pasting a little too quickly...:)

Will fix.

>> +    Creating an allocator for CMA needs four functions to be
>> +    implemented.
>> +
>> +
>> +    The first two are used to initialise an allocator far given driver
>> +    and clean up afterwards:
>> +
>> +            int  cma_foo_init(struct cma_region *reg);
>> +            void cma_foo_done(struct cma_region *reg);
>> +
>> +    The first is called during platform initialisation.  The
>> +    cma_region structure has saved starting address of the region as
>> +    well as its size.  It has also alloc_params field with optional
>> +    parameters passed via command line (allocator is free to interpret
>> +    those in any way it pleases).  Any data that allocate associated
>> +    with the region can be saved in private_data field.
>> +
>> +    The second call cleans up and frees all resources the allocator
>> +    has allocated for the region.  The function can assume that all
>> +    chunks allocated form this region have been freed thus the whole
>> +    region is free.
>> +
>> +
>> +    The two other calls are used for allocating and freeing chunks.
>> +    They are:
>> +
>> +            struct cma_chunk *cma_foo_alloc(struct cma_region *reg,
>> +                                            unsigned long size,
>> +                                            unsigned long alignment);
>> +            void cma_foo_free(struct cma_chunk *chunk);
>> +
>> +    As names imply the first allocates a chunk and the other frees
>> +    a chunk of memory.  It also manages a cma_chunk object
>> +    representing the chunk in physical memory.
>> +
>> +    Either of those function can assume that they are the only thread
>> +    accessing the region.  Therefore, allocator does not need to worry
>> +    about concurrency.
>> +
>> +
>> +    When allocator is ready, all that is left is register it by adding
>> +    a line to "mm/cma-allocators.h" file:
>> +
>> +            CMA_ALLOCATOR("foo", foo)
>> +
>> +    The first "foo" is a named that will be available to use with
>> +    command line argument.  The second is the part used in function
>> +    names.

> This is a bit of an awkward way to register new allocators.  Why not just
> have new allocators fill in an operations structure can call something like
> cma_allocator_register() at initialization time?  That would let people
> write allocators as modules and would eliminate the need to add allocators
> to a central include file.  It would also get rid of some ugly and (IMHO)
> unnecessary preprocessor hackery.

At the moment the list of allocators has to be available early during boot up.
This is because regions are initialised (that is allocators are attached to
regions) from initcall (subsys_initcall to be precise).  This means
allocators cannot be modules (ie. they cannot be dynamically loaded) but
only compiled in.  Because of all those, I decided that creating an array with
all allocators would be, maybe not very beautiful, but a good solution.

Even if I were to provide a “cma_register_allocator()” call it would have to be
called before subsys initcalls and as such it would be of little usefulness I
believe.

I agree that it would be nice to be able to have allocators loaded dynamically
but it is not possible as of yet.

>> +** Future work
>> +
>> +    In the future, implementation of mechanisms that would allow the
>> +    free space inside the regions to be used as page cache, filesystem
>> +    buffers or swap devices is planned.  With such mechanisms, the
>> +    memory would not be wasted when not used.
>
> Ouch.  You'd need to be able to evacuate that space again when it's needed,
> or the whole point of CMA has been lost.  Once again, is it worth the
> complexity?

I believe it is.  All of the regions could well take like 64M or so.  If most
of the times the device drivers would not be used the space would be wasted.
If, instead, it could be used for some read-only data or other data that is
easy to remove from memory the whole system could benefit.

Still, this is a future work so for now it's in the dominion of dreams and
good-night stories. ;)  Bottom line is, we will think about it when the time
will come.

>> diff --git a/include/linux/cma-int.h b/include/linux/cma-int.h
>> new file mode 100644
>> index 0000000..b588e9b
>> --- /dev/null
>> +++ b/include/linux/cma-int.h
>
>> +struct cma_region {
>> +	const char *name;
>> +	unsigned long start;
>> +	unsigned long size, free_space;
>> +	unsigned long alignment;
>> +
>> +	struct cma_allocator *alloc;
>> +	const char *alloc_name;
>> +	const char *alloc_params;
>> +	void *private_data;
>> +
>> +	unsigned users;
>> +	/*
>> +	 * Protects the "users" and "free_space" fields and any calls
>> +	 * to allocator on this region thus guarantees only one call
>> +	 * to allocator will operate on this region..
>> +	 */
>> +	struct mutex mutex;
>> +};

> The use of mutexes means that allocation/free functions cannot be called
> from atomic context.  Perhaps that will never be a problem, but it might
> also be possible to use spinlocks instead?

Mutexes should not be a problem.  In all use cases that we came up with,
allocation and freeing was done from user context when some operation
is initialised.  User launches an application to record video with a
camera or launches a video player and at this moment buffers are
initialised.  We don't see any use case where CMA would be used from
an interrupt or some such.

At the same time, the use of spinlocks would limit allocators (which is
probably a minor issue) but what's more it would limit our possibility to
use unused space of the regions for page cache/buffers/swap/you-name-it.

In general, I believe that requiring that cma_alloc()/cma_put() cannot be
called from atomic context have more benefits then drawbacks (the latter
could check if it is called from atomic context and if so let a worker do
the actual freeing if there would be cases where it would be nice to use
cma_put() in atomic context).

>> diff --git a/mm/cma-allocators.h b/mm/cma-allocators.h
>> new file mode 100644
>> index 0000000..564f705
>> --- /dev/null
>> +++ b/mm/cma-allocators.h
>> @@ -0,0 +1,42 @@
>> +#ifdef __CMA_ALLOCATORS_H
>> +
>> +/* List all existing allocators here using CMA_ALLOCATOR macro. */
>> +
>> +#ifdef CONFIG_CMA_BEST_FIT
>> +CMA_ALLOCATOR("bf", bf)
>> +#endif
>
> This is the kind of thing I think it would be nice to avoid; is there any
> real reason why allocators need to be put into this central file?
>
> This is some weird ifdef stuff as well; it processes the CMA_ALLOCATOR()
> invocations if it's included twice?

I wanted to make registering of entries in the array as easy as possible.
The idea is that allocator authors just add a single line to the file and
do not have to worry about the rest.  To put it in other words, add a line
and do not worry about how it works. ;)

>> +
>> +#  undef CMA_ALLOCATOR
>> +#else
>> +#  define __CMA_ALLOCATORS_H
>> +
>> +/* Function prototypes */
>> +#  ifndef __LINUX_CMA_ALLOCATORS_H
>> +#    define __LINUX_CMA_ALLOCATORS_H
>> +#    define CMA_ALLOCATOR(name, infix)				\
>> +	extern int cma_ ## infix ## _init(struct cma_region *);		\
>> +	extern void cma_ ## infix ## _cleanup(struct cma_region *);	\
>> +	extern struct cma_chunk *					\
>> +	cma_ ## infix ## _alloc(struct cma_region *,			\
>> +			      unsigned long, unsigned long);		\
>> +	extern void cma_ ## infix ## _free(struct cma_chunk *);
>> +#    include "cma-allocators.h"
>> +#  endif
>> +
>> +/* The cma_allocators array */
>> +#  ifdef CMA_ALLOCATORS_LIST
>> +#    define CMA_ALLOCATOR(_name, infix) {		\
>> +		.name    = _name,			\
>> +		.init    = cma_ ## infix ## _init,	\
>> +		.cleanup = cma_ ## infix ## _cleanup,	\
>> +		.alloc   = cma_ ## infix ## _alloc,	\
>> +		.free    = cma_ ## infix ## _free,	\
>> +	},
>
> Different implementations of the macro in different places in the same
> kernel can cause confusion.  To what end?  As I said before, a simple
> registration function called by the allocators would eliminate the need for
> this kind of stuff.

Yes, it would, expect at the moment, a registration function may be not
the best option...  I'm still trying to think how it could work (dynamic
allocators that is).

>> diff --git a/mm/cma-best-fit.c b/mm/cma-best-fit.c
>
> [...]
>
>> +int cma_bf_init(struct cma_region *reg)
>> +{
>> +	struct cma_bf_private *prv;
>> +	struct cma_bf_item *item;
>> +
>> +	prv = kzalloc(sizeof *prv, GFP_NOWAIT);
>> +	if (unlikely(!prv))
>> +		return -ENOMEM;
>
> I'll say this once, but the comment applies all over this code: I hate it
> when people go nuts with likely/unlikely().  This is an initialization
> function, we don't actually care if the branch prediction gets it wrong.
> Classic premature optimization.  The truth of the matter is that
> *programmers* often get this wrong.  Have you profiled all these
> ocurrences?  Maybe it would be better to take them out?

My rule of thumbs is that errors are unlikely and I use that consistently
among all of my code.  The other rational is that we want error-free code
to work as fast as possible letting the error-recovery path be slower.

>> +struct cma_chunk *cma_bf_alloc(struct cma_region *reg,
>> +			       unsigned long size, unsigned long alignment)
>> +{
>> +	struct cma_bf_private *prv = reg->private_data;
>> +	struct rb_node *node = prv->by_size_root.rb_node;
>> +	struct cma_bf_item *item = NULL;
>> +	unsigned long start, end;
>> +
>> +	/* First first item that is large enough */
>> +	while (node) {
>> +		struct cma_bf_item *i =
>> +			rb_entry(node, struct cma_bf_item, by_size);
>
> This is about where I start to wonder about locking.  I take it that the
> allocator code is relying upon locking at the CMA level to prevent
> concurrent calls?  If so, it would be good to document what guarantees the
> CMA level provides.

The cma-int.h says:

> /**
> * struct cma_allocator - a CMA allocator.
[...]
> * @alloc:	Allocates a chunk of memory of given size in bytes and
> * 		with given alignment.  Alignment is a power of
> * 		two (thus non-zero) and callback does not need to check it.
> * 		May also assume that it is the only call that uses given
> * 		region (ie. access to the region is synchronised with
> * 		a mutex).  This has to allocate the chunk object (it may be
> * 		contained in a bigger structure with allocator-specific data.
> * 		May sleep.
> * @free:	Frees allocated chunk.  May also assume that it is the only
> * 		call that uses given region.  This has to kfree() the chunk
> * 		object as well.  May sleep.
> */

Do you think that it needs more clarification?  In more places?  If so where?

>> +/************************* Basic Tree Manipulation *************************/
>> +
>> +#define __CMA_BF_HOLE_INSERT(root, node, field) ({			\
>> +	bool equal = false;						\
>> +	struct rb_node **link = &(root).rb_node, *parent = NULL;	\
>> +	const unsigned long value = item->field;			\
>> +	while (*link) {							\
>> +		struct cma_bf_item *i;					\
>> +		parent = *link;						\
>> +		i = rb_entry(parent, struct cma_bf_item, node);		\
>> +		link = value <= i->field				\
>> +			? &parent->rb_left				\
>> +			: &parent->rb_right;				\
>> +		equal = equal || value == i->field;			\
>> +	}								\
>> +	rb_link_node(&item->node, parent, link);			\
>> +	rb_insert_color(&item->node, &root);				\
>> +	equal;								\
>> +})
>
> Is there a reason why this is a macro?  The code might be more readable if
> you just wrote out the two versions that you need.

I didn't want to duplicate the code but will fix per request.

>> diff --git a/mm/cma.c b/mm/cma.c
>> new file mode 100644
>> index 0000000..6a0942f
>> --- /dev/null
>> +++ b/mm/cma.c
>
> [...]
>
>> +static const char *__must_check
>> +__cma_where_from(const struct device *dev, const char *kind)
>> +{
>> +	/*
>> +	 * This function matches the pattern given at command line
>> +	 * parameter agains given device name and kind.  Kind may be
>> +	 * of course NULL or an emtpy string.
>> +	 */
>> +
>> +	const char **spec, *name;
>> +	int name_matched = 0;
>> +
>> +	/* Make sure dev was given and has name */
>> +	if (unlikely(!dev))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	name = dev_name(dev);
>> +	if (WARN_ON(!name || !*name))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	/* kind == NULL is just like an empty kind */
>> +	if (!kind)
>> +		kind = "";
>> +
>> +	/*
>> +	 * Now we go throught the cma_map array.  It is an array of
>> +	 * pointers to chars (ie. array of strings) so in each
>> +	 * iteration we take each of the string.  The strings is
>> +	 * basically what user provided at the command line separated
>> +	 * by semicolons.
>> +	 */
>> +	for (spec = cma_map; *spec; ++spec) {
>> +		/*
>> +		 * This macro tries to match pattern pointed by s to
>> +		 * @what.  If, while reading the spec, we ecnounter
>> +		 * comma it means that the pattern does not match and
>> +		 * we need to start over with another spec.  If there
>> +		 * is a character that does not match, we neet to try
>> +		 * again looking if there is another spec.
>> +		 */
>> +#define TRY_MATCH(what) do {				\
>> +		const char *c = what;			\
>> +		for (; *s != '*' && *c; ++c, ++s)	\
>> +			if (*s == ',')			\
>> +				goto again;		\
>> +			else if (*s != '?' && *c != *s)	\
>> +				goto again_maybe;	\
>> +		if (*s == '*')				\
>> +			++s;				\
>> +	} while (0)

> This kind of thing rarely contributes to the readability or maintainability
> of the code.  Is it really necessary?  Or (as asked before) is all this
> functionality really necessary?

Removed the macro.  As of whether the functionality is needed, as explained
above, I believe it is.

> One other comment: it might be nice if drivers could provide allocation
> regions of their own.  The viafb driver, for example, really needs an
> allocator to hand out chunks of framebuffer memory - including large chunks
> for things like video frames.  If that driver could hand responsibility
> for that over to CMA, it could eliminate the need for yet another
> driver-quality memory manager.

Are we talking about viafb having access to some “magic” memory known only for
itself?  If so, it should be fairly easy to let drivers add their own, already
reserved regions.  As a matter of fact, the region could be completely unnamed
and private for the device, ie:

	... device reserves some memory ...
	struct cma_region *reg = kmalloc(sizeof *reg, GFP_KERNEL);

	reg->size  = ... size ...;
	reg->start = ... start ...;
	reg->alloc_name = ... allocator name or NULL ...;

	ret = cma_region_init(reg);
	if (ret)
		/* Failed to initialise */
		return ret;

and then later, when allocating:

	addr = cma_alloc_from_region(reg, ... size ..., ... alignment ...);

and when unloading:

	cma_region_cleanup(reg);

what do you think?

On Wed, 21 Jul 2010 02:12:39 +0200, Jonathan Corbet <corbet@lwn.net> wrote:
> One other thing occurred to me as I was thinking about this...

>> +    There are four calls provided by the CMA framework to devices.  To
>> +    allocate a chunk of memory cma_alloc() function needs to be used:
>> +
>> +            unsigned long cma_alloc(const struct device *dev,
>> +                                    const char *kind,
>> +                                    unsigned long size,
>> +                                    unsigned long alignment);
>
> The purpose behind this interface, I believe, is pretty much always
> going to be to allocate memory for DMA buffers.  Given that, might it
> make more sense to integrate the API with the current DMA mapping API?
> Then the allocation function could stop messing around with long values
> and, instead, just hand back a void * kernel-space pointer and a
> dma_addr_t to hand to the device.  That would make life a little easier
> in driverland...

In our use cases mapping the region was never needed.  It is mostly used
with V4L which handles mapping, cache coherency, etc.  It also is outside
of the scope of the CMA framework.

As of changing the type to dma_addr_t it may be a good idea, I'm going to
change that.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 10:16         ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 10:16 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

Hello Jonathan,

Thank you for review and comments!

> On Tue, 20 Jul 2010 17:51:25 +0200 Michal Nazarewicz wrote:
>> The Contiguous Memory Allocator framework is a set of APIs for
>> allocating physically contiguous chunks of memory.
>>
>> Various chips require contiguous blocks of memory to operate.  Those
>> chips include devices such as cameras, hardware video decoders and
>> encoders, etc.

On Tue, 20 Jul 2010 22:52:38 +0200, Jonathan Corbet <corbet@lwn.net> wrote:
> Certainly this is something that many of us have run into; a general
> solution would make life easier. I do wonder if this implementation
> isn't a bit more complex than is really needed, though.
>
>> diff --git a/Documentation/cma.txt b/Documentation/cma.txt
>
> "cma.txt" is not a name that will say much to people browsing the
> directory, especially since you didn't add a 00-INDEX entry for it.  Maybe
> something like contiguous-memory.txt would be better?

Will fix.

>> +    For instance, let say that there are two memory banks and for
>> +    performance reasons a device uses buffers in both of them.  In
>> +    such case, the device driver would define two kinds and use it for
>> +    different buffers.  Command line arguments could look as follows:
>> +
>> +            cma=a=32M@0,b=32M@512M cma_map=foo/a=a;foo/b=b

> About the time I get here I really have to wonder if we *really* need all
> of this.  A rather large portion of the entire patch is parsing code.  Are
> there real-world use cases for this kind of functionality?

As of "cma" parameter: we encountered a system where all of the information
(expect for allocator) that it is possible to specify is needed.

1. The size is needed from obvious reasons.
2. Our platform have two banks of memory and one of the devices needs
     some buffers to be allocated in one bank and other buffers in the
     other bank.  The start address that can be specified let us
     specify regions in both banks.
3. At least one of our drivers needs a buffer for firmware that is aligned
     to 128K (if recall correctly).  Due to other, unrelated reasons it needs
     to be in a region on its own so we need to reserve a region aligned
     at least to 128K.
4. As of allocator, we use only best-fit but I believe that letting user
     specify desired allocator is desirable.

As of "cma_map" parameter: It is needed because different devices are
assigned to different regions.  Also, at least one of our drivers uses
three kinds of memory (bank 1, bank 2 and firmware) and hence we also
need the optional kind.

The remaining question is whether we need the pattern matching (like '?'
and '*').  I agree that the matching code may be not the most beautiful
piece of software but I believe it may be useful.  In particular letting
user write something like the following may be nice:

    cma_map=foo-dev=foo-region;*/*=bar-region

This lets one say that foo-dev should use its own region and all other
devices should share the other region.  Similarly, if at one point the driver
I described above (that uses 3 kinds) were to receive a firmware upgrade or
be installed on different platform and regions in two banks would no longer
be necessary the command line could be set to:

    cma_map=baz-dev/firmware=baz-firmware;baz-dev/*=baz-region

and everything would start working fine without the need to change the
driver itself -- it would be completely unaware of the change.

Generally I see that the asterisk may be quite useful.

>> +    And whenever the driver allocated the memory it would specify the
>> +    kind of memory:
>> +
>> +            buffer1 = cma_alloc(dev, 1 << 20, 0, "a");
>> +            buffer2 = cma_alloc(dev, 1 << 20, 0, "b");

> This example, above, is not consistent with:

>> +
>> +    There are four calls provided by the CMA framework to devices.  To
>> +    allocate a chunk of memory cma_alloc() function needs to be used:
>> +
>> +            unsigned long cma_alloc(const struct device *dev,
>> +                                    const char *kind,
>> +                                    unsigned long size,
>> +                                    unsigned long alignment);

> It looks like the API changed and the example didn't get updated?

Yep, will fix.

>> +
>> +    If required, device may specify alignment that the chunk need to
>> +    satisfy.  It have to be a power of two or zero.  The chunks are
>> +    always aligned at least to a page.
>
> So is the alignment specified in bytes or pages?

In bytes, will fix.

>> +    Allocated chunk is freed via a cma_put() function:
>> +
>> +            int cma_put(unsigned long addr);
>> +
>> +    It takes physical address of the chunk as an argument and
>> +    decreases it's reference counter.  If the counter reaches zero the
>> +    chunk is freed.  Most of the time users do not need to think about
>> +    reference counter and simply use the cma_put() as a free call.
>
> A return value from a put() function is mildly different;

Not sure what you mean.  cma_put() returns either -ENOENT if there is no
chunk with given address or whatever kref_put() returned.

> when would that value be useful?

I dunno.  I'm just returning what kref_put() returns.

>
>> +    If one, however, were to share a chunk with others built in
>> +    reference counter may turn out to be handy.  To increment it, one
>> +    needs to use cma_get() function:
>> +
>> +            int cma_put(unsigned long addr);
>
> Somebody's been cut-n-pasting a little too quickly...:)

Will fix.

>> +    Creating an allocator for CMA needs four functions to be
>> +    implemented.
>> +
>> +
>> +    The first two are used to initialise an allocator far given driver
>> +    and clean up afterwards:
>> +
>> +            int  cma_foo_init(struct cma_region *reg);
>> +            void cma_foo_done(struct cma_region *reg);
>> +
>> +    The first is called during platform initialisation.  The
>> +    cma_region structure has saved starting address of the region as
>> +    well as its size.  It has also alloc_params field with optional
>> +    parameters passed via command line (allocator is free to interpret
>> +    those in any way it pleases).  Any data that allocate associated
>> +    with the region can be saved in private_data field.
>> +
>> +    The second call cleans up and frees all resources the allocator
>> +    has allocated for the region.  The function can assume that all
>> +    chunks allocated form this region have been freed thus the whole
>> +    region is free.
>> +
>> +
>> +    The two other calls are used for allocating and freeing chunks.
>> +    They are:
>> +
>> +            struct cma_chunk *cma_foo_alloc(struct cma_region *reg,
>> +                                            unsigned long size,
>> +                                            unsigned long alignment);
>> +            void cma_foo_free(struct cma_chunk *chunk);
>> +
>> +    As names imply the first allocates a chunk and the other frees
>> +    a chunk of memory.  It also manages a cma_chunk object
>> +    representing the chunk in physical memory.
>> +
>> +    Either of those function can assume that they are the only thread
>> +    accessing the region.  Therefore, allocator does not need to worry
>> +    about concurrency.
>> +
>> +
>> +    When allocator is ready, all that is left is register it by adding
>> +    a line to "mm/cma-allocators.h" file:
>> +
>> +            CMA_ALLOCATOR("foo", foo)
>> +
>> +    The first "foo" is a named that will be available to use with
>> +    command line argument.  The second is the part used in function
>> +    names.

> This is a bit of an awkward way to register new allocators.  Why not just
> have new allocators fill in an operations structure can call something like
> cma_allocator_register() at initialization time?  That would let people
> write allocators as modules and would eliminate the need to add allocators
> to a central include file.  It would also get rid of some ugly and (IMHO)
> unnecessary preprocessor hackery.

At the moment the list of allocators has to be available early during boot up.
This is because regions are initialised (that is allocators are attached to
regions) from initcall (subsys_initcall to be precise).  This means
allocators cannot be modules (ie. they cannot be dynamically loaded) but
only compiled in.  Because of all those, I decided that creating an array with
all allocators would be, maybe not very beautiful, but a good solution.

Even if I were to provide a “cma_register_allocator()” call it would have to be
called before subsys initcalls and as such it would be of little usefulness I
believe.

I agree that it would be nice to be able to have allocators loaded dynamically
but it is not possible as of yet.

>> +** Future work
>> +
>> +    In the future, implementation of mechanisms that would allow the
>> +    free space inside the regions to be used as page cache, filesystem
>> +    buffers or swap devices is planned.  With such mechanisms, the
>> +    memory would not be wasted when not used.
>
> Ouch.  You'd need to be able to evacuate that space again when it's needed,
> or the whole point of CMA has been lost.  Once again, is it worth the
> complexity?

I believe it is.  All of the regions could well take like 64M or so.  If most
of the times the device drivers would not be used the space would be wasted.
If, instead, it could be used for some read-only data or other data that is
easy to remove from memory the whole system could benefit.

Still, this is a future work so for now it's in the dominion of dreams and
good-night stories. ;)  Bottom line is, we will think about it when the time
will come.

>> diff --git a/include/linux/cma-int.h b/include/linux/cma-int.h
>> new file mode 100644
>> index 0000000..b588e9b
>> --- /dev/null
>> +++ b/include/linux/cma-int.h
>
>> +struct cma_region {
>> +	const char *name;
>> +	unsigned long start;
>> +	unsigned long size, free_space;
>> +	unsigned long alignment;
>> +
>> +	struct cma_allocator *alloc;
>> +	const char *alloc_name;
>> +	const char *alloc_params;
>> +	void *private_data;
>> +
>> +	unsigned users;
>> +	/*
>> +	 * Protects the "users" and "free_space" fields and any calls
>> +	 * to allocator on this region thus guarantees only one call
>> +	 * to allocator will operate on this region..
>> +	 */
>> +	struct mutex mutex;
>> +};

> The use of mutexes means that allocation/free functions cannot be called
> from atomic context.  Perhaps that will never be a problem, but it might
> also be possible to use spinlocks instead?

Mutexes should not be a problem.  In all use cases that we came up with,
allocation and freeing was done from user context when some operation
is initialised.  User launches an application to record video with a
camera or launches a video player and at this moment buffers are
initialised.  We don't see any use case where CMA would be used from
an interrupt or some such.

At the same time, the use of spinlocks would limit allocators (which is
probably a minor issue) but what's more it would limit our possibility to
use unused space of the regions for page cache/buffers/swap/you-name-it.

In general, I believe that requiring that cma_alloc()/cma_put() cannot be
called from atomic context have more benefits then drawbacks (the latter
could check if it is called from atomic context and if so let a worker do
the actual freeing if there would be cases where it would be nice to use
cma_put() in atomic context).

>> diff --git a/mm/cma-allocators.h b/mm/cma-allocators.h
>> new file mode 100644
>> index 0000000..564f705
>> --- /dev/null
>> +++ b/mm/cma-allocators.h
>> @@ -0,0 +1,42 @@
>> +#ifdef __CMA_ALLOCATORS_H
>> +
>> +/* List all existing allocators here using CMA_ALLOCATOR macro. */
>> +
>> +#ifdef CONFIG_CMA_BEST_FIT
>> +CMA_ALLOCATOR("bf", bf)
>> +#endif
>
> This is the kind of thing I think it would be nice to avoid; is there any
> real reason why allocators need to be put into this central file?
>
> This is some weird ifdef stuff as well; it processes the CMA_ALLOCATOR()
> invocations if it's included twice?

I wanted to make registering of entries in the array as easy as possible.
The idea is that allocator authors just add a single line to the file and
do not have to worry about the rest.  To put it in other words, add a line
and do not worry about how it works. ;)

>> +
>> +#  undef CMA_ALLOCATOR
>> +#else
>> +#  define __CMA_ALLOCATORS_H
>> +
>> +/* Function prototypes */
>> +#  ifndef __LINUX_CMA_ALLOCATORS_H
>> +#    define __LINUX_CMA_ALLOCATORS_H
>> +#    define CMA_ALLOCATOR(name, infix)				\
>> +	extern int cma_ ## infix ## _init(struct cma_region *);		\
>> +	extern void cma_ ## infix ## _cleanup(struct cma_region *);	\
>> +	extern struct cma_chunk *					\
>> +	cma_ ## infix ## _alloc(struct cma_region *,			\
>> +			      unsigned long, unsigned long);		\
>> +	extern void cma_ ## infix ## _free(struct cma_chunk *);
>> +#    include "cma-allocators.h"
>> +#  endif
>> +
>> +/* The cma_allocators array */
>> +#  ifdef CMA_ALLOCATORS_LIST
>> +#    define CMA_ALLOCATOR(_name, infix) {		\
>> +		.name    = _name,			\
>> +		.init    = cma_ ## infix ## _init,	\
>> +		.cleanup = cma_ ## infix ## _cleanup,	\
>> +		.alloc   = cma_ ## infix ## _alloc,	\
>> +		.free    = cma_ ## infix ## _free,	\
>> +	},
>
> Different implementations of the macro in different places in the same
> kernel can cause confusion.  To what end?  As I said before, a simple
> registration function called by the allocators would eliminate the need for
> this kind of stuff.

Yes, it would, expect at the moment, a registration function may be not
the best option...  I'm still trying to think how it could work (dynamic
allocators that is).

>> diff --git a/mm/cma-best-fit.c b/mm/cma-best-fit.c
>
> [...]
>
>> +int cma_bf_init(struct cma_region *reg)
>> +{
>> +	struct cma_bf_private *prv;
>> +	struct cma_bf_item *item;
>> +
>> +	prv = kzalloc(sizeof *prv, GFP_NOWAIT);
>> +	if (unlikely(!prv))
>> +		return -ENOMEM;
>
> I'll say this once, but the comment applies all over this code: I hate it
> when people go nuts with likely/unlikely().  This is an initialization
> function, we don't actually care if the branch prediction gets it wrong.
> Classic premature optimization.  The truth of the matter is that
> *programmers* often get this wrong.  Have you profiled all these
> ocurrences?  Maybe it would be better to take them out?

My rule of thumbs is that errors are unlikely and I use that consistently
among all of my code.  The other rational is that we want error-free code
to work as fast as possible letting the error-recovery path be slower.

>> +struct cma_chunk *cma_bf_alloc(struct cma_region *reg,
>> +			       unsigned long size, unsigned long alignment)
>> +{
>> +	struct cma_bf_private *prv = reg->private_data;
>> +	struct rb_node *node = prv->by_size_root.rb_node;
>> +	struct cma_bf_item *item = NULL;
>> +	unsigned long start, end;
>> +
>> +	/* First first item that is large enough */
>> +	while (node) {
>> +		struct cma_bf_item *i =
>> +			rb_entry(node, struct cma_bf_item, by_size);
>
> This is about where I start to wonder about locking.  I take it that the
> allocator code is relying upon locking at the CMA level to prevent
> concurrent calls?  If so, it would be good to document what guarantees the
> CMA level provides.

The cma-int.h says:

> /**
> * struct cma_allocator - a CMA allocator.
[...]
> * @alloc:	Allocates a chunk of memory of given size in bytes and
> * 		with given alignment.  Alignment is a power of
> * 		two (thus non-zero) and callback does not need to check it.
> * 		May also assume that it is the only call that uses given
> * 		region (ie. access to the region is synchronised with
> * 		a mutex).  This has to allocate the chunk object (it may be
> * 		contained in a bigger structure with allocator-specific data.
> * 		May sleep.
> * @free:	Frees allocated chunk.  May also assume that it is the only
> * 		call that uses given region.  This has to kfree() the chunk
> * 		object as well.  May sleep.
> */

Do you think that it needs more clarification?  In more places?  If so where?

>> +/************************* Basic Tree Manipulation *************************/
>> +
>> +#define __CMA_BF_HOLE_INSERT(root, node, field) ({			\
>> +	bool equal = false;						\
>> +	struct rb_node **link = &(root).rb_node, *parent = NULL;	\
>> +	const unsigned long value = item->field;			\
>> +	while (*link) {							\
>> +		struct cma_bf_item *i;					\
>> +		parent = *link;						\
>> +		i = rb_entry(parent, struct cma_bf_item, node);		\
>> +		link = value <= i->field				\
>> +			? &parent->rb_left				\
>> +			: &parent->rb_right;				\
>> +		equal = equal || value == i->field;			\
>> +	}								\
>> +	rb_link_node(&item->node, parent, link);			\
>> +	rb_insert_color(&item->node, &root);				\
>> +	equal;								\
>> +})
>
> Is there a reason why this is a macro?  The code might be more readable if
> you just wrote out the two versions that you need.

I didn't want to duplicate the code but will fix per request.

>> diff --git a/mm/cma.c b/mm/cma.c
>> new file mode 100644
>> index 0000000..6a0942f
>> --- /dev/null
>> +++ b/mm/cma.c
>
> [...]
>
>> +static const char *__must_check
>> +__cma_where_from(const struct device *dev, const char *kind)
>> +{
>> +	/*
>> +	 * This function matches the pattern given at command line
>> +	 * parameter agains given device name and kind.  Kind may be
>> +	 * of course NULL or an emtpy string.
>> +	 */
>> +
>> +	const char **spec, *name;
>> +	int name_matched = 0;
>> +
>> +	/* Make sure dev was given and has name */
>> +	if (unlikely(!dev))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	name = dev_name(dev);
>> +	if (WARN_ON(!name || !*name))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	/* kind == NULL is just like an empty kind */
>> +	if (!kind)
>> +		kind = "";
>> +
>> +	/*
>> +	 * Now we go throught the cma_map array.  It is an array of
>> +	 * pointers to chars (ie. array of strings) so in each
>> +	 * iteration we take each of the string.  The strings is
>> +	 * basically what user provided at the command line separated
>> +	 * by semicolons.
>> +	 */
>> +	for (spec = cma_map; *spec; ++spec) {
>> +		/*
>> +		 * This macro tries to match pattern pointed by s to
>> +		 * @what.  If, while reading the spec, we ecnounter
>> +		 * comma it means that the pattern does not match and
>> +		 * we need to start over with another spec.  If there
>> +		 * is a character that does not match, we neet to try
>> +		 * again looking if there is another spec.
>> +		 */
>> +#define TRY_MATCH(what) do {				\
>> +		const char *c = what;			\
>> +		for (; *s != '*' && *c; ++c, ++s)	\
>> +			if (*s == ',')			\
>> +				goto again;		\
>> +			else if (*s != '?' && *c != *s)	\
>> +				goto again_maybe;	\
>> +		if (*s == '*')				\
>> +			++s;				\
>> +	} while (0)

> This kind of thing rarely contributes to the readability or maintainability
> of the code.  Is it really necessary?  Or (as asked before) is all this
> functionality really necessary?

Removed the macro.  As of whether the functionality is needed, as explained
above, I believe it is.

> One other comment: it might be nice if drivers could provide allocation
> regions of their own.  The viafb driver, for example, really needs an
> allocator to hand out chunks of framebuffer memory - including large chunks
> for things like video frames.  If that driver could hand responsibility
> for that over to CMA, it could eliminate the need for yet another
> driver-quality memory manager.

Are we talking about viafb having access to some “magic” memory known only for
itself?  If so, it should be fairly easy to let drivers add their own, already
reserved regions.  As a matter of fact, the region could be completely unnamed
and private for the device, ie:

	... device reserves some memory ...
	struct cma_region *reg = kmalloc(sizeof *reg, GFP_KERNEL);

	reg->size  = ... size ...;
	reg->start = ... start ...;
	reg->alloc_name = ... allocator name or NULL ...;

	ret = cma_region_init(reg);
	if (ret)
		/* Failed to initialise */
		return ret;

and then later, when allocating:

	addr = cma_alloc_from_region(reg, ... size ..., ... alignment ...);

and when unloading:

	cma_region_cleanup(reg);

what do you think?

On Wed, 21 Jul 2010 02:12:39 +0200, Jonathan Corbet <corbet@lwn.net> wrote:
> One other thing occurred to me as I was thinking about this...

>> +    There are four calls provided by the CMA framework to devices.  To
>> +    allocate a chunk of memory cma_alloc() function needs to be used:
>> +
>> +            unsigned long cma_alloc(const struct device *dev,
>> +                                    const char *kind,
>> +                                    unsigned long size,
>> +                                    unsigned long alignment);
>
> The purpose behind this interface, I believe, is pretty much always
> going to be to allocate memory for DMA buffers.  Given that, might it
> make more sense to integrate the API with the current DMA mapping API?
> Then the allocation function could stop messing around with long values
> and, instead, just hand back a void * kernel-space pointer and a
> dma_addr_t to hand to the device.  That would make life a little easier
> in driverland...

In our use cases mapping the region was never needed.  It is mostly used
with V4L which handles mapping, cache coherency, etc.  It also is outside
of the scope of the CMA framework.

As of changing the type to dma_addr_t it may be a good idea, I'm going to
change that.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 19:38           ` Daniel Walker
@ 2010-07-21 12:01             ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 12:01 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 20 Jul 2010 21:38:18 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Tue, 2010-07-20 at 21:14 +0200, Michał Nazarewicz wrote:
>> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>>
>> > On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
>> >> +** Use cases
>> >> +
>> >> +    Lets analyse some imaginary system that uses the CMA to see how
>> >> +    the framework can be used and configured.
>> >> +
>> >> +
>> >> +    We have a platform with a hardware video decoder and a camera
>> >> each
>> >> +    needing 20 MiB of memory in worst case.  Our system is written in
>> >> +    such a way though that the two devices are never used at the same
>> >> +    time and memory for them may be shared.  In such a system the
>> >> +    following two command line arguments would be used:
>> >> +
>> >> +        cma=r=20M cma_map=video,camera=r
>> >
>> > This seems inelegant to me.. It seems like these should be connected
>> > with the drivers themselves vs. doing it on the command like for
>> > everything. You could have the video driver declare it needs 20megs, and
>> > the the camera does the same but both indicate it's shared ..
>> >
>> > If you have this disconnected from the drivers it will just cause
>> > confusion, since few will know what these parameters should be for a
>> > given driver set. It needs to be embedded in the kernel.
>>
>> I see your point but the problem is that devices drivers don't know the
>> rest of the system neither they know what kind of use cases the system
>> should support.
>>
>>
>> Lets say, we have a camera, a JPEG encoder, a video decoder and
>> scaler (ie. devices that scales raw image).  We want to support the
>> following 3 use cases:
>>
>> 1. Camera's output is scaled and displayed in real-time.
>> 2. Single frame is taken from camera and saved as JPEG image.
>> 3. A video file is decoded, scaled and displayed.
>>
>> What is apparent is that camera and video decoder are never running
>> at the same time.  The same situation is with JPEG encoder and scaler.
>>  From this knowledge we can construct the following:
>>
>>    cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b
>
> It should be implicit tho. If the video driver isn't using the memory
> then it should tell your framework that the memory is not used. That way
> something else can use it.

What you are asking for is:

	cma=a=100M cma_map=*/*=a

All devices will share the same region so that "if the video driver isn't
using the memory" then "something else can use it". (please excuse me quoting
you, it was stronger then me ;) ).

Driver has to little information to say whether it really stopped using
memory.  Maybe the next call will be to allocate buffers for frames and
initialise the chip?  Sure, some “good enough” defaults can be provided
(and the framework allows that) but still platform architect might need
more power.

> (btw, these strings your creating yikes, talk about confusing ..)

They are not that scary really.  Let's look at cma:

	a=10M;b=10M

Split it on semicolon:

	a=10M
	b=10M

and you see that it defines two regions (a and b) 10M each.

As of cma_map:

	camera,video=a;jpeg,scaler=b

Again split it on semicolon:

	camera,video=a
	jpeg,scaler=b

Now, substitute equal sign by "use(s) region(s)":

	camera,video	use(s) region(s):	a
	jpeg,scaler	use(s) region(s):	b

No black magic here. ;)

>> One of the purposes of the CMA framework is to make it let device
>> drivers completely forget about the memory management and enjoy
>> a simple API.
>
> The driver, and it's maintainer, are really the best people to know how
> much memory they need and when it's used/unused. You don't really want
> to architect them out.

This might be true if there is only one device but even then it's not
always the case.  If many devices need physically-contiguous memory
there is no way for them to communicate and share memory.  For best
performance someone must look at them and say who gets what.

Still, with updated version it will be possible for drivers to use
private regions.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 12:01             ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 12:01 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Tue, 20 Jul 2010 21:38:18 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Tue, 2010-07-20 at 21:14 +0200, Michał Nazarewicz wrote:
>> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>>
>> > On Tue, 2010-07-20 at 17:51 +0200, Michal Nazarewicz wrote:
>> >> +** Use cases
>> >> +
>> >> +    Lets analyse some imaginary system that uses the CMA to see how
>> >> +    the framework can be used and configured.
>> >> +
>> >> +
>> >> +    We have a platform with a hardware video decoder and a camera
>> >> each
>> >> +    needing 20 MiB of memory in worst case.  Our system is written in
>> >> +    such a way though that the two devices are never used at the same
>> >> +    time and memory for them may be shared.  In such a system the
>> >> +    following two command line arguments would be used:
>> >> +
>> >> +        cma=r=20M cma_map=video,camera=r
>> >
>> > This seems inelegant to me.. It seems like these should be connected
>> > with the drivers themselves vs. doing it on the command like for
>> > everything. You could have the video driver declare it needs 20megs, and
>> > the the camera does the same but both indicate it's shared ..
>> >
>> > If you have this disconnected from the drivers it will just cause
>> > confusion, since few will know what these parameters should be for a
>> > given driver set. It needs to be embedded in the kernel.
>>
>> I see your point but the problem is that devices drivers don't know the
>> rest of the system neither they know what kind of use cases the system
>> should support.
>>
>>
>> Lets say, we have a camera, a JPEG encoder, a video decoder and
>> scaler (ie. devices that scales raw image).  We want to support the
>> following 3 use cases:
>>
>> 1. Camera's output is scaled and displayed in real-time.
>> 2. Single frame is taken from camera and saved as JPEG image.
>> 3. A video file is decoded, scaled and displayed.
>>
>> What is apparent is that camera and video decoder are never running
>> at the same time.  The same situation is with JPEG encoder and scaler.
>>  From this knowledge we can construct the following:
>>
>>    cma=a=10M;b=10M cma_map=camera,video=a;jpeg,scaler=b
>
> It should be implicit tho. If the video driver isn't using the memory
> then it should tell your framework that the memory is not used. That way
> something else can use it.

What you are asking for is:

	cma=a=100M cma_map=*/*=a

All devices will share the same region so that "if the video driver isn't
using the memory" then "something else can use it". (please excuse me quoting
you, it was stronger then me ;) ).

Driver has to little information to say whether it really stopped using
memory.  Maybe the next call will be to allocate buffers for frames and
initialise the chip?  Sure, some “good enough” defaults can be provided
(and the framework allows that) but still platform architect might need
more power.

> (btw, these strings your creating yikes, talk about confusing ..)

They are not that scary really.  Let's look at cma:

	a=10M;b=10M

Split it on semicolon:

	a=10M
	b=10M

and you see that it defines two regions (a and b) 10M each.

As of cma_map:

	camera,video=a;jpeg,scaler=b

Again split it on semicolon:

	camera,video=a
	jpeg,scaler=b

Now, substitute equal sign by "use(s) region(s)":

	camera,video	use(s) region(s):	a
	jpeg,scaler	use(s) region(s):	b

No black magic here. ;)

>> One of the purposes of the CMA framework is to make it let device
>> drivers completely forget about the memory management and enjoy
>> a simple API.
>
> The driver, and it's maintainer, are really the best people to know how
> much memory they need and when it's used/unused. You don't really want
> to architect them out.

This might be true if there is only one device but even then it's not
always the case.  If many devices need physically-contiguous memory
there is no way for them to communicate and share memory.  For best
performance someone must look at them and say who gets what.

Still, with updated version it will be possible for drivers to use
private regions.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 19:14         ` Michał Nazarewicz
@ 2010-07-21 13:52           ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-21 13:52 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Tue, Jul 20, 2010 at 09:14:58PM +0200, Micha?? Nazarewicz wrote:
> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> > If you have this disconnected from the drivers it will just cause
> > confusion, since few will know what these parameters should be for a
> > given driver set. It needs to be embedded in the kernel.

> I see your point but the problem is that devices drivers don't know the
> rest of the system neither they know what kind of use cases the system
> should support.

If this does need to be configured per system would having platform data
of some kind in the kernel not be a sensible a place to do it, or even
having a way of configuring this at runtime (after all, the set of
currently active users may vary depending on the current configuration
and keeping everything allocated all the time may be wasteful)?

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 13:52           ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-21 13:52 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Tue, Jul 20, 2010 at 09:14:58PM +0200, Micha?? Nazarewicz wrote:
> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> > If you have this disconnected from the drivers it will just cause
> > confusion, since few will know what these parameters should be for a
> > given driver set. It needs to be embedded in the kernel.

> I see your point but the problem is that devices drivers don't know the
> rest of the system neither they know what kind of use cases the system
> should support.

If this does need to be configured per system would having platform data
of some kind in the kernel not be a sensible a place to do it, or even
having a way of configuring this at runtime (after all, the set of
currently active users may vary depending on the current configuration
and keeping everything allocated all the time may be wasteful)?

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 13:52           ` Mark Brown
@ 2010-07-21 14:31             ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 14:31 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Tue, Jul 20, 2010 at 09:14:58PM +0200, Micha?? Nazarewicz wrote:
>> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>
>> > If you have this disconnected from the drivers it will just cause
>> > confusion, since few will know what these parameters should be for a
>> > given driver set. It needs to be embedded in the kernel.
>
>> I see your point but the problem is that devices drivers don't know the
>> rest of the system neither they know what kind of use cases the system
>> should support.
>
> If this does need to be configured per system would having platform data
> of some kind in the kernel not be a sensible a place to do it,

The current version (and the next version I'm working on) of the code
has cma_defaults() call.  It is intended to be called from platform
initialisation code to provide defaults.

> or even
> having a way of configuring this at runtime (after all, the set of
> currently active users may vary depending on the current configuration
> and keeping everything allocated all the time may be wasteful)?

I am currently working on making the whole thing more dynamic.  I imagine
the list of regions would stay pretty much the same after kernel has
started (that's because one cannot reliably allocate new big contiguous
memory regions) but it will be possible to change the set of rules, etc.


-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 14:31             ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 14:31 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Tue, Jul 20, 2010 at 09:14:58PM +0200, Micha?? Nazarewicz wrote:
>> On Tue, 20 Jul 2010 20:15:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>
>> > If you have this disconnected from the drivers it will just cause
>> > confusion, since few will know what these parameters should be for a
>> > given driver set. It needs to be embedded in the kernel.
>
>> I see your point but the problem is that devices drivers don't know the
>> rest of the system neither they know what kind of use cases the system
>> should support.
>
> If this does need to be configured per system would having platform data
> of some kind in the kernel not be a sensible a place to do it,

The current version (and the next version I'm working on) of the code
has cma_defaults() call.  It is intended to be called from platform
initialisation code to provide defaults.

> or even
> having a way of configuring this at runtime (after all, the set of
> currently active users may vary depending on the current configuration
> and keeping everything allocated all the time may be wasteful)?

I am currently working on making the whole thing more dynamic.  I imagine
the list of regions would stay pretty much the same after kernel has
started (that's because one cannot reliably allocate new big contiguous
memory regions) but it will be possible to change the set of rules, etc.


-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 12:01             ` Michał Nazarewicz
@ 2010-07-21 17:35               ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 17:35 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 14:01 +0200, Michał Nazarewicz wrote:

> What you are asking for is:
> 
> 	cma=a=100M cma_map=*/*=a
> 
> All devices will share the same region so that "if the video driver isn't
> using the memory" then "something else can use it". (please excuse me quoting
> you, it was stronger then me ;) ).

Ok ..

> Driver has to little information to say whether it really stopped using
> memory.  Maybe the next call will be to allocate buffers for frames and
> initialise the chip?  Sure, some “good enough” defaults can be provided
> (and the framework allows that) but still platform architect might need
> more power.

I think your talking more about optimization .. You can take that into
account ..

> > (btw, these strings your creating yikes, talk about confusing ..)
> 
> They are not that scary really.  Let's look at cma:
> 
> 	a=10M;b=10M
> 
> Split it on semicolon:
> 
> 	a=10M
> 	b=10M
> 
> and you see that it defines two regions (a and b) 10M each.

I think your assuming a lot .. I've never seen the notation before I
wouldn't assuming there's regions or whatever ..

> As of cma_map:
> 
> 	camera,video=a;jpeg,scaler=b
> 
> Again split it on semicolon:
> 
> 	camera,video=a
> 	jpeg,scaler=b
> 
> Now, substitute equal sign by "use(s) region(s)":
> 
> 	camera,video	use(s) region(s):	a
> 	jpeg,scaler	use(s) region(s):	b
> 
> No black magic here. ;)

It way too complicated .. Users (i.e. not programmers) has to use
this ..

> >> One of the purposes of the CMA framework is to make it let device
> >> drivers completely forget about the memory management and enjoy
> >> a simple API.
> >
> > The driver, and it's maintainer, are really the best people to know how
> > much memory they need and when it's used/unused. You don't really want
> > to architect them out.
> 
> This might be true if there is only one device but even then it's not
> always the case.  If many devices need physically-contiguous memory
> there is no way for them to communicate and share memory.  For best
> performance someone must look at them and say who gets what.

How do you think regular memory allocation work? I mean there's many
devices that all need different amounts of memory and they get along.
Yet your saying it's not possible .

Daniel


-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 17:35               ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 17:35 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 14:01 +0200, MichaA? Nazarewicz wrote:

> What you are asking for is:
> 
> 	cma=a=100M cma_map=*/*=a
> 
> All devices will share the same region so that "if the video driver isn't
> using the memory" then "something else can use it". (please excuse me quoting
> you, it was stronger then me ;) ).

Ok ..

> Driver has to little information to say whether it really stopped using
> memory.  Maybe the next call will be to allocate buffers for frames and
> initialise the chip?  Sure, some a??good enougha?? defaults can be provided
> (and the framework allows that) but still platform architect might need
> more power.

I think your talking more about optimization .. You can take that into
account ..

> > (btw, these strings your creating yikes, talk about confusing ..)
> 
> They are not that scary really.  Let's look at cma:
> 
> 	a=10M;b=10M
> 
> Split it on semicolon:
> 
> 	a=10M
> 	b=10M
> 
> and you see that it defines two regions (a and b) 10M each.

I think your assuming a lot .. I've never seen the notation before I
wouldn't assuming there's regions or whatever ..

> As of cma_map:
> 
> 	camera,video=a;jpeg,scaler=b
> 
> Again split it on semicolon:
> 
> 	camera,video=a
> 	jpeg,scaler=b
> 
> Now, substitute equal sign by "use(s) region(s)":
> 
> 	camera,video	use(s) region(s):	a
> 	jpeg,scaler	use(s) region(s):	b
> 
> No black magic here. ;)

It way too complicated .. Users (i.e. not programmers) has to use
this ..

> >> One of the purposes of the CMA framework is to make it let device
> >> drivers completely forget about the memory management and enjoy
> >> a simple API.
> >
> > The driver, and it's maintainer, are really the best people to know how
> > much memory they need and when it's used/unused. You don't really want
> > to architect them out.
> 
> This might be true if there is only one device but even then it's not
> always the case.  If many devices need physically-contiguous memory
> there is no way for them to communicate and share memory.  For best
> performance someone must look at them and say who gets what.

How do you think regular memory allocation work? I mean there's many
devices that all need different amounts of memory and they get along.
Yet your saying it's not possible .

Daniel


-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 17:35               ` Daniel Walker
@ 2010-07-21 18:11                 ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:11 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 19:35:50 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 14:01 +0200, Michał Nazarewicz wrote:
>
>> What you are asking for is:
>>
>> 	cma=a=100M cma_map=*/*=a
>>
>> All devices will share the same region so that "if the video driver isn't
>> using the memory" then "something else can use it". (please excuse me quoting
>> you, it was stronger then me ;) ).
>
> Ok ..
>
>> Driver has to little information to say whether it really stopped using
>> memory.  Maybe the next call will be to allocate buffers for frames and
>> initialise the chip?  Sure, some “good enough” defaults can be provided
>> (and the framework allows that) but still platform architect might need
>> more power.
>
> I think your talking more about optimization .. You can take that into
> account ..

Well, yes, that's one of the points: to minimise amount of memory reserved
for devices.

>> > (btw, these strings your creating yikes, talk about confusing ..)
>>
>> They are not that scary really.  Let's look at cma:
>>
>> 	a=10M;b=10M
>>
>> Split it on semicolon:
>>
>> 	a=10M
>> 	b=10M
>>
>> and you see that it defines two regions (a and b) 10M each.
>
> I think your assuming a lot .. I've never seen the notation before I
> wouldn't assuming there's regions or whatever ..

That's why there is documentation with grammar included. :)

>> As of cma_map:
>>
>> 	camera,video=a;jpeg,scaler=b
>>
>> Again split it on semicolon:
>>
>> 	camera,video=a
>> 	jpeg,scaler=b
>>
>> Now, substitute equal sign by "use(s) region(s)":
>>
>> 	camera,video	use(s) region(s):	a
>> 	jpeg,scaler	use(s) region(s):	b
>>
>> No black magic here. ;)
>
> It way too complicated .. Users (i.e. not programmers) has to use
> this ..

Not really.  This will probably be used mostly on embedded systems
where users don't have much to say as far as hardware included on the
platform is concerned, etc.  Once a phone, tablet, etc. is released
users will have little need for customising those strings.

On desktop computers on the other hand, the whole framework may be
completely useless as devices are more likely to have IO map or scatter/getter
capabilities.

Plus, as I mentioned above, some “good enough” defaults can be provided.

>> >> One of the purposes of the CMA framework is to make it let device
>> >> drivers completely forget about the memory management and enjoy
>> >> a simple API.
>> >
>> > The driver, and it's maintainer, are really the best people to know how
>> > much memory they need and when it's used/unused. You don't really want
>> > to architect them out.
>>
>> This might be true if there is only one device but even then it's not
>> always the case.  If many devices need physically-contiguous memory
>> there is no way for them to communicate and share memory.  For best
>> performance someone must look at them and say who gets what.
>
> How do you think regular memory allocation work? I mean there's many
> devices that all need different amounts of memory and they get along.
> Yet your saying it's not possible .

Regular memory allocation either does not allow you to allocate big chunks
of memory (kmalloc) or uses MMU (vmalloc).  The purpose of CMA is to provide
a framework for allocators of big physically-contiguous chunks of memory.

If a driver needs several KiB it just uses kmalloc() which handles such
allocations just fine.  However, we are taking about 6MiB full-HD frame
or a photo from 5 megapixel camera.

Currently, drivers are developed which create their own mechanism for
allocating such chunks of memory.  Often based on bootmem.  CMA will unify
all those mechanism and let it easier to manage them plus will allow for
many drivers to share regions.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:11                 ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:11 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 19:35:50 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 14:01 +0200, Michał Nazarewicz wrote:
>
>> What you are asking for is:
>>
>> 	cma=a=100M cma_map=*/*=a
>>
>> All devices will share the same region so that "if the video driver isn't
>> using the memory" then "something else can use it". (please excuse me quoting
>> you, it was stronger then me ;) ).
>
> Ok ..
>
>> Driver has to little information to say whether it really stopped using
>> memory.  Maybe the next call will be to allocate buffers for frames and
>> initialise the chip?  Sure, some “good enough” defaults can be provided
>> (and the framework allows that) but still platform architect might need
>> more power.
>
> I think your talking more about optimization .. You can take that into
> account ..

Well, yes, that's one of the points: to minimise amount of memory reserved
for devices.

>> > (btw, these strings your creating yikes, talk about confusing ..)
>>
>> They are not that scary really.  Let's look at cma:
>>
>> 	a=10M;b=10M
>>
>> Split it on semicolon:
>>
>> 	a=10M
>> 	b=10M
>>
>> and you see that it defines two regions (a and b) 10M each.
>
> I think your assuming a lot .. I've never seen the notation before I
> wouldn't assuming there's regions or whatever ..

That's why there is documentation with grammar included. :)

>> As of cma_map:
>>
>> 	camera,video=a;jpeg,scaler=b
>>
>> Again split it on semicolon:
>>
>> 	camera,video=a
>> 	jpeg,scaler=b
>>
>> Now, substitute equal sign by "use(s) region(s)":
>>
>> 	camera,video	use(s) region(s):	a
>> 	jpeg,scaler	use(s) region(s):	b
>>
>> No black magic here. ;)
>
> It way too complicated .. Users (i.e. not programmers) has to use
> this ..

Not really.  This will probably be used mostly on embedded systems
where users don't have much to say as far as hardware included on the
platform is concerned, etc.  Once a phone, tablet, etc. is released
users will have little need for customising those strings.

On desktop computers on the other hand, the whole framework may be
completely useless as devices are more likely to have IO map or scatter/getter
capabilities.

Plus, as I mentioned above, some “good enough” defaults can be provided.

>> >> One of the purposes of the CMA framework is to make it let device
>> >> drivers completely forget about the memory management and enjoy
>> >> a simple API.
>> >
>> > The driver, and it's maintainer, are really the best people to know how
>> > much memory they need and when it's used/unused. You don't really want
>> > to architect them out.
>>
>> This might be true if there is only one device but even then it's not
>> always the case.  If many devices need physically-contiguous memory
>> there is no way for them to communicate and share memory.  For best
>> performance someone must look at them and say who gets what.
>
> How do you think regular memory allocation work? I mean there's many
> devices that all need different amounts of memory and they get along.
> Yet your saying it's not possible .

Regular memory allocation either does not allow you to allocate big chunks
of memory (kmalloc) or uses MMU (vmalloc).  The purpose of CMA is to provide
a framework for allocators of big physically-contiguous chunks of memory.

If a driver needs several KiB it just uses kmalloc() which handles such
allocations just fine.  However, we are taking about 6MiB full-HD frame
or a photo from 5 megapixel camera.

Currently, drivers are developed which create their own mechanism for
allocating such chunks of memory.  Often based on bootmem.  CMA will unify
all those mechanism and let it easier to manage them plus will allow for
many drivers to share regions.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:11                 ` Michał Nazarewicz
@ 2010-07-21 18:19                   ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 18:19 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:

> >> > (btw, these strings your creating yikes, talk about confusing ..)
> >>
> >> They are not that scary really.  Let's look at cma:
> >>
> >> 	a=10M;b=10M
> >>
> >> Split it on semicolon:
> >>
> >> 	a=10M
> >> 	b=10M
> >>
> >> and you see that it defines two regions (a and b) 10M each.
> >
> > I think your assuming a lot .. I've never seen the notation before I
> > wouldn't assuming there's regions or whatever ..
> 
> That's why there is documentation with grammar included. :)
> 
> >> As of cma_map:
> >>
> >> 	camera,video=a;jpeg,scaler=b
> >>
> >> Again split it on semicolon:
> >>
> >> 	camera,video=a
> >> 	jpeg,scaler=b
> >>
> >> Now, substitute equal sign by "use(s) region(s)":
> >>
> >> 	camera,video	use(s) region(s):	a
> >> 	jpeg,scaler	use(s) region(s):	b
> >>
> >> No black magic here. ;)
> >
> > It way too complicated .. Users (i.e. not programmers) has to use
> > this ..
> 
> Not really.  This will probably be used mostly on embedded systems
> where users don't have much to say as far as hardware included on the
> platform is concerned, etc.  Once a phone, tablet, etc. is released
> users will have little need for customising those strings.

You can't assume that user won't want to reflash their own kernel on the
device. Your assuming way too much.

If you assume they do want their own kernel then they would need this
string from someplace. If your right and this wouldn't need to change,
why bother allowing it to be configured at all ?

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:19                   ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 18:19 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 20:11 +0200, MichaA? Nazarewicz wrote:

> >> > (btw, these strings your creating yikes, talk about confusing ..)
> >>
> >> They are not that scary really.  Let's look at cma:
> >>
> >> 	a=10M;b=10M
> >>
> >> Split it on semicolon:
> >>
> >> 	a=10M
> >> 	b=10M
> >>
> >> and you see that it defines two regions (a and b) 10M each.
> >
> > I think your assuming a lot .. I've never seen the notation before I
> > wouldn't assuming there's regions or whatever ..
> 
> That's why there is documentation with grammar included. :)
> 
> >> As of cma_map:
> >>
> >> 	camera,video=a;jpeg,scaler=b
> >>
> >> Again split it on semicolon:
> >>
> >> 	camera,video=a
> >> 	jpeg,scaler=b
> >>
> >> Now, substitute equal sign by "use(s) region(s)":
> >>
> >> 	camera,video	use(s) region(s):	a
> >> 	jpeg,scaler	use(s) region(s):	b
> >>
> >> No black magic here. ;)
> >
> > It way too complicated .. Users (i.e. not programmers) has to use
> > this ..
> 
> Not really.  This will probably be used mostly on embedded systems
> where users don't have much to say as far as hardware included on the
> platform is concerned, etc.  Once a phone, tablet, etc. is released
> users will have little need for customising those strings.

You can't assume that user won't want to reflash their own kernel on the
device. Your assuming way too much.

If you assume they do want their own kernel then they would need this
string from someplace. If your right and this wouldn't need to change,
why bother allowing it to be configured at all ?

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 14:31             ` Michał Nazarewicz
@ 2010-07-21 18:24               ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-21 18:24 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, Jul 21, 2010 at 04:31:35PM +0200, Micha?? Nazarewicz wrote:
> On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> > If this does need to be configured per system would having platform data
> > of some kind in the kernel not be a sensible a place to do it,

> The current version (and the next version I'm working on) of the code
> has cma_defaults() call.  It is intended to be called from platform
> initialisation code to provide defaults.

So the command line is just a way of overriding that?  That makes things
a lot nicer - normally the device would use the defaults and the command
line would be used in development.

> > or even
> > having a way of configuring this at runtime (after all, the set of
> > currently active users may vary depending on the current configuration
> > and keeping everything allocated all the time may be wasteful)?

> I am currently working on making the whole thing more dynamic.  I imagine
> the list of regions would stay pretty much the same after kernel has
> started (that's because one cannot reliably allocate new big contiguous
> memory regions) but it will be possible to change the set of rules, etc.

Yes, I think it will be much easier to be able to grab the regions at
startup but hopefully the allocation within those regions can be made
much more dynamic.  This would render most of the configuration syntax
unneeded.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:24               ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-21 18:24 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, Jul 21, 2010 at 04:31:35PM +0200, Micha?? Nazarewicz wrote:
> On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> > If this does need to be configured per system would having platform data
> > of some kind in the kernel not be a sensible a place to do it,

> The current version (and the next version I'm working on) of the code
> has cma_defaults() call.  It is intended to be called from platform
> initialisation code to provide defaults.

So the command line is just a way of overriding that?  That makes things
a lot nicer - normally the device would use the defaults and the command
line would be used in development.

> > or even
> > having a way of configuring this at runtime (after all, the set of
> > currently active users may vary depending on the current configuration
> > and keeping everything allocated all the time may be wasteful)?

> I am currently working on making the whole thing more dynamic.  I imagine
> the list of regions would stay pretty much the same after kernel has
> started (that's because one cannot reliably allocate new big contiguous
> memory regions) but it will be possible to change the set of rules, etc.

Yes, I think it will be much easier to be able to grab the regions at
startup but hopefully the allocation within those regions can be made
much more dynamic.  This would render most of the configuration syntax
unneeded.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:19                   ` Daniel Walker
@ 2010-07-21 18:38                     ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:38 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

> On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
>> Not really.  This will probably be used mostly on embedded systems
>> where users don't have much to say as far as hardware included on the
>> platform is concerned, etc.  Once a phone, tablet, etc. is released
>> users will have little need for customising those strings.

On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> You can't assume that user won't want to reflash their own kernel on the
> device. Your assuming way too much.

If user is clever enough to reflash a phone she will find the strings
easy especially that they are provided from: (i) bootloader which is
even less likely to be reflashed and if someone do reflash bootloader
she is a guru who'd know how to make the strings; or (ii) platform
defaults which will be available with the rest of the source code
for the platform.

> If you assume they do want their own kernel then they would need this
> string from someplace. If your right and this wouldn't need to change,
> why bother allowing it to be configured at all ?

Imagine a developer who needs to recompile the kernel and reflash the
device each time she wants to change the configuration...  Command line
arguments seems a better option for development.

And the configuration is needed because it is platform-dependent
so it needs to be set for each platform.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:38                     ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:38 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

> On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
>> Not really.  This will probably be used mostly on embedded systems
>> where users don't have much to say as far as hardware included on the
>> platform is concerned, etc.  Once a phone, tablet, etc. is released
>> users will have little need for customising those strings.

On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> You can't assume that user won't want to reflash their own kernel on the
> device. Your assuming way too much.

If user is clever enough to reflash a phone she will find the strings
easy especially that they are provided from: (i) bootloader which is
even less likely to be reflashed and if someone do reflash bootloader
she is a guru who'd know how to make the strings; or (ii) platform
defaults which will be available with the rest of the source code
for the platform.

> If you assume they do want their own kernel then they would need this
> string from someplace. If your right and this wouldn't need to change,
> why bother allowing it to be configured at all ?

Imagine a developer who needs to recompile the kernel and reflash the
device each time she wants to change the configuration...  Command line
arguments seems a better option for development.

And the configuration is needed because it is platform-dependent
so it needs to be set for each platform.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:24               ` Mark Brown
@ 2010-07-21 18:41                 ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:41 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Wed, Jul 21, 2010 at 04:31:35PM +0200, Micha?? Nazarewicz wrote:
>> On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
>
>> > If this does need to be configured per system would having platform data
>> > of some kind in the kernel not be a sensible a place to do it,
>
>> The current version (and the next version I'm working on) of the code
>> has cma_defaults() call.  It is intended to be called from platform
>> initialisation code to provide defaults.
>
> So the command line is just a way of overriding that?  That makes things
> a lot nicer - normally the device would use the defaults and the command
> line would be used in development.

Correct.

>> > or even
>> > having a way of configuring this at runtime (after all, the set of
>> > currently active users may vary depending on the current configuration
>> > and keeping everything allocated all the time may be wasteful)?
>
>> I am currently working on making the whole thing more dynamic.  I imagine
>> the list of regions would stay pretty much the same after kernel has
>> started (that's because one cannot reliably allocate new big contiguous
>> memory regions) but it will be possible to change the set of rules, etc.
>
> Yes, I think it will be much easier to be able to grab the regions at
> startup but hopefully the allocation within those regions can be made
> much more dynamic.  This would render most of the configuration syntax
> unneeded.

Not sure what you mean by the last sentence.  Maybe we have different
things in mind?

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:41                 ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 18:41 UTC (permalink / raw)
  To: Mark Brown
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Wed, Jul 21, 2010 at 04:31:35PM +0200, Micha?? Nazarewicz wrote:
>> On Wed, 21 Jul 2010 15:52:30 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
>
>> > If this does need to be configured per system would having platform data
>> > of some kind in the kernel not be a sensible a place to do it,
>
>> The current version (and the next version I'm working on) of the code
>> has cma_defaults() call.  It is intended to be called from platform
>> initialisation code to provide defaults.
>
> So the command line is just a way of overriding that?  That makes things
> a lot nicer - normally the device would use the defaults and the command
> line would be used in development.

Correct.

>> > or even
>> > having a way of configuring this at runtime (after all, the set of
>> > currently active users may vary depending on the current configuration
>> > and keeping everything allocated all the time may be wasteful)?
>
>> I am currently working on making the whole thing more dynamic.  I imagine
>> the list of regions would stay pretty much the same after kernel has
>> started (that's because one cannot reliably allocate new big contiguous
>> memory regions) but it will be possible to change the set of rules, etc.
>
> Yes, I think it will be much easier to be able to grab the regions at
> startup but hopefully the allocation within those regions can be made
> much more dynamic.  This would render most of the configuration syntax
> unneeded.

Not sure what you mean by the last sentence.  Maybe we have different
things in mind?

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:38                     ` Michał Nazarewicz
@ 2010-07-21 18:58                       ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 18:58 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 20:38 +0200, Michał Nazarewicz wrote:
> > On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
> >> Not really.  This will probably be used mostly on embedded systems
> >> where users don't have much to say as far as hardware included on the
> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
> >> users will have little need for customising those strings.
> 
> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > You can't assume that user won't want to reflash their own kernel on the
> > device. Your assuming way too much.
> 
> If user is clever enough to reflash a phone she will find the strings
> easy especially that they are provided from: (i) bootloader which is
> even less likely to be reflashed and if someone do reflash bootloader
> she is a guru who'd know how to make the strings; or (ii) platform
> defaults which will be available with the rest of the source code
> for the platform.

Your, again, assuming all sorts of stuff .. On my phone for example it
is very easy to reflash, personally, I think most devices will be like
that in the future. so you don't _need_ to be clever to reflash the
device.

> > If you assume they do want their own kernel then they would need this
> > string from someplace. If your right and this wouldn't need to change,
> > why bother allowing it to be configured at all ?
> 
> Imagine a developer who needs to recompile the kernel and reflash the
> device each time she wants to change the configuration...  Command line
> arguments seems a better option for development.

So make it a default off debug configuration option ..

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 18:58                       ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 18:58 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 20:38 +0200, MichaA? Nazarewicz wrote:
> > On Wed, 2010-07-21 at 20:11 +0200, MichaA? Nazarewicz wrote:
> >> Not really.  This will probably be used mostly on embedded systems
> >> where users don't have much to say as far as hardware included on the
> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
> >> users will have little need for customising those strings.
> 
> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > You can't assume that user won't want to reflash their own kernel on the
> > device. Your assuming way too much.
> 
> If user is clever enough to reflash a phone she will find the strings
> easy especially that they are provided from: (i) bootloader which is
> even less likely to be reflashed and if someone do reflash bootloader
> she is a guru who'd know how to make the strings; or (ii) platform
> defaults which will be available with the rest of the source code
> for the platform.

Your, again, assuming all sorts of stuff .. On my phone for example it
is very easy to reflash, personally, I think most devices will be like
that in the future. so you don't _need_ to be clever to reflash the
device.

> > If you assume they do want their own kernel then they would need this
> > string from someplace. If your right and this wouldn't need to change,
> > why bother allowing it to be configured at all ?
> 
> Imagine a developer who needs to recompile the kernel and reflash the
> device each time she wants to change the configuration...  Command line
> arguments seems a better option for development.

So make it a default off debug configuration option ..

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:58                       ` Daniel Walker
@ 2010-07-21 19:21                         ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 19:21 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 20:58:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 20:38 +0200, Michał Nazarewicz wrote:
>> > On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
>> >> Not really.  This will probably be used mostly on embedded systems
>> >> where users don't have much to say as far as hardware included on the
>> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
>> >> users will have little need for customising those strings.
>>
>> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > You can't assume that user won't want to reflash their own kernel on the
>> > device. Your assuming way too much.
>>
>> If user is clever enough to reflash a phone she will find the strings
>> easy especially that they are provided from: (i) bootloader which is
>> even less likely to be reflashed and if someone do reflash bootloader
>> she is a guru who'd know how to make the strings; or (ii) platform
>> defaults which will be available with the rest of the source code
>> for the platform.
>
> Your, again, assuming all sorts of stuff .. On my phone for example it
> is very easy to reflash, personally, I think most devices will be like
> that in the future. so you don't _need_ to be clever to reflash the
> device.

Bottom line is: if you reflash the device you (i) get an image from
somewhere and it has the strings in it, (ii) reflash the kernel and
parameters are provided by bootloader so they still remain, (iii)
use platform default strings which you get with the source codes and
include when kernel is built, or (iv) are a guru who knows what to
do.

>> > If you assume they do want their own kernel then they would need this
>> > string from someplace. If your right and this wouldn't need to change,
>> > why bother allowing it to be configured at all ?
>>
>> Imagine a developer who needs to recompile the kernel and reflash the
>> device each time she wants to change the configuration...  Command line
>> arguments seems a better option for development.
>
> So make it a default off debug configuration option ..

I don't really see the point of doing that.  Adding the command line
parameters is really a minor cost so there will be no benefits from
removing it.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 19:21                         ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 19:21 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 20:58:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 20:38 +0200, Michał Nazarewicz wrote:
>> > On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
>> >> Not really.  This will probably be used mostly on embedded systems
>> >> where users don't have much to say as far as hardware included on the
>> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
>> >> users will have little need for customising those strings.
>>
>> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > You can't assume that user won't want to reflash their own kernel on the
>> > device. Your assuming way too much.
>>
>> If user is clever enough to reflash a phone she will find the strings
>> easy especially that they are provided from: (i) bootloader which is
>> even less likely to be reflashed and if someone do reflash bootloader
>> she is a guru who'd know how to make the strings; or (ii) platform
>> defaults which will be available with the rest of the source code
>> for the platform.
>
> Your, again, assuming all sorts of stuff .. On my phone for example it
> is very easy to reflash, personally, I think most devices will be like
> that in the future. so you don't _need_ to be clever to reflash the
> device.

Bottom line is: if you reflash the device you (i) get an image from
somewhere and it has the strings in it, (ii) reflash the kernel and
parameters are provided by bootloader so they still remain, (iii)
use platform default strings which you get with the source codes and
include when kernel is built, or (iv) are a guru who knows what to
do.

>> > If you assume they do want their own kernel then they would need this
>> > string from someplace. If your right and this wouldn't need to change,
>> > why bother allowing it to be configured at all ?
>>
>> Imagine a developer who needs to recompile the kernel and reflash the
>> device each time she wants to change the configuration...  Command line
>> arguments seems a better option for development.
>
> So make it a default off debug configuration option ..

I don't really see the point of doing that.  Adding the command line
parameters is really a minor cost so there will be no benefits from
removing it.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 19:21                         ` Michał Nazarewicz
@ 2010-07-21 19:37                           ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 19:37 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 21:21 +0200, Michał Nazarewicz wrote:
> On Wed, 21 Jul 2010 20:58:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Wed, 2010-07-21 at 20:38 +0200, Michał Nazarewicz wrote:
> >> > On Wed, 2010-07-21 at 20:11 +0200, Michał Nazarewicz wrote:
> >> >> Not really.  This will probably be used mostly on embedded systems
> >> >> where users don't have much to say as far as hardware included on the
> >> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
> >> >> users will have little need for customising those strings.
> >>
> >> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> >> > You can't assume that user won't want to reflash their own kernel on the
> >> > device. Your assuming way too much.
> >>
> >> If user is clever enough to reflash a phone she will find the strings
> >> easy especially that they are provided from: (i) bootloader which is
> >> even less likely to be reflashed and if someone do reflash bootloader
> >> she is a guru who'd know how to make the strings; or (ii) platform
> >> defaults which will be available with the rest of the source code
> >> for the platform.
> >
> > Your, again, assuming all sorts of stuff .. On my phone for example it
> > is very easy to reflash, personally, I think most devices will be like
> > that in the future. so you don't _need_ to be clever to reflash the
> > device.
> 
> Bottom line is: if you reflash the device you (i) get an image from
> somewhere and it has the strings in it, (ii) reflash the kernel and
> parameters are provided by bootloader so they still remain, (iii)
> use platform default strings which you get with the source codes and
> include when kernel is built, or (iv) are a guru who knows what to
> do.

What makes you assume that the bootloader would have these strings?
Do your devices have these strings? Maybe mine don't have them.

Assume the strings are gone and you can't find them, or have no idea
what they should be. What do you do then?

> >> > If you assume they do want their own kernel then they would need this
> >> > string from someplace. If your right and this wouldn't need to change,
> >> > why bother allowing it to be configured at all ?
> >>
> >> Imagine a developer who needs to recompile the kernel and reflash the
> >> device each time she wants to change the configuration...  Command line
> >> arguments seems a better option for development.
> >
> > So make it a default off debug configuration option ..
> 
> I don't really see the point of doing that.  Adding the command line
> parameters is really a minor cost so there will be no benefits from
> removing it.

Well, I like my kernel minus bloat so that's a good reason. I don't see
a good reason to keep the interface in a production situation .. Maybe
during development , but really I don't see even a developer needing to
make the kind of changes your suggesting very often.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 19:37                           ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 19:37 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 21:21 +0200, MichaA? Nazarewicz wrote:
> On Wed, 21 Jul 2010 20:58:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Wed, 2010-07-21 at 20:38 +0200, MichaA? Nazarewicz wrote:
> >> > On Wed, 2010-07-21 at 20:11 +0200, MichaA? Nazarewicz wrote:
> >> >> Not really.  This will probably be used mostly on embedded systems
> >> >> where users don't have much to say as far as hardware included on the
> >> >> platform is concerned, etc.  Once a phone, tablet, etc. is released
> >> >> users will have little need for customising those strings.
> >>
> >> On Wed, 21 Jul 2010 20:19:08 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> >> > You can't assume that user won't want to reflash their own kernel on the
> >> > device. Your assuming way too much.
> >>
> >> If user is clever enough to reflash a phone she will find the strings
> >> easy especially that they are provided from: (i) bootloader which is
> >> even less likely to be reflashed and if someone do reflash bootloader
> >> she is a guru who'd know how to make the strings; or (ii) platform
> >> defaults which will be available with the rest of the source code
> >> for the platform.
> >
> > Your, again, assuming all sorts of stuff .. On my phone for example it
> > is very easy to reflash, personally, I think most devices will be like
> > that in the future. so you don't _need_ to be clever to reflash the
> > device.
> 
> Bottom line is: if you reflash the device you (i) get an image from
> somewhere and it has the strings in it, (ii) reflash the kernel and
> parameters are provided by bootloader so they still remain, (iii)
> use platform default strings which you get with the source codes and
> include when kernel is built, or (iv) are a guru who knows what to
> do.

What makes you assume that the bootloader would have these strings?
Do your devices have these strings? Maybe mine don't have them.

Assume the strings are gone and you can't find them, or have no idea
what they should be. What do you do then?

> >> > If you assume they do want their own kernel then they would need this
> >> > string from someplace. If your right and this wouldn't need to change,
> >> > why bother allowing it to be configured at all ?
> >>
> >> Imagine a developer who needs to recompile the kernel and reflash the
> >> device each time she wants to change the configuration...  Command line
> >> arguments seems a better option for development.
> >
> > So make it a default off debug configuration option ..
> 
> I don't really see the point of doing that.  Adding the command line
> parameters is really a minor cost so there will be no benefits from
> removing it.

Well, I like my kernel minus bloat so that's a good reason. I don't see
a good reason to keep the interface in a production situation .. Maybe
during development , but really I don't see even a developer needing to
make the kind of changes your suggesting very often.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 19:37                           ` Daniel Walker
@ 2010-07-21 19:53                             ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 19:53 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> What makes you assume that the bootloader would have these strings?
> Do your devices have these strings? Maybe mine don't have them.

I don't assume.  I only state it as one of the possibilities.

> Assume the strings are gone and you can't find them, or have no idea
> what they should be. What do you do then?

Ask Google?

I have a better question for you though: assume the "mem" parameter is
lost and you have no idea what it should be?  There are many parameters
passed to kernel by bootloader and you could ask about all of them.

Passing cma configuration via command line is one of the possibilities
-- especially convenient during development -- but I would expect platform
defaults in a final product so you may well not need to worry about it.

Bottom line: if you destroyed your device, you are screwed.

>>>> Imagine a developer who needs to recompile the kernel and reflash the
>>>> device each time she wants to change the configuration...  Command line
>>>> arguments seems a better option for development.

>>> So make it a default off debug configuration option ..

>> I don't really see the point of doing that.  Adding the command line
>> parameters is really a minor cost so there will be no benefits from
>> removing it.

> Well, I like my kernel minus bloat so that's a good reason. I don't see
> a good reason to keep the interface in a production situation .. Maybe
> during development , but really I don't see even a developer needing to
> make the kind of changes your suggesting very often.

As I've said, removing the command line parameters would not benefit the
kernel that much.  It's like 1% of the code or less.  On the other hand,
it would add complexity to the CMA framework which is a good reason not
to do that.

Would you also argue about removing all the other kernel parameters as
well? I bet you don't use most of them.  Still they are there because
removing them would add too much complexity to the code (conditional
compilation, etc.).

I'm not saying that removing “bloat” (or unused options if you will)
 from the kernel is a bad thing but there is a line where costs of
doing so negate the benefits.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 19:53                             ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 19:53 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> What makes you assume that the bootloader would have these strings?
> Do your devices have these strings? Maybe mine don't have them.

I don't assume.  I only state it as one of the possibilities.

> Assume the strings are gone and you can't find them, or have no idea
> what they should be. What do you do then?

Ask Google?

I have a better question for you though: assume the "mem" parameter is
lost and you have no idea what it should be?  There are many parameters
passed to kernel by bootloader and you could ask about all of them.

Passing cma configuration via command line is one of the possibilities
-- especially convenient during development -- but I would expect platform
defaults in a final product so you may well not need to worry about it.

Bottom line: if you destroyed your device, you are screwed.

>>>> Imagine a developer who needs to recompile the kernel and reflash the
>>>> device each time she wants to change the configuration...  Command line
>>>> arguments seems a better option for development.

>>> So make it a default off debug configuration option ..

>> I don't really see the point of doing that.  Adding the command line
>> parameters is really a minor cost so there will be no benefits from
>> removing it.

> Well, I like my kernel minus bloat so that's a good reason. I don't see
> a good reason to keep the interface in a production situation .. Maybe
> during development , but really I don't see even a developer needing to
> make the kind of changes your suggesting very often.

As I've said, removing the command line parameters would not benefit the
kernel that much.  It's like 1% of the code or less.  On the other hand,
it would add complexity to the CMA framework which is a good reason not
to do that.

Would you also argue about removing all the other kernel parameters as
well? I bet you don't use most of them.  Still they are there because
removing them would add too much complexity to the code (conditional
compilation, etc.).

I'm not saying that removing “bloat” (or unused options if you will)
 from the kernel is a bad thing but there is a line where costs of
doing so negate the benefits.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 19:53                             ` Michał Nazarewicz
@ 2010-07-21 20:03                               ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:03 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 21:53 +0200, Michał Nazarewicz wrote:
> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > What makes you assume that the bootloader would have these strings?
> > Do your devices have these strings? Maybe mine don't have them.
> 
> I don't assume.  I only state it as one of the possibilities.
> 
> > Assume the strings are gone and you can't find them, or have no idea
> > what they should be. What do you do then?
> 
> Ask Google?

Exactly, that's why they need to be in the kernel ..

> I have a better question for you though: assume the "mem" parameter is
> lost and you have no idea what it should be?  There are many parameters
> passed to kernel by bootloader and you could ask about all of them.

That's hardware based tho. Of course you need info on what your hardware
is. What your doing isn't based on hardware specifics, it's based on
optimizations.

> Passing cma configuration via command line is one of the possibilities
> -- especially convenient during development -- but I would expect platform
> defaults in a final product so you may well not need to worry about it.

I honestly don't thing the "development" angle flies either , but if you
keep this there's no way it should be enabled for anything but debug.

> > Well, I like my kernel minus bloat so that's a good reason. I don't see
> > a good reason to keep the interface in a production situation .. Maybe
> > during development , but really I don't see even a developer needing to
> > make the kind of changes your suggesting very often.
> 
> As I've said, removing the command line parameters would not benefit the
> kernel that much.  It's like 1% of the code or less.  On the other hand,
> it would add complexity to the CMA framework which is a good reason not
> to do that.

If we allowed everyone to add there little tiny bit of bloat where would
we be?

> Would you also argue about removing all the other kernel parameters as
> well? I bet you don't use most of them.  Still they are there because
> removing them would add too much complexity to the code (conditional
> compilation, etc.).

Your is at a different level of complexity ..

Daniel


-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:03                               ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:03 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 21:53 +0200, MichaA? Nazarewicz wrote:
> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > What makes you assume that the bootloader would have these strings?
> > Do your devices have these strings? Maybe mine don't have them.
> 
> I don't assume.  I only state it as one of the possibilities.
> 
> > Assume the strings are gone and you can't find them, or have no idea
> > what they should be. What do you do then?
> 
> Ask Google?

Exactly, that's why they need to be in the kernel ..

> I have a better question for you though: assume the "mem" parameter is
> lost and you have no idea what it should be?  There are many parameters
> passed to kernel by bootloader and you could ask about all of them.

That's hardware based tho. Of course you need info on what your hardware
is. What your doing isn't based on hardware specifics, it's based on
optimizations.

> Passing cma configuration via command line is one of the possibilities
> -- especially convenient during development -- but I would expect platform
> defaults in a final product so you may well not need to worry about it.

I honestly don't thing the "development" angle flies either , but if you
keep this there's no way it should be enabled for anything but debug.

> > Well, I like my kernel minus bloat so that's a good reason. I don't see
> > a good reason to keep the interface in a production situation .. Maybe
> > during development , but really I don't see even a developer needing to
> > make the kind of changes your suggesting very often.
> 
> As I've said, removing the command line parameters would not benefit the
> kernel that much.  It's like 1% of the code or less.  On the other hand,
> it would add complexity to the CMA framework which is a good reason not
> to do that.

If we allowed everyone to add there little tiny bit of bloat where would
we be?

> Would you also argue about removing all the other kernel parameters as
> well? I bet you don't use most of them.  Still they are there because
> removing them would add too much complexity to the code (conditional
> compilation, etc.).

Your is at a different level of complexity ..

Daniel


-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:03                               ` Daniel Walker
@ 2010-07-21 20:22                                 ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:22 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 22:03:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 21:53 +0200, Michał Nazarewicz wrote:
>> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > What makes you assume that the bootloader would have these strings?
>> > Do your devices have these strings? Maybe mine don't have them.
>>
>> I don't assume.  I only state it as one of the possibilities.
>>
>> > Assume the strings are gone and you can't find them, or have no idea
>> > what they should be. What do you do then?
>>
>> Ask Google?
>
> Exactly, that's why they need to be in the kernel ..

Right.....  Please show me a place where I've written that it won't be in
the kernel? I keep repeating command line is only one of the possibilities.
I would imagine that in final product defaults from platform would be used
and bootloader would be left alone.

>> I have a better question for you though: assume the "mem" parameter is
>> lost and you have no idea what it should be?  There are many parameters
>> passed to kernel by bootloader and you could ask about all of them.
>
> That's hardware based tho. Of course you need info on what your hardware
> is. What your doing isn't based on hardware specifics, it's based on
> optimizations.
>
>> Passing cma configuration via command line is one of the possibilities
>> -- especially convenient during development -- but I would expect platform
>> defaults in a final product so you may well not need to worry about it.
>
> I honestly don't thing the "development" angle flies either , but if you
> keep this there's no way it should be enabled for anything but debug.

If you are developing the whole platform and optimising the allocators,
etc. it's very convenient.  If you develop something else then it's not
needed but then again it's usually the case that if you develop “foo”
then “bar” is not needed.

>> Would you also argue about removing all the other kernel parameters as
>> well? I bet you don't use most of them.  Still they are there because
>> removing them would add too much complexity to the code (conditional
>> compilation, etc.).
>
> Your is at a different level of complexity ..

Which most of will remain even if the command line parameters were to
be removed.  One needs to specify this configuration somehow and no
matter how you do it it will be complex in one way or another.  In my
code the complexity is parsing of the strings, in a different approach
it would be complex in a different way.

At the same time, the fact that the parameters can be provided via command
line is has a minimal impact on the code.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:22                                 ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:22 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 22:03:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 21:53 +0200, Michał Nazarewicz wrote:
>> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > What makes you assume that the bootloader would have these strings?
>> > Do your devices have these strings? Maybe mine don't have them.
>>
>> I don't assume.  I only state it as one of the possibilities.
>>
>> > Assume the strings are gone and you can't find them, or have no idea
>> > what they should be. What do you do then?
>>
>> Ask Google?
>
> Exactly, that's why they need to be in the kernel ..

Right.....  Please show me a place where I've written that it won't be in
the kernel? I keep repeating command line is only one of the possibilities.
I would imagine that in final product defaults from platform would be used
and bootloader would be left alone.

>> I have a better question for you though: assume the "mem" parameter is
>> lost and you have no idea what it should be?  There are many parameters
>> passed to kernel by bootloader and you could ask about all of them.
>
> That's hardware based tho. Of course you need info on what your hardware
> is. What your doing isn't based on hardware specifics, it's based on
> optimizations.
>
>> Passing cma configuration via command line is one of the possibilities
>> -- especially convenient during development -- but I would expect platform
>> defaults in a final product so you may well not need to worry about it.
>
> I honestly don't thing the "development" angle flies either , but if you
> keep this there's no way it should be enabled for anything but debug.

If you are developing the whole platform and optimising the allocators,
etc. it's very convenient.  If you develop something else then it's not
needed but then again it's usually the case that if you develop “foo”
then “bar” is not needed.

>> Would you also argue about removing all the other kernel parameters as
>> well? I bet you don't use most of them.  Still they are there because
>> removing them would add too much complexity to the code (conditional
>> compilation, etc.).
>
> Your is at a different level of complexity ..

Which most of will remain even if the command line parameters were to
be removed.  One needs to specify this configuration somehow and no
matter how you do it it will be complex in one way or another.  In my
code the complexity is parsing of the strings, in a different approach
it would be complex in a different way.

At the same time, the fact that the parameters can be provided via command
line is has a minimal impact on the code.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:22                                 ` Michał Nazarewicz
@ 2010-07-21 20:34                                   ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:34 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:22 +0200, Michał Nazarewicz wrote:
> On Wed, 21 Jul 2010 22:03:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Wed, 2010-07-21 at 21:53 +0200, Michał Nazarewicz wrote:
> >> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> >> > What makes you assume that the bootloader would have these strings?
> >> > Do your devices have these strings? Maybe mine don't have them.
> >>
> >> I don't assume.  I only state it as one of the possibilities.
> >>
> >> > Assume the strings are gone and you can't find them, or have no idea
> >> > what they should be. What do you do then?
> >>
> >> Ask Google?
> >
> > Exactly, that's why they need to be in the kernel ..
> 
> Right.....  Please show me a place where I've written that it won't be in
> the kernel? I keep repeating command line is only one of the possibilities.
> I would imagine that in final product defaults from platform would be used
> and bootloader would be left alone.

It should never be anyplace else.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:34                                   ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:34 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:22 +0200, MichaA? Nazarewicz wrote:
> On Wed, 21 Jul 2010 22:03:24 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> 
> > On Wed, 2010-07-21 at 21:53 +0200, MichaA? Nazarewicz wrote:
> >> On Wed, 21 Jul 2010 21:37:09 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> >> > What makes you assume that the bootloader would have these strings?
> >> > Do your devices have these strings? Maybe mine don't have them.
> >>
> >> I don't assume.  I only state it as one of the possibilities.
> >>
> >> > Assume the strings are gone and you can't find them, or have no idea
> >> > what they should be. What do you do then?
> >>
> >> Ask Google?
> >
> > Exactly, that's why they need to be in the kernel ..
> 
> Right.....  Please show me a place where I've written that it won't be in
> the kernel? I keep repeating command line is only one of the possibilities.
> I would imagine that in final product defaults from platform would be used
> and bootloader would be left alone.

It should never be anyplace else.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:34                                   ` Daniel Walker
@ 2010-07-21 20:43                                     ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:43 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

> On Wed, 2010-07-21 at 22:22 +0200, Michał Nazarewicz wrote:
>> Right.....  Please show me a place where I've written that it won't be in
>> the kernel? I keep repeating command line is only one of the possibilities.
>> I would imagine that in final product defaults from platform would be used
>> and bootloader would be left alone.

On Wed, 21 Jul 2010 22:34:32 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> It should never be anyplace else.

I disagree.  There are countless “dubug_level” kernel parameters or even
some “printk” related parameters.  Those are completely hardware-independent.
There are also parameters that are hardware dependent but most users won't
care to set them.  That's how the things are: there are some defaults but
you can override them by command line parameters.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:43                                     ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:43 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

> On Wed, 2010-07-21 at 22:22 +0200, Michał Nazarewicz wrote:
>> Right.....  Please show me a place where I've written that it won't be in
>> the kernel? I keep repeating command line is only one of the possibilities.
>> I would imagine that in final product defaults from platform would be used
>> and bootloader would be left alone.

On Wed, 21 Jul 2010 22:34:32 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> It should never be anyplace else.

I disagree.  There are countless “dubug_level” kernel parameters or even
some “printk” related parameters.  Those are completely hardware-independent.
There are also parameters that are hardware dependent but most users won't
care to set them.  That's how the things are: there are some defaults but
you can override them by command line parameters.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:43                                     ` Michał Nazarewicz
@ 2010-07-21 20:45                                       ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:45 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:43 +0200, Michał Nazarewicz wrote:
> > On Wed, 2010-07-21 at 22:22 +0200, Michał Nazarewicz wrote:
> >> Right.....  Please show me a place where I've written that it won't be in
> >> the kernel? I keep repeating command line is only one of the possibilities.
> >> I would imagine that in final product defaults from platform would be used
> >> and bootloader would be left alone.
> 
> On Wed, 21 Jul 2010 22:34:32 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > It should never be anyplace else.
> 
> I disagree.  There are countless “dubug_level” kernel parameters or even
> some “printk” related parameters.  Those are completely hardware-independent.
> There are also parameters that are hardware dependent but most users won't
> care to set them.  That's how the things are: there are some defaults but
> you can override them by command line parameters.

Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:45                                       ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 20:45 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:43 +0200, MichaA? Nazarewicz wrote:
> > On Wed, 2010-07-21 at 22:22 +0200, MichaA? Nazarewicz wrote:
> >> Right.....  Please show me a place where I've written that it won't be in
> >> the kernel? I keep repeating command line is only one of the possibilities.
> >> I would imagine that in final product defaults from platform would be used
> >> and bootloader would be left alone.
> 
> On Wed, 21 Jul 2010 22:34:32 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > It should never be anyplace else.
> 
> I disagree.  There are countless a??dubug_levela?? kernel parameters or even
> some a??printka?? related parameters.  Those are completely hardware-independent.
> There are also parameters that are hardware dependent but most users won't
> care to set them.  That's how the things are: there are some defaults but
> you can override them by command line parameters.

Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:45                                       ` Daniel Walker
@ 2010-07-21 20:56                                         ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:56 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.

Remove what exactly?

The command line parameter? It's like 50 lines of code, so I don't
see any benefits.

The possibility to specify the configuration? It would defy the whole
purpose of CMA, so I won't do that.

The complexity has to be there one way or the other and even though
I am aware that less complex code is the better and am trying to
remove unnecessary complexity but saying “remove it” won't make any
good unless you provide me with a better alternative.  At this point,
I am still convinced that the string parameters are the best option.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 20:56                                         ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-21 20:56 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.

Remove what exactly?

The command line parameter? It's like 50 lines of code, so I don't
see any benefits.

The possibility to specify the configuration? It would defy the whole
purpose of CMA, so I won't do that.

The complexity has to be there one way or the other and even though
I am aware that less complex code is the better and am trying to
remove unnecessary complexity but saying “remove it” won't make any
good unless you provide me with a better alternative.  At this point,
I am still convinced that the string parameters are the best option.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 20:56                                         ` Michał Nazarewicz
@ 2010-07-21 21:01                                           ` Daniel Walker
  -1 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 21:01 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:56 +0200, Michał Nazarewicz wrote:
> On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.
> 
> Remove what exactly?

Remove the command line option and all related code, or make it all a
debug option.

Arguing with me isn't going to help your cause.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-21 21:01                                           ` Daniel Walker
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Walker @ 2010-07-21 21:01 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 2010-07-21 at 22:56 +0200, MichaA? Nazarewicz wrote:
> On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
> > Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.
> 
> Remove what exactly?

Remove the command line option and all related code, or make it all a
debug option.

Arguing with me isn't going to help your cause.

Daniel

-- 
Sent by an consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
@ 2010-07-22  4:54       ` Zach Pfeffer
  2010-07-20 18:15       ` Daniel Walker
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 98+ messages in thread
From: Zach Pfeffer @ 2010-07-22  4:54 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:
> The Contiguous Memory Allocator framework is a set of APIs for
> allocating physically contiguous chunks of memory.
> 
> Various chips require contiguous blocks of memory to operate.  Those
> chips include devices such as cameras, hardware video decoders and
> encoders, etc.
> 
> The code is highly modular and customisable to suit the needs of
> various users.  Set of regions reserved for CMA can be configured on
> run-time and it is easy to add custom allocator algorithms if one
> has such need.
> 
> Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> ---
>  Documentation/cma.txt               |  435 +++++++++++++++++++
>  Documentation/kernel-parameters.txt |    7 +
>  include/linux/cma-int.h             |  183 ++++++++
>  include/linux/cma.h                 |   92 ++++
>  mm/Kconfig                          |   41 ++
>  mm/Makefile                         |    3 +
>  mm/cma-allocators.h                 |   42 ++
>  mm/cma-best-fit.c                   |  360 ++++++++++++++++
>  mm/cma.c                            |  778 +++++++++++++++++++++++++++++++++++
>  9 files changed, 1941 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/cma.txt
>  create mode 100644 include/linux/cma-int.h
>  create mode 100644 include/linux/cma.h
>  create mode 100644 mm/cma-allocators.h
>  create mode 100644 mm/cma-best-fit.c
>  create mode 100644 mm/cma.c
> 
> diff --git a/Documentation/cma.txt b/Documentation/cma.txt
> new file mode 100644
> index 0000000..7edc20a
> --- /dev/null
> +++ b/Documentation/cma.txt
> @@ -0,0 +1,435 @@
> +                                                             -*- org -*-
> +
> +* Contiguous Memory Allocator
> +
> +   The Contiguous Memory Allocator (CMA) is a framework, which allows
> +   setting up a machine-specific configuration for physically-contiguous
> +   memory management. Memory for devices is then allocated according
> +   to that configuration.
> +
> +   The main role of the framework is not to allocate memory, but to
> +   parse and manage memory configurations, as well as to act as an
> +   in-between between device drivers and pluggable allocators. It is
> +   thus not tied to any memory allocation method or strategy.
> +

This topic seems very hot lately. I recently sent out a few RFCs that
implement something called a Virtual Contiguous Memory Manager that
does what this patch does, and works for IOMMU and works for CPU
mappings. It also does multihomed memory targeting (use physical set 1
memory for A allocations and use physical memory set 2 for B
allocations). Check out:

mm: iommu: An API to unify IOMMU, CPU and device memory management
mm: iommu: A physical allocator for the VCMM
mm: iommu: The Virtual Contiguous Memory Manager

It unifies IOMMU and physical mappings by creating a one-to-one
software IOMMU for all devices that map memory physically.

It looks like you've got some good ideas though. Perhaps we can
leverage each other's work.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  4:54       ` Zach Pfeffer
  0 siblings, 0 replies; 98+ messages in thread
From: Zach Pfeffer @ 2010-07-22  4:54 UTC (permalink / raw)
  To: Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park

On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:
> The Contiguous Memory Allocator framework is a set of APIs for
> allocating physically contiguous chunks of memory.
> 
> Various chips require contiguous blocks of memory to operate.  Those
> chips include devices such as cameras, hardware video decoders and
> encoders, etc.
> 
> The code is highly modular and customisable to suit the needs of
> various users.  Set of regions reserved for CMA can be configured on
> run-time and it is easy to add custom allocator algorithms if one
> has such need.
> 
> Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> ---
>  Documentation/cma.txt               |  435 +++++++++++++++++++
>  Documentation/kernel-parameters.txt |    7 +
>  include/linux/cma-int.h             |  183 ++++++++
>  include/linux/cma.h                 |   92 ++++
>  mm/Kconfig                          |   41 ++
>  mm/Makefile                         |    3 +
>  mm/cma-allocators.h                 |   42 ++
>  mm/cma-best-fit.c                   |  360 ++++++++++++++++
>  mm/cma.c                            |  778 +++++++++++++++++++++++++++++++++++
>  9 files changed, 1941 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/cma.txt
>  create mode 100644 include/linux/cma-int.h
>  create mode 100644 include/linux/cma.h
>  create mode 100644 mm/cma-allocators.h
>  create mode 100644 mm/cma-best-fit.c
>  create mode 100644 mm/cma.c
> 
> diff --git a/Documentation/cma.txt b/Documentation/cma.txt
> new file mode 100644
> index 0000000..7edc20a
> --- /dev/null
> +++ b/Documentation/cma.txt
> @@ -0,0 +1,435 @@
> +                                                             -*- org -*-
> +
> +* Contiguous Memory Allocator
> +
> +   The Contiguous Memory Allocator (CMA) is a framework, which allows
> +   setting up a machine-specific configuration for physically-contiguous
> +   memory management. Memory for devices is then allocated according
> +   to that configuration.
> +
> +   The main role of the framework is not to allocate memory, but to
> +   parse and manage memory configurations, as well as to act as an
> +   in-between between device drivers and pluggable allocators. It is
> +   thus not tied to any memory allocation method or strategy.
> +

This topic seems very hot lately. I recently sent out a few RFCs that
implement something called a Virtual Contiguous Memory Manager that
does what this patch does, and works for IOMMU and works for CPU
mappings. It also does multihomed memory targeting (use physical set 1
memory for A allocations and use physical memory set 2 for B
allocations). Check out:

mm: iommu: An API to unify IOMMU, CPU and device memory management
mm: iommu: A physical allocator for the VCMM
mm: iommu: The Virtual Contiguous Memory Manager

It unifies IOMMU and physical mappings by creating a one-to-one
software IOMMU for all devices that map memory physically.

It looks like you've got some good ideas though. Perhaps we can
leverage each other's work.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21  0:12       ` Jonathan Corbet
@ 2010-07-22  5:37         ` FUJITA Tomonori
  -1 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22  5:37 UTC (permalink / raw)
  To: corbet
  Cc: m.nazarewicz, linux-mm, m.szyprowski, p.osciak, xiaolin.zhang,
	hvaibhav, robert.fekete, marcus.xm.lorentzon, linux-kernel,
	kyungmin.park

On Tue, 20 Jul 2010 18:12:39 -0600
Jonathan Corbet <corbet@lwn.net> wrote:

> One other thing occurred to me as I was thinking about this...
> 
> > +    There are four calls provided by the CMA framework to devices.  To
> > +    allocate a chunk of memory cma_alloc() function needs to be used:
> > +
> > +            unsigned long cma_alloc(const struct device *dev,
> > +                                    const char *kind,
> > +                                    unsigned long size,
> > +                                    unsigned long alignment);
> 
> The purpose behind this interface, I believe, is pretty much always
> going to be to allocate memory for DMA buffers.  Given that, might it
> make more sense to integrate the API with the current DMA mapping
> API?

IMO, having separate APIs for allocating memory and doing DMA mapping
is much better. The DMA API covers the latter well. We could extend
the current API to allocate memory or create new one similar to the
current. 

I don't see any benefit of a new abstraction that does both magically.


About the framework, it looks too complicated than we actually need
(the command line stuff looks insane).

Why can't we have something simpler, like using memblock to reserve
contiguous memory at boot and using kinda mempool to share such memory
between devices?

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  5:37         ` FUJITA Tomonori
  0 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22  5:37 UTC (permalink / raw)
  To: corbet
  Cc: m.nazarewicz, linux-mm, m.szyprowski, p.osciak, xiaolin.zhang,
	hvaibhav, robert.fekete, marcus.xm.lorentzon, linux-kernel,
	kyungmin.park

On Tue, 20 Jul 2010 18:12:39 -0600
Jonathan Corbet <corbet@lwn.net> wrote:

> One other thing occurred to me as I was thinking about this...
> 
> > +    There are four calls provided by the CMA framework to devices.  To
> > +    allocate a chunk of memory cma_alloc() function needs to be used:
> > +
> > +            unsigned long cma_alloc(const struct device *dev,
> > +                                    const char *kind,
> > +                                    unsigned long size,
> > +                                    unsigned long alignment);
> 
> The purpose behind this interface, I believe, is pretty much always
> going to be to allocate memory for DMA buffers.  Given that, might it
> make more sense to integrate the API with the current DMA mapping
> API?

IMO, having separate APIs for allocating memory and doing DMA mapping
is much better. The DMA API covers the latter well. We could extend
the current API to allocate memory or create new one similar to the
current. 

I don't see any benefit of a new abstraction that does both magically.


About the framework, it looks too complicated than we actually need
(the command line stuff looks insane).

Why can't we have something simpler, like using memblock to reserve
contiguous memory at boot and using kinda mempool to share such memory
between devices?

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  5:37         ` FUJITA Tomonori
@ 2010-07-22  7:28           ` Marek Szyprowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  7:28 UTC (permalink / raw)
  To: 'FUJITA Tomonori', corbet
  Cc: m.nazarewicz, linux-mm, p.osciak, xiaolin.zhang, hvaibhav,
	robert.fekete, marcus.xm.lorentzon, linux-kernel, kyungmin.park

Hello,

On Thursday, July 22, 2010 7:38 AM FUJITA Tomonori wrote:

> On Tue, 20 Jul 2010 18:12:39 -0600
> Jonathan Corbet <corbet@lwn.net> wrote:
> 
> > One other thing occurred to me as I was thinking about this...
> >
> > > +    There are four calls provided by the CMA framework to devices.  To
> > > +    allocate a chunk of memory cma_alloc() function needs to be used:
> > > +
> > > +            unsigned long cma_alloc(const struct device *dev,
> > > +                                    const char *kind,
> > > +                                    unsigned long size,
> > > +                                    unsigned long alignment);
> >
> > The purpose behind this interface, I believe, is pretty much always
> > going to be to allocate memory for DMA buffers.  Given that, might it
> > make more sense to integrate the API with the current DMA mapping
> > API?
> 
> IMO, having separate APIs for allocating memory and doing DMA mapping
> is much better. The DMA API covers the latter well. We could extend
> the current API to allocate memory or create new one similar to the
> current.
> 
> I don't see any benefit of a new abstraction that does both magically.

That's true. DMA mapping API is quite stable and already working.
 
> About the framework, it looks too complicated than we actually need
> (the command line stuff looks insane).

Well, this command line stuff was designed to provide a way to configure
memory allocation for devices with very sophisticated memory requirements.
It might look insane in first sight, but we haven't implemented it just
for fun. We have just taken the real requirements for our multimedia
devices (especially hardware video codec) tried to create a solution that
would cover all of them.

However I understand your point. It might be really good idea to set a
default mapping as a "one global memory pool for all devices". This way
the complicated cma boot argument would need to be provided only on
machines that really require it, all other can use it without any advanced
command line magic.

> Why can't we have something simpler, like using memblock to reserve
> contiguous memory at boot and using kinda mempool to share such memory
> between devices?

There are a few problems with such simple approach:

1. It does not provide all required functionality for our multimedia
devices. The main problem is the fact that our multimedia devices
require particular kind of buffers to be allocated in particular memory
bank. Then add 2 more requirements: a proper alignment (for some of them
it is even 128Kb) and particular range of addresses requirement (some
buffers must be allocated at higher addresses than the firmware).
This is very hard to achieve with such simple allocator.

2. One global memory pool heavily increases fragmentation issues and
gives no way to control or limit it. The opposite solution - like having
a separate pools per each multimedia device solves some fragmentation
issues but it's a huge waste a of the memory. Our idea was to provide
something configurable that can be placed between both solutions, that
can take advantages of both.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  7:28           ` Marek Szyprowski
  0 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  7:28 UTC (permalink / raw)
  To: 'FUJITA Tomonori', corbet
  Cc: m.nazarewicz, linux-mm, p.osciak, xiaolin.zhang, hvaibhav,
	robert.fekete, marcus.xm.lorentzon, linux-kernel, kyungmin.park

Hello,

On Thursday, July 22, 2010 7:38 AM FUJITA Tomonori wrote:

> On Tue, 20 Jul 2010 18:12:39 -0600
> Jonathan Corbet <corbet@lwn.net> wrote:
> 
> > One other thing occurred to me as I was thinking about this...
> >
> > > +    There are four calls provided by the CMA framework to devices.  To
> > > +    allocate a chunk of memory cma_alloc() function needs to be used:
> > > +
> > > +            unsigned long cma_alloc(const struct device *dev,
> > > +                                    const char *kind,
> > > +                                    unsigned long size,
> > > +                                    unsigned long alignment);
> >
> > The purpose behind this interface, I believe, is pretty much always
> > going to be to allocate memory for DMA buffers.  Given that, might it
> > make more sense to integrate the API with the current DMA mapping
> > API?
> 
> IMO, having separate APIs for allocating memory and doing DMA mapping
> is much better. The DMA API covers the latter well. We could extend
> the current API to allocate memory or create new one similar to the
> current.
> 
> I don't see any benefit of a new abstraction that does both magically.

That's true. DMA mapping API is quite stable and already working.
 
> About the framework, it looks too complicated than we actually need
> (the command line stuff looks insane).

Well, this command line stuff was designed to provide a way to configure
memory allocation for devices with very sophisticated memory requirements.
It might look insane in first sight, but we haven't implemented it just
for fun. We have just taken the real requirements for our multimedia
devices (especially hardware video codec) tried to create a solution that
would cover all of them.

However I understand your point. It might be really good idea to set a
default mapping as a "one global memory pool for all devices". This way
the complicated cma boot argument would need to be provided only on
machines that really require it, all other can use it without any advanced
command line magic.

> Why can't we have something simpler, like using memblock to reserve
> contiguous memory at boot and using kinda mempool to share such memory
> between devices?

There are a few problems with such simple approach:

1. It does not provide all required functionality for our multimedia
devices. The main problem is the fact that our multimedia devices
require particular kind of buffers to be allocated in particular memory
bank. Then add 2 more requirements: a proper alignment (for some of them
it is even 128Kb) and particular range of addresses requirement (some
buffers must be allocated at higher addresses than the firmware).
This is very hard to achieve with such simple allocator.

2. One global memory pool heavily increases fragmentation issues and
gives no way to control or limit it. The opposite solution - like having
a separate pools per each multimedia device solves some fragmentation
issues but it's a huge waste a of the memory. Our idea was to provide
something configurable that can be placed between both solutions, that
can take advantages of both.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center


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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  4:54       ` Zach Pfeffer
@ 2010-07-22  7:49         ` Marek Szyprowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  7:49 UTC (permalink / raw)
  To: 'Zach Pfeffer', Michal Nazarewicz
  Cc: linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park'

Hello,

On Thursday, July 22, 2010 6:55 AM Zach Pfeffer wrote:

> On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:
> > The Contiguous Memory Allocator framework is a set of APIs for
> > allocating physically contiguous chunks of memory.
> >
> > Various chips require contiguous blocks of memory to operate.  Those
> > chips include devices such as cameras, hardware video decoders and
> > encoders, etc.
> >
> > The code is highly modular and customisable to suit the needs of
> > various users.  Set of regions reserved for CMA can be configured on
> > run-time and it is easy to add custom allocator algorithms if one
> > has such need.
> >
> > Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> > Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> > ---
> >  Documentation/cma.txt               |  435 +++++++++++++++++++
> >  Documentation/kernel-parameters.txt |    7 +
> >  include/linux/cma-int.h             |  183 ++++++++
> >  include/linux/cma.h                 |   92 ++++
> >  mm/Kconfig                          |   41 ++
> >  mm/Makefile                         |    3 +
> >  mm/cma-allocators.h                 |   42 ++
> >  mm/cma-best-fit.c                   |  360 ++++++++++++++++
> >  mm/cma.c                            |  778
> +++++++++++++++++++++++++++++++++++
> >  9 files changed, 1941 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/cma.txt
> >  create mode 100644 include/linux/cma-int.h
> >  create mode 100644 include/linux/cma.h
> >  create mode 100644 mm/cma-allocators.h
> >  create mode 100644 mm/cma-best-fit.c
> >  create mode 100644 mm/cma.c
> >
> > diff --git a/Documentation/cma.txt b/Documentation/cma.txt
> > new file mode 100644
> > index 0000000..7edc20a
> > --- /dev/null
> > +++ b/Documentation/cma.txt
> > @@ -0,0 +1,435 @@
> > +                                                             -*- org -*-
> > +
> > +* Contiguous Memory Allocator
> > +
> > +   The Contiguous Memory Allocator (CMA) is a framework, which allows
> > +   setting up a machine-specific configuration for physically-contiguous
> > +   memory management. Memory for devices is then allocated according
> > +   to that configuration.
> > +
> > +   The main role of the framework is not to allocate memory, but to
> > +   parse and manage memory configurations, as well as to act as an
> > +   in-between between device drivers and pluggable allocators. It is
> > +   thus not tied to any memory allocation method or strategy.
> > +
> 
> This topic seems very hot lately. I recently sent out a few RFCs that
> implement something called a Virtual Contiguous Memory Manager that
> does what this patch does, and works for IOMMU and works for CPU
> mappings. It also does multihomed memory targeting (use physical set 1
> memory for A allocations and use physical memory set 2 for B
> allocations). Check out:
> 
> mm: iommu: An API to unify IOMMU, CPU and device memory management
> mm: iommu: A physical allocator for the VCMM
> mm: iommu: The Virtual Contiguous Memory Manager
> 
> It unifies IOMMU and physical mappings by creating a one-to-one
> software IOMMU for all devices that map memory physically.
> 
> It looks like you've got some good ideas though. Perhaps we can
> leverage each other's work.

We are aware of your patches. However our CMA solves the problem that is
a bit orthogonal to the setting up iommu. When you have IOMMU you don't really
need to care about memory fragmentation. In CMA approach we had to care
about it.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  7:49         ` Marek Szyprowski
  0 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  7:49 UTC (permalink / raw)
  To: 'Zach Pfeffer', Michal Nazarewicz
  Cc: linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park'

Hello,

On Thursday, July 22, 2010 6:55 AM Zach Pfeffer wrote:

> On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:
> > The Contiguous Memory Allocator framework is a set of APIs for
> > allocating physically contiguous chunks of memory.
> >
> > Various chips require contiguous blocks of memory to operate.  Those
> > chips include devices such as cameras, hardware video decoders and
> > encoders, etc.
> >
> > The code is highly modular and customisable to suit the needs of
> > various users.  Set of regions reserved for CMA can be configured on
> > run-time and it is easy to add custom allocator algorithms if one
> > has such need.
> >
> > Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> > Reviewed-by: Pawel Osciak <p.osciak@samsung.com>
> > ---
> >  Documentation/cma.txt               |  435 +++++++++++++++++++
> >  Documentation/kernel-parameters.txt |    7 +
> >  include/linux/cma-int.h             |  183 ++++++++
> >  include/linux/cma.h                 |   92 ++++
> >  mm/Kconfig                          |   41 ++
> >  mm/Makefile                         |    3 +
> >  mm/cma-allocators.h                 |   42 ++
> >  mm/cma-best-fit.c                   |  360 ++++++++++++++++
> >  mm/cma.c                            |  778
> +++++++++++++++++++++++++++++++++++
> >  9 files changed, 1941 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/cma.txt
> >  create mode 100644 include/linux/cma-int.h
> >  create mode 100644 include/linux/cma.h
> >  create mode 100644 mm/cma-allocators.h
> >  create mode 100644 mm/cma-best-fit.c
> >  create mode 100644 mm/cma.c
> >
> > diff --git a/Documentation/cma.txt b/Documentation/cma.txt
> > new file mode 100644
> > index 0000000..7edc20a
> > --- /dev/null
> > +++ b/Documentation/cma.txt
> > @@ -0,0 +1,435 @@
> > +                                                             -*- org -*-
> > +
> > +* Contiguous Memory Allocator
> > +
> > +   The Contiguous Memory Allocator (CMA) is a framework, which allows
> > +   setting up a machine-specific configuration for physically-contiguous
> > +   memory management. Memory for devices is then allocated according
> > +   to that configuration.
> > +
> > +   The main role of the framework is not to allocate memory, but to
> > +   parse and manage memory configurations, as well as to act as an
> > +   in-between between device drivers and pluggable allocators. It is
> > +   thus not tied to any memory allocation method or strategy.
> > +
> 
> This topic seems very hot lately. I recently sent out a few RFCs that
> implement something called a Virtual Contiguous Memory Manager that
> does what this patch does, and works for IOMMU and works for CPU
> mappings. It also does multihomed memory targeting (use physical set 1
> memory for A allocations and use physical memory set 2 for B
> allocations). Check out:
> 
> mm: iommu: An API to unify IOMMU, CPU and device memory management
> mm: iommu: A physical allocator for the VCMM
> mm: iommu: The Virtual Contiguous Memory Manager
> 
> It unifies IOMMU and physical mappings by creating a one-to-one
> software IOMMU for all devices that map memory physically.
> 
> It looks like you've got some good ideas though. Perhaps we can
> leverage each other's work.

We are aware of your patches. However our CMA solves the problem that is
a bit orthogonal to the setting up iommu. When you have IOMMU you don't really
need to care about memory fragmentation. In CMA approach we had to care
about it.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center


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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 18:41                 ` Michał Nazarewicz
@ 2010-07-22  9:06                   ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22  9:06 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, Jul 21, 2010 at 08:41:12PM +0200, Micha?? Nazarewicz wrote:
> On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> >> I am currently working on making the whole thing more dynamic.  I imagine

> > Yes, I think it will be much easier to be able to grab the regions at
> > startup but hopefully the allocation within those regions can be made
> > much more dynamic.  This would render most of the configuration syntax
> > unneeded.

> Not sure what you mean by the last sentence.  Maybe we have different
> things in mind?

I mean that if the drivers are able to request things dynamically and
have some knowledge of their own requirements then that removes the need
to manually specify exactly which regions go to which drivers which
means that most of the complexity of the existing syntax is not needed
since it can be figured out at runtime.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  9:06                   ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22  9:06 UTC (permalink / raw)
  To: Micha?? Nazarewicz
  Cc: Daniel Walker, linux-mm, Marek Szyprowski, Pawel Osciak,
	Xiaolin Zhang, Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon,
	linux-kernel, Kyungmin Park, linux-arm-msm

On Wed, Jul 21, 2010 at 08:41:12PM +0200, Micha?? Nazarewicz wrote:
> On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> >> I am currently working on making the whole thing more dynamic.  I imagine

> > Yes, I think it will be much easier to be able to grab the regions at
> > startup but hopefully the allocation within those regions can be made
> > much more dynamic.  This would render most of the configuration syntax
> > unneeded.

> Not sure what you mean by the last sentence.  Maybe we have different
> things in mind?

I mean that if the drivers are able to request things dynamically and
have some knowledge of their own requirements then that removes the need
to manually specify exactly which regions go to which drivers which
means that most of the complexity of the existing syntax is not needed
since it can be figured out at runtime.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  9:06                   ` Mark Brown
@ 2010-07-22  9:25                     ` Marek Szyprowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  9:25 UTC (permalink / raw)
  To: 'Mark Brown', Michal Nazarewicz
  Cc: 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

Hello,

On Thursday, July 22, 2010 11:06 AM Mark Brown wrote:

> On Wed, Jul 21, 2010 at 08:41:12PM +0200, Micha?? Nazarewicz wrote:
> > On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown
> <broonie@opensource.wolfsonmicro.com> wrote:
> 
> > >> I am currently working on making the whole thing more dynamic.  I
> imagine
> 
> > > Yes, I think it will be much easier to be able to grab the regions at
> > > startup but hopefully the allocation within those regions can be made
> > > much more dynamic.  This would render most of the configuration syntax
> > > unneeded.
> 
> > Not sure what you mean by the last sentence.  Maybe we have different
> > things in mind?
> 
> I mean that if the drivers are able to request things dynamically and
> have some knowledge of their own requirements then that removes the need
> to manually specify exactly which regions go to which drivers which
> means that most of the complexity of the existing syntax is not needed
> since it can be figured out at runtime.

The driver may specify memory requirements (like memory address range or
alignment), but it cannot provide enough information to avoid or reduce
memory fragmentation. More than one memory region can be perfectly used
to reduce memory fragmentation IF common usage patterns are known. In
embedded world usually not all integrated device are being used at the
same time. This way some memory regions can be shared by 2 or more devices. 

Just assume that gfx accelerator allocates memory is rather small chunks,
but keeps it while relevant surface is being displayed or processed by
application. It is not surprising that GUI (accelerated by the hardware
engine) is used almost all the time on a mobile device. This usage pattern
would produce a lot of fragmentation in the memory pool that is used by gfx
accelerator. Then we want to run a camera capture device to take a 8Mpix
photo. This require a large contiguous buffer. If we try to allocate it from
common pool it might happen that it is not possible (because of the
fragmentation).

With CMA approach we can create 2 memory regions for this case. One for gfx
accelerator and the other for camera capture device, video decoder or jpeg
decoder, because common usage analysis showed that these 3 devices usually
are not used at the same time.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center



^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  9:25                     ` Marek Szyprowski
  0 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2010-07-22  9:25 UTC (permalink / raw)
  To: 'Mark Brown', Michal Nazarewicz
  Cc: 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

Hello,

On Thursday, July 22, 2010 11:06 AM Mark Brown wrote:

> On Wed, Jul 21, 2010 at 08:41:12PM +0200, Micha?? Nazarewicz wrote:
> > On Wed, 21 Jul 2010 20:24:58 +0200, Mark Brown
> <broonie@opensource.wolfsonmicro.com> wrote:
> 
> > >> I am currently working on making the whole thing more dynamic.  I
> imagine
> 
> > > Yes, I think it will be much easier to be able to grab the regions at
> > > startup but hopefully the allocation within those regions can be made
> > > much more dynamic.  This would render most of the configuration syntax
> > > unneeded.
> 
> > Not sure what you mean by the last sentence.  Maybe we have different
> > things in mind?
> 
> I mean that if the drivers are able to request things dynamically and
> have some knowledge of their own requirements then that removes the need
> to manually specify exactly which regions go to which drivers which
> means that most of the complexity of the existing syntax is not needed
> since it can be figured out at runtime.

The driver may specify memory requirements (like memory address range or
alignment), but it cannot provide enough information to avoid or reduce
memory fragmentation. More than one memory region can be perfectly used
to reduce memory fragmentation IF common usage patterns are known. In
embedded world usually not all integrated device are being used at the
same time. This way some memory regions can be shared by 2 or more devices. 

Just assume that gfx accelerator allocates memory is rather small chunks,
but keeps it while relevant surface is being displayed or processed by
application. It is not surprising that GUI (accelerated by the hardware
engine) is used almost all the time on a mobile device. This usage pattern
would produce a lot of fragmentation in the memory pool that is used by gfx
accelerator. Then we want to run a camera capture device to take a 8Mpix
photo. This require a large contiguous buffer. If we try to allocate it from
common pool it might happen that it is not possible (because of the
fragmentation).

With CMA approach we can create 2 memory regions for this case. One for gfx
accelerator and the other for camera capture device, video decoder or jpeg
decoder, because common usage analysis showed that these 3 devices usually
are not used at the same time.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center


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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-21 21:01                                           ` Daniel Walker
@ 2010-07-22  9:34                                             ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22  9:34 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 23:01:42 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 22:56 +0200, Michał Nazarewicz wrote:
>> On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.
>>
>> Remove what exactly?
>
> Remove the command line option and all related code, or make it all a
> debug option.

How convenient... you have stripped the part of my mail where I described
why this is request have no sense.  I'll quote myself then:

>> The command line parameter? It's like 50 lines of code, so I don't
>> see any benefits.

As such, I'm not going to add bunch of #ifdefs just to remove 50 lines
of code.

>> The possibility to specify the configuration? It would defy the whole
>> purpose of CMA, so I won't do that.

Simply as that.  We work with a platform where whole of the functionality
provided by CMA is required (many regions, region start address, region
alignment, device->region mapping).

This means, what I keep repeating and you keep ignoring, that the complexity
will be there if not as a parsing code then moved to the platform
initialisation code and drivers code.

One of the purposes of CMA is to hide the complexity inside CMA framework so
device driver authors and platform maintainers can use a simpler interface.


Some time age (like year or two) I've posted some other solution to the
problem which served our purpose just well and had very little complexity
in it.  Unfortunately, customising that solution was quite hard (required
changes to a header file and adding modifying code for reserving space).

Also, in this old solution, adding or removing regions required device
drivers to be modified.

This was not nice, not nice at all.  True, however, the core wasn't complex.


So when you say remove the complicity I say: I have been there, it's ugly.


> Arguing with me isn't going to help your cause.

It's you who keep repeating “remove it, it's to complex” without
hearing my arguments.  I keep trying to show that all of the
functionality is required and is being used on our development
platform.

If your hardware does not require that complexity... well, you're one
lucky man.  Unfortunately, we are not, and we need a complex solution
to work with complex hardware.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  9:34                                             ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22  9:34 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linux-mm, Marek Szyprowski, Pawel Osciak, Xiaolin Zhang,
	Hiremath Vaibhav, Robert Fekete, Marcus Lorentzon, linux-kernel,
	Kyungmin Park, linux-arm-msm

On Wed, 21 Jul 2010 23:01:42 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:

> On Wed, 2010-07-21 at 22:56 +0200, Michał Nazarewicz wrote:
>> On Wed, 21 Jul 2010 22:45:43 +0200, Daniel Walker <dwalker@codeaurora.org> wrote:
>> > Your not hearing the issues.. IT'S TOO COMPLEX! Please remove it.
>>
>> Remove what exactly?
>
> Remove the command line option and all related code, or make it all a
> debug option.

How convenient... you have stripped the part of my mail where I described
why this is request have no sense.  I'll quote myself then:

>> The command line parameter? It's like 50 lines of code, so I don't
>> see any benefits.

As such, I'm not going to add bunch of #ifdefs just to remove 50 lines
of code.

>> The possibility to specify the configuration? It would defy the whole
>> purpose of CMA, so I won't do that.

Simply as that.  We work with a platform where whole of the functionality
provided by CMA is required (many regions, region start address, region
alignment, device->region mapping).

This means, what I keep repeating and you keep ignoring, that the complexity
will be there if not as a parsing code then moved to the platform
initialisation code and drivers code.

One of the purposes of CMA is to hide the complexity inside CMA framework so
device driver authors and platform maintainers can use a simpler interface.


Some time age (like year or two) I've posted some other solution to the
problem which served our purpose just well and had very little complexity
in it.  Unfortunately, customising that solution was quite hard (required
changes to a header file and adding modifying code for reserving space).

Also, in this old solution, adding or removing regions required device
drivers to be modified.

This was not nice, not nice at all.  True, however, the core wasn't complex.


So when you say remove the complicity I say: I have been there, it's ugly.


> Arguing with me isn't going to help your cause.

It's you who keep repeating “remove it, it's to complex” without
hearing my arguments.  I keep trying to show that all of the
functionality is required and is being used on our development
platform.

If your hardware does not require that complexity... well, you're one
lucky man.  Unfortunately, we are not, and we need a complex solution
to work with complex hardware.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  7:28           ` Marek Szyprowski
@ 2010-07-22  9:35             ` FUJITA Tomonori
  -1 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22  9:35 UTC (permalink / raw)
  To: m.szyprowski
  Cc: fujita.tomonori, corbet, m.nazarewicz, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 09:28:02 +0200
Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> > About the framework, it looks too complicated than we actually need
> > (the command line stuff looks insane).
> 
> Well, this command line stuff was designed to provide a way to configure
> memory allocation for devices with very sophisticated memory requirements.

You have the feature in the wrong place.

Your example: a camera driver and a video driver can share 20MB, then
they want 20MB exclusively.

You can reserve 20MB and make them share it. Then you can reserve 20MB
for both exclusively.

You know how the whole system works. Adjust drivers (probably, with
module parameters).


> > Why can't we have something simpler, like using memblock to reserve
> > contiguous memory at boot and using kinda mempool to share such memory
> > between devices?
> 
> There are a few problems with such simple approach:
> 
> 1. It does not provide all required functionality for our multimedia
> devices. The main problem is the fact that our multimedia devices
> require particular kind of buffers to be allocated in particular memory
> bank. Then add 2 more requirements: a proper alignment (for some of them
> it is even 128Kb) and particular range of addresses requirement (some
> buffers must be allocated at higher addresses than the firmware).
> This is very hard to achieve with such simple allocator.

When a video driver needs 20MB to work properly, what's the point of
releasing the 20MB for others then trying to get it again later?

Even with the above example (two devices never use the memory at the
same time), the driver needs memory regularly. What's the point of
split the 20MB to small chunks and allocate them to others?

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  9:35             ` FUJITA Tomonori
  0 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22  9:35 UTC (permalink / raw)
  To: m.szyprowski
  Cc: fujita.tomonori, corbet, m.nazarewicz, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 09:28:02 +0200
Marek Szyprowski <m.szyprowski@samsung.com> wrote:

> > About the framework, it looks too complicated than we actually need
> > (the command line stuff looks insane).
> 
> Well, this command line stuff was designed to provide a way to configure
> memory allocation for devices with very sophisticated memory requirements.

You have the feature in the wrong place.

Your example: a camera driver and a video driver can share 20MB, then
they want 20MB exclusively.

You can reserve 20MB and make them share it. Then you can reserve 20MB
for both exclusively.

You know how the whole system works. Adjust drivers (probably, with
module parameters).


> > Why can't we have something simpler, like using memblock to reserve
> > contiguous memory at boot and using kinda mempool to share such memory
> > between devices?
> 
> There are a few problems with such simple approach:
> 
> 1. It does not provide all required functionality for our multimedia
> devices. The main problem is the fact that our multimedia devices
> require particular kind of buffers to be allocated in particular memory
> bank. Then add 2 more requirements: a proper alignment (for some of them
> it is even 128Kb) and particular range of addresses requirement (some
> buffers must be allocated at higher addresses than the firmware).
> This is very hard to achieve with such simple allocator.

When a video driver needs 20MB to work properly, what's the point of
releasing the 20MB for others then trying to get it again later?

Even with the above example (two devices never use the memory at the
same time), the driver needs memory regularly. What's the point of
split the 20MB to small chunks and allocate them to others?

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  9:35             ` FUJITA Tomonori
@ 2010-07-22  9:50               ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22  9:50 UTC (permalink / raw)
  To: m.szyprowski, FUJITA Tomonori
  Cc: corbet, linux-mm, p.osciak, xiaolin.zhang, hvaibhav,
	robert.fekete, marcus.xm.lorentzon, linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 11:35:07 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> You have the feature in the wrong place.
>
> Your example: a camera driver and a video driver can share 20MB, then
> they want 20MB exclusively.
>
> You can reserve 20MB and make them share it. Then you can reserve 20MB
> for both exclusively.
>
> You know how the whole system works. Adjust drivers (probably, with
> module parameters).

So you are talking about moving complexity from the CMA core to the drivers.
Ie. instead of configuring regions and mapping via CMA command line
parameters, the whole configuration is pushed to modules.  We consider that
suboptimal because it (i) does not reduce complexity -- it just moves it
somewhere else, (ii) spreads the complexity to many modules instead of
single core of CMA, and (iii) spreads the configuration to many modules
instead of keeping it in one place.


> When a video driver needs 20MB to work properly, what's the point of
> releasing the 20MB for others then trying to get it again later?

If you have a video driver that needs 20MiB and a camera that needs 20MiB
will you reserve 40MiB total? That's 20MiB wasted if on your system those
two can never work at the same time.  So do you reserve 20MiB and share?
That won't work if on your system the two can work at the same time.

With CMA you can configure the kernel for both cases.

> Even with the above example (two devices never use the memory at the
> same time), the driver needs memory regularly. What's the point of
> split the 20MB to small chunks and allocate them to others?

Lost you there...  If something does not make sense on your system you
don't configure CMA to do that.  That's one of the points of CMA.  What
does not make sense on your platform may make perfect sense on some
other system, with some other drivers maybe.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22  9:50               ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22  9:50 UTC (permalink / raw)
  To: m.szyprowski, FUJITA Tomonori
  Cc: corbet, linux-mm, p.osciak, xiaolin.zhang, hvaibhav,
	robert.fekete, marcus.xm.lorentzon, linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 11:35:07 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> You have the feature in the wrong place.
>
> Your example: a camera driver and a video driver can share 20MB, then
> they want 20MB exclusively.
>
> You can reserve 20MB and make them share it. Then you can reserve 20MB
> for both exclusively.
>
> You know how the whole system works. Adjust drivers (probably, with
> module parameters).

So you are talking about moving complexity from the CMA core to the drivers.
Ie. instead of configuring regions and mapping via CMA command line
parameters, the whole configuration is pushed to modules.  We consider that
suboptimal because it (i) does not reduce complexity -- it just moves it
somewhere else, (ii) spreads the complexity to many modules instead of
single core of CMA, and (iii) spreads the configuration to many modules
instead of keeping it in one place.


> When a video driver needs 20MB to work properly, what's the point of
> releasing the 20MB for others then trying to get it again later?

If you have a video driver that needs 20MiB and a camera that needs 20MiB
will you reserve 40MiB total? That's 20MiB wasted if on your system those
two can never work at the same time.  So do you reserve 20MiB and share?
That won't work if on your system the two can work at the same time.

With CMA you can configure the kernel for both cases.

> Even with the above example (two devices never use the memory at the
> same time), the driver needs memory regularly. What's the point of
> split the 20MB to small chunks and allocate them to others?

Lost you there...  If something does not make sense on your system you
don't configure CMA to do that.  That's one of the points of CMA.  What
does not make sense on your platform may make perfect sense on some
other system, with some other drivers maybe.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  9:50               ` Michał Nazarewicz
@ 2010-07-22 10:17                 ` FUJITA Tomonori
  -1 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22 10:17 UTC (permalink / raw)
  To: m.nazarewicz
  Cc: m.szyprowski, fujita.tomonori, corbet, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 11:50:58 +0200
**UNKNOWN CHARSET** <m.nazarewicz@samsung.com> wrote:

> On Thu, 22 Jul 2010 11:35:07 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> > You have the feature in the wrong place.
> >
> > Your example: a camera driver and a video driver can share 20MB, then
> > they want 20MB exclusively.
> >
> > You can reserve 20MB and make them share it. Then you can reserve 20MB
> > for both exclusively.
> >
> > You know how the whole system works. Adjust drivers (probably, with
> > module parameters).
> 
> So you are talking about moving complexity from the CMA core to the drivers.

I don't think that adjusting some drivers about how they use memory is
so complicated. Just about how much and exclusive or share.

And adjusting drivers in embedded systems is necessary anyway.

It's too complicated feature that isn't useful for the majority.


> > When a video driver needs 20MB to work properly, what's the point of
> > releasing the 20MB for others then trying to get it again later?
> 
> If you have a video driver that needs 20MiB and a camera that needs 20MiB
> will you reserve 40MiB total? That's 20MiB wasted if on your system those
> two can never work at the same time. So do you reserve 20MiB and share?
> That won't work if on your system the two can work at the same time.
> 
> With CMA you can configure the kernel for both cases.

See above. You can do without such complicated framework.


> Lost you there...  If something does not make sense on your system you
> don't configure CMA to do that. That's one of the points of CMA.  What
> does not make sense on your platform may make perfect sense on some
> other system, with some other drivers maybe.

What's your point? The majority of features (e.g. scsi, ata, whatever)
works in that way. They are useful on some and not on some.

Are you saying, "my system needs this feature. You can disable it if
you don't need it. so let's merge it. it doesn't break your system."?

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 10:17                 ` FUJITA Tomonori
  0 siblings, 0 replies; 98+ messages in thread
From: FUJITA Tomonori @ 2010-07-22 10:17 UTC (permalink / raw)
  To: m.nazarewicz
  Cc: m.szyprowski, fujita.tomonori, corbet, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, 22 Jul 2010 11:50:58 +0200
**UNKNOWN CHARSET** <m.nazarewicz@samsung.com> wrote:

> On Thu, 22 Jul 2010 11:35:07 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> > You have the feature in the wrong place.
> >
> > Your example: a camera driver and a video driver can share 20MB, then
> > they want 20MB exclusively.
> >
> > You can reserve 20MB and make them share it. Then you can reserve 20MB
> > for both exclusively.
> >
> > You know how the whole system works. Adjust drivers (probably, with
> > module parameters).
> 
> So you are talking about moving complexity from the CMA core to the drivers.

I don't think that adjusting some drivers about how they use memory is
so complicated. Just about how much and exclusive or share.

And adjusting drivers in embedded systems is necessary anyway.

It's too complicated feature that isn't useful for the majority.


> > When a video driver needs 20MB to work properly, what's the point of
> > releasing the 20MB for others then trying to get it again later?
> 
> If you have a video driver that needs 20MiB and a camera that needs 20MiB
> will you reserve 40MiB total? That's 20MiB wasted if on your system those
> two can never work at the same time. So do you reserve 20MiB and share?
> That won't work if on your system the two can work at the same time.
> 
> With CMA you can configure the kernel for both cases.

See above. You can do without such complicated framework.


> Lost you there...  If something does not make sense on your system you
> don't configure CMA to do that. That's one of the points of CMA.  What
> does not make sense on your platform may make perfect sense on some
> other system, with some other drivers maybe.

What's your point? The majority of features (e.g. scsi, ata, whatever)
works in that way. They are useful on some and not on some.

Are you saying, "my system needs this feature. You can disable it if
you don't need it. so let's merge it. it doesn't break your system."?

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  9:25                     ` Marek Szyprowski
@ 2010-07-22 10:52                       ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 10:52 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Michal Nazarewicz, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 11:25:48AM +0200, Marek Szyprowski wrote:

> The driver may specify memory requirements (like memory address range or
> alignment), but it cannot provide enough information to avoid or reduce
> memory fragmentation. More than one memory region can be perfectly used
> to reduce memory fragmentation IF common usage patterns are known. In
> embedded world usually not all integrated device are being used at the
> same time. This way some memory regions can be shared by 2 or more devices. 

I do have some passing familiarity with the area, typically a lot of the
features of a SoC won't get used at all at runtime on any given system.

> Just assume that gfx accelerator allocates memory is rather small chunks,
> but keeps it while relevant surface is being displayed or processed by
> application. It is not surprising that GUI (accelerated by the hardware
> engine) is used almost all the time on a mobile device. This usage pattern
> would produce a lot of fragmentation in the memory pool that is used by gfx
> accelerator. Then we want to run a camera capture device to take a 8Mpix

I'd expect that the devices would be able to reserve blocks of memory to
play with separately to the actual allocations (ie, allocate regions
like those on the command line) and things like the GPU would make use
of that.  I think you're already doing part of this?

> photo. This require a large contiguous buffer. If we try to allocate it from
> common pool it might happen that it is not possible (because of the
> fragmentation).

Sure, but none of this is saying to me that it's specifically important
to supply a static configuration via this textual configuration language
on the command line - half the problem is that you're trying to write
the configuration down in a format which is fairly tightly constrained
by needing to be there.  If the configuration is more dynamic there's a
lot more flexibility to either allow the system to figure things out
dynamically (which will hopefully work a lot of the time, for example in
your use case only the GPU really needs memory reserving).

Remember also that if you can configure this at runtime (as you say
you're working towards) then even if you have a fairly static
configuration you can inject it into the kernel from the application
layer rather than having to either hard code it in the image or bodge it
in via the command line.  This keeps the resource allocation joined up
with the application layer (which is after all what determines the
resource usage).

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 10:52                       ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 10:52 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Michal Nazarewicz, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 11:25:48AM +0200, Marek Szyprowski wrote:

> The driver may specify memory requirements (like memory address range or
> alignment), but it cannot provide enough information to avoid or reduce
> memory fragmentation. More than one memory region can be perfectly used
> to reduce memory fragmentation IF common usage patterns are known. In
> embedded world usually not all integrated device are being used at the
> same time. This way some memory regions can be shared by 2 or more devices. 

I do have some passing familiarity with the area, typically a lot of the
features of a SoC won't get used at all at runtime on any given system.

> Just assume that gfx accelerator allocates memory is rather small chunks,
> but keeps it while relevant surface is being displayed or processed by
> application. It is not surprising that GUI (accelerated by the hardware
> engine) is used almost all the time on a mobile device. This usage pattern
> would produce a lot of fragmentation in the memory pool that is used by gfx
> accelerator. Then we want to run a camera capture device to take a 8Mpix

I'd expect that the devices would be able to reserve blocks of memory to
play with separately to the actual allocations (ie, allocate regions
like those on the command line) and things like the GPU would make use
of that.  I think you're already doing part of this?

> photo. This require a large contiguous buffer. If we try to allocate it from
> common pool it might happen that it is not possible (because of the
> fragmentation).

Sure, but none of this is saying to me that it's specifically important
to supply a static configuration via this textual configuration language
on the command line - half the problem is that you're trying to write
the configuration down in a format which is fairly tightly constrained
by needing to be there.  If the configuration is more dynamic there's a
lot more flexibility to either allow the system to figure things out
dynamically (which will hopefully work a lot of the time, for example in
your use case only the GPU really needs memory reserving).

Remember also that if you can configure this at runtime (as you say
you're working towards) then even if you have a fairly static
configuration you can inject it into the kernel from the application
layer rather than having to either hard code it in the image or bodge it
in via the command line.  This keeps the resource allocation joined up
with the application layer (which is after all what determines the
resource usage).

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 10:17                 ` FUJITA Tomonori
@ 2010-07-22 10:55                   ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 10:55 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: m.nazarewicz, m.szyprowski, corbet, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, Jul 22, 2010 at 07:17:42PM +0900, FUJITA Tomonori wrote:

> And adjusting drivers in embedded systems is necessary anyway.

Actually for embedded systems we make strong efforts to ensure that
drivers do not need tuning per system and that where this is unavoidable
we separate the configuration from the driver itself (using either a
driver specific interface or a subsystem one depending on the
genericness) so that the driver does not need modifying.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 10:55                   ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 10:55 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: m.nazarewicz, m.szyprowski, corbet, linux-mm, p.osciak,
	xiaolin.zhang, hvaibhav, robert.fekete, marcus.xm.lorentzon,
	linux-kernel, kyungmin.park

On Thu, Jul 22, 2010 at 07:17:42PM +0900, FUJITA Tomonori wrote:

> And adjusting drivers in embedded systems is necessary anyway.

Actually for embedded systems we make strong efforts to ensure that
drivers do not need tuning per system and that where this is unavoidable
we separate the configuration from the driver itself (using either a
driver specific interface or a subsystem one depending on the
genericness) so that the driver does not need modifying.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 10:52                       ` Mark Brown
@ 2010-07-22 11:30                         ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 11:30 UTC (permalink / raw)
  To: Marek Szyprowski, Mark Brown
  Cc: 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, 22 Jul 2010 12:52:03 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> I'd expect that the devices would be able to reserve blocks of memory to
> play with separately to the actual allocations (ie, allocate regions
> like those on the command line) and things like the GPU would make use
> of that.  I think you're already doing part of this?

In the patchset I've sent it is not possible but I already have a version that
supports this.  Regions can be registered at any time.  What's more, such
regions can be completely private to drivers that register them.

> Sure, but none of this is saying to me that it's specifically important
> to supply a static configuration via this textual configuration language
> on the command line - half the problem is that you're trying to write
> the configuration down in a format which is fairly tightly constrained
> by needing to be there.  If the configuration is more dynamic there's a
> lot more flexibility to either allow the system to figure things out
> dynamically (which will hopefully work a lot of the time, for example in
> your use case only the GPU really needs memory reserving).
>
> Remember also that if you can configure this at runtime (as you say
> you're working towards) then even if you have a fairly static
> configuration you can inject it into the kernel from the application
> layer rather than having to either hard code it in the image or bodge it
> in via the command line.  This keeps the resource allocation joined up
> with the application layer (which is after all what determines the
> resource usage).

There are two command line arguments to consider: cma and cma_map.


The first one, I believe, should be there as to specify the regions
that are to be reserved.  Drivers and platform will still be able to
add their own regions but I believe that in vest majority of cases,
it will be enough to just pass the list of region on a command line.

Alternatively, instead of the textual description of platform could
provide an array of regions it want reserved.  It would remove like
50 lines of code from CMA core (in the version I have on my drive at
least, where part of the syntax was simplified) however it would
remove the possibility to easily change the configuration from
command line (ie. no need to recompile which is handy when you need
to optimise this and test various configurations) and would add more
code to the platform initialisation code, ie: instead of:

	cma_defaults("reg1=20M;reg2=20M", NULL);

one would have to define an array with the regions descriptors.
Personally, I don't see much benefits from this.


As of the second parameter, "cma_map", which validating and parsing
is like 150 lines of code, I consider it handy because you can manage
all the memory regions in one place and it moves some of the complexity
 from device drivers to CMA.  I'm also working on providing a sysfs
entry so that the it would be possible to change the mapping at runtime.

For example, consider a driver I have mentioned before: video decoder
that needs to allocate memory from 3 different regions (for firmware,
the first bank of memory and the second bank of memory).  With CMA you
define the regions:

	cma=vf=1M/128K;a=20M;b=20M@512M;

and then map video driver to them like so:

	cma_map=video/a=a;video/b=b;video/f=vf

I agree that parsing it is not nice but thanks to it, all you need to
do in the driver is:

	cma_alloc(dev, "a", ...)
	cma_alloc(dev, "b", ...)
	cma_alloc(dev, "f", ...)

Without cma_map you'd have to pass names of the region to the driver
and make the driver use those.

It would also make it impossible or hard to change the mapping once
the driver is loaded.


What I'm trying to say is that I'm trying to move complexity out of
the drivers into the framework (as I believe that's what frameworks
are for).


As of dynamic, runtime, automatic configuration, I don't really see
that.  I'm still wondering how to make as little configuration
necessary as possible but I don't think everything can be done
in such a way.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 11:30                         ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 11:30 UTC (permalink / raw)
  To: Marek Szyprowski, Mark Brown
  Cc: 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, 22 Jul 2010 12:52:03 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> I'd expect that the devices would be able to reserve blocks of memory to
> play with separately to the actual allocations (ie, allocate regions
> like those on the command line) and things like the GPU would make use
> of that.  I think you're already doing part of this?

In the patchset I've sent it is not possible but I already have a version that
supports this.  Regions can be registered at any time.  What's more, such
regions can be completely private to drivers that register them.

> Sure, but none of this is saying to me that it's specifically important
> to supply a static configuration via this textual configuration language
> on the command line - half the problem is that you're trying to write
> the configuration down in a format which is fairly tightly constrained
> by needing to be there.  If the configuration is more dynamic there's a
> lot more flexibility to either allow the system to figure things out
> dynamically (which will hopefully work a lot of the time, for example in
> your use case only the GPU really needs memory reserving).
>
> Remember also that if you can configure this at runtime (as you say
> you're working towards) then even if you have a fairly static
> configuration you can inject it into the kernel from the application
> layer rather than having to either hard code it in the image or bodge it
> in via the command line.  This keeps the resource allocation joined up
> with the application layer (which is after all what determines the
> resource usage).

There are two command line arguments to consider: cma and cma_map.


The first one, I believe, should be there as to specify the regions
that are to be reserved.  Drivers and platform will still be able to
add their own regions but I believe that in vest majority of cases,
it will be enough to just pass the list of region on a command line.

Alternatively, instead of the textual description of platform could
provide an array of regions it want reserved.  It would remove like
50 lines of code from CMA core (in the version I have on my drive at
least, where part of the syntax was simplified) however it would
remove the possibility to easily change the configuration from
command line (ie. no need to recompile which is handy when you need
to optimise this and test various configurations) and would add more
code to the platform initialisation code, ie: instead of:

	cma_defaults("reg1=20M;reg2=20M", NULL);

one would have to define an array with the regions descriptors.
Personally, I don't see much benefits from this.


As of the second parameter, "cma_map", which validating and parsing
is like 150 lines of code, I consider it handy because you can manage
all the memory regions in one place and it moves some of the complexity
 from device drivers to CMA.  I'm also working on providing a sysfs
entry so that the it would be possible to change the mapping at runtime.

For example, consider a driver I have mentioned before: video decoder
that needs to allocate memory from 3 different regions (for firmware,
the first bank of memory and the second bank of memory).  With CMA you
define the regions:

	cma=vf=1M/128K;a=20M;b=20M@512M;

and then map video driver to them like so:

	cma_map=video/a=a;video/b=b;video/f=vf

I agree that parsing it is not nice but thanks to it, all you need to
do in the driver is:

	cma_alloc(dev, "a", ...)
	cma_alloc(dev, "b", ...)
	cma_alloc(dev, "f", ...)

Without cma_map you'd have to pass names of the region to the driver
and make the driver use those.

It would also make it impossible or hard to change the mapping once
the driver is loaded.


What I'm trying to say is that I'm trying to move complexity out of
the drivers into the framework (as I believe that's what frameworks
are for).


As of dynamic, runtime, automatic configuration, I don't really see
that.  I'm still wondering how to make as little configuration
necessary as possible but I don't think everything can be done
in such a way.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 10:17                 ` FUJITA Tomonori
@ 2010-07-22 11:49                   ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 11:49 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: m.szyprowski, corbet, linux-mm, p.osciak, xiaolin.zhang,
	hvaibhav, robert.fekete, marcus.xm.lorentzon, linux-kernel,
	kyungmin.park

> On Thu, 22 Jul 2010 11:50:58 +0200
> **UNKNOWN CHARSET** <m.nazarewicz@samsung.com> wrote:
>> So you are talking about moving complexity from the CMA core to the drivers.

On Thu, 22 Jul 2010 12:17:42 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> I don't think that adjusting some drivers about how they use memory is
> so complicated. Just about how much and exclusive or share.

I don't believe it is that simple.  If shared then with what?  What if
foo-dev can share with bar-dev and baz-dev can share with qux-dev?

Also, even if its 10 lines of code in each driver isn't it worth
removing from the driver and not let it worry about it?

The configuration needs to be specified one way of another, my approach
with CMA was to centralise it so that drivers do not need to worry about
it.

> And adjusting drivers in embedded systems is necessary anyway.

It should not be...

> It's too complicated feature that isn't useful for the majority.

Please consider what I've written in discussion with Mark Brown.

>> Lost you there...  If something does not make sense on your system you
>> don't configure CMA to do that. That's one of the points of CMA.  What
>> does not make sense on your platform may make perfect sense on some
>> other system, with some other drivers maybe.

> What's your point? The majority of features (e.g. scsi, ata, whatever)
> works in that way. They are useful on some and not on some.

My point is, that you can configure CMA the way you want...

> Are you saying, "my system needs this feature. You can disable it if
> you don't need it. so let's merge it. it doesn't break your system."?

No.  I'm saying many of the embedded systems without IO MMU need to be
able to allocate contiguous memory chunks.  I'm also saying there is at
least one system where some non-trivial configuration is needed and
adding configuration handling to CMA is not as big of a cost as one may
imagine.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 11:49                   ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 11:49 UTC (permalink / raw)
  To: FUJITA Tomonori
  Cc: m.szyprowski, corbet, linux-mm, p.osciak, xiaolin.zhang,
	hvaibhav, robert.fekete, marcus.xm.lorentzon, linux-kernel,
	kyungmin.park

> On Thu, 22 Jul 2010 11:50:58 +0200
> **UNKNOWN CHARSET** <m.nazarewicz@samsung.com> wrote:
>> So you are talking about moving complexity from the CMA core to the drivers.

On Thu, 22 Jul 2010 12:17:42 +0200, FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
> I don't think that adjusting some drivers about how they use memory is
> so complicated. Just about how much and exclusive or share.

I don't believe it is that simple.  If shared then with what?  What if
foo-dev can share with bar-dev and baz-dev can share with qux-dev?

Also, even if its 10 lines of code in each driver isn't it worth
removing from the driver and not let it worry about it?

The configuration needs to be specified one way of another, my approach
with CMA was to centralise it so that drivers do not need to worry about
it.

> And adjusting drivers in embedded systems is necessary anyway.

It should not be...

> It's too complicated feature that isn't useful for the majority.

Please consider what I've written in discussion with Mark Brown.

>> Lost you there...  If something does not make sense on your system you
>> don't configure CMA to do that. That's one of the points of CMA.  What
>> does not make sense on your platform may make perfect sense on some
>> other system, with some other drivers maybe.

> What's your point? The majority of features (e.g. scsi, ata, whatever)
> works in that way. They are useful on some and not on some.

My point is, that you can configure CMA the way you want...

> Are you saying, "my system needs this feature. You can disable it if
> you don't need it. so let's merge it. it doesn't break your system."?

No.  I'm saying many of the embedded systems without IO MMU need to be
able to allocate contiguous memory chunks.  I'm also saying there is at
least one system where some non-trivial configuration is needed and
adding configuration handling to CMA is not as big of a cost as one may
imagine.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 11:30                         ` Michał Nazarewicz
@ 2010-07-22 12:46                           ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 12:46 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 01:30:52PM +0200, Michał Nazarewicz wrote:

> The first one, I believe, should be there as to specify the regions
> that are to be reserved.  Drivers and platform will still be able to
> add their own regions but I believe that in vest majority of cases,
> it will be enough to just pass the list of region on a command line.

The command line is a real pain for stuff like this since it's not
usually committed to revision control so robustly and it's normally more
painful to change the bootloader to pass the desired command line in
than it is to change either the kernel or userspace (some bootloaders
are just completely unconfigurable without reflashing, and if your only
recovery mechanism is JTAG that can be a bit of a concern).

> Alternatively, instead of the textual description of platform could
> provide an array of regions it want reserved.  It would remove like
> 50 lines of code from CMA core (in the version I have on my drive at
> least, where part of the syntax was simplified) however it would
> remove the possibility to easily change the configuration from
> command line (ie. no need to recompile which is handy when you need
> to optimise this and test various configurations) and would add more
> code to the platform initialisation code, ie: instead of:

> 	cma_defaults("reg1=20M;reg2=20M", NULL);

> one would have to define an array with the regions descriptors.
> Personally, I don't see much benefits from this.

I think it'd be vastly more legible, especially if the list of regions
gets large.  I had thought the only reason for the text format was to
put it onto the command line.

> I agree that parsing it is not nice but thanks to it, all you need to
> do in the driver is:

> 	cma_alloc(dev, "a", ...)
> 	cma_alloc(dev, "b", ...)
> 	cma_alloc(dev, "f", ...)

> Without cma_map you'd have to pass names of the region to the driver
> and make the driver use those.

I agree that a mapping facility for the names is essential, especially
if drivers need to share regions.

> What I'm trying to say is that I'm trying to move complexity out of
> the drivers into the framework (as I believe that's what frameworks
> are for).

It sounds like apart from the way you're passing the configuration in
you're doing roughly what I'd suggest.  I'd expect that in a lot of
cases the map could be satisfied from the default region so there'd be
no need to explicitly set one up.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 12:46                           ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 12:46 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 01:30:52PM +0200, MichaA? Nazarewicz wrote:

> The first one, I believe, should be there as to specify the regions
> that are to be reserved.  Drivers and platform will still be able to
> add their own regions but I believe that in vest majority of cases,
> it will be enough to just pass the list of region on a command line.

The command line is a real pain for stuff like this since it's not
usually committed to revision control so robustly and it's normally more
painful to change the bootloader to pass the desired command line in
than it is to change either the kernel or userspace (some bootloaders
are just completely unconfigurable without reflashing, and if your only
recovery mechanism is JTAG that can be a bit of a concern).

> Alternatively, instead of the textual description of platform could
> provide an array of regions it want reserved.  It would remove like
> 50 lines of code from CMA core (in the version I have on my drive at
> least, where part of the syntax was simplified) however it would
> remove the possibility to easily change the configuration from
> command line (ie. no need to recompile which is handy when you need
> to optimise this and test various configurations) and would add more
> code to the platform initialisation code, ie: instead of:

> 	cma_defaults("reg1=20M;reg2=20M", NULL);

> one would have to define an array with the regions descriptors.
> Personally, I don't see much benefits from this.

I think it'd be vastly more legible, especially if the list of regions
gets large.  I had thought the only reason for the text format was to
put it onto the command line.

> I agree that parsing it is not nice but thanks to it, all you need to
> do in the driver is:

> 	cma_alloc(dev, "a", ...)
> 	cma_alloc(dev, "b", ...)
> 	cma_alloc(dev, "f", ...)

> Without cma_map you'd have to pass names of the region to the driver
> and make the driver use those.

I agree that a mapping facility for the names is essential, especially
if drivers need to share regions.

> What I'm trying to say is that I'm trying to move complexity out of
> the drivers into the framework (as I believe that's what frameworks
> are for).

It sounds like apart from the way you're passing the configuration in
you're doing roughly what I'd suggest.  I'd expect that in a lot of
cases the map could be satisfied from the default region so there'd be
no need to explicitly set one up.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 12:46                           ` Mark Brown
@ 2010-07-22 13:24                             ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 13:24 UTC (permalink / raw)
  To: Mark Brown
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

> On Thu, Jul 22, 2010 at 01:30:52PM +0200, Michał Nazarewicz wrote:
>> The first one, I believe, should be there as to specify the regions
>> that are to be reserved.  Drivers and platform will still be able to
>> add their own regions but I believe that in vest majority of cases,
>> it will be enough to just pass the list of region on a command line.

On Thu, 22 Jul 2010 14:46:00 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> The command line is a real pain for stuff like this since it's not
> usually committed to revision control so robustly and it's normally more
> painful to change the bootloader to pass the desired command line in
> than it is to change either the kernel or userspace (some bootloaders
> are just completely unconfigurable without reflashing, and if your only
> recovery mechanism is JTAG that can be a bit of a concern).

That's why command line is only intended as a way to overwrite the
defaults which are provided by the platform.  In a final product,
configuration should be specified in platform code and not on
command line.

>> Alternatively, instead of the textual description of platform could
>> provide an array of regions it want reserved.  It would remove like
>> 50 lines of code from CMA core (in the version I have on my drive at
>> least, where part of the syntax was simplified) however it would
>> remove the possibility to easily change the configuration from
>> command line (ie. no need to recompile which is handy when you need
>> to optimise this and test various configurations) and would add more
>> code to the platform initialisation code, ie: instead of:
>>
>> 	cma_defaults("reg1=20M;reg2=20M", NULL);
>
>> one would have to define an array with the regions descriptors.
>> Personally, I don't see much benefits from this.
>
> I think it'd be vastly more legible, especially if the list of regions
> gets large.  I had thought the only reason for the text format was to
> put it onto the command line.

Command line was one of the reasons for using textual interface.  I surely
wouldn't go with parsing the strings if I could manage without it allowing
easy platform-level configuration at the same time.

>> I agree that parsing it is not nice but thanks to it, all you need to
>> do in the driver is:
>>
>> 	cma_alloc(dev, "a", ...)
>> 	cma_alloc(dev, "b", ...)
>> 	cma_alloc(dev, "f", ...)
>>
>> Without cma_map you'd have to pass names of the region to the driver
>> and make the driver use those.
>
> I agree that a mapping facility for the names is essential, especially
> if drivers need to share regions.
>
>> What I'm trying to say is that I'm trying to move complexity out of
>> the drivers into the framework (as I believe that's what frameworks
>> are for).
>
> It sounds like apart from the way you're passing the configuration in
> you're doing roughly what I'd suggest.  I'd expect that in a lot of
> cases the map could be satisfied from the default region so there'd be
> no need to explicitly set one up.

Platform can specify something like:

	cma_defaults("reg=20M", "*/*=reg");

which would make all the drivers share 20 MiB region by default.  I'm also
thinking if something like:

	cma_defaults("reg=20M", "*/*=*");

(ie. asterisk instead of list of regions) should be allowed.  It would make
the default to be that all allocations are performed from all named regions.
I'll see how much coding is that and maybe add it.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 13:24                             ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 13:24 UTC (permalink / raw)
  To: Mark Brown
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

> On Thu, Jul 22, 2010 at 01:30:52PM +0200, Michał Nazarewicz wrote:
>> The first one, I believe, should be there as to specify the regions
>> that are to be reserved.  Drivers and platform will still be able to
>> add their own regions but I believe that in vest majority of cases,
>> it will be enough to just pass the list of region on a command line.

On Thu, 22 Jul 2010 14:46:00 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:
> The command line is a real pain for stuff like this since it's not
> usually committed to revision control so robustly and it's normally more
> painful to change the bootloader to pass the desired command line in
> than it is to change either the kernel or userspace (some bootloaders
> are just completely unconfigurable without reflashing, and if your only
> recovery mechanism is JTAG that can be a bit of a concern).

That's why command line is only intended as a way to overwrite the
defaults which are provided by the platform.  In a final product,
configuration should be specified in platform code and not on
command line.

>> Alternatively, instead of the textual description of platform could
>> provide an array of regions it want reserved.  It would remove like
>> 50 lines of code from CMA core (in the version I have on my drive at
>> least, where part of the syntax was simplified) however it would
>> remove the possibility to easily change the configuration from
>> command line (ie. no need to recompile which is handy when you need
>> to optimise this and test various configurations) and would add more
>> code to the platform initialisation code, ie: instead of:
>>
>> 	cma_defaults("reg1=20M;reg2=20M", NULL);
>
>> one would have to define an array with the regions descriptors.
>> Personally, I don't see much benefits from this.
>
> I think it'd be vastly more legible, especially if the list of regions
> gets large.  I had thought the only reason for the text format was to
> put it onto the command line.

Command line was one of the reasons for using textual interface.  I surely
wouldn't go with parsing the strings if I could manage without it allowing
easy platform-level configuration at the same time.

>> I agree that parsing it is not nice but thanks to it, all you need to
>> do in the driver is:
>>
>> 	cma_alloc(dev, "a", ...)
>> 	cma_alloc(dev, "b", ...)
>> 	cma_alloc(dev, "f", ...)
>>
>> Without cma_map you'd have to pass names of the region to the driver
>> and make the driver use those.
>
> I agree that a mapping facility for the names is essential, especially
> if drivers need to share regions.
>
>> What I'm trying to say is that I'm trying to move complexity out of
>> the drivers into the framework (as I believe that's what frameworks
>> are for).
>
> It sounds like apart from the way you're passing the configuration in
> you're doing roughly what I'd suggest.  I'd expect that in a lot of
> cases the map could be satisfied from the default region so there'd be
> no need to explicitly set one up.

Platform can specify something like:

	cma_defaults("reg=20M", "*/*=reg");

which would make all the drivers share 20 MiB region by default.  I'm also
thinking if something like:

	cma_defaults("reg=20M", "*/*=*");

(ie. asterisk instead of list of regions) should be allowed.  It would make
the default to be that all allocations are performed from all named regions.
I'll see how much coding is that and maybe add it.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 13:24                             ` Michał Nazarewicz
@ 2010-07-22 13:40                               ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 13:40 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 03:24:26PM +0200, Michał Nazarewicz wrote:

> That's why command line is only intended as a way to overwrite the
> defaults which are provided by the platform.  In a final product,
> configuration should be specified in platform code and not on
> command line.

Yeah, agreed though I'm not convinced we can't do it via userspace
(initrd would give us a chance to do stuff early) or just kernel
rebuilds.

> >It sounds like apart from the way you're passing the configuration in
> >you're doing roughly what I'd suggest.  I'd expect that in a lot of
> >cases the map could be satisfied from the default region so there'd be
> >no need to explicitly set one up.

> Platform can specify something like:

> 	cma_defaults("reg=20M", "*/*=reg");

> which would make all the drivers share 20 MiB region by default.  I'm also
> thinking if something like:

Yes, exactly - probably you can even have a default region backed by
normal vmalloc() RAM which would at least be able to take a stab at
working by default.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 13:40                               ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 13:40 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 03:24:26PM +0200, MichaA? Nazarewicz wrote:

> That's why command line is only intended as a way to overwrite the
> defaults which are provided by the platform.  In a final product,
> configuration should be specified in platform code and not on
> command line.

Yeah, agreed though I'm not convinced we can't do it via userspace
(initrd would give us a chance to do stuff early) or just kernel
rebuilds.

> >It sounds like apart from the way you're passing the configuration in
> >you're doing roughly what I'd suggest.  I'd expect that in a lot of
> >cases the map could be satisfied from the default region so there'd be
> >no need to explicitly set one up.

> Platform can specify something like:

> 	cma_defaults("reg=20M", "*/*=reg");

> which would make all the drivers share 20 MiB region by default.  I'm also
> thinking if something like:

Yes, exactly - probably you can even have a default region backed by
normal vmalloc() RAM which would at least be able to take a stab at
working by default.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 13:40                               ` Mark Brown
@ 2010-07-22 14:58                                 ` Michał Nazarewicz
  -1 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 14:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, 22 Jul 2010 15:40:56 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Thu, Jul 22, 2010 at 03:24:26PM +0200, Michał Nazarewicz wrote:
>
>> That's why command line is only intended as a way to overwrite the
>> defaults which are provided by the platform.  In a final product,
>> configuration should be specified in platform code and not on
>> command line.
>
> Yeah, agreed though I'm not convinced we can't do it via userspace
> (initrd would give us a chance to do stuff early) or just kernel
> rebuilds.

If there's any other easy way of overwriting platform's default I'm happy
to listen. :)

>> >It sounds like apart from the way you're passing the configuration in
>> >you're doing roughly what I'd suggest.  I'd expect that in a lot of
>> >cases the map could be satisfied from the default region so there'd be
>> >no need to explicitly set one up.
>
>> Platform can specify something like:
>
>> 	cma_defaults("reg=20M", "*/*=reg");
>
>> which would make all the drivers share 20 MiB region by default.
>
> Yes, exactly - probably you can even have a default region backed by
> normal vmalloc() RAM which would at least be able to take a stab at
> working by default.

Not sure what you mean here.  vmalloc() allocated buffers cannot be used
with CMA since they are not contiguous in memory.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 14:58                                 ` Michał Nazarewicz
  0 siblings, 0 replies; 98+ messages in thread
From: Michał Nazarewicz @ 2010-07-22 14:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, 22 Jul 2010 15:40:56 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> On Thu, Jul 22, 2010 at 03:24:26PM +0200, Michał Nazarewicz wrote:
>
>> That's why command line is only intended as a way to overwrite the
>> defaults which are provided by the platform.  In a final product,
>> configuration should be specified in platform code and not on
>> command line.
>
> Yeah, agreed though I'm not convinced we can't do it via userspace
> (initrd would give us a chance to do stuff early) or just kernel
> rebuilds.

If there's any other easy way of overwriting platform's default I'm happy
to listen. :)

>> >It sounds like apart from the way you're passing the configuration in
>> >you're doing roughly what I'd suggest.  I'd expect that in a lot of
>> >cases the map could be satisfied from the default region so there'd be
>> >no need to explicitly set one up.
>
>> Platform can specify something like:
>
>> 	cma_defaults("reg=20M", "*/*=reg");
>
>> which would make all the drivers share 20 MiB region by default.
>
> Yes, exactly - probably you can even have a default region backed by
> normal vmalloc() RAM which would at least be able to take a stab at
> working by default.

Not sure what you mean here.  vmalloc() allocated buffers cannot be used
with CMA since they are not contiguous in memory.

-- 
Best regards,                                        _     _
| Humble Liege of Serenely Enlightened Majesty of  o' \,=./ `o
| Computer Science,  Michał "mina86" Nazarewicz       (o o)
+----[mina86*mina86.com]---[mina86*jabber.org]----ooO--(_)--Ooo--

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22 14:58                                 ` Michał Nazarewicz
@ 2010-07-22 15:05                                   ` Mark Brown
  -1 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 15:05 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 04:58:43PM +0200, Michał Nazarewicz wrote:
> On Thu, 22 Jul 2010 15:40:56 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> >Yeah, agreed though I'm not convinced we can't do it via userspace
> >(initrd would give us a chance to do stuff early) or just kernel
> >rebuilds.

> If there's any other easy way of overwriting platform's default I'm happy
> to listen. :)

Netlink or similar, for example?

> >Yes, exactly - probably you can even have a default region backed by
> >normal vmalloc() RAM which would at least be able to take a stab at
> >working by default.

> Not sure what you mean here.  vmalloc() allocated buffers cannot be used
> with CMA since they are not contiguous in memory.

Sorry, thinko - I just meant allocated at runtime.  It'd fail a a lot of
the time so might not be worth bothering.

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-22 15:05                                   ` Mark Brown
  0 siblings, 0 replies; 98+ messages in thread
From: Mark Brown @ 2010-07-22 15:05 UTC (permalink / raw)
  To: Michał Nazarewicz
  Cc: Marek Szyprowski, 'Daniel Walker',
	linux-mm, Pawel Osciak, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park',
	linux-arm-msm

On Thu, Jul 22, 2010 at 04:58:43PM +0200, MichaA? Nazarewicz wrote:
> On Thu, 22 Jul 2010 15:40:56 +0200, Mark Brown <broonie@opensource.wolfsonmicro.com> wrote:

> >Yeah, agreed though I'm not convinced we can't do it via userspace
> >(initrd would give us a chance to do stuff early) or just kernel
> >rebuilds.

> If there's any other easy way of overwriting platform's default I'm happy
> to listen. :)

Netlink or similar, for example?

> >Yes, exactly - probably you can even have a default region backed by
> >normal vmalloc() RAM which would at least be able to take a stab at
> >working by default.

> Not sure what you mean here.  vmalloc() allocated buffers cannot be used
> with CMA since they are not contiguous in memory.

Sorry, thinko - I just meant allocated at runtime.  It'd fail a a lot of
the time so might not be worth bothering.

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

^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
  2010-07-22  4:54       ` Zach Pfeffer
@ 2010-07-23  7:06         ` Pawel Osciak
  -1 siblings, 0 replies; 98+ messages in thread
From: Pawel Osciak @ 2010-07-23  7:06 UTC (permalink / raw)
  To: 'Zach Pfeffer', Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park'

Hi Zach,

>Zach Pfeffer <zpfeffer@codeaurora.org> wrote:
>On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:

(snip)

>> +* Contiguous Memory Allocator
>> +
>> +   The Contiguous Memory Allocator (CMA) is a framework, which allows
>> +   setting up a machine-specific configuration for physically-contiguous
>> +   memory management. Memory for devices is then allocated according
>> +   to that configuration.
>> +
>> +   The main role of the framework is not to allocate memory, but to
>> +   parse and manage memory configurations, as well as to act as an
>> +   in-between between device drivers and pluggable allocators. It is
>> +   thus not tied to any memory allocation method or strategy.
>> +
>
>This topic seems very hot lately. I recently sent out a few RFCs that
>implement something called a Virtual Contiguous Memory Manager that
>does what this patch does, and works for IOMMU and works for CPU
>mappings. It also does multihomed memory targeting (use physical set 1
>memory for A allocations and use physical memory set 2 for B
>allocations). Check out:
>
>mm: iommu: An API to unify IOMMU, CPU and device memory management
>mm: iommu: A physical allocator for the VCMM
>mm: iommu: The Virtual Contiguous Memory Manager
>
>It unifies IOMMU and physical mappings by creating a one-to-one
>software IOMMU for all devices that map memory physically.
>
>It looks like you've got some good ideas though. Perhaps we can
>leverage each other's work.

Yes, I have read your RFCs when they originally come out and I think
that CMA could be used as a physical memory allocator for VCMM, if such
a need arises. Of course this would only make sense in special cases.
One idea I have is that this could be useful if we wanted to have
a common kernel for devices with and without an IOMMU. This way the
same virtual address spaces could be set up on top of different
allocators for different systems and use discontiguous memory for
SoCs with an IOMMU and contiguous for SoCs without it. What do you
think?

I am aware that you have your own physical memory allocator, but from
what you wrote, you use pools of contiguous memory consisting of
indivisible, fixed-size blocks (which is of course a good idea in the
presence of an IOMMU). Moreover, those advanced region traits and
sharing specification features of CMA are a must for us.

I don't perceive VCMM and CMA as competing solutions for the same
problem, they solve different problems and I believe could not only
coexist, but be used together in specific use cases.


Best regards
--
Pawel Osciak
Linux Platform Group
Samsung Poland R&D Center






^ permalink raw reply	[flat|nested] 98+ messages in thread

* RE: [PATCH 2/4] mm: cma: Contiguous Memory Allocator added
@ 2010-07-23  7:06         ` Pawel Osciak
  0 siblings, 0 replies; 98+ messages in thread
From: Pawel Osciak @ 2010-07-23  7:06 UTC (permalink / raw)
  To: 'Zach Pfeffer', Michal Nazarewicz
  Cc: linux-mm, Marek Szyprowski, 'Xiaolin Zhang',
	'Hiremath Vaibhav', 'Robert Fekete',
	'Marcus Lorentzon', linux-kernel, 'Kyungmin Park'

Hi Zach,

>Zach Pfeffer <zpfeffer@codeaurora.org> wrote:
>On Tue, Jul 20, 2010 at 05:51:25PM +0200, Michal Nazarewicz wrote:

(snip)

>> +* Contiguous Memory Allocator
>> +
>> +   The Contiguous Memory Allocator (CMA) is a framework, which allows
>> +   setting up a machine-specific configuration for physically-contiguous
>> +   memory management. Memory for devices is then allocated according
>> +   to that configuration.
>> +
>> +   The main role of the framework is not to allocate memory, but to
>> +   parse and manage memory configurations, as well as to act as an
>> +   in-between between device drivers and pluggable allocators. It is
>> +   thus not tied to any memory allocation method or strategy.
>> +
>
>This topic seems very hot lately. I recently sent out a few RFCs that
>implement something called a Virtual Contiguous Memory Manager that
>does what this patch does, and works for IOMMU and works for CPU
>mappings. It also does multihomed memory targeting (use physical set 1
>memory for A allocations and use physical memory set 2 for B
>allocations). Check out:
>
>mm: iommu: An API to unify IOMMU, CPU and device memory management
>mm: iommu: A physical allocator for the VCMM
>mm: iommu: The Virtual Contiguous Memory Manager
>
>It unifies IOMMU and physical mappings by creating a one-to-one
>software IOMMU for all devices that map memory physically.
>
>It looks like you've got some good ideas though. Perhaps we can
>leverage each other's work.

Yes, I have read your RFCs when they originally come out and I think
that CMA could be used as a physical memory allocator for VCMM, if such
a need arises. Of course this would only make sense in special cases.
One idea I have is that this could be useful if we wanted to have
a common kernel for devices with and without an IOMMU. This way the
same virtual address spaces could be set up on top of different
allocators for different systems and use discontiguous memory for
SoCs with an IOMMU and contiguous for SoCs without it. What do you
think?

I am aware that you have your own physical memory allocator, but from
what you wrote, you use pools of contiguous memory consisting of
indivisible, fixed-size blocks (which is of course a good idea in the
presence of an IOMMU). Moreover, those advanced region traits and
sharing specification features of CMA are a must for us.

I don't perceive VCMM and CMA as competing solutions for the same
problem, they solve different problems and I believe could not only
coexist, but be used together in specific use cases.


Best regards
--
Pawel Osciak
Linux Platform Group
Samsung Poland R&D Center





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

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2010-07-23  7:08 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-20 15:51 [PATCH 0/4] The Contiguous Memory Allocator Michal Nazarewicz
2010-07-20 15:51 ` Michal Nazarewicz
2010-07-20 15:51 ` [PATCH 1/4] lib: rbtree: rb_root_init() function added Michal Nazarewicz
2010-07-20 15:51   ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Michal Nazarewicz
2010-07-20 15:51     ` [PATCH 3/4] mm: cma: Test device and application added Michal Nazarewicz
2010-07-20 15:51       ` [PATCH 4/4] arm: Added CMA to Aquila and Goni Michal Nazarewicz
2010-07-20 18:15     ` [PATCH 2/4] mm: cma: Contiguous Memory Allocator added Daniel Walker
2010-07-20 18:15       ` Daniel Walker
2010-07-20 19:14       ` Michał Nazarewicz
2010-07-20 19:14         ` Michał Nazarewicz
2010-07-20 19:38         ` Daniel Walker
2010-07-20 19:38           ` Daniel Walker
2010-07-21 12:01           ` Michał Nazarewicz
2010-07-21 12:01             ` Michał Nazarewicz
2010-07-21 17:35             ` Daniel Walker
2010-07-21 17:35               ` Daniel Walker
2010-07-21 18:11               ` Michał Nazarewicz
2010-07-21 18:11                 ` Michał Nazarewicz
2010-07-21 18:19                 ` Daniel Walker
2010-07-21 18:19                   ` Daniel Walker
2010-07-21 18:38                   ` Michał Nazarewicz
2010-07-21 18:38                     ` Michał Nazarewicz
2010-07-21 18:58                     ` Daniel Walker
2010-07-21 18:58                       ` Daniel Walker
2010-07-21 19:21                       ` Michał Nazarewicz
2010-07-21 19:21                         ` Michał Nazarewicz
2010-07-21 19:37                         ` Daniel Walker
2010-07-21 19:37                           ` Daniel Walker
2010-07-21 19:53                           ` Michał Nazarewicz
2010-07-21 19:53                             ` Michał Nazarewicz
2010-07-21 20:03                             ` Daniel Walker
2010-07-21 20:03                               ` Daniel Walker
2010-07-21 20:22                               ` Michał Nazarewicz
2010-07-21 20:22                                 ` Michał Nazarewicz
2010-07-21 20:34                                 ` Daniel Walker
2010-07-21 20:34                                   ` Daniel Walker
2010-07-21 20:43                                   ` Michał Nazarewicz
2010-07-21 20:43                                     ` Michał Nazarewicz
2010-07-21 20:45                                     ` Daniel Walker
2010-07-21 20:45                                       ` Daniel Walker
2010-07-21 20:56                                       ` Michał Nazarewicz
2010-07-21 20:56                                         ` Michał Nazarewicz
2010-07-21 21:01                                         ` Daniel Walker
2010-07-21 21:01                                           ` Daniel Walker
2010-07-22  9:34                                           ` Michał Nazarewicz
2010-07-22  9:34                                             ` Michał Nazarewicz
2010-07-21 13:52         ` Mark Brown
2010-07-21 13:52           ` Mark Brown
2010-07-21 14:31           ` Michał Nazarewicz
2010-07-21 14:31             ` Michał Nazarewicz
2010-07-21 18:24             ` Mark Brown
2010-07-21 18:24               ` Mark Brown
2010-07-21 18:41               ` Michał Nazarewicz
2010-07-21 18:41                 ` Michał Nazarewicz
2010-07-22  9:06                 ` Mark Brown
2010-07-22  9:06                   ` Mark Brown
2010-07-22  9:25                   ` Marek Szyprowski
2010-07-22  9:25                     ` Marek Szyprowski
2010-07-22 10:52                     ` Mark Brown
2010-07-22 10:52                       ` Mark Brown
2010-07-22 11:30                       ` Michał Nazarewicz
2010-07-22 11:30                         ` Michał Nazarewicz
2010-07-22 12:46                         ` Mark Brown
2010-07-22 12:46                           ` Mark Brown
2010-07-22 13:24                           ` Michał Nazarewicz
2010-07-22 13:24                             ` Michał Nazarewicz
2010-07-22 13:40                             ` Mark Brown
2010-07-22 13:40                               ` Mark Brown
2010-07-22 14:58                               ` Michał Nazarewicz
2010-07-22 14:58                                 ` Michał Nazarewicz
2010-07-22 15:05                                 ` Mark Brown
2010-07-22 15:05                                   ` Mark Brown
2010-07-20 20:52     ` Jonathan Corbet
2010-07-20 20:52       ` Jonathan Corbet
2010-07-21 10:16       ` Michał Nazarewicz
2010-07-21 10:16         ` Michał Nazarewicz
2010-07-21  0:12     ` Jonathan Corbet
2010-07-21  0:12       ` Jonathan Corbet
2010-07-22  5:37       ` FUJITA Tomonori
2010-07-22  5:37         ` FUJITA Tomonori
2010-07-22  7:28         ` Marek Szyprowski
2010-07-22  7:28           ` Marek Szyprowski
2010-07-22  9:35           ` FUJITA Tomonori
2010-07-22  9:35             ` FUJITA Tomonori
2010-07-22  9:50             ` Michał Nazarewicz
2010-07-22  9:50               ` Michał Nazarewicz
2010-07-22 10:17               ` FUJITA Tomonori
2010-07-22 10:17                 ` FUJITA Tomonori
2010-07-22 10:55                 ` Mark Brown
2010-07-22 10:55                   ` Mark Brown
2010-07-22 11:49                 ` Michał Nazarewicz
2010-07-22 11:49                   ` Michał Nazarewicz
2010-07-22  4:54     ` Zach Pfeffer
2010-07-22  4:54       ` Zach Pfeffer
2010-07-22  7:49       ` Marek Szyprowski
2010-07-22  7:49         ` Marek Szyprowski
2010-07-23  7:06       ` Pawel Osciak
2010-07-23  7:06         ` Pawel Osciak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.