📄 my_memory.c
字号:
/* common/my_memory.c * * vi: set autoindent tabstop=8 shiftwidth=8 : * * This defines the generic functions used * by both the iSCSI target and the iSCSI initiator for dynamic memory * allocation. * * This file contains auxilliary functions for iscsi initiator * code that are responsible for dealing with error recovery. * * Copyright (C) 2001-2004 InterOperability Lab (IOL) * University of New Hampshire (UNH) * Durham, NH 03824 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * The name of IOL and/or UNH may not be used to endorse or promote * products derived from this software without specific prior * written permission.*/#include <linux/kernel.h>#include <linux/types.h>#include <linux/slab.h>/* for definition of in_interrupt() */#include <linux/interrupt.h>#include "iscsi_common.h"#include "debug.h"#include "my_memory.h"#ifdef ISCSI_CHECK_MEMORY#define MEMORY_TABLE_SIZE 512static void *my_memory_address_table[MEMORY_TABLE_SIZE];static char *my_memory_id_table[MEMORY_TABLE_SIZE];static int my_memory_last = -1; /* currently the last used slot */static int my_memory_first = 0; /* currently 1st possible unused slot */static int my_memory_max = -1; /* maximum last used slot so far */static spinlock_t unh_memory_lock = SPIN_LOCK_UNLOCKED;#endif/* called to allocate memory and keep a record of it */void *my_kmalloc(__u32 size, char *id){ void *ptr; TRACE(TRACE_MY_MEMORY, "Enter my_kmalloc %u bytes for %s\n", size, id); if ((ptr = kmalloc(size,/* Ming Zhang, mingz@ele.uri.edu */#ifdef K26 ((in_interrupt() || irqs_disabled())#else (in_interrupt()#endif ? GFP_ATOMIC : GFP_KERNEL))) == NULL) { TRACE_ERROR("Cannot allocate %u bytes for %s\n", size, id); goto out; }#ifdef ISCSI_CHECK_MEMORY { int i; unsigned long flags; /* search for an unused slot, starting with first possible empty one */ spin_lock_irqsave(&unh_memory_lock, flags); for (i = my_memory_first; i < MEMORY_TABLE_SIZE; i++) { if (my_memory_address_table[i] == NULL) { my_memory_address_table[i] = ptr; my_memory_id_table[i] = id; if (my_memory_last < i) { my_memory_last = i; if (my_memory_max < i) my_memory_max = i; } /* first possible unused slot */ my_memory_first = i + 1; spin_unlock_irqrestore(&unh_memory_lock, flags); goto out; } } /* if loop finishes, table is full so we cannot track our allocations */ spin_unlock_irqrestore(&unh_memory_lock, flags); TRACE_ERROR("my_memory_table full, %d slots\n", MEMORY_TABLE_SIZE); /* BUG(); */ }#endifout: TRACE(TRACE_MY_MEMORY, "Leave my_kmalloc %p for %s\n", ptr, id); return ptr;}#ifdef ISCSI_CHECK_MEMORY/* release dynamically allocated memory pointed to by non-NULL ptr */void_my_kfree(void **ptr, char *id){ { int i; unsigned long flags; TRACE(TRACE_MY_MEMORY, "Enter my_kfree %p, last %d, for %s\n", *ptr, my_memory_last, id); /* seach table backwards to find slot containing this pointer */ spin_lock_irqsave(&unh_memory_lock, flags); for (i = my_memory_last; i >= 0; i--) { if (my_memory_address_table[i] == *ptr) { /* found the slot containing pointer, NULL everything */ kfree(*ptr); *ptr = NULL; my_memory_address_table[i] = NULL; if (my_memory_first > i) { my_memory_first = i; } while (my_memory_last >= 0 && my_memory_address_table[my_memory_last] == NULL) { if (my_memory_first > my_memory_last) { my_memory_first = my_memory_last; } my_memory_last--; } spin_unlock_irqrestore(&unh_memory_lock, flags); goto out; } } spin_unlock_irqrestore(&unh_memory_lock, flags); TRACE_ERROR("trying to free non-malloced memory %p for %s\n", *ptr, id); /* BUG(); */out: TRACE(TRACE_MY_MEMORY, "Leave my_kfree, last %d, for %s\n", my_memory_last, id); }}/* "prints" statistics on my memory usage into buf, * returns no. of chars printed. */int_print_my_kmemory(char *buf){ if (buf == NULL) return printk("iscsi Maximum of %d memory slots used out of %d\n", my_memory_max + 1, MEMORY_TABLE_SIZE); else return sprintf(buf, "Maximum of %d memory slots used out of %d\n", my_memory_max + 1, MEMORY_TABLE_SIZE);}/* called only once, at very end when module is unloaded, * to check for any allocated but not freed memory */void_my_kempty(void){ TRACE((TRACE_ENTER_LEAVE | TRACE_MY_MEMORY), "Enter my_kempty, last %d\n", my_memory_last); print_my_kmemory(NULL); while (my_memory_last >= 0) { if (my_memory_address_table[my_memory_last] != NULL) { TRACE_ERROR("Unfreed memory[%d] %p for %s\n", my_memory_last, my_memory_address_table[my_memory_last], my_memory_id_table[my_memory_last]); /*** kfree(my_memory_address_table[my_memory_last]); ***/ my_memory_address_table[my_memory_last] = NULL; } my_memory_last--; } /* everything should now be reset to initial state */ my_memory_max = -1; my_memory_first = 0; TRACE((TRACE_ENTER_LEAVE | TRACE_MY_MEMORY), "Leave my_kempty, last %d\n", my_memory_last);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -