From ad4a1e15877aff3da889c0c433475d3173a677e4 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 17 Jul 2011 22:47:51 +0200 Subject: Support forceful clean-up of kernel memory --- cli.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'cli.c') diff --git a/cli.c b/cli.c index 5deee17..de796dc 100644 --- a/cli.c +++ b/cli.c @@ -92,6 +92,7 @@ typedef enum { OPT_ITERATIONS, OPT_LIST_KMEM, OPT_FREE_KMEM, + OPT_FORCE, OPT_HELP = 'h', } OPTIONS; @@ -116,8 +117,9 @@ static struct option long_options[] = { {"stop-dma", optional_argument, 0, OPT_STOP_DMA }, {"wait-irq", optional_argument, 0, OPT_WAIT_IRQ }, {"list-kernel-memory", no_argument, 0, OPT_LIST_KMEM }, - {"free-kernel-memory", optional_argument, 0, OPT_FREE_KMEM }, + {"free-kernel-memory", required_argument, 0, OPT_FREE_KMEM }, {"quiete", no_argument, 0, OPT_QUIETE }, + {"force", no_argument, 0, OPT_FORCE }, {"help", no_argument, 0, OPT_HELP }, { 0, 0, 0, 0 } }; @@ -157,7 +159,9 @@ void Usage(int argc, char *argv[], const char *format, ...) { "\n" " Kernel Modes:\n" " --list-kernel-memory - List kernel buffers\n" -" --free-kernel-memory [use] - Cleans lost kernel space buffers (DANGEROUS)\n" +" --free-kernel-memory - Cleans lost kernel space buffers (DANGEROUS)\n" +" dma - Remove all buffers allocated by DMA subsystem\n" +" #number - Remove all buffers with the specified use id\n" "\n" " Addressing:\n" " -d - FPGA device (/dev/fpga0)\n" @@ -1087,6 +1091,38 @@ int ListKMEM(pcilib_t *handle, const char *device) { return 0; } +int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) { + int err; + int i; + + unsigned long useid; + + pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; + if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well. + + if (!strcasecmp(use, "dma")) { + for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) { + err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags); + if (err) Error("Error cleaning DMA%i C2S Ring buffer", i); + err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags); + if (err) Error("Error cleaning DMA%i S2C Ring buffer", i); + err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags); + if (err) Error("Error cleaning DMA%i C2S Page buffers", i); + err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags); + if (err) Error("Error cleaning DMA%i S2C Page buffers", i); + } + + return 0; + } + + if ((!isxnumber(use))||(sscanf(use, "%lx", &useid) != 1)) Error("Invalid use (%s) is specified", use); + + err = pcilib_clean_kernel_memory(handle, useid, flags); + if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid); + + return 0; +} + int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_source_t irq_source, pcilib_timeout_t timeout) { int err; size_t count; @@ -1113,6 +1149,7 @@ int main(int argc, char **argv) { int details = 0; int quiete = 0; + int force = 0; pcilib_model_t model = PCILIB_MODEL_DETECT; pcilib_model_description_t *model_info; @@ -1311,6 +1348,9 @@ int main(int argc, char **argv) { case OPT_QUIETE: quiete = 1; break; + case OPT_FORCE: + force = 1; + break; default: Usage(argc, argv, "Unknown option (%s)", argv[optind]); } @@ -1494,6 +1534,9 @@ int main(int argc, char **argv) { case MODE_LIST_KMEM: ListKMEM(handle, fpga_device); break; + case MODE_FREE_KMEM: + FreeKMEM(handle, fpga_device, use, force); + break; } pcilib_close(handle); -- cgit v1.2.3