X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=libcfs%2Flibcfs%2Fwinnt%2Fwinnt-prim.c;h=2fe3a7b2d7a3bdfbf0cb0c98e6eec16715958a27;hb=a66e12d6ede2afda3bb7a5b1f22b8c17c1176584;hp=e77ac737f35d7d6a302499d4752e623f1e987de0;hpb=6869932b552ac705f411de3362f01bd50c1f6f7d;p=fs%2Flustre-release.git diff --git a/libcfs/libcfs/winnt/winnt-prim.c b/libcfs/libcfs/winnt/winnt-prim.c index e77ac73..2fe3a7b 100644 --- a/libcfs/libcfs/winnt/winnt-prim.c +++ b/libcfs/libcfs/winnt/winnt-prim.c @@ -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. @@ -26,8 +24,10 @@ * 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/ @@ -54,16 +54,14 @@ * 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); -CFS_LIST_HEAD(cfs_symbol_list); +static DECLARE_RWSEM(cfs_symbol_lock); +struct list_head cfs_symbol_list = LIST_HEAD_INIT(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; + struct list_head *walker; + struct cfs_symbol *sym = NULL; - down_read(&cfs_symbol_lock); + down_read(&cfs_symbol_lock); list_for_each(walker, &cfs_symbol_list) { - sym = list_entry (walker, struct cfs_symbol, sym_list); + sym = 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; + struct list_head *walker; + struct cfs_symbol *sym = NULL; - down_read(&cfs_symbol_lock); + down_read(&cfs_symbol_lock); list_for_each(walker, &cfs_symbol_list) { - sym = list_entry (walker, struct cfs_symbol, sym_list); + sym = 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; + struct list_head *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); + 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); + kfree(new); + return 0; /* alreay registerred */ + } + } + 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; + struct list_head *walker; + struct list_head *nxt; + struct cfs_symbol *sym = NULL; - down_write(&cfs_symbol_lock); + down_write(&cfs_symbol_lock); list_for_each_safe(walker, nxt, &cfs_symbol_list) { - sym = list_entry (walker, struct cfs_symbol, sym_list); + sym = 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); + 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; + struct list_head *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); + 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); + 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);