From: Alex Markuze Date: Tue, 18 Mar 2025 20:04:31 +0000 (+0000) Subject: pf iterator debug X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e9a817800b25cf3143bb5c71b3f3e8383f566a66;p=ceph-client.git pf iterator debug --- diff --git a/include/linux/ceph/ceph_san_logger.h b/include/linux/ceph/ceph_san_logger.h index b4c2cec7cd5b..6d6dc6d00670 100644 --- a/include/linux/ceph/ceph_san_logger.h +++ b/include/linux/ceph/ceph_san_logger.h @@ -44,6 +44,7 @@ struct ceph_san_log_iter { struct cephsan_pagefrag *pf; /* Pagefrag being iterated */ u64 current_offset; /* Current offset in pagefrag */ u64 end_offset; /* End offset in pagefrag */ + u64 prev_offset; /* Previous offset for debugging */ }; /* Initialize the iterator for a specific pagefrag */ diff --git a/include/linux/ceph/ceph_san_pagefrag.h b/include/linux/ceph/ceph_san_pagefrag.h index fc7e08246dc5..3ea5ba460d1f 100644 --- a/include/linux/ceph/ceph_san_pagefrag.h +++ b/include/linux/ceph/ceph_san_pagefrag.h @@ -15,6 +15,7 @@ struct cephsan_pagefrag { spinlock_t lock; /* protects head and tail */ unsigned int head; unsigned int tail; + unsigned int alloc_count; }; int cephsan_pagefrag_init(struct cephsan_pagefrag *pf); diff --git a/net/ceph/ceph_san_logger.c b/net/ceph/ceph_san_logger.c index faa564250595..0d5e76146223 100644 --- a/net/ceph/ceph_san_logger.c +++ b/net/ceph/ceph_san_logger.c @@ -244,6 +244,7 @@ void ceph_san_log_iter_init(struct ceph_san_log_iter *iter, struct cephsan_pagef iter->pf = pf; iter->current_offset = pf->tail; iter->end_offset = pf->head; + iter->prev_offset = pf->tail; } EXPORT_SYMBOL(ceph_san_log_iter_init); @@ -257,18 +258,33 @@ struct ceph_san_log_entry *ceph_san_log_iter_next(struct ceph_san_log_iter *iter { struct ceph_san_log_entry *entry; - if (!iter->pf || iter->current_offset== iter->end_offset) + if (!iter->pf || iter->current_offset == iter->end_offset) return NULL; /* Get current entry */ entry = cephsan_pagefrag_get_ptr(iter->pf, iter->current_offset); /* Verify entry is valid */ if (!entry || entry->debug_poison != CEPH_SAN_LOG_ENTRY_POISON || entry->len == 0) { + /* Get previous entry if available */ + struct ceph_san_log_entry *prev_entry = NULL; + prev_entry = cephsan_pagefrag_get_ptr(iter->pf, iter->prev_offset); + pr_err("Previous entry: entry=%px poison=%x len=%u prev_offset=%llu\n", + prev_entry, prev_entry->debug_poison, prev_entry->len, iter->prev_offset); + + iter->prev_offset = iter->current_offset; iter->current_offset = iter->end_offset; + pr_err("Pagefrag corruption detected: entry=%px poison=%x len=%u\n" + "pf: head=%u tail=%u buffer=%px alloc_count=%u prev_offset=%llu\n", + entry, entry->debug_poison, entry->len, + iter->pf->head, iter->pf->tail, iter->pf->buffer, + iter->pf->alloc_count, iter->prev_offset); + BUG_ON(entry->debug_poison != CEPH_SAN_LOG_ENTRY_POISON); return NULL; } + /* Store current offset before moving to next */ + iter->prev_offset = iter->current_offset; /* Move to next entry */ iter->current_offset += entry->len & CEPHSAN_PAGEFRAG_MASK; diff --git a/net/ceph/ceph_san_pagefrag.c b/net/ceph/ceph_san_pagefrag.c index 416f969810cb..22b37f1545e3 100644 --- a/net/ceph/ceph_san_pagefrag.c +++ b/net/ceph/ceph_san_pagefrag.c @@ -61,6 +61,7 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n) if (pf->tail > pf->head) { if (pf->tail - pf->head > n) { pf->head += n; + pf->alloc_count++; return ((u64)n << 32) | prev_head; } else { return 0; @@ -73,6 +74,7 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n) if (unlikely(delta < 64)) { n += delta; pf->head = 0; + pf->alloc_count++; return ((u64)n << 32) | prev_head; } pf->head += n; @@ -81,6 +83,7 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n) if (pf->tail > n) { /* Need to wrap around return a partial allocation*/ pf->head = n; + pf->alloc_count++; return ((u64)(delta + n) << 32) | prev_head; } else { return 0; @@ -177,6 +180,7 @@ void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf) spin_lock(&pf->lock); pf->head = 0; pf->tail = 0; + pf->alloc_count = 0; spin_unlock(&pf->lock); } EXPORT_SYMBOL(cephsan_pagefrag_reset);