pool: use own lock to protect the slices lists
authorKay Sievers <kay@vrfy.org>
Wed, 8 Jan 2014 23:37:22 +0000 (07:37 +0800)
committerKay Sievers <kay@vrfy.org>
Wed, 8 Jan 2014 23:59:52 +0000 (07:59 +0800)
handle.c
pool.c
pool.h

index 2a7c3f4ee83383d23b051914dc7e17879628695a..3a03a0ea2f61455682662bfe1a9a5a94dc21f507 100644 (file)
--- a/handle.c
+++ b/handle.c
@@ -559,9 +559,7 @@ static long kdbus_handle_ioctl_ep_connected(struct file *file, unsigned int cmd,
                        break;
                }
 
-               mutex_lock(&conn->lock);
                ret = kdbus_pool_free_range(conn->pool, off);
-               mutex_unlock(&conn->lock);
                break;
        }
 
diff --git a/pool.c b/pool.c
index 5f7339e6f06e487ba9d5b387373e1d93ed848864..e3e29950162ff510e68acb5a70d76b7feb4e3dbb 100644 (file)
--- a/pool.c
+++ b/pool.c
@@ -33,6 +33,7 @@
  * @f:                 The backing shmem file
  * @size:              The size of the file
  * @busy:              The currently used size
+ * @lock               Pool data lock
  * @slices:            All slices sorted by address
  * @slices_busy:       Tree of allocated slices
  * @slices_free:       Tree of free slices
@@ -53,6 +54,7 @@ struct kdbus_pool {
        struct file *f;
        size_t size;
        size_t busy;
+       struct mutex lock;
 
        struct list_head slices;
        struct rb_root slices_busy;
@@ -318,6 +320,7 @@ int kdbus_pool_new(struct kdbus_pool **pool, size_t size)
        p->busy = 0;
        p->slices_free = RB_ROOT;
        p->slices_busy = RB_ROOT;
+       mutex_init(&p->lock);
 
        INIT_LIST_HEAD(&p->slices);
        list_add(&s->entry, &p->slices);
@@ -359,9 +362,15 @@ void kdbus_pool_free(struct kdbus_pool *pool)
  *
  * Returns: the number of unallocated bytes in the pool
  */
-size_t kdbus_pool_remain(const struct kdbus_pool *pool)
+size_t kdbus_pool_remain(struct kdbus_pool *pool)
 {
-       return pool->size - pool->busy;
+       size_t size;
+
+       mutex_lock(&pool->lock);
+       size =  pool->size - pool->busy;
+       mutex_unlock(&pool->lock);
+
+       return size;
 }
 
 /**
@@ -381,7 +390,9 @@ int kdbus_pool_alloc_range(struct kdbus_pool *pool, size_t size, size_t *off)
        struct kdbus_slice *s;
        int ret;
 
+       mutex_lock(&pool->lock);
        ret = kdbus_pool_alloc_slice(pool, size, &s);
+       mutex_unlock(&pool->lock);
        if (ret < 0)
                return ret;
 
@@ -402,19 +413,28 @@ int kdbus_pool_alloc_range(struct kdbus_pool *pool, size_t size, size_t *off)
 int kdbus_pool_free_range(struct kdbus_pool *pool, size_t off)
 {
        struct kdbus_slice *slice;
+       int ret = 0;
 
        if (!pool)
                return 0;
 
-       if (off >= pool->size)
-               return -EINVAL;
+       mutex_lock(&pool->lock);
+       if (off >= pool->size) {
+               ret = -EINVAL;
+               goto exit_unlock;
+       }
 
        slice = kdbus_pool_find_slice(pool, off);
-       if (!slice)
-               return -ENXIO;
+       if (!slice) {
+               ret = -ENXIO;
+               goto exit_unlock;
+       }
 
        kdbus_pool_free_slice(pool, slice);
-       return 0;
+
+exit_unlock:
+       mutex_unlock(&pool->lock);
+       return ret;
 }
 
 /* copy data from a file to ia page in the receiver's pool */
diff --git a/pool.h b/pool.h
index a450ff4e5053fdd44e2441fcb915fb84e16e9522..b0453b2cb59e124fa1aec78ac54e24424576f592 100644 (file)
--- a/pool.h
+++ b/pool.h
@@ -20,7 +20,7 @@ void kdbus_pool_free(struct kdbus_pool *pool);
 
 int kdbus_pool_alloc_range(struct kdbus_pool *pool, size_t size, size_t *off);
 int kdbus_pool_free_range(struct kdbus_pool *pool, size_t off);
-size_t kdbus_pool_remain(const struct kdbus_pool *pool);
+size_t kdbus_pool_remain(struct kdbus_pool *pool);
 ssize_t kdbus_pool_write(const struct kdbus_pool *pool, size_t off,
                         void *data, size_t len);
 ssize_t kdbus_pool_write_user(const struct kdbus_pool *pool, size_t off,