Whamcloud - gitweb
LU-1346 libcfs: cleanup libcfs primitive (linux-prim.h)
[fs/lustre-release.git] / libcfs / libcfs / winnt / winnt-prim.c
index 26738a3..077f3a4 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -16,8 +14,8 @@
  * in the LICENSE file that accompanied this code).
  *
  * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see [sun.com URL with a
- * copy of GPLv2].
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  *
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
  * Return Value:
  *   void: N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
 void
-cfs_thread_proc(
-    void * context
-    )
+cfs_thread_proc(void *context)
 {
-    cfs_thread_context_t * thread_context = 
+    cfs_thread_context_t * thread_context =
         (cfs_thread_context_t *) context;
 
     /* Execute the specified function ... */
@@ -73,8 +71,8 @@ cfs_thread_proc(
     }
 
     /* Free the context memory */
-   
-    cfs_free(context);
+
+    kfree(context);
 
     /* Terminate this system thread */
 
@@ -82,33 +80,33 @@ cfs_thread_proc(
 }
 
 /*
- * cfs_kernel_thread
+ * kthread_run
  *   Create a system thread to execute the routine specified
  *
  * Arguments:
  *   func:  function to be executed in the thread
  *   arg:   argument transferred to func function
- *   flag:  thread creation flags.
+ *   name:  thread name to create
  *
  * Return Value:
- *   int:   0 on success or error codes
+ *   struct task_struct:   0 on success or error codes
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-int cfs_kernel_thread(int (*func)(void *), void *arg, int flag)
+struct task_struct kthread_run(int (*func)(void *), void *arg, char *name)
 {
     cfs_handle_t  thread = NULL;
     NTSTATUS      status;
-    cfs_thread_context_t * context = NULL;
+    cfs_thread_context_t *context = NULL;
 
     /* Allocate the context to be transferred to system thread */
 
-    context = cfs_alloc(sizeof(cfs_thread_context_t), CFS_ALLOC_ZERO);
+    context = kmalloc(sizeof(cfs_thread_context_t), __GFP_ZERO);
 
     if (!context) {
-        return -ENOMEM;
+       return ERR_PTR(-ENOMEM);
     }
 
     context->func  = func;
@@ -126,11 +124,11 @@ int cfs_kernel_thread(int (*func)(void *), void *arg, int flag)
     if (!NT_SUCCESS(status)) {
 
 
-        cfs_free(context);
+       kfree(context);
 
         /* We need translate the nt status to linux error code */
 
-        return cfs_error_code(status);
+       return ERR_PTR(cfs_error_code(status));
     }
 
     //
@@ -139,7 +137,7 @@ int cfs_kernel_thread(int (*func)(void *), void *arg, int flag)
 
     ZwClose(thread);
 
-    return 0;
+       return (struct task_struct)0;
 }
 
 
@@ -148,10 +146,10 @@ int cfs_kernel_thread(int (*func)(void *), void *arg, int flag)
  */
 
 
-static CFS_DECL_RWSEM(cfs_symbol_lock);
+static DECLARE_RWSEM(cfs_symbol_lock);
 CFS_LIST_HEAD(cfs_symbol_list);
 
