From: Alex Markuze Date: Sun, 16 Mar 2025 19:03:51 +0000 (+0000) Subject: fixup buffer allocation X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b756c73bb29c0acb3b2509081debd5dc20045242;p=ceph-client.git fixup buffer allocation --- diff --git a/include/linux/ceph/ceph_san_logger.h b/include/linux/ceph/ceph_san_logger.h index d45c353250e2..7d7846f10839 100644 --- a/include/linux/ceph/ceph_san_logger.h +++ b/include/linux/ceph/ceph_san_logger.h @@ -53,4 +53,4 @@ struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void); #define CEPH_SAN_LOG(fmt, ...) \ ceph_san_log(__FILE__, __LINE__, fmt, ##__VA_ARGS__) -#endif /* CEPH_SAN_LOGGER_H */ \ No newline at end of file +#endif /* CEPH_SAN_LOGGER_H */ \ No newline at end of file diff --git a/include/linux/ceph/ceph_san_pagefrag.h b/include/linux/ceph/ceph_san_pagefrag.h index 56907417765c..2475d90fc09f 100644 --- a/include/linux/ceph/ceph_san_pagefrag.h +++ b/include/linux/ceph/ceph_san_pagefrag.h @@ -17,8 +17,10 @@ struct cephsan_pagefrag { int cephsan_pagefrag_init(struct cephsan_pagefrag *pf); int cephsan_pagefrag_init_with_buffer(struct cephsan_pagefrag *pf, void *buffer, size_t size); u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n); +void *cephsan_pagefrag_get_ptr_from_tail(struct cephsan_pagefrag *pf); 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); #define CEPHSAN_PAGEFRAG_GET_N(val) ((val) >> 32) diff --git a/net/ceph/ceph_san_logger.c b/net/ceph/ceph_san_logger.c index 7726a539ce0a..dd120785fcc5 100644 --- a/net/ceph/ceph_san_logger.c +++ b/net/ceph/ceph_san_logger.c @@ -95,7 +95,7 @@ struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void) list_add(&ctx->list, &g_logger.contexts); spin_unlock(&g_logger.lock); } - + cephsan_pagefrag_reset(&ctx->pf); /* Set up TLS */ current->tls.state = ctx; current->tls.release = ceph_san_tls_release; @@ -119,6 +119,7 @@ void ceph_san_log(const char *file, unsigned int line, const char *fmt, ...) struct ceph_san_tls_ctx *ctx; struct ceph_san_log_entry *entry; va_list args; + u64 alloc; int len; ctx = ceph_san_get_tls_ctx(); @@ -130,9 +131,12 @@ void ceph_san_log(const char *file, unsigned int line, const char *fmt, ...) va_end(args); /* Allocate entry from pagefrag */ //We need a spinlock here to protect printing - u64 alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1); - if (!alloc) - return; + alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1); + while (!alloc) { + entry = cephsan_pagefrag_get_ptr_from_tail(&ctx->pf); + cephsan_pagefrag_free(&ctx->pf, entry->len); + alloc = cephsan_pagefrag_alloc(&ctx->pf, sizeof(*entry) + len + 1); + } entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc); /* Copy to entry buffer */ diff --git a/net/ceph/ceph_san_pagefrag.c b/net/ceph/ceph_san_pagefrag.c index 7557721a1616..d34918044173 100644 --- a/net/ceph/ceph_san_pagefrag.c +++ b/net/ceph/ceph_san_pagefrag.c @@ -54,12 +54,11 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n) { /* Case 1: tail > head */ if (pf->tail > pf->head) { - if (pf->tail - pf->head >= n) { + if (pf->tail - pf->head > n) { unsigned int prev_head = pf->head; pf->head += n; return ((u64)n << 32) | prev_head; } else { - pr_err("Not enough space in pagefrag buffer\n"); return 0; } } @@ -71,12 +70,11 @@ u64 cephsan_pagefrag_alloc(struct cephsan_pagefrag *pf, unsigned int n) return ((u64)n << 32) | prev_head; } else { /* Need to wrap around */ - if (n <= pf->tail) { + if (n < pf->tail) { pf->head = n; n += CEPHSAN_PAGEFRAG_SIZE - pf->head; return ((u64)n << 32) | 0; } else { - pr_err("Not enough space for wrap-around allocation\n"); return 0; } } @@ -98,6 +96,19 @@ void *cephsan_pagefrag_get_ptr(struct cephsan_pagefrag *pf, u64 val) } EXPORT_SYMBOL(cephsan_pagefrag_get_ptr); +/** + * cephsan_pagefrag_get_ptr_from_tail - Get buffer pointer from pagefrag tail + * @pf: pagefrag allocator + * @n: number of bytes to get pointer from + * + * Returns pointer to the buffer region at the tail pointer minus @n bytes. + */ +void *cephsan_pagefrag_get_ptr_from_tail(struct cephsan_pagefrag *pf) +{ + return pf->buffer + pf->tail; +} +EXPORT_SYMBOL(cephsan_pagefrag_get_ptr_from_tail); + /** * cephsan_pagefrag_free - Free bytes in the pagefrag allocator. * @n: number of bytes to free. @@ -126,3 +137,15 @@ void cephsan_pagefrag_deinit(struct cephsan_pagefrag *pf) pf->head = pf->tail = 0; } EXPORT_SYMBOL(cephsan_pagefrag_deinit); + +/** + * cephsan_pagefrag_reset - Reset the pagefrag allocator. + * + * Resets the head and tail pointers to the beginning of the buffer. + */ +void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf) +{ + pf->head = 0; + pf->tail = 0; +} +EXPORT_SYMBOL(cephsan_pagefrag_reset);