X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=libcfs%2Flibcfs%2Flinux%2Flinux-prim.c;h=1df8542e0eb7f9bb8f58ae7a786fb52bb69da894;hp=e46076071caf848de5bef9e7cb61a024b338e6dc;hb=11c2c0ec77125041e9c8143a80e7e51aede653ea;hpb=0f8dca08a4f68cba82c2c822998ecc309d3b7aaf diff --git a/libcfs/libcfs/linux/linux-prim.c b/libcfs/libcfs/linux/linux-prim.c index e460760..1df8542 100644 --- a/libcfs/libcfs/linux/linux-prim.c +++ b/libcfs/libcfs/linux/linux-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. @@ -28,6 +26,8 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011, Whamcloud, Inc. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -35,9 +35,6 @@ */ #define DEBUG_SUBSYSTEM S_LNET -#ifndef AUTOCONF_INCLUDED -#include -#endif #include #include #include @@ -73,6 +70,17 @@ cfs_waitq_add(cfs_waitq_t *waitq, cfs_waitlink_t *link) } EXPORT_SYMBOL(cfs_waitq_add); +#ifndef HAVE___ADD_WAIT_QUEUE_EXCLUSIVE + +static inline void __add_wait_queue_exclusive(wait_queue_head_t *q, + wait_queue_t *wait) +{ + wait->flags |= WQ_FLAG_EXCLUSIVE; + __add_wait_queue(q, wait); +} + +#endif /* HAVE___ADD_WAIT_QUEUE_EXCLUSIVE */ + void cfs_waitq_add_exclusive(cfs_waitq_t *waitq, cfs_waitlink_t *link) @@ -81,6 +89,30 @@ cfs_waitq_add_exclusive(cfs_waitq_t *waitq, } EXPORT_SYMBOL(cfs_waitq_add_exclusive); +/** + * wait_queue_t of Linux (version < 2.6.34) is a FIFO list for exclusively + * waiting threads, which is not always desirable because all threads will + * be waken up again and again, even user only needs a few of them to be + * active most time. This is not good for performance because cache can + * be polluted by different threads. + * + * LIFO list can resolve this problem because we always wakeup the most + * recent active thread by default. + * + * NB: please don't call non-exclusive & exclusive wait on the same + * waitq if cfs_waitq_add_exclusive_head is used. + */ +void +cfs_waitq_add_exclusive_head(cfs_waitq_t *waitq, cfs_waitlink_t *link) +{ + unsigned long flags; + + spin_lock_irqsave(&LINUX_WAITQ_HEAD(waitq)->lock, flags); + __add_wait_queue_exclusive(LINUX_WAITQ_HEAD(waitq), LINUX_WAITQ(link)); + spin_unlock_irqrestore(&LINUX_WAITQ_HEAD(waitq)->lock, flags); +} +EXPORT_SYMBOL(cfs_waitq_add_exclusive_head); + void cfs_waitq_del(cfs_waitq_t *waitq, cfs_waitlink_t *link) { @@ -232,13 +264,11 @@ void cfs_enter_debugger(void) void cfs_daemonize(char *str) { unsigned long flags; - lock_kernel(); daemonize(str); SIGNAL_MASK_LOCK(current, flags); sigfillset(¤t->blocked); RECALC_SIGPENDING; SIGNAL_MASK_UNLOCK(current, flags); - unlock_kernel(); } int cfs_daemonize_ctxt(char *str) { @@ -261,18 +291,6 @@ int cfs_daemonize_ctxt(char *str) { } sigset_t -cfs_get_blockedsigs(void) -{ - unsigned long flags; - sigset_t old; - - SIGNAL_MASK_LOCK(current, flags); - old = current->blocked; - SIGNAL_MASK_UNLOCK(current, flags); - return old; -} - -sigset_t cfs_block_allsigs(void) { unsigned long flags; @@ -287,18 +305,32 @@ cfs_block_allsigs(void) return old; } -sigset_t -cfs_block_sigs(sigset_t bits) +sigset_t cfs_block_sigs(unsigned long sigs) { - unsigned long flags; - sigset_t old; + unsigned long flags; + sigset_t old; - SIGNAL_MASK_LOCK(current, flags); - old = current->blocked; - current->blocked = bits; - RECALC_SIGPENDING; - SIGNAL_MASK_UNLOCK(current, flags); - return old; + SIGNAL_MASK_LOCK(current, flags); + old = current->blocked; + sigaddsetmask(¤t->blocked, sigs); + RECALC_SIGPENDING; + SIGNAL_MASK_UNLOCK(current, flags); + return old; +} + +/* Block all signals except for the @sigs */ +sigset_t cfs_block_sigsinv(unsigned long sigs) +{ + unsigned long flags; + sigset_t old; + + SIGNAL_MASK_LOCK(current, flags); + old = current->blocked; + sigaddsetmask(¤t->blocked, ~sigs); + RECALC_SIGPENDING; + SIGNAL_MASK_UNLOCK(current, flags); + + return old; } void @@ -347,7 +379,7 @@ EXPORT_SYMBOL(cfs_daemonize); EXPORT_SYMBOL(cfs_daemonize_ctxt); EXPORT_SYMBOL(cfs_block_allsigs); EXPORT_SYMBOL(cfs_block_sigs); -EXPORT_SYMBOL(cfs_get_blockedsigs); +EXPORT_SYMBOL(cfs_block_sigsinv); EXPORT_SYMBOL(cfs_restore_sigs); EXPORT_SYMBOL(cfs_signal_pending); EXPORT_SYMBOL(cfs_clear_sigpending);