Tofu: keep track of stags per memory range
Change-Id: I033beaeee3b141dab4485dd3a2a3848eaa84e54e
This commit is contained in:
committed by
Masamichi Takagi
parent
75694152f0
commit
0b82c8942b
@ -395,6 +395,9 @@ struct vm_range {
|
|||||||
off_t objoff;
|
off_t objoff;
|
||||||
int pgshift; /* page size. 0 means THP */
|
int pgshift; /* page size. 0 means THP */
|
||||||
int padding;
|
int padding;
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
struct list_head tofu_stag_list;
|
||||||
|
#endif
|
||||||
void *private_data;
|
void *private_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -764,6 +767,9 @@ struct thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define VM_RANGE_CACHE_SIZE 4
|
#define VM_RANGE_CACHE_SIZE 4
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
#define TOFU_STAG_HASH_SIZE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
struct process_vm {
|
struct process_vm {
|
||||||
struct address_space *address_space;
|
struct address_space *address_space;
|
||||||
@ -796,6 +802,12 @@ struct process_vm {
|
|||||||
struct vm_range *range_cache[VM_RANGE_CACHE_SIZE];
|
struct vm_range *range_cache[VM_RANGE_CACHE_SIZE];
|
||||||
int range_cache_ind;
|
int range_cache_ind;
|
||||||
struct swapinfo *swapinfo;
|
struct swapinfo *swapinfo;
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
/* Tofu STAG hash */
|
||||||
|
ihk_spinlock_t tofu_stag_lock;
|
||||||
|
struct list_head tofu_stag_hash[TOFU_STAG_HASH_SIZE];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int has_cap_ipc_lock(struct thread *th)
|
static inline int has_cap_ipc_lock(struct thread *th)
|
||||||
|
|||||||
@ -36,6 +36,9 @@
|
|||||||
#include <rusage_private.h>
|
#include <rusage_private.h>
|
||||||
#include <ihk/monitor.h>
|
#include <ihk/monitor.h>
|
||||||
#include <ihk/debug.h>
|
#include <ihk/debug.h>
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
#include <tofu/tofu_stag_range.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_PRINT_PROCESS
|
//#define DEBUG_PRINT_PROCESS
|
||||||
|
|
||||||
@ -269,6 +272,12 @@ init_process_vm(struct process *owner, struct address_space *asp, struct process
|
|||||||
}
|
}
|
||||||
vm->range_cache_ind = 0;
|
vm->range_cache_ind = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
ihk_mc_spinlock_init(&vm->tofu_stag_lock);
|
||||||
|
for (i = 0; i < TOFU_STAG_HASH_SIZE; ++i) {
|
||||||
|
INIT_LIST_HEAD(&vm->tofu_stag_hash[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,6 +964,11 @@ int split_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
|||||||
newrange->pgshift = range->pgshift;
|
newrange->pgshift = range->pgshift;
|
||||||
newrange->private_data = range->private_data;
|
newrange->private_data = range->private_data;
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
/* TODO: figure out which entries to put on which list! */
|
||||||
|
INIT_LIST_HEAD(&newrange->tofu_stag_list);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (range->memobj) {
|
if (range->memobj) {
|
||||||
memobj_ref(range->memobj);
|
memobj_ref(range->memobj);
|
||||||
newrange->memobj = range->memobj;
|
newrange->memobj = range->memobj;
|
||||||
@ -1023,6 +1037,28 @@ int join_process_memory_range(struct process_vm *vm,
|
|||||||
if (vm->range_cache[i] == merging)
|
if (vm->range_cache[i] == merging)
|
||||||
vm->range_cache[i] = surviving;
|
vm->range_cache[i] = surviving;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
/* Move Tofu stag range entries */
|
||||||
|
if (vm->proc->enable_tofu) {
|
||||||
|
struct tofu_stag_range *tsr, *next;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
list_for_each_entry_safe(tsr, next,
|
||||||
|
&merging->tofu_stag_list, list) {
|
||||||
|
|
||||||
|
list_del(&tsr->list);
|
||||||
|
list_add_tail(&tsr->list, &surviving->tofu_stag_list);
|
||||||
|
dkprintf("%s: stag: %d @ %p:%lu moved in VM range merge\n",
|
||||||
|
__func__,
|
||||||
|
tsr->stag,
|
||||||
|
tsr->start,
|
||||||
|
(unsigned long)(tsr->end - tsr->start));
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
kfree(merging);
|
kfree(merging);
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
@ -1137,6 +1173,24 @@ static int free_process_memory_range(struct process_vm *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
straight_out:
|
straight_out:
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
if (vm->proc->enable_tofu) {
|
||||||
|
int entries;
|
||||||
|
extern int tofu_stag_range_remove_overlapping(struct process_vm *vm,
|
||||||
|
struct vm_range *range);
|
||||||
|
|
||||||
|
entries = tofu_stag_range_remove_overlapping(vm, range);
|
||||||
|
if (entries > 0) {
|
||||||
|
kprintf("%s: removed %d Tofu stag entries for range 0x%lx:%lu\n",
|
||||||
|
__func__,
|
||||||
|
entries,
|
||||||
|
range->start,
|
||||||
|
range->end - range->start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
rb_erase(&range->vm_rb_node, &vm->vm_range_tree);
|
rb_erase(&range->vm_rb_node, &vm->vm_range_tree);
|
||||||
for (i = 0; i < VM_RANGE_CACHE_SIZE; ++i) {
|
for (i = 0; i < VM_RANGE_CACHE_SIZE; ++i) {
|
||||||
if (vm->range_cache[i] == range)
|
if (vm->range_cache[i] == range)
|
||||||
@ -1428,6 +1482,9 @@ int add_process_memory_range(struct process_vm *vm,
|
|||||||
range->pgshift = pgshift;
|
range->pgshift = pgshift;
|
||||||
range->private_data = NULL;
|
range->private_data = NULL;
|
||||||
range->straight_start = 0;
|
range->straight_start = 0;
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
INIT_LIST_HEAD(&range->tofu_stag_list);
|
||||||
|
#endif
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if (phys == NOPHYS) {
|
if (phys == NOPHYS) {
|
||||||
|
|||||||
@ -1390,6 +1390,15 @@ void terminate(int rc, int sig)
|
|||||||
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
mcs_rwlock_writer_unlock(&proc->threads_lock, &lock);
|
||||||
|
|
||||||
vm = proc->vm;
|
vm = proc->vm;
|
||||||
|
|
||||||
|
#ifdef ENABLE_TOFU
|
||||||
|
if (proc->enable_tofu) {
|
||||||
|
extern void tof_utofu_finalize();
|
||||||
|
|
||||||
|
tof_utofu_finalize();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
free_all_process_memory_range(vm);
|
free_all_process_memory_range(vm);
|
||||||
|
|
||||||
if (proc->saved_cmdline) {
|
if (proc->saved_cmdline) {
|
||||||
|
|||||||
@ -43,6 +43,121 @@ typedef void (*tof_core_signal_handler)(int, int, uint64_t, uint64_t);
|
|||||||
#include <tofu/tofu_generated-tof_utofu_bg.h>
|
#include <tofu/tofu_generated-tof_utofu_bg.h>
|
||||||
#include <tofu/tofu_generated-tof_utofu_mbpt.h>
|
#include <tofu/tofu_generated-tof_utofu_mbpt.h>
|
||||||
|
|
||||||
|
#include <tofu/tofu_stag_range.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tofu STAG regions list keeps track of stags in a given VM range..
|
||||||
|
* Per-process tree is protected by process' vm_range_lock.
|
||||||
|
*/
|
||||||
|
int tof_utofu_stag_range_insert(struct process_vm *vm,
|
||||||
|
struct vm_range *range,
|
||||||
|
uintptr_t start, uintptr_t end,
|
||||||
|
struct tof_utofu_cq *ucq, int stag)
|
||||||
|
{
|
||||||
|
struct tofu_stag_range *tsr = kmalloc(sizeof(*tsr), IHK_MC_AP_NOWAIT);
|
||||||
|
|
||||||
|
if (!tsr) {
|
||||||
|
kprintf("%s: error: allocating tofu_stag_range\n", __func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsr->start = start;
|
||||||
|
tsr->end = end;
|
||||||
|
tsr->ucq = ucq;
|
||||||
|
tsr->stag = stag;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
list_add_tail(&tsr->list, &range->tofu_stag_list);
|
||||||
|
list_add_tail(&tsr->hash, &vm->tofu_stag_hash[stag % TOFU_STAG_HASH_SIZE]);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
|
|
||||||
|
dkprintf("%s: stag: %d for TNI %d CQ %d @ %p:%lu\n",
|
||||||
|
__func__,
|
||||||
|
tsr->stag,
|
||||||
|
tsr->ucq->tni,
|
||||||
|
tsr->ucq->cqid,
|
||||||
|
tsr->start,
|
||||||
|
(unsigned long)(tsr->end - tsr->start));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tofu_stag_range *tofu_stag_range_lookup_by_stag(struct process_vm *vm,
|
||||||
|
int stag)
|
||||||
|
{
|
||||||
|
struct tofu_stag_range *tsr;
|
||||||
|
struct tofu_stag_range *match = NULL;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
list_for_each_entry(tsr,
|
||||||
|
&vm->tofu_stag_hash[stag % TOFU_STAG_HASH_SIZE], hash) {
|
||||||
|
if (tsr->stag == stag) {
|
||||||
|
match = tsr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: vm->tofu_stag_lock must be held */
|
||||||
|
void __tofu_stag_range_remove(struct process_vm *vm, struct tofu_stag_range *tsr)
|
||||||
|
{
|
||||||
|
dkprintf("%s: stag: %d for TNI %d CQ %d @ %p:%lu\n",
|
||||||
|
__func__,
|
||||||
|
tsr->stag,
|
||||||
|
tsr->ucq->tni,
|
||||||
|
tsr->ucq->cqid,
|
||||||
|
tsr->start,
|
||||||
|
(unsigned long)(tsr->end - tsr->start));
|
||||||
|
|
||||||
|
list_del(&tsr->list);
|
||||||
|
list_del(&tsr->hash);
|
||||||
|
kfree(tsr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tofu_stag_range_remove(struct process_vm *vm, struct tofu_stag_range *tsr)
|
||||||
|
{
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
__tofu_stag_range_remove(vm, tsr);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tof_utofu_free_stag(struct tof_utofu_cq *ucq, int stag);
|
||||||
|
|
||||||
|
int tofu_stag_range_remove_overlapping(struct process_vm *vm,
|
||||||
|
struct vm_range *range)
|
||||||
|
{
|
||||||
|
struct tofu_stag_range *tsr, *next;
|
||||||
|
int entries = 0;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(tsr, next,
|
||||||
|
&range->tofu_stag_list, list) {
|
||||||
|
|
||||||
|
dkprintf("%s: stag: %d @ %p:%lu\n",
|
||||||
|
__func__,
|
||||||
|
tsr->stag,
|
||||||
|
tsr->start,
|
||||||
|
(unsigned long)(tsr->end - tsr->start));
|
||||||
|
|
||||||
|
linux_spin_lock(&tsr->ucq->trans.mru_lock);
|
||||||
|
tof_utofu_free_stag(tsr->ucq, tsr->stag);
|
||||||
|
linux_spin_unlock(&tsr->ucq->trans.mru_lock);
|
||||||
|
|
||||||
|
__tofu_stag_range_remove(vm, tsr);
|
||||||
|
++entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TOF_UTOFU_VERSION TOF_UAPI_VERSION
|
#define TOF_UTOFU_VERSION TOF_UAPI_VERSION
|
||||||
#define TOF_UTOFU_NUM_STAG_NTYPES 3
|
#define TOF_UTOFU_NUM_STAG_NTYPES 3
|
||||||
#define TOF_UTOFU_NUM_STAG_BITS(size) ((size) + 13)
|
#define TOF_UTOFU_NUM_STAG_BITS(size) ((size) + 13)
|
||||||
@ -1016,6 +1131,7 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
|
|||||||
size_t pgsz;
|
size_t pgsz;
|
||||||
int ret = -ENOTSUPP;
|
int ret = -ENOTSUPP;
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
struct vm_range *range = NULL;
|
||||||
|
|
||||||
ucq = container_of(dev, struct tof_utofu_cq, common);
|
ucq = container_of(dev, struct tof_utofu_cq, common);
|
||||||
if(!ucq->common.enabled){
|
if(!ucq->common.enabled){
|
||||||
@ -1037,7 +1153,46 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly = (req.flags & 1) != 0;
|
readonly = (req.flags & 1) != 0;
|
||||||
|
|
||||||
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
ihk_rwspinlock_read_lock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
|
/* Assume smallest page size at first */
|
||||||
|
start = round_down((uintptr_t)req.va, PAGE_SIZE);
|
||||||
|
end = round_up((uintptr_t)req.va + req.len, PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Find range, straight mapping special lookup */
|
||||||
|
if (vm->proc->straight_va &&
|
||||||
|
start >= (unsigned long)vm->proc->straight_va &&
|
||||||
|
end <= ((unsigned long)vm->proc->straight_va +
|
||||||
|
vm->proc->straight_len) &&
|
||||||
|
!(start == (unsigned long)vm->proc->straight_va &&
|
||||||
|
end == ((unsigned long)vm->proc->straight_va +
|
||||||
|
vm->proc->straight_len))) {
|
||||||
|
struct vm_range *range_iter;
|
||||||
|
|
||||||
|
range_iter = lookup_process_memory_range(vm, 0, -1);
|
||||||
|
|
||||||
|
while (range_iter) {
|
||||||
|
if (range_iter->straight_start &&
|
||||||
|
start >= range_iter->straight_start &&
|
||||||
|
start < (range_iter->straight_start +
|
||||||
|
(range_iter->end - range_iter->start))) {
|
||||||
|
range = range_iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
range_iter = next_process_memory_range(vm, range_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
range = lookup_process_memory_range(vm, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!range) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock_out;
|
||||||
|
}
|
||||||
|
|
||||||
pgszbits = PAGE_SHIFT;
|
pgszbits = PAGE_SHIFT;
|
||||||
if (req.flags & TOF_UTOFU_ALLOC_STAG_LPG) {
|
if (req.flags & TOF_UTOFU_ALLOC_STAG_LPG) {
|
||||||
ret = tof_utofu_get_pagesize_locked((uintptr_t)req.va,
|
ret = tof_utofu_get_pagesize_locked((uintptr_t)req.va,
|
||||||
@ -1113,6 +1268,12 @@ static int tof_utofu_ioctl_alloc_stag(struct tof_utofu_device *dev, unsigned lon
|
|||||||
|
|
||||||
//up(&ucq->ucq_sem);
|
//up(&ucq->ucq_sem);
|
||||||
ihk_mc_spinlock_unlock_noirq(&tofu_tni_cq_lock[ucq->tni][ucq->cqid]);
|
ihk_mc_spinlock_unlock_noirq(&tofu_tni_cq_lock[ucq->tni][ucq->cqid]);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
tof_utofu_stag_range_insert(vm, range, start, end, ucq, req.stag);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_out:
|
||||||
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
ihk_rwspinlock_read_unlock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
@ -1336,6 +1497,21 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
|
|||||||
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
ret = tof_utofu_free_stag(ucq, stags[i]);
|
ret = tof_utofu_free_stag(ucq, stags[i]);
|
||||||
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct tofu_stag_range *tsr;
|
||||||
|
|
||||||
|
tsr = tofu_stag_range_lookup_by_stag(
|
||||||
|
cpu_local_var(current)->vm, stags[i]);
|
||||||
|
|
||||||
|
if (tsr) {
|
||||||
|
tofu_stag_range_remove(cpu_local_var(current)->vm, tsr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kprintf("%s: no stag range object for %d??\n", __func__, stags[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(ret == 0){
|
if(ret == 0){
|
||||||
stags[i] = -1;
|
stags[i] = -1;
|
||||||
}
|
}
|
||||||
@ -1378,9 +1554,11 @@ static int tof_utofu_ioctl_free_stags(struct tof_utofu_device *dev, unsigned lon
|
|||||||
void tof_utofu_release_cq(void *pde_data)
|
void tof_utofu_release_cq(void *pde_data)
|
||||||
{
|
{
|
||||||
struct tof_utofu_cq *ucq;
|
struct tof_utofu_cq *ucq;
|
||||||
int stag;
|
//int stag;
|
||||||
struct tof_utofu_device *dev;
|
struct tof_utofu_device *dev;
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
|
int do_free = 1;
|
||||||
|
|
||||||
dev = (struct tof_utofu_device *)pde_data;
|
dev = (struct tof_utofu_device *)pde_data;
|
||||||
ucq = container_of(dev, struct tof_utofu_cq, common);
|
ucq = container_of(dev, struct tof_utofu_cq, common);
|
||||||
@ -1388,13 +1566,43 @@ void tof_utofu_release_cq(void *pde_data)
|
|||||||
if (!ucq->common.enabled) {
|
if (!ucq->common.enabled) {
|
||||||
kprintf("%s: UCQ TNI %d, CQ %d is disabled\n",
|
kprintf("%s: UCQ TNI %d, CQ %d is disabled\n",
|
||||||
__func__, ucq->tni, ucq->cqid);
|
__func__, ucq->tni, ucq->cqid);
|
||||||
return;
|
do_free = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
for (stag = 0; stag < TOF_UTOFU_NUM_STAG(ucq->num_stag); stag++) {
|
for (stag = 0; stag < TOF_UTOFU_NUM_STAG(ucq->num_stag); stag++) {
|
||||||
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
tof_utofu_free_stag(ucq, stag);
|
tof_utofu_free_stag(ucq, stag);
|
||||||
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct tofu_stag_range *tsr, *next;
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&vm->tofu_stag_lock);
|
||||||
|
for (i = 0; i < TOFU_STAG_HASH_SIZE; ++i) {
|
||||||
|
list_for_each_entry_safe(tsr, next,
|
||||||
|
&vm->tofu_stag_hash[i], hash) {
|
||||||
|
if (tsr->ucq != ucq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (do_free) {
|
||||||
|
dkprintf("%s: removing stag %d for TNI %d CQ %d\n",
|
||||||
|
__func__, tsr->stag, ucq->tni, ucq->cqid);
|
||||||
|
|
||||||
|
linux_spin_lock_irqsave(&ucq->trans.mru_lock, irqflags);
|
||||||
|
tof_utofu_free_stag(tsr->ucq, tsr->stag);
|
||||||
|
linux_spin_unlock_irqrestore(&ucq->trans.mru_lock, irqflags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kprintf("%s: WARNING: could not free stag %d for TNI %d CQ %d (UCQ is disabled)\n",
|
||||||
|
__func__, tsr->stag, ucq->tni, ucq->cqid);
|
||||||
|
}
|
||||||
|
|
||||||
|
__tofu_stag_range_remove(vm, tsr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&vm->tofu_stag_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
dkprintf("%s: UCQ (pde: %p) TNI %d, CQ %d\n",
|
dkprintf("%s: UCQ (pde: %p) TNI %d, CQ %d\n",
|
||||||
@ -2131,6 +2339,24 @@ void tof_utofu_finalize(void)
|
|||||||
{
|
{
|
||||||
struct tofu_globals *tg = ihk_mc_get_tofu_globals();
|
struct tofu_globals *tg = ihk_mc_get_tofu_globals();
|
||||||
|
|
||||||
|
/* Could be called from idle.. */
|
||||||
|
if (cpu_local_var(current)->proc->enable_tofu) {
|
||||||
|
int i;
|
||||||
|
struct process_vm *vm = cpu_local_var(current)->vm;
|
||||||
|
struct tofu_stag_range *tsr, *next;
|
||||||
|
|
||||||
|
for (i = 0; i < TOFU_STAG_HASH_SIZE; ++i) {
|
||||||
|
list_for_each_entry_safe(tsr, next,
|
||||||
|
&vm->tofu_stag_hash[i], hash) {
|
||||||
|
|
||||||
|
dkprintf("%s: WARNING: stray stag %d for TNI %d CQ %d?\n",
|
||||||
|
__func__, tsr->stag, tsr->ucq->tni, tsr->ucq->cqid);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kprintf("%s: STAG processing done\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
ihk_mc_clear_kernel_range((void *)tg->linux_vmalloc_start,
|
ihk_mc_clear_kernel_range((void *)tg->linux_vmalloc_start,
|
||||||
(void *)tg->linux_vmalloc_end);
|
(void *)tg->linux_vmalloc_end);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user