Thread (8 messages) 8 messages, 2 authors, 2023-10-26

Re: [PATCH v5 2/4] apparmor: exponential backoff on cache buffer contention

From: John Johansen <john.johansen@canonical.com>
Date: 2023-10-17 09:24:32
Also in: lkml
Subsystem: apparmor security module, security subsystem, the rest · Maintainers: John Johansen, Paul Moore, James Morris, "Serge E. Hallyn", Linus Torvalds

Reduce contention on the global buffers lock by using  an exponential
back off strategy where the amount tries to hold is doubled when
contention is encoutered and backed off linearly when there isn't
contention.

Signed-off-by: John Johansen <john.johansen@canonical.com>
---
  security/apparmor/lsm.c | 18 ++++++++++++++++--
  1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index ce4f3e7a784d..fd6779ff0da4 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -50,6 +50,7 @@ union aa_buffer {
  };
  
  struct aa_local_cache {
+	unsigned int contention;
  	unsigned int hold;
  	unsigned int count;
  	struct list_head head;
@@ -1793,6 +1794,14 @@ static int param_set_mode(const char *val, const struct kernel_param *kp)
  	return 0;
  }
  
+static void update_contention(struct aa_local_cache *cache)
+{
+	cache->contention += 1;
+	if (cache->contention > 9)
+		cache->contention = 9;
+	cache->hold += 1 << cache->contention;		/* 2, 4, 8, ... */
+}
+
  char *aa_get_buffer(bool in_atomic)
  {
  	union aa_buffer *aa_buf;
@@ -1814,11 +1823,13 @@ char *aa_get_buffer(bool in_atomic)
  
  	if (!spin_trylock(&aa_buffers_lock)) {
  		cache = get_cpu_ptr(&aa_local_buffers);
-		cache->hold += 1;
+		update_contention(cache);
  		put_cpu_ptr(&aa_local_buffers);
  		spin_lock(&aa_buffers_lock);
  	} else {
  		cache = get_cpu_ptr(&aa_local_buffers);
+		if (cache->contention)
+			cache->contention--;
  		put_cpu_ptr(&aa_local_buffers);
  	}
  retry:
@@ -1875,12 +1886,14 @@ void aa_put_buffer(char *buf)
  			buffer_count++;
  			spin_unlock(&aa_buffers_lock);
  			cache = get_cpu_ptr(&aa_local_buffers);
+			if (cache->contention)
+				cache->contention--;
  			put_cpu_ptr(&aa_local_buffers);
  			return;
  		}
  		/* contention on global list, fallback to percpu */
  		cache = get_cpu_ptr(&aa_local_buffers);
-		cache->hold += 1;
+		update_contention(cache);
  	}
  
  	/* cache in percpu list */
@@ -1933,6 +1946,7 @@ static int __init alloc_buffers(void)
  	 * lock contention
  	 */
  	for_each_possible_cpu(i) {
+		per_cpu(aa_local_buffers, i).contention = 0;
  		per_cpu(aa_local_buffers, i).hold = 0;
  		per_cpu(aa_local_buffers, i).count = 0;
  		INIT_LIST_HEAD(&per_cpu(aa_local_buffers, i).head);
-- 
2.34.1

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help