lib/genalloc.c: add genpool range check function
authorLaura Abbott <lauraa@codeaurora.org>
Thu, 9 Oct 2014 22:26:38 +0000 (15:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Oct 2014 02:25:52 +0000 (22:25 -0400)
After allocating an address from a particular genpool, there is no good
way to verify if that address actually belongs to a genpool.  Introduce
addr_in_gen_pool which will return if an address plus size falls
completely within the genpool range.

Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Olof Johansson <olof@lixom.net>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: David Riley <davidriley@chromium.org>
Cc: Ritesh Harjain <ritesh.harjani@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/genalloc.h
lib/genalloc.c

index 3cd0934d62ba3496d7c5e73beb00dd059db6539d..1ccaab44abcc80541a1aebc024b62e650cb3982c 100644 (file)
@@ -121,6 +121,9 @@ extern struct gen_pool *devm_gen_pool_create(struct device *dev,
                int min_alloc_order, int nid);
 extern struct gen_pool *dev_get_gen_pool(struct device *dev);
 
+bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
+                       size_t size);
+
 #ifdef CONFIG_OF
 extern struct gen_pool *of_get_named_gen_pool(struct device_node *np,
        const char *propname, int index);
index 166f17b9f1691290649ec7bebc4152cc3e971ad1..cce4dd68c40da211948177f6903917d4ac81b176 100644 (file)
@@ -402,6 +402,35 @@ void gen_pool_for_each_chunk(struct gen_pool *pool,
 }
 EXPORT_SYMBOL(gen_pool_for_each_chunk);
 
+/**
+ * addr_in_gen_pool - checks if an address falls within the range of a pool
+ * @pool:      the generic memory pool
+ * @start:     start address
+ * @size:      size of the region
+ *
+ * Check if the range of addresses falls within the specified pool. Returns
+ * true if the entire range is contained in the pool and false otherwise.
+ */
+bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
+                       size_t size)
+{
+       bool found = false;
+       unsigned long end = start + size;
+       struct gen_pool_chunk *chunk;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) {
+               if (start >= chunk->start_addr && start <= chunk->end_addr) {
+                       if (end <= chunk->end_addr) {
+                               found = true;
+                               break;
+                       }
+               }
+       }
+       rcu_read_unlock();
+       return found;
+}
+
 /**
  * gen_pool_avail - get available free space of the pool
  * @pool: pool to get available free space