Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
bdc2911c
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看板
提交
bdc2911c
编写于
6月 02, 2009
作者:
J
Joerg Roedel
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'dma-debug/fixes' and 'dma-debug/driver-filter' into dma-debug/2.6.31
上级
88f3907f
016ea687
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
185 addition
and
1 deletion
+185
-1
Documentation/DMA-API.txt
Documentation/DMA-API.txt
+12
-0
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+7
-0
lib/dma-debug.c
lib/dma-debug.c
+166
-1
未找到文件。
Documentation/DMA-API.txt
浏览文件 @
bdc2911c
...
...
@@ -704,12 +704,24 @@ this directory the following files can currently be found:
The current number of free dma_debug_entries
in the allocator.
dma-api/driver-filter
You can write a name of a driver into this file
to limit the debug output to requests from that
particular driver. Write an empty string to
that file to disable the filter and see
all errors again.
If you have this code compiled into your kernel it will be enabled by default.
If you want to boot without the bookkeeping anyway you can provide
'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
Notice that you can not enable it again at runtime. You have to reboot to do
so.
If you want to see debug messages only for a special device driver you can
specify the dma_debug_driver=<drivername> parameter. This will enable the
driver filter at boot time. The debug code will only print errors for that
driver afterwards. This filter can be disabled or changed later using debugfs.
When the code disables itself at runtime this is most likely because it ran
out of dma_debug_entries. These entries are preallocated at boot. The number
of preallocated entries is defined per architecture. If it is too low for you
...
...
Documentation/kernel-parameters.txt
浏览文件 @
bdc2911c
...
...
@@ -646,6 +646,13 @@ and is between 256 and 4096 characters. It is defined in the file
DMA-API debugging code disables itself because the
architectural default is too low.
dma_debug_driver=<driver_name>
With this option the DMA-API debugging driver
filter feature can be enabled at boot time. Just
pass the driver to filter for as the parameter.
The filter can be disabled or changed to another
driver later using sysfs.
dscc4.setup= [NET]
dtc3181e= [HW,SCSI]
...
...
lib/dma-debug.c
浏览文件 @
bdc2911c
...
...
@@ -23,9 +23,11 @@
#include <linux/dma-debug.h>
#include <linux/spinlock.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/slab.h>
...
...
@@ -98,6 +100,16 @@ static struct dentry *show_all_errors_dent __read_mostly;
static
struct
dentry
*
show_num_errors_dent
__read_mostly
;
static
struct
dentry
*
num_free_entries_dent
__read_mostly
;
static
struct
dentry
*
min_free_entries_dent
__read_mostly
;
static
struct
dentry
*
filter_dent
__read_mostly
;
/* per-driver filter related state */
#define NAME_MAX_LEN 64
static
char
current_driver_name
[
NAME_MAX_LEN
]
__read_mostly
;
static
struct
device_driver
*
current_driver
__read_mostly
;
static
DEFINE_RWLOCK
(
driver_name_lock
);
static
const
char
*
type2name
[
4
]
=
{
"single"
,
"page"
,
"scather-gather"
,
"coherent"
};
...
...
@@ -133,9 +145,48 @@ static inline void dump_entry_trace(struct dma_debug_entry *entry)
#endif
}
static
bool
driver_filter
(
struct
device
*
dev
)
{
/* driver filter off */
if
(
likely
(
!
current_driver_name
[
0
]))
return
true
;
/* driver filter on and initialized */
if
(
current_driver
&&
dev
->
driver
==
current_driver
)
return
true
;
/* driver filter on but not yet initialized */
if
(
!
current_driver
&&
current_driver_name
[
0
])
{
struct
device_driver
*
drv
=
get_driver
(
dev
->
driver
);
unsigned
long
flags
;
bool
ret
=
false
;
if
(
!
drv
)
return
false
;
/* lock to protect against change of current_driver_name */
read_lock_irqsave
(
&
driver_name_lock
,
flags
);
if
(
drv
->
name
&&
strncmp
(
current_driver_name
,
drv
->
name
,
NAME_MAX_LEN
-
1
)
==
0
)
{
current_driver
=
drv
;
ret
=
true
;
}
read_unlock_irqrestore
(
&
driver_name_lock
,
flags
);
put_driver
(
drv
);
return
ret
;
}
return
false
;
}
#define err_printk(dev, entry, format, arg...) do { \
error_count += 1; \
if (show_all_errors || show_num_errors > 0) { \
if (driver_filter(dev) && \
(show_all_errors || show_num_errors > 0)) { \
WARN(1, "%s %s: " format, \
dev_driver_string(dev), \
dev_name(dev) , ## arg); \
...
...
@@ -412,6 +463,97 @@ static int prealloc_memory(u32 num_entries)
return
-
ENOMEM
;
}
static
ssize_t
filter_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
unsigned
long
flags
;
char
buf
[
NAME_MAX_LEN
+
1
];
int
len
;
if
(
!
current_driver_name
[
0
])
return
0
;
/*
* We can't copy to userspace directly because current_driver_name can
* only be read under the driver_name_lock with irqs disabled. So
* create a temporary copy first.
*/
read_lock_irqsave
(
&
driver_name_lock
,
flags
);
len
=
scnprintf
(
buf
,
NAME_MAX_LEN
+
1
,
"%s
\n
"
,
current_driver_name
);
read_unlock_irqrestore
(
&
driver_name_lock
,
flags
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
}
static
ssize_t
filter_write
(
struct
file
*
file
,
const
char
__user
*
userbuf
,
size_t
count
,
loff_t
*
ppos
)
{
unsigned
long
flags
;
char
buf
[
NAME_MAX_LEN
];
size_t
len
=
NAME_MAX_LEN
-
1
;
int
i
;
/*
* We can't copy from userspace directly. Access to
* current_driver_name is protected with a write_lock with irqs
* disabled. Since copy_from_user can fault and may sleep we
* need to copy to temporary buffer first
*/
len
=
min
(
count
,
len
);
if
(
copy_from_user
(
buf
,
userbuf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
0
;
write_lock_irqsave
(
&
driver_name_lock
,
flags
);
/* Now handle the string we got from userspace very carefully.
* The rules are:
* - only use the first token we got
* - token delimiter is everything looking like a space
* character (' ', '\n', '\t' ...)
*
*/
if
(
!
isalnum
(
buf
[
0
]))
{
/*
If the first character userspace gave us is not
* alphanumerical then assume the filter should be
* switched off.
*/
if
(
current_driver_name
[
0
])
printk
(
KERN_INFO
"DMA-API: switching off dma-debug "
"driver filter
\n
"
);
current_driver_name
[
0
]
=
0
;
current_driver
=
NULL
;
goto
out_unlock
;
}
/*
* Now parse out the first token and use it as the name for the
* driver to filter for.
*/
for
(
i
=
0
;
i
<
NAME_MAX_LEN
;
++
i
)
{
current_driver_name
[
i
]
=
buf
[
i
];
if
(
isspace
(
buf
[
i
])
||
buf
[
i
]
==
' '
||
buf
[
i
]
==
0
)
break
;
}
current_driver_name
[
i
]
=
0
;
current_driver
=
NULL
;
printk
(
KERN_INFO
"DMA-API: enable driver filter for driver [%s]
\n
"
,
current_driver_name
);
out_unlock:
write_unlock_irqrestore
(
&
driver_name_lock
,
flags
);
return
count
;
}
const
struct
file_operations
filter_fops
=
{
.
read
=
filter_read
,
.
write
=
filter_write
,
};
static
int
dma_debug_fs_init
(
void
)
{
dma_debug_dent
=
debugfs_create_dir
(
"dma-api"
,
NULL
);
...
...
@@ -455,6 +597,11 @@ static int dma_debug_fs_init(void)
if
(
!
min_free_entries_dent
)
goto
out_err
;
filter_dent
=
debugfs_create_file
(
"driver_filter"
,
0644
,
dma_debug_dent
,
NULL
,
&
filter_fops
);
if
(
!
filter_dent
)
goto
out_err
;
return
0
;
out_err:
...
...
@@ -1044,3 +1191,21 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
}
EXPORT_SYMBOL
(
debug_dma_sync_sg_for_device
);
static
int
__init
dma_debug_driver_setup
(
char
*
str
)
{
int
i
;
for
(
i
=
0
;
i
<
NAME_MAX_LEN
-
1
;
++
i
,
++
str
)
{
current_driver_name
[
i
]
=
*
str
;
if
(
*
str
==
0
)
break
;
}
if
(
current_driver_name
[
0
])
printk
(
KERN_INFO
"DMA-API: enable driver filter for "
"driver [%s]
\n
"
,
current_driver_name
);
return
1
;
}
__setup
(
"dma_debug_driver="
,
dma_debug_driver_setup
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录