Initial commit
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
78
modules/cas_cache/utils/utils_gc.c
Normal file
78
modules/cas_cache/utils/utils_gc.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright(c) 2012-2019 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "utils_gc.h"
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#if defined (CAS_GARBAGE_COLLECTOR)
|
||||
struct cas_vfree_item {
|
||||
struct llist_head list;
|
||||
struct work_struct ws;
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct cas_vfree_item, cas_vfree_item);
|
||||
|
||||
static atomic_t freed = ATOMIC_INIT(0);
|
||||
|
||||
static void cas_garbage_collector(struct work_struct *w)
|
||||
{
|
||||
struct cas_vfree_item *item = container_of(w, struct cas_vfree_item,
|
||||
ws);
|
||||
struct llist_node *llnode = llist_del_all(&item->list);
|
||||
|
||||
while (llnode) {
|
||||
void *item = llnode;
|
||||
|
||||
llnode = llnode->next;
|
||||
atomic_dec(&freed);
|
||||
vfree(item);
|
||||
}
|
||||
}
|
||||
|
||||
void cas_vfree(const void *addr)
|
||||
{
|
||||
struct cas_vfree_item *item = this_cpu_ptr(&cas_vfree_item);
|
||||
|
||||
atomic_inc(&freed);
|
||||
|
||||
if (llist_add((struct llist_node *)addr, &item->list))
|
||||
schedule_work(&item->ws);
|
||||
}
|
||||
|
||||
void cas_garbage_collector_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cas_vfree_item *item;
|
||||
|
||||
item = &per_cpu(cas_vfree_item, i);
|
||||
init_llist_head(&item->list);
|
||||
INIT_WORK(&item->ws, cas_garbage_collector);
|
||||
}
|
||||
}
|
||||
|
||||
void cas_garbage_collector_deinit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
struct cas_vfree_item *item;
|
||||
|
||||
item = &per_cpu(cas_vfree_item, i);
|
||||
while (work_pending(&item->ws))
|
||||
schedule();
|
||||
}
|
||||
|
||||
WARN(atomic_read(&freed) != 0,
|
||||
OCF_PREFIX_SHORT" Not all memory deallocated\n");
|
||||
}
|
||||
#else
|
||||
void cas_garbage_collector_init(void) {};
|
||||
|
||||
void cas_garbage_collector_deinit(void) {};
|
||||
|
||||
void cas_vfree(const void *addr) { vfree(addr); };
|
||||
#endif
|
Reference in New Issue
Block a user