#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/spinlock.h>
#define CEPHSAN_PAGEFRAG_SIZE (1<<21) /* 2MB */
#define CEPHSAN_PAGEFRAG_MASK (CEPHSAN_PAGEFRAG_SIZE - 1)
struct cephsan_pagefrag {
struct page *pages;
void *buffer;
+ spinlock_t lock; /* protects head and tail */
unsigned int head;
unsigned int tail;
};
va_end(args);
needed_size = sizeof(*entry) + len + 1;
- /* Allocate entry from pagefrag */ //We need a spinlock here to protect printing
+ /* Allocate entry from pagefrag - We need a spinlock here to protect access iterators */
+ spin_lock(&ctx->pf.lock);
alloc = cephsan_pagefrag_alloc(&ctx->pf, needed_size);
while (!alloc) {
entry = cephsan_pagefrag_get_ptr_from_tail(&ctx->pf);
}
entry = cephsan_pagefrag_get_ptr(&ctx->pf, alloc);
- /* Copy to entry buffer */
- memcpy(entry->buffer, buf, len + 1);
- entry->buffer[len] = '\0';
-
/* Fill in entry details */
entry->debug_poison = CEPH_SAN_LOG_ENTRY_POISON;
entry->ts = jiffies;
entry->line = line;
entry->file = file;
entry->len = cephsan_pagefrag_get_alloc_size(alloc);
+ spin_unlock(&ctx->pf.lock);
+
+ /* Copy to entry buffer */
+ memcpy(entry->buffer, buf, len + 1);
+ entry->buffer[len] = '\0';
}
EXPORT_SYMBOL(ceph_san_log);
*/
int cephsan_pagefrag_init(struct cephsan_pagefrag *pf)
{
+ spin_lock_init(&pf->lock);
pf->pages = alloc_pages(GFP_KERNEL, get_order(CEPHSAN_PAGEFRAG_SIZE));
if (!pf->pages)
return -ENOMEM;
*/
int cephsan_pagefrag_init_with_buffer(struct cephsan_pagefrag *pf, void *buffer, size_t size)
{
+ spin_lock_init(&pf->lock);
pf->pages = NULL; /* No pages allocated, using provided buffer */
pf->buffer = buffer;
pf->head = 0;
*/
void cephsan_pagefrag_reset(struct cephsan_pagefrag *pf)
{
+ spin_lock(&pf->lock);
pf->head = 0;
pf->tail = 0;
+ spin_unlock(&pf->lock);
}
EXPORT_SYMBOL(cephsan_pagefrag_reset);