-int MPSystem = FALSE;
+int libcfs_is_mp_system = FALSE;
 
 /*
  * cfs_symbol_get
@@ -164,27 +162,27 @@ int MPSystem = FALSE;
  *   If the symbol is in the table, return the address of it.
  *   If not, return NULL.
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
 void *
 cfs_symbol_get(const char *name)
 {
-    struct list_head    *walker;
-    struct cfs_symbol   *sym = NULL;
+    cfs_list_t              *walker;
+    struct cfs_symbol       *sym = NULL;
 
-    down_read(&cfs_symbol_lock);
-    list_for_each(walker, &cfs_symbol_list) {
-        sym = list_entry (walker, struct cfs_symbol, sym_list);
+       down_read(&cfs_symbol_lock);
+    cfs_list_for_each(walker, &cfs_symbol_list) {
+        sym = cfs_list_entry (walker, struct cfs_symbol, sym_list);
         if (!strcmp(sym->name, name)) {
             sym->ref ++;
             break;
-        } 
-    } 
-    up_read(&cfs_symbol_lock);
+        }
+    }
+       up_read(&cfs_symbol_lock);
 
-    if (sym != NULL) 
+    if (sym != NULL)
         return sym->value;
 
     return NULL;
@@ -200,26 +198,26 @@ cfs_symbol_get(const char *name)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
 void
 cfs_symbol_put(const char *name)
 {
-    struct list_head    *walker;
-    struct cfs_symbol   *sym = NULL;
+    cfs_list_t              *walker;
+    struct cfs_symbol       *sym = NULL;
 
-    down_read(&cfs_symbol_lock);
-    list_for_each(walker, &cfs_symbol_list) {
-        sym = list_entry (walker, struct cfs_symbol, sym_list);
+       down_read(&cfs_symbol_lock);
+    cfs_list_for_each(walker, &cfs_symbol_list) {
+        sym = cfs_list_entry (walker, struct cfs_symbol, sym_list);
         if (!strcmp(sym->name, name)) {
             LASSERT(sym->ref > 0);
             sym->ref--;
             break;
-        } 
-    } 
-    up_read(&cfs_symbol_lock);
+        }
+    }
+       up_read(&cfs_symbol_lock);
 
     LASSERT(sym != NULL);
 }
@@ -236,7 +234,7 @@ cfs_symbol_put(const char *name)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   Zero: Succeed to register
  *   Non-Zero: Fail to register the symbol
  */
@@ -244,30 +242,30 @@ cfs_symbol_put(const char *name)
 int
 cfs_symbol_register(const char *name, const void *value)
 {
-    struct list_head    *walker;
-    struct cfs_symbol   *sym = NULL;
-    struct cfs_symbol   *new = NULL;
+    cfs_list_t              *walker;
+    struct cfs_symbol       *sym = NULL;
+    struct cfs_symbol       *new = NULL;
+
+       new = kmalloc(sizeof(struct cfs_symbol), __GFP_ZERO);
+       if (!new)
+               return -ENOMEM;
 
-    new = cfs_alloc(sizeof(struct cfs_symbol), CFS_ALLOC_ZERO);
-    if (!new) {
-        return (-ENOMEM);
-    }
     strncpy(new->name, name, CFS_SYMBOL_LEN);
     new->value = (void *)value;
     new->ref = 0;
     CFS_INIT_LIST_HEAD(&new->sym_list);
 
-    down_write(&cfs_symbol_lock);
-    list_for_each(walker, &cfs_symbol_list) {
-        sym = list_entry (walker, struct cfs_symbol, sym_list);
-        if (!strcmp(sym->name, name)) {
-            up_write(&cfs_symbol_lock);
-            cfs_free(new);
-            return 0; // alreay registerred
-        }
-    }
-    list_add_tail(&new->sym_list, &cfs_symbol_list);
-    up_write(&cfs_symbol_lock);
+       down_write(&cfs_symbol_lock);
+       cfs_list_for_each(walker, &cfs_symbol_list) {
+               sym = cfs_list_entry (walker, struct cfs_symbol, sym_list);
+               if (!strcmp(sym->name, name)) {
+                       up_write(&cfs_symbol_lock);
+                       kfree(new);
+                       return 0; /* alreay registerred */
+               }
+       }
+       cfs_list_add_tail(&new->sym_list, &cfs_symbol_list);
+       up_write(&cfs_symbol_lock);
 
     return 0;
 }
