kmalloc/pagealloc tracker: fix race condition bug
This commit is contained in:
36
kernel/mem.c
36
kernel/mem.c
@ -179,7 +179,7 @@ void *_ihk_mc_alloc_aligned_pages(int npages, int p2align,
|
|||||||
}
|
}
|
||||||
|
|
||||||
entry->line = line;
|
entry->line = line;
|
||||||
ihk_atomic_set(&entry->alloc_count, 0);
|
ihk_atomic_set(&entry->alloc_count, 1);
|
||||||
ihk_mc_spinlock_init(&entry->addr_list_lock);
|
ihk_mc_spinlock_init(&entry->addr_list_lock);
|
||||||
INIT_LIST_HEAD(&entry->addr_list);
|
INIT_LIST_HEAD(&entry->addr_list);
|
||||||
|
|
||||||
@ -197,10 +197,11 @@ void *_ihk_mc_alloc_aligned_pages(int npages, int p2align,
|
|||||||
dkprintf("%s entry %s:%d npages: %d added\n", __FUNCTION__,
|
dkprintf("%s entry %s:%d npages: %d added\n", __FUNCTION__,
|
||||||
file, line, npages);
|
file, line, npages);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ihk_atomic_inc(&entry->alloc_count);
|
||||||
|
}
|
||||||
ihk_mc_spinlock_unlock(&pagealloc_track_hash_locks[hash], irqflags);
|
ihk_mc_spinlock_unlock(&pagealloc_track_hash_locks[hash], irqflags);
|
||||||
|
|
||||||
ihk_atomic_inc(&entry->alloc_count);
|
|
||||||
|
|
||||||
/* Add new addr entry for this allocation entry */
|
/* Add new addr entry for this allocation entry */
|
||||||
addr_entry = ___kmalloc(sizeof(*addr_entry), IHK_MC_AP_NOWAIT);
|
addr_entry = ___kmalloc(sizeof(*addr_entry), IHK_MC_AP_NOWAIT);
|
||||||
if (!addr_entry) {
|
if (!addr_entry) {
|
||||||
@ -379,13 +380,15 @@ void _ihk_mc_free_pages(void *ptr, int npages, char *file, int line)
|
|||||||
___kfree(addr_entry);
|
___kfree(addr_entry);
|
||||||
|
|
||||||
/* Do we need to remove tracking entry as well? */
|
/* Do we need to remove tracking entry as well? */
|
||||||
if (!ihk_atomic_dec_and_test(&entry->alloc_count)) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = (strlen(entry->file) + entry->line) &
|
hash = (strlen(entry->file) + entry->line) &
|
||||||
PAGEALLOC_TRACK_HASH_MASK;
|
PAGEALLOC_TRACK_HASH_MASK;
|
||||||
irqflags = ihk_mc_spinlock_lock(&pagealloc_track_hash_locks[hash]);
|
irqflags = ihk_mc_spinlock_lock(&pagealloc_track_hash_locks[hash]);
|
||||||
|
|
||||||
|
if (!ihk_atomic_dec_and_test(&entry->alloc_count)) {
|
||||||
|
ihk_mc_spinlock_unlock(&pagealloc_track_hash_locks[hash], irqflags);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
list_del(&entry->hash);
|
list_del(&entry->hash);
|
||||||
ihk_mc_spinlock_unlock(&pagealloc_track_hash_locks[hash], irqflags);
|
ihk_mc_spinlock_unlock(&pagealloc_track_hash_locks[hash], irqflags);
|
||||||
|
|
||||||
@ -1351,13 +1354,14 @@ void *_kmalloc(int size, enum ihk_mc_ap_flag flag, char *file, int line)
|
|||||||
if (!entry) {
|
if (!entry) {
|
||||||
entry = ___kmalloc(sizeof(*entry), IHK_MC_AP_NOWAIT);
|
entry = ___kmalloc(sizeof(*entry), IHK_MC_AP_NOWAIT);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
||||||
kprintf("%s: ERROR: allocating tracking entry\n");
|
kprintf("%s: ERROR: allocating tracking entry\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->line = line;
|
entry->line = line;
|
||||||
entry->size = size;
|
entry->size = size;
|
||||||
ihk_atomic_set(&entry->alloc_count, 0);
|
ihk_atomic_set(&entry->alloc_count, 1);
|
||||||
ihk_mc_spinlock_init(&entry->addr_list_lock);
|
ihk_mc_spinlock_init(&entry->addr_list_lock);
|
||||||
INIT_LIST_HEAD(&entry->addr_list);
|
INIT_LIST_HEAD(&entry->addr_list);
|
||||||
|
|
||||||
@ -1371,14 +1375,16 @@ void *_kmalloc(int size, enum ihk_mc_ap_flag flag, char *file, int line)
|
|||||||
|
|
||||||
strcpy(entry->file, file);
|
strcpy(entry->file, file);
|
||||||
entry->file[strlen(file)] = 0;
|
entry->file[strlen(file)] = 0;
|
||||||
|
INIT_LIST_HEAD(&entry->hash);
|
||||||
list_add(&entry->hash, &kmalloc_track_hash[hash]);
|
list_add(&entry->hash, &kmalloc_track_hash[hash]);
|
||||||
dkprintf("%s entry %s:%d size: %d added\n", __FUNCTION__,
|
dkprintf("%s entry %s:%d size: %d added\n", __FUNCTION__,
|
||||||
file, line, size);
|
file, line, size);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ihk_atomic_inc(&entry->alloc_count);
|
||||||
|
}
|
||||||
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
||||||
|
|
||||||
ihk_atomic_inc(&entry->alloc_count);
|
|
||||||
|
|
||||||
/* Add new addr entry for this allocation entry */
|
/* Add new addr entry for this allocation entry */
|
||||||
addr_entry = ___kmalloc(sizeof(*addr_entry), IHK_MC_AP_NOWAIT);
|
addr_entry = ___kmalloc(sizeof(*addr_entry), IHK_MC_AP_NOWAIT);
|
||||||
if (!addr_entry) {
|
if (!addr_entry) {
|
||||||
@ -1447,13 +1453,15 @@ void _kfree(void *ptr, char *file, int line)
|
|||||||
___kfree(addr_entry);
|
___kfree(addr_entry);
|
||||||
|
|
||||||
/* Do we need to remove tracking entry as well? */
|
/* Do we need to remove tracking entry as well? */
|
||||||
if (!ihk_atomic_dec_and_test(&entry->alloc_count)) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash = (strlen(entry->file) + entry->line + entry->size) &
|
hash = (strlen(entry->file) + entry->line + entry->size) &
|
||||||
KMALLOC_TRACK_HASH_MASK;
|
KMALLOC_TRACK_HASH_MASK;
|
||||||
irqflags = ihk_mc_spinlock_lock(&kmalloc_track_hash_locks[hash]);
|
irqflags = ihk_mc_spinlock_lock(&kmalloc_track_hash_locks[hash]);
|
||||||
|
|
||||||
|
if (!ihk_atomic_dec_and_test(&entry->alloc_count)) {
|
||||||
|
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
list_del(&entry->hash);
|
list_del(&entry->hash);
|
||||||
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
ihk_mc_spinlock_unlock(&kmalloc_track_hash_locks[hash], irqflags);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user