[PATCH] futex: Add a get_pi_state wrapper

From: Darren Hart
Date: Sun Dec 20 2015 - 01:57:05 EST


For audit purposes, add an inline wrapper, get_pi_state(), around
atomic_inc(&pi_state->refcount) to parallel the newly renamed
put_pi_state().

To make the get/set parallel and more explicit, keep the refcount at 0
while in the cache and only inc to 1 when it is allocated to a waiter
via alloc_pi_state().

Signed-off-by: Darren Hart <dvhart@xxxxxxxxxxxxxxx>
---
kernel/futex.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/kernel/futex.c b/kernel/futex.c
index ae83ea7..4c71c86 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -706,7 +706,7 @@ static int refill_pi_state_cache(void)
INIT_LIST_HEAD(&pi_state->list);
/* pi_mutex gets initialized later */
pi_state->owner = NULL;
- atomic_set(&pi_state->refcount, 1);
+ atomic_set(&pi_state->refcount, 0);
pi_state->key = FUTEX_KEY_INIT;

current->pi_state_cache = pi_state;
@@ -714,12 +714,21 @@ static int refill_pi_state_cache(void)
return 0;
}

+/*
+ * Adds a reference to the pi_state object.
+ */
+static inline void get_pi_state(struct futex_pi_state *pi_state)
+{
+ atomic_inc(&pi_state->refcount);
+}
+
static struct futex_pi_state * alloc_pi_state(void)
{
struct futex_pi_state *pi_state = current->pi_state_cache;

WARN_ON(!pi_state);
current->pi_state_cache = NULL;
+ get_pi_state(pi_state);

return pi_state;
}
@@ -756,10 +765,9 @@ static void put_pi_state(struct futex_pi_state *pi_state)
/*
* pi_state->list is already empty.
* clear pi_state->owner.
- * refcount is at 0 - put it back to 1.
+ * refcount is already at 0.
*/
pi_state->owner = NULL;
- atomic_set(&pi_state->refcount, 1);
current->pi_state_cache = pi_state;
}
}
@@ -954,7 +962,7 @@ static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state,
if (pid != task_pid_vnr(pi_state->owner))
return -EINVAL;
out_state:
- atomic_inc(&pi_state->refcount);
+ get_pi_state(pi_state);
*ps = pi_state;
return 0;
}
@@ -1813,7 +1821,7 @@ retry_private:
* refcount on the pi_state and store the pointer in
* the futex_q object of the waiter.
*/
- atomic_inc(&pi_state->refcount);
+ get_pi_state(pi_state);
this->pi_state = pi_state;
ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
this->rt_waiter,
--
2.1.4


--
Darren Hart
Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/