@@ -282,28 +280,28 @@ cfs_symbol_register(const char *name, const void *value)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
 void
 cfs_symbol_unregister(const char *name)
 {
-    struct list_head    *walker;
-    struct list_head    *nxt;
-    struct cfs_symbol   *sym = NULL;
+    cfs_list_t              *walker;
+    cfs_list_t              *nxt;
+    struct cfs_symbol       *sym = NULL;
 
-    down_write(&cfs_symbol_lock);
-    list_for_each_safe(walker, nxt, &cfs_symbol_list) {
-        sym = list_entry (walker, struct cfs_symbol, sym_list);
+       down_write(&cfs_symbol_lock);
+    cfs_list_for_each_safe(walker, nxt, &cfs_symbol_list) {
+        sym = cfs_list_entry (walker, struct cfs_symbol, sym_list);
         if (!strcmp(sym->name, name)) {
             LASSERT(sym->ref == 0);
-            list_del (&sym->sym_list);
-            cfs_free(sym);
+            cfs_list_del (&sym->sym_list);
+           kfree(sym);
             break;
         }
     }
-    up_write(&cfs_symbol_lock);
+       up_write(&cfs_symbol_lock);
 }
 
 /*
@@ -316,25 +314,25 @@ cfs_symbol_unregister(const char *name)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
 void
 cfs_symbol_clean()
 {
-    struct list_head    *walker;
+    cfs_list_t          *walker;
     struct cfs_symbol   *sym = NULL;
 
-    down_write(&cfs_symbol_lock);
-    list_for_each(walker, &cfs_symbol_list) {
-        sym = list_entry (walker, struct cfs_symbol, sym_list);
-        LASSERT(sym->ref == 0);
-        list_del (&sym->sym_list);
-        cfs_free(sym);
-    }
-    up_write(&cfs_symbol_lock);
-    return;
+       down_write(&cfs_symbol_lock);
+       cfs_list_for_each(walker, &cfs_symbol_list) {
+               sym = cfs_list_entry (walker, struct cfs_symbol, sym_list);
+               LASSERT(sym->ref == 0);
+               cfs_list_del (&sym->sym_list);
+               kfree(sym);
+       }
+       up_write(&cfs_symbol_lock);
+       return;
 }
 
 
@@ -345,7 +343,7 @@ cfs_symbol_clean()
 
 
 /* Timer dpc procedure */
+
 static void
 cfs_timer_dpc_proc (
     IN PKDPC Dpc,
@@ -353,10 +351,10 @@ cfs_timer_dpc_proc (
     IN PVOID SystemArgument1,
     IN PVOID SystemArgument2)
 {
-    cfs_timer_t *   timer;
+    struct timer_list *   timer;
     KIRQL           Irql;
 
-    timer = (cfs_timer_t *) DeferredContext;
+    timer = (struct timer_list *) DeferredContext;
 
     /* clear the flag */
     KeAcquireSpinLock(&(timer->Lock), &Irql);
@@ -364,12 +362,17 @@ cfs_timer_dpc_proc (
     KeReleaseSpinLock(&(timer->Lock), Irql);
 
     /* call the user specified timer procedure */
-    timer->proc((unsigned long)(timer->arg));
+    timer->proc((long_ptr_t)timer->arg);
+}
+
+void cfs_init_timer(struct timer_list *timer)
+{
+    memset(timer, 0, sizeof(struct timer_list));
 }
 
 /*
  * cfs_timer_init
- *   To initialize the cfs_timer_t
+ *   To initialize the struct timer_list
  *
  * Arguments:
  *   timer:  the cfs_timer to be initialized
@@ -379,13 +382,13 @@ cfs_timer_dpc_proc (
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-void cfs_timer_init(cfs_timer_t *timer, void (*func)(unsigned long), void *arg)
+void cfs_timer_init(struct timer_list *timer, void (*func)(ulong_ptr_t), void *arg)
 {
-    memset(timer, 0, sizeof(cfs_timer_t));
+    memset(timer, 0, sizeof(struct timer_list));
 
     timer->proc = func;
     timer->arg  = arg;
@@ -399,7 +402,7 @@ void cfs_timer_init(cfs_timer_t *timer, void (*func)(unsigned long), void *arg)
 
 /*
  * cfs_timer_done
- *   To finialize the cfs_timer_t (unused)
+ *   To finialize the struct timer_list (unused)
  *
  * Arguments:
  *   timer:  the cfs_timer to be cleaned up
@@ -407,11 +410,11 @@ void cfs_timer_init(cfs_timer_t *timer, void (*func)(unsigned long), void *arg)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-void cfs_timer_done(cfs_timer_t *timer)
+void cfs_timer_done(struct timer_list *timer)
 {
     return;
 }
@@ -427,11 +430,11 @@ void cfs_timer_done(cfs_timer_t *timer)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-void cfs_timer_arm(cfs_timer_t *timer, cfs_time_t deadline)
+void cfs_timer_arm(struct timer_list *timer, cfs_time_t deadline)
 {
     LARGE_INTEGER   timeout;
     KIRQL           Irql;
@@ -439,9 +442,9 @@ void cfs_timer_arm(cfs_timer_t *timer, cfs_time_t deadline)
     KeAcquireSpinLock(&(timer->Lock), &Irql);
     if (!cfs_is_flag_set(timer->Flags, CFS_TIMER_FLAG_TIMERED)){
 
-        timeout.QuadPart = (LONGLONG)-1*1000*1000*10/HZ*deadline;
+       timeout.QuadPart = (LONGLONG)-1*1000*1000*10/HZ*deadline;
 
-        if (KeSetTimer(&timer->Timer, timeout, &timer->Dpc )) {
+        if (KeSetTimer(&timer->Timer, timeout, &timer->Dpc)) {
             cfs_set_flag(timer->Flags, CFS_TIMER_FLAG_TIMERED);
         }
 
@@ -461,11 +464,11 @@ void cfs_timer_arm(cfs_timer_t *timer, cfs_time_t deadline)
  * Return Value:
  *   N/A
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-void cfs_timer_disarm(cfs_timer_t *timer)
+void cfs_timer_disarm(struct timer_list *timer)
 {
     KIRQL   Irql;
 
@@ -487,11 +490,11 @@ void cfs_timer_disarm(cfs_timer_t *timer)
  *   1:  if it's armed.
  *   0:  if it's not.
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-int cfs_timer_is_armed(cfs_timer_t *timer)
+int cfs_timer_is_armed(struct timer_list *timer)
 {
     int     rc = 0;
     KIRQL   Irql;
@@ -515,44 +518,42 @@ int cfs_timer_is_armed(cfs_timer_t *timer)
  * Return Value:
  *   the deadline value
  *
- * Notes: 
+ * Notes:
  *   N/A
  */
 
-cfs_time_t cfs_timer_deadline(cfs_timer_t * timer)
+cfs_time_t cfs_timer_deadline(struct timer_list * timer)
 {
     return timer->deadline;
 }
 
-/*
- * daemonize routine stub
- */
-
-void cfs_daemonize(char *str)
+int unshare_fs_struct()
 {
-    return;
+       return 0;
 }
 
 /*
  *  routine related with sigals
  */
 
-cfs_sigset_t cfs_get_blockedsigs()
+sigset_t cfs_block_allsigs()
 {
         return 0;
 }
 
-cfs_sigset_t cfs_block_allsigs()
+sigset_t cfs_block_sigs(sigset_t bit)
 {
         return 0;
 }
 
-cfs_sigset_t cfs_block_sigs(sigset_t bit)
+/* Block all signals except for the @sigs. It's only used in
+ * Linux kernel, just a dummy here. */
+sigset_t cfs_block_sigsinv(unsigned long sigs)
 {
         return 0;
 }
 
-void cfs_restore_sigs(cfs_sigset_t old)
+void cfs_restore_sigs(sigset_t old)
 {
 }
 
@@ -566,39 +567,218 @@ void cfs_clear_sigpending(void)
     return;
 }
 
+/*
+ *  thread cpu affinity routines
+ */
+
+typedef struct _THREAD_BASIC_INFORMATION {
+    NTSTATUS ExitStatus;
+    PVOID TebBaseAddress;
+    CLIENT_ID ClientId;
+    ULONG_PTR AffinityMask;
+    KPRIORITY Priority;
+    LONG BasePriority;
+} THREAD_BASIC_INFORMATION;
+
+typedef THREAD_BASIC_INFORMATION *PTHREAD_BASIC_INFORMATION;
+
+#define THREAD_QUERY_INFORMATION       (0x0040)
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwOpenThread (
+    __out PHANDLE ThreadHandle,
+    __in ACCESS_MASK DesiredAccess,
+    __in POBJECT_ATTRIBUTES ObjectAttributes,
+    __in_opt PCLIENT_ID ClientId
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwQueryInformationThread (
+    __in HANDLE ThreadHandle,
+    __in THREADINFOCLASS ThreadInformationClass,
+    __out_bcount(ThreadInformationLength) PVOID ThreadInformation,
+    __in ULONG ThreadInformationLength,
+    __out_opt PULONG ReturnLength
+    );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+ZwSetInformationThread (
+    __in HANDLE ThreadHandle,
+    __in THREADINFOCLASS ThreadInformationClass,
+    __in_bcount(ThreadInformationLength) PVOID ThreadInformation,
+    __in ULONG ThreadInformationLength
+    );
+
+HANDLE
+cfs_open_current_thread()
+{
+    NTSTATUS         status;
+    HANDLE           handle = NULL;
+    OBJECT_ATTRIBUTES oa;
+    CLIENT_ID        cid;
+
+    /* initialize object attributes */
+    InitializeObjectAttributes( &oa, NULL, OBJ_KERNEL_HANDLE |
+                                OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+    /* initialize client id */
+    cid.UniqueProcess = PsGetCurrentProcessId();
+    cid.UniqueThread  = PsGetCurrentThreadId();
+
+    /* get thread handle */
+    status = ZwOpenThread( &handle, THREAD_QUERY_INFORMATION |
+                           THREAD_SET_INFORMATION, &oa, &cid);
+    if (!NT_SUCCESS(status)) {
+        handle = NULL;
+    }
+
+    return handle;
+}
+
+void
+cfs_close_thread_handle(HANDLE handle)
+{
+    if (handle)
+        ZwClose(handle);
+}
+
+KAFFINITY
+cfs_query_thread_affinity()
+{
+    NTSTATUS         status;
+    HANDLE           handle = NULL;
+    DWORD            size;
+    THREAD_BASIC_INFORMATION TBI = {0};
+
+    /* open current thread */
+    handle = cfs_open_current_thread();
+    if (!handle) {
+        goto errorout;
+    }
+
+    /* query thread cpu affinity */
+    status = ZwQueryInformationThread(handle, ThreadBasicInformation,
+                       &TBI, sizeof(THREAD_BASIC_INFORMATION), &size);
+    if (!NT_SUCCESS(status)) {
+        goto errorout;
+    }
+
+errorout:
+
+    cfs_close_thread_handle(handle);
+    return TBI.AffinityMask;
+}
+
+int
+cfs_set_thread_affinity(KAFFINITY affinity)
+{
+    NTSTATUS         status;
+    HANDLE           handle = NULL;
+
+    /* open current thread */
+    handle = cfs_open_current_thread();
+    if (!handle) {
+        goto errorout;
+    }
+
+    /* set thread cpu affinity */
+    status = ZwSetInformationThread(handle, ThreadAffinityMask,
+                                    &affinity, sizeof(KAFFINITY));
+    if (!NT_SUCCESS(status)) {
+        goto errorout;
+    }
+
+errorout:
+
+    cfs_close_thread_handle(handle);
+    return NT_SUCCESS(status);
+}
+
+int
+cfs_tie_thread_to_cpu(int cpu)
+{
+    return cfs_set_thread_affinity((KAFFINITY) (1 << cpu));
+}
+
+int
+cfs_set_thread_priority(KPRIORITY priority)
+{
+    NTSTATUS         status;
+    HANDLE           handle = NULL;
+
+    /* open current thread */
+    handle = cfs_open_current_thread();
+    if (!handle) {
+        goto errorout;
+    }
+
+    /* set thread cpu affinity */
+    status = ZwSetInformationThread(handle, ThreadPriority,
+                                    &priority, sizeof(KPRIORITY));
+    if (!NT_SUCCESS(status)) {
+        KdPrint(("set_thread_priority failed: %xh\n", status));
+        goto errorout;
+    }
+
+errorout:
+
+    cfs_close_thread_handle(handle);
+    return NT_SUCCESS(status);
+}
+
+int need_resched(void)
+{
+        return 0;
+}
+
+void cond_resched(void)
+{
+}
+
 /**
- **  Initialize routines 
+ **  Initialize routines
  **/
 
+void cfs_libc_init();
+
 int
 libcfs_arch_init(void)
-{ 
-    int         rc;
+{
+       int             rc;
+       spinlock_t      lock;
 
-    spinlock_t  lock;
-    /* Workground to check the system is MP build or UP build */
-    spin_lock_init(&lock);
-    spin_lock(&lock);
-    MPSystem = (int)lock.lock;
-    /* MP build system: it's a real spin, for UP build system, it
-       only raises the IRQL to DISPATCH_LEVEL */
-    spin_unlock(&lock);
+       /* Workground to check the system is MP build or UP build */
+       spin_lock_init(&lock);
+       spin_lock(&lock);
+       libcfs_is_mp_system = (int)lock.lock;
+       /* MP build system: it's a real spin, for UP build system, it
+        * only raises the IRQL to DISPATCH_LEVEL */
+       spin_unlock(&lock);
 
-    /* create slab memory caches for page alloctors */
-    cfs_page_t_slab = cfs_mem_cache_create(
-        "CPGT", sizeof(cfs_page_t), 0, 0 );
+    /* initialize libc routines (confliction between libcnptr.lib
+       and kernel ntoskrnl.lib) */
+    cfs_libc_init();
 
-    cfs_page_p_slab = cfs_mem_cache_create(
-        "CPGP", CFS_PAGE_SIZE, 0, 0 );
+       /* create slab memory caches for page alloctors */
+       cfs_page_t_slab = kmem_cache_create("CPGT", sizeof(struct page),
+                                           0, 0, NULL);
+
+       cfs_page_p_slab = kmem_cache_create("CPGP", PAGE_CACHE_SIZE,
+                                           0, 0, NULL);
 
     if ( cfs_page_t_slab == NULL ||
          cfs_page_p_slab == NULL ){
         rc = -ENOMEM;
         goto errorout;
-    }    
+    }
 
     rc = init_task_manager();
-
     if (rc != 0) {
         cfs_enter_debugger();
         KdPrint(("winnt-prim.c:libcfs_arch_init: error initializing task manager ...\n"));
@@ -607,7 +787,6 @@ libcfs_arch_init(void)
 
     /* initialize the proc file system */
     rc = proc_init_fs();
-
     if (rc != 0) {
         cfs_enter_debugger();
         KdPrint(("winnt-prim.c:libcfs_arch_init: error initializing proc fs ...\n"));
@@ -617,26 +796,25 @@ libcfs_arch_init(void)
 
     /* initialize the tdi data */
     rc = ks_init_tdi_data();
-
     if (rc != 0) {
         cfs_enter_debugger();
-        KdPrint(("winnt-prim.c:libcfs_arch_init: error initializing tdi ...\n"));
+        KdPrint(("winnt-prim.c:libcfs_arch_init: failed to initialize tdi.\n"));
         proc_destroy_fs();
         cleanup_task_manager();
         goto errorout;
     }
 
+    rc = start_shrinker_timer();
+
 errorout:
 
-    if (rc != 0) {
-        /* destroy the taskslot cache slab */
-        if (cfs_page_t_slab) {
-            cfs_mem_cache_destroy(cfs_page_t_slab);
-        }
-        if (cfs_page_p_slab) {
-            cfs_mem_cache_destroy(cfs_page_p_slab);
-        }
-    }
+       if (rc != 0) {
+               /* destroy the taskslot cache slab */
+               if (cfs_page_t_slab)
+                       kmem_cache_destroy(cfs_page_t_slab);
+               if (cfs_page_p_slab)
+                       kmem_cache_destroy(cfs_page_p_slab);
+       }
 
     return rc;
 }
@@ -644,22 +822,28 @@ errorout:
 void
 libcfs_arch_cleanup(void)
 {
+    /* stop shrinker timer */
+    stop_shrinker_timer();
+
     /* finialize the tdi data */
     ks_fini_tdi_data();
 
     /* detroy the whole proc fs tree and nodes */
     proc_destroy_fs();
 
+    /* cleanup context of task manager */
+    cleanup_task_manager();
+
     /* destroy the taskslot cache slab */
     if (cfs_page_t_slab) {
-        cfs_mem_cache_destroy(cfs_page_t_slab);
+kmem_cache_destroy(cfs_page_t_slab);
     }
 
     if (cfs_page_p_slab) {
-        cfs_mem_cache_destroy(cfs_page_p_slab);
+kmem_cache_destroy(cfs_page_p_slab);
     }
 
-       return; 
+    return;
 }
 
 EXPORT_SYMBOL(libcfs_arch_init);