Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
c2df88cb
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c2df88cb
编写于
1月 24, 2011
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'irq/numa' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
上级
5bdc22a5
cd7eab44
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
117 addition
and
1 deletion
+117
-1
include/linux/interrupt.h
include/linux/interrupt.h
+32
-1
include/linux/irqdesc.h
include/linux/irqdesc.h
+3
-0
kernel/irq/manage.c
kernel/irq/manage.c
+82
-0
未找到文件。
include/linux/interrupt.h
浏览文件 @
c2df88cb
...
...
@@ -14,6 +14,8 @@
#include <linux/smp.h>
#include <linux/percpu.h>
#include <linux/hrtimer.h>
#include <linux/kref.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
#include <asm/ptrace.h>
...
...
@@ -240,6 +242,35 @@ extern int irq_can_set_affinity(unsigned int irq);
extern
int
irq_select_affinity
(
unsigned
int
irq
);
extern
int
irq_set_affinity_hint
(
unsigned
int
irq
,
const
struct
cpumask
*
m
);
/**
* struct irq_affinity_notify - context for notification of IRQ affinity changes
* @irq: Interrupt to which notification applies
* @kref: Reference count, for internal use
* @work: Work item, for internal use
* @notify: Function to be called on change. This will be
* called in process context.
* @release: Function to be called on release. This will be
* called in process context. Once registered, the
* structure must only be freed when this function is
* called or later.
*/
struct
irq_affinity_notify
{
unsigned
int
irq
;
struct
kref
kref
;
struct
work_struct
work
;
void
(
*
notify
)(
struct
irq_affinity_notify
*
,
const
cpumask_t
*
mask
);
void
(
*
release
)(
struct
kref
*
ref
);
};
extern
int
irq_set_affinity_notifier
(
unsigned
int
irq
,
struct
irq_affinity_notify
*
notify
);
static
inline
void
irq_run_affinity_notifiers
(
void
)
{
flush_scheduled_work
();
}
#else
/* CONFIG_SMP */
static
inline
int
irq_set_affinity
(
unsigned
int
irq
,
const
struct
cpumask
*
m
)
...
...
@@ -255,7 +286,7 @@ static inline int irq_can_set_affinity(unsigned int irq)
static
inline
int
irq_select_affinity
(
unsigned
int
irq
)
{
return
0
;
}
static
inline
int
irq_set_affinity_hint
(
unsigned
int
irq
,
const
struct
cpumask
*
m
)
const
struct
cpumask
*
m
)
{
return
-
EINVAL
;
}
...
...
include/linux/irqdesc.h
浏览文件 @
c2df88cb
...
...
@@ -8,6 +8,7 @@
* For now it's included from <linux/irq.h>
*/
struct
irq_affinity_notify
;
struct
proc_dir_entry
;
struct
timer_rand_state
;
/**
...
...
@@ -24,6 +25,7 @@ struct timer_rand_state;
* @last_unhandled: aging timer for unhandled count
* @irqs_unhandled: stats field for spurious unhandled interrupts
* @lock: locking for SMP
* @affinity_notify: context for notification of affinity changes
* @pending_mask: pending rebalanced interrupts
* @threads_active: number of irqaction threads currently running
* @wait_for_threads: wait queue for sync_irq to wait for threaded handlers
...
...
@@ -70,6 +72,7 @@ struct irq_desc {
raw_spinlock_t
lock
;
#ifdef CONFIG_SMP
const
struct
cpumask
*
affinity_hint
;
struct
irq_affinity_notify
*
affinity_notify
;
#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_var_t
pending_mask
;
#endif
...
...
kernel/irq/manage.c
浏览文件 @
c2df88cb
...
...
@@ -134,6 +134,10 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
irq_set_thread_affinity
(
desc
);
}
#endif
if
(
desc
->
affinity_notify
)
{
kref_get
(
&
desc
->
affinity_notify
->
kref
);
schedule_work
(
&
desc
->
affinity_notify
->
work
);
}
desc
->
status
|=
IRQ_AFFINITY_SET
;
raw_spin_unlock_irqrestore
(
&
desc
->
lock
,
flags
);
return
0
;
...
...
@@ -155,6 +159,79 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
}
EXPORT_SYMBOL_GPL
(
irq_set_affinity_hint
);
static
void
irq_affinity_notify
(
struct
work_struct
*
work
)
{
struct
irq_affinity_notify
*
notify
=
container_of
(
work
,
struct
irq_affinity_notify
,
work
);
struct
irq_desc
*
desc
=
irq_to_desc
(
notify
->
irq
);
cpumask_var_t
cpumask
;
unsigned
long
flags
;
if
(
!
desc
)
goto
out
;
if
(
!
alloc_cpumask_var
(
&
cpumask
,
GFP_KERNEL
))
goto
out
;
raw_spin_lock_irqsave
(
&
desc
->
lock
,
flags
);
#ifdef CONFIG_GENERIC_PENDING_IRQ
if
(
desc
->
status
&
IRQ_MOVE_PENDING
)
cpumask_copy
(
cpumask
,
desc
->
pending_mask
);
else
#endif
cpumask_copy
(
cpumask
,
desc
->
affinity
);
raw_spin_unlock_irqrestore
(
&
desc
->
lock
,
flags
);
notify
->
notify
(
notify
,
cpumask
);
free_cpumask_var
(
cpumask
);
out:
kref_put
(
&
notify
->
kref
,
notify
->
release
);
}
/**
* irq_set_affinity_notifier - control notification of IRQ affinity changes
* @irq: Interrupt for which to enable/disable notification
* @notify: Context for notification, or %NULL to disable
* notification. Function pointers must be initialised;
* the other fields will be initialised by this function.
*
* Must be called in process context. Notification may only be enabled
* after the IRQ is allocated and must be disabled before the IRQ is
* freed using free_irq().
*/
int
irq_set_affinity_notifier
(
unsigned
int
irq
,
struct
irq_affinity_notify
*
notify
)
{
struct
irq_desc
*
desc
=
irq_to_desc
(
irq
);
struct
irq_affinity_notify
*
old_notify
;
unsigned
long
flags
;
/* The release function is promised process context */
might_sleep
();
if
(
!
desc
)
return
-
EINVAL
;
/* Complete initialisation of *notify */
if
(
notify
)
{
notify
->
irq
=
irq
;
kref_init
(
&
notify
->
kref
);
INIT_WORK
(
&
notify
->
work
,
irq_affinity_notify
);
}
raw_spin_lock_irqsave
(
&
desc
->
lock
,
flags
);
old_notify
=
desc
->
affinity_notify
;
desc
->
affinity_notify
=
notify
;
raw_spin_unlock_irqrestore
(
&
desc
->
lock
,
flags
);
if
(
old_notify
)
kref_put
(
&
old_notify
->
kref
,
old_notify
->
release
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
irq_set_affinity_notifier
);
#ifndef CONFIG_AUTO_IRQ_AFFINITY
/*
* Generic version of the affinity autoselector.
...
...
@@ -1004,6 +1081,11 @@ void free_irq(unsigned int irq, void *dev_id)
if
(
!
desc
)
return
;
#ifdef CONFIG_SMP
if
(
WARN_ON
(
desc
->
affinity_notify
))
desc
->
affinity_notify
=
NULL
;
#endif
chip_bus_lock
(
desc
);
kfree
(
__free_irq
(
irq
,
dev_id
));
chip_bus_sync_unlock
(
desc
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录