Merge branch 'master' into next
Conflicts: security/smack/smack_lsm.c Verified and added fix by Stephen Rothwell <sfr@canb.auug.org.au> Ok'd by Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: James Morris <jmorris@namei.org>
这个提交包含在:
@@ -210,4 +210,7 @@ config GENERIC_ATOMIC64
|
||||
config LRU_CACHE
|
||||
tristate
|
||||
|
||||
config AVERAGE
|
||||
bool
|
||||
|
||||
endmenu
|
||||
|
@@ -173,7 +173,8 @@ config LOCKUP_DETECTOR
|
||||
An NMI is generated every 60 seconds or so to check for hardlockups.
|
||||
|
||||
config HARDLOCKUP_DETECTOR
|
||||
def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI
|
||||
def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \
|
||||
!ARCH_HAS_NMI_WATCHDOG
|
||||
|
||||
config BOOTPARAM_SOFTLOCKUP_PANIC
|
||||
bool "Panic (Reboot) On Soft Lockups"
|
||||
|
@@ -8,7 +8,7 @@ KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS))
|
||||
endif
|
||||
|
||||
lib-y := ctype.o string.o vsprintf.o cmdline.o \
|
||||
rbtree.o radix-tree.o dump_stack.o \
|
||||
rbtree.o radix-tree.o dump_stack.o timerqueue.o\
|
||||
idr.o int_sqrt.o extable.o prio_tree.o \
|
||||
sha1.o irq_regs.o reciprocal_div.o argv_split.o \
|
||||
proportions.o prio_heap.o ratelimit.o show_mem.o \
|
||||
@@ -106,6 +106,8 @@ obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
|
||||
|
||||
obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
|
||||
|
||||
obj-$(CONFIG_AVERAGE) += average.o
|
||||
|
||||
hostprogs-y := gen_crc32table
|
||||
clean-files := crc32table.h
|
||||
|
||||
|
61
lib/average.c
普通文件
61
lib/average.c
普通文件
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* lib/average.c
|
||||
*
|
||||
* This source code is licensed under the GNU General Public License,
|
||||
* Version 2. See the file COPYING for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/average.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
/**
|
||||
* DOC: Exponentially Weighted Moving Average (EWMA)
|
||||
*
|
||||
* These are generic functions for calculating Exponentially Weighted Moving
|
||||
* Averages (EWMA). We keep a structure with the EWMA parameters and a scaled
|
||||
* up internal representation of the average value to prevent rounding errors.
|
||||
* The factor for scaling up and the exponential weight (or decay rate) have to
|
||||
* be specified thru the init fuction. The structure should not be accessed
|
||||
* directly but only thru the helper functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ewma_init() - Initialize EWMA parameters
|
||||
* @avg: Average structure
|
||||
* @factor: Factor to use for the scaled up internal value. The maximum value
|
||||
* of averages can be ULONG_MAX/(factor*weight). For performance reasons
|
||||
* factor has to be a power of 2.
|
||||
* @weight: Exponential weight, or decay rate. This defines how fast the
|
||||
* influence of older values decreases. For performance reasons weight has
|
||||
* to be a power of 2.
|
||||
*
|
||||
* Initialize the EWMA parameters for a given struct ewma @avg.
|
||||
*/
|
||||
void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight)
|
||||
{
|
||||
WARN_ON(!is_power_of_2(weight) || !is_power_of_2(factor));
|
||||
|
||||
avg->weight = ilog2(weight);
|
||||
avg->factor = ilog2(factor);
|
||||
avg->internal = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ewma_init);
|
||||
|
||||
/**
|
||||
* ewma_add() - Exponentially weighted moving average (EWMA)
|
||||
* @avg: Average structure
|
||||
* @val: Current value
|
||||
*
|
||||
* Add a sample to the average.
|
||||
*/
|
||||
struct ewma *ewma_add(struct ewma *avg, unsigned long val)
|
||||
{
|
||||
avg->internal = avg->internal ?
|
||||
(((avg->internal << avg->weight) - avg->internal) +
|
||||
(val << avg->factor)) >> avg->weight :
|
||||
(val << avg->factor);
|
||||
return avg;
|
||||
}
|
||||
EXPORT_SYMBOL(ewma_add);
|
@@ -8,7 +8,6 @@
|
||||
*
|
||||
* Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
@@ -39,7 +38,6 @@ int debug_locks_off(void)
|
||||
{
|
||||
if (__debug_locks_off()) {
|
||||
if (!debug_locks_silent) {
|
||||
oops_in_progress = 1;
|
||||
console_verbose();
|
||||
return 1;
|
||||
}
|
||||
|
22
lib/nlattr.c
22
lib/nlattr.c
@@ -15,7 +15,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
|
||||
static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
||||
[NLA_U8] = sizeof(u8),
|
||||
[NLA_U16] = sizeof(u16),
|
||||
[NLA_U32] = sizeof(u32),
|
||||
@@ -23,7 +23,7 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = {
|
||||
[NLA_NESTED] = NLA_HDRLEN,
|
||||
};
|
||||
|
||||
static int validate_nla(struct nlattr *nla, int maxtype,
|
||||
static int validate_nla(const struct nlattr *nla, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
{
|
||||
const struct nla_policy *pt;
|
||||
@@ -115,10 +115,10 @@ static int validate_nla(struct nlattr *nla, int maxtype,
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_validate(struct nlattr *head, int len, int maxtype,
|
||||
int nla_validate(const struct nlattr *head, int len, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
const struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
@@ -173,10 +173,10 @@ nla_policy_len(const struct nla_policy *p, int n)
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
|
||||
const struct nla_policy *policy)
|
||||
int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
|
||||
int len, const struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
const struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
|
||||
@@ -191,7 +191,7 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tb[type] = nla;
|
||||
tb[type] = (struct nlattr *)nla;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,14 +212,14 @@ errout:
|
||||
*
|
||||
* Returns the first attribute in the stream matching the specified type.
|
||||
*/
|
||||
struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
|
||||
struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
const struct nlattr *nla;
|
||||
int rem;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem)
|
||||
if (nla_type(nla) == attrtype)
|
||||
return nla;
|
||||
return (struct nlattr *)nla;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -72,18 +72,16 @@ EXPORT_SYMBOL(percpu_counter_set);
|
||||
void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
|
||||
{
|
||||
s64 count;
|
||||
s32 *pcount;
|
||||
|
||||
preempt_disable();
|
||||
pcount = this_cpu_ptr(fbc->counters);
|
||||
count = *pcount + amount;
|
||||
count = __this_cpu_read(*fbc->counters) + amount;
|
||||
if (count >= batch || count <= -batch) {
|
||||
spin_lock(&fbc->lock);
|
||||
fbc->count += count;
|
||||
*pcount = 0;
|
||||
__this_cpu_write(*fbc->counters, 0);
|
||||
spin_unlock(&fbc->lock);
|
||||
} else {
|
||||
*pcount = count;
|
||||
__this_cpu_write(*fbc->counters, count);
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
|
107
lib/timerqueue.c
普通文件
107
lib/timerqueue.c
普通文件
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Generic Timer-queue
|
||||
*
|
||||
* Manages a simple queue of timers, ordered by expiration time.
|
||||
* Uses rbtrees for quick list adds and expiration.
|
||||
*
|
||||
* NOTE: All of the following functions need to be serialized
|
||||
* to avoid races. No locking is done by this libary code.
|
||||
*
|
||||
* 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 of the License, 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
|
||||
*/
|
||||
|
||||
#include <linux/timerqueue.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/**
|
||||
* timerqueue_add - Adds timer to timerqueue.
|
||||
*
|
||||
* @head: head of timerqueue
|
||||
* @node: timer node to be added
|
||||
*
|
||||
* Adds the timer node to the timerqueue, sorted by the
|
||||
* node's expires value.
|
||||
*/
|
||||
void timerqueue_add(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
struct rb_node **p = &head->head.rb_node;
|
||||
struct rb_node *parent = NULL;
|
||||
struct timerqueue_node *ptr;
|
||||
|
||||
/* Make sure we don't add nodes that are already added */
|
||||
WARN_ON_ONCE(!RB_EMPTY_NODE(&node->node));
|
||||
|
||||
while (*p) {
|
||||
parent = *p;
|
||||
ptr = rb_entry(parent, struct timerqueue_node, node);
|
||||
if (node->expires.tv64 < ptr->expires.tv64)
|
||||
p = &(*p)->rb_left;
|
||||
else
|
||||
p = &(*p)->rb_right;
|
||||
}
|
||||
rb_link_node(&node->node, parent, p);
|
||||
rb_insert_color(&node->node, &head->head);
|
||||
|
||||
if (!head->next || node->expires.tv64 < head->next->expires.tv64)
|
||||
head->next = node;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_add);
|
||||
|
||||
/**
|
||||
* timerqueue_del - Removes a timer from the timerqueue.
|
||||
*
|
||||
* @head: head of timerqueue
|
||||
* @node: timer node to be removed
|
||||
*
|
||||
* Removes the timer node from the timerqueue.
|
||||
*/
|
||||
void timerqueue_del(struct timerqueue_head *head, struct timerqueue_node *node)
|
||||
{
|
||||
WARN_ON_ONCE(RB_EMPTY_NODE(&node->node));
|
||||
|
||||
/* update next pointer */
|
||||
if (head->next == node) {
|
||||
struct rb_node *rbn = rb_next(&node->node);
|
||||
|
||||
head->next = rbn ?
|
||||
rb_entry(rbn, struct timerqueue_node, node) : NULL;
|
||||
}
|
||||
rb_erase(&node->node, &head->head);
|
||||
RB_CLEAR_NODE(&node->node);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_del);
|
||||
|
||||
/**
|
||||
* timerqueue_iterate_next - Returns the timer after the provided timer
|
||||
*
|
||||
* @node: Pointer to a timer.
|
||||
*
|
||||
* Provides the timer that is after the given node. This is used, when
|
||||
* necessary, to iterate through the list of timers in a timer list
|
||||
* without modifying the list.
|
||||
*/
|
||||
struct timerqueue_node *timerqueue_iterate_next(struct timerqueue_node *node)
|
||||
{
|
||||
struct rb_node *next;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
next = rb_next(&node->node);
|
||||
if (!next)
|
||||
return NULL;
|
||||
return container_of(next, struct timerqueue_node, node);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(timerqueue_iterate_next);
|
在新工单中引用
屏蔽一个用户