]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
better wrapparound handling
authorAlex Markuze <amarkuze@redhat.com>
Tue, 18 Mar 2025 19:35:02 +0000 (19:35 +0000)
committerAlex Markuze <amarkuze@redhat.com>
Tue, 18 Mar 2025 19:35:02 +0000 (19:35 +0000)
include/linux/ceph/ceph_san_pagefrag.h
net/ceph/ceph_san_logger.c
net/ceph/ceph_san_pagefrag.c

index 85248b851b64396d25e38b522332dad365032dab..fc7e08246dc5404b3ea1254393c26035ba0ccb3f 100644 (file)
@@ -25,6 +25,7 @@ void cephsan_pagefrag_free(struct cephsan_pagefrag *pf, unsigned int n);
 void cephsan_pagefrag_deinit(struct cephsan_pagefrag *pf);
 void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf);
 void *cephsan_pagefrag_get_ptr(struct cephsan_pagefrag *pf, u64 val);
+bool cephsan_pagefrag_is_wraparound(u64 val);
 
 /* Get allocation size from pagefrag allocation result */
 u64 cephsan_pagefrag_get_alloc_size(u64 val);
index 0c43c38b2e387696d6629c1df772b32a4a6d457f..70c86d2af5ed2b357da6d1f335e1a94396d8a849 100644 (file)
@@ -147,13 +147,6 @@ void ceph_san_log(const char *file, const char *func, unsigned int line, const c
         BUG_ON(entry->len == 0);
         cephsan_pagefrag_free(&ctx->pf, entry->len);
         alloc = cephsan_pagefrag_alloc(&ctx->pf, needed_size);
-        //In case we hit the wrap around, we may get a partial allocation that should be marked as used
-        if (alloc && cephsan_pagefrag_get_alloc_size(alloc) < needed_size) {
-            entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc);
-            memset(entry->buffer, 0, sizeof(entry->buffer));
-            entry->len = cephsan_pagefrag_get_alloc_size(alloc);
-            alloc = 0;
-        }
     }
     entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc);
 
@@ -163,7 +156,11 @@ void ceph_san_log(const char *file, const char *func, unsigned int line, const c
     entry->line = line;
     entry->file = file;
     entry->func = func;
-    entry->buffer = (char *)(entry + 1);
+    if (unlikely(cephsan_pagefrag_is_wraparound(alloc))) {
+        entry->buffer = cephsan_pagefrag_get_ptr(&ctx->pf, 0);
+    } else {
+        entry->buffer = (char *)(entry + 1);
+    }
     entry->len = cephsan_pagefrag_get_alloc_size(alloc);
     spin_unlock(&ctx->pf.lock);
 
index 80d34d04585468a22397f52ca3ccdaacc4b96ead..416f969810cb908f989088aabab6275d9be1cd22 100644 (file)
@@ -78,9 +78,13 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n)
         pf->head += n;
         return ((u64)n << 32) | prev_head;
     } else {
-        /* Need to wrap around return a partial allocation*/
-        pf->head = 0;
-        return ((u64)delta << 32) | prev_head;
+        if (pf->tail > n) {
+            /* Need to wrap around return a partial allocation*/
+            pf->head = n;
+            return ((u64)(delta + n) << 32) | prev_head;
+        } else {
+            return 0;
+        }
     }
 }
 EXPORT_SYMBOL(cephsan_pagefrag_alloc);
@@ -104,6 +108,23 @@ u64 cephsan_pagefrag_get_alloc_size(u64 val)
 }
 EXPORT_SYMBOL(cephsan_pagefrag_get_alloc_size);
 
+/**
+ * cephsan_pagefrag_is_wraparound - Check if allocation wraps around buffer end
+ * @val: Return value from cephsan_pagefrag_alloc
+ *
+ * Checks if the allocation represented by @val wraps around the end of the
+ * pagefrag buffer by verifying if alloc_size + address > CEPHSAN_PAGEFRAG_SIZE.
+ *
+ * Return: true if allocation wraps around, false otherwise
+ */
+bool cephsan_pagefrag_is_wraparound(u64 val)
+{
+    u32 addr = val & 0xFFFFFFFF;
+    u32 size = val >> 32;
+    return (addr + size) > CEPHSAN_PAGEFRAG_SIZE;
+}
+EXPORT_SYMBOL(cephsan_pagefrag_is_wraparound);
+
 /**
  * cephsan_pagefrag_get_ptr_from_tail - Get buffer pointer from pagefrag tail
  * @pf: pagefrag allocator