Linux那些事儿之我是Block层(3)驱动不过一出戏,内存申请为哪般?
2010-08-08 22:05
453 查看
下一个函数
,alloc_disk().
在
sd.c
中咱们传递进来的参数是
16.
720 struct gendisk *alloc_disk(int minors)
721 {
722
return alloc_disk_node(minors, -1);
723 }
724
725 struct gendisk *alloc_disk_node(int minors, int node_id)
726 {
727
struct gendisk *disk;
728
729
disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
730
if (disk) {
731
memset(disk, 0, sizeof(struct gendisk));
732
if (!init_disk_stats(disk)) {
733
kfree(disk);
734
return NULL;
735
}
736
if (minors > 1) {
737
int size = (minors - 1) * sizeof(struct hd_struct *);
738
disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
739
if (!disk->part) {
740
kfree(disk);
741
return NULL;
742
}
743
memset(disk->part, 0, size);
744
}
745
disk->minors = minors;
746
kobj_set_kset_s(disk,block_subsys);
747
kobject_init(&disk->kobj);
748
rand_initialize_disk(disk);
749
INIT_WORK(&disk->async_notify,
750
media_change_notify_thread);
751
}
752
return disk;
753 }
因此我们做的事情就是申请了一个
struct gendisk
结构体
.
毫无疑问
,
这个结构体是我们这个故事中最重要的结构体之一
,
来自
include/linux/genhd.h:
113 struct gendisk {
114
int major;
/* major number of driver */
115
int first_minor;
116
int minors;
/* maximum number of minors, =1 for
117
* disks that can't be partitioned. */
118
char disk_name[32];
/* name of major driver */
119
struct hd_struct **part;
/* [indexed by minor] */
120
int part_uevent_suppress;
121
struct block_device_operations *fops;
122
struct request_queue *queue;
123
void *private_data;
124
sector_t capacity;
125
126
int flags;
127
struct device *driverfs_dev;
128
struct kobject kobj;
129
struct kobject *holder_dir;
130
struct kobject *slave_dir;
131
132
struct timer_rand_state *random;
133
int policy;
134
135
atomic_t sync_io;
/* RAID */
136
unsigned long stamp;
137
int in_flight;
138 #ifdef
CONFIG_SMP
139
struct disk_stats *dkstats;
140 #else
141
struct disk_stats dkstats;
142 #endif
143
struct work_struct async_notify;
144 };
因为
minors
我们给的是
16,
所以
736
行的
if
语句肯定是满足的
.
于是
size
等于
15
个
sizeof(struct hd_struct *),
而
part
我们看到是
struct hd_struct
的二级指针
,
这里我们看到
kmalloc_node(),
这个函数中的
node/node_id
这些概念指的是
NUMA
技术中的节点
,
对于咱们这些根本就不会接触
NUMA
的人来说
kmalloc_node()
就等于
kmalloc(),
因此这里做的就是申请内存并且初始化为
0.
要说明的一点是
,part
就是
partition
的意思
,
日后它将扮演我们常说的分区的角色
.
然后
,disk->minors
设置为了
16.
746
行
,kobj_set_kset_s(),block_subsys
是我们前面注册的子系统
,
从数据结构来说
,
它的定义如下
,
来自
block/genhd.c:
20 struct kset block_subsys;
其实也就是一个
struct kset.
而这里的
kobj_set_kset_s
的作用就是让
disk
对应
kobject
的
kset
等于
block_subsys.
也就是说让
kobject
找到它的
kset.(
如果你还记得当初我们在我是
Sysfs
中分析的
kobject
和
kset
的那套理论的话
,
你不会不明白这里的意图
.)
而
kobject_init()
初始化一个
kobject,
这个函数通常就是出现在设置了
kobject
的
kset
之后
.
网友
”
暗恋未遂
”
打断了我
,
他说这行代码并不是定义一个结构体
.
它更像是一个声明
,
而不像是定义
.
我仔细一看
,
似乎真的是的
,
这里的确是声明
,
而定义并不在这里
,Linux
内核代码的确是虚虚实实真真假假
,
一不小心就会看走眼
,
写代码的哥们儿果然是深谙兵不厌诈的道理
.但愿
他们只是借此表达他们对现实社会的不满吧
,
毕竟在这年头
,
只有假货是真的
,
别的都是假的
.
那么定义在哪里呢
?
同一个文件中
:
610 decl_subsys(block, &ktype_block, &block_uevent_ops);
这个
decl_subsys
来自
include/linux/kobject.h:
173 #define decl_subsys(_name,_type,_uevent_ops) /
174 struct kset _name##_subsys = { /
175
.kobj = { .name = __stringify(_name) }, /
176
.ktype = _type, /
177
.uevent_ops =_uevent_ops, /
178 }
结合这个宏的定义
,
我们知道
,
我们等效于做了下面这么一件事情
:
174 struct kset block_subsys = { /
175
.kobj = { .name = __stringify(block) }, /
176
.ktype = &ktype_block, /
177
.uevent_ops = &block_uevent_ops, /
178 }
正是因为有了这么一个定义
,
正是因为这里我们把
”block”
给了
block_subsys
的
kobj
的
name
成员
,
所以当我们在
block
子系统初始化的时候调用
subsystem_register(&block_subsys)
之后
,
我们才会在
/sys/
目录下面看到
”block”
子目录
.
localhost:~ # ls /sys/
block
bus
class
devices
firmware
fs
kernel
module
power
749
行
,
初始化一个工作队列
.
到时候用到了再来看
.
至此
,alloc_disk_node
就将返回
,
从而
alloc_disk
也就返回了
.
,alloc_disk().
在
sd.c
中咱们传递进来的参数是
16.
720 struct gendisk *alloc_disk(int minors)
721 {
722
return alloc_disk_node(minors, -1);
723 }
724
725 struct gendisk *alloc_disk_node(int minors, int node_id)
726 {
727
struct gendisk *disk;
728
729
disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
730
if (disk) {
731
memset(disk, 0, sizeof(struct gendisk));
732
if (!init_disk_stats(disk)) {
733
kfree(disk);
734
return NULL;
735
}
736
if (minors > 1) {
737
int size = (minors - 1) * sizeof(struct hd_struct *);
738
disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
739
if (!disk->part) {
740
kfree(disk);
741
return NULL;
742
}
743
memset(disk->part, 0, size);
744
}
745
disk->minors = minors;
746
kobj_set_kset_s(disk,block_subsys);
747
kobject_init(&disk->kobj);
748
rand_initialize_disk(disk);
749
INIT_WORK(&disk->async_notify,
750
media_change_notify_thread);
751
}
752
return disk;
753 }
因此我们做的事情就是申请了一个
struct gendisk
结构体
.
毫无疑问
,
这个结构体是我们这个故事中最重要的结构体之一
,
来自
include/linux/genhd.h:
113 struct gendisk {
114
int major;
/* major number of driver */
115
int first_minor;
116
int minors;
/* maximum number of minors, =1 for
117
* disks that can't be partitioned. */
118
char disk_name[32];
/* name of major driver */
119
struct hd_struct **part;
/* [indexed by minor] */
120
int part_uevent_suppress;
121
struct block_device_operations *fops;
122
struct request_queue *queue;
123
void *private_data;
124
sector_t capacity;
125
126
int flags;
127
struct device *driverfs_dev;
128
struct kobject kobj;
129
struct kobject *holder_dir;
130
struct kobject *slave_dir;
131
132
struct timer_rand_state *random;
133
int policy;
134
135
atomic_t sync_io;
/* RAID */
136
unsigned long stamp;
137
int in_flight;
138 #ifdef
CONFIG_SMP
139
struct disk_stats *dkstats;
140 #else
141
struct disk_stats dkstats;
142 #endif
143
struct work_struct async_notify;
144 };
因为
minors
我们给的是
16,
所以
736
行的
if
语句肯定是满足的
.
于是
size
等于
15
个
sizeof(struct hd_struct *),
而
part
我们看到是
struct hd_struct
的二级指针
,
这里我们看到
kmalloc_node(),
这个函数中的
node/node_id
这些概念指的是
NUMA
技术中的节点
,
对于咱们这些根本就不会接触
NUMA
的人来说
kmalloc_node()
就等于
kmalloc(),
因此这里做的就是申请内存并且初始化为
0.
要说明的一点是
,part
就是
partition
的意思
,
日后它将扮演我们常说的分区的角色
.
然后
,disk->minors
设置为了
16.
746
行
,kobj_set_kset_s(),block_subsys
是我们前面注册的子系统
,
从数据结构来说
,
它的定义如下
,
来自
block/genhd.c:
20 struct kset block_subsys;
其实也就是一个
struct kset.
而这里的
kobj_set_kset_s
的作用就是让
disk
对应
kobject
的
kset
等于
block_subsys.
也就是说让
kobject
找到它的
kset.(
如果你还记得当初我们在我是
Sysfs
中分析的
kobject
和
kset
的那套理论的话
,
你不会不明白这里的意图
.)
而
kobject_init()
初始化一个
kobject,
这个函数通常就是出现在设置了
kobject
的
kset
之后
.
网友
”
暗恋未遂
”
打断了我
,
他说这行代码并不是定义一个结构体
.
它更像是一个声明
,
而不像是定义
.
我仔细一看
,
似乎真的是的
,
这里的确是声明
,
而定义并不在这里
,Linux
内核代码的确是虚虚实实真真假假
,
一不小心就会看走眼
,
写代码的哥们儿果然是深谙兵不厌诈的道理
.但愿
他们只是借此表达他们对现实社会的不满吧
,
毕竟在这年头
,
只有假货是真的
,
别的都是假的
.
那么定义在哪里呢
?
同一个文件中
:
610 decl_subsys(block, &ktype_block, &block_uevent_ops);
这个
decl_subsys
来自
include/linux/kobject.h:
173 #define decl_subsys(_name,_type,_uevent_ops) /
174 struct kset _name##_subsys = { /
175
.kobj = { .name = __stringify(_name) }, /
176
.ktype = _type, /
177
.uevent_ops =_uevent_ops, /
178 }
结合这个宏的定义
,
我们知道
,
我们等效于做了下面这么一件事情
:
174 struct kset block_subsys = { /
175
.kobj = { .name = __stringify(block) }, /
176
.ktype = &ktype_block, /
177
.uevent_ops = &block_uevent_ops, /
178 }
正是因为有了这么一个定义
,
正是因为这里我们把
”block”
给了
block_subsys
的
kobj
的
name
成员
,
所以当我们在
block
子系统初始化的时候调用
subsystem_register(&block_subsys)
之后
,
我们才会在
/sys/
目录下面看到
”block”
子目录
.
localhost:~ # ls /sys/
block
bus
class
devices
firmware
fs
kernel
module
power
749
行
,
初始化一个工作队列
.
到时候用到了再来看
.
至此
,alloc_disk_node
就将返回
,
从而
alloc_disk
也就返回了
.
相关文章推荐
- Linux那些事儿之我是Block层(3)驱动不过一出戏,alloc_disk内存申请为哪般?
- Linux那些事儿之我是Block层(3)驱动不过一出戏,内存申请为哪般?
- Linux那些事儿之我是Block层(3)驱动不过一出戏,内存申请为哪般?
- Linux驱动技术(一) _内存申请
- Linux驱动技术(一) _内存申请
- 5、linux设备驱动---内存申请
- linux驱动开发--内核空间中内存的申请与释放
- Linux驱动技术(一) _内存申请
- Linux那些事儿 之 戏说USB(35)驱动的生命线(三)
- 【转】Linux那些事儿 之 戏说USB(35)驱动的生命线(三)
- 让Linux使用malloc申请更多的内存
- Linux驱动开发常用调试工具---之内存读写工具devmem和devkmem
- Linux那些事儿之我是UHCI(4)IO内存和IO端口
- Linux那些事儿之我是Block层(8)scsi命令的前世今生(二)
- Linux那些事儿 之 戏说USB(36)驱动的生命线(四)
- Linux-2.6驱动开发 4 内存分配
- linux-011中位图操作函数(申请释放节点,申请释放block)解析
- Linux那些事儿之我是U盘(9)总线,设备,和驱动(下)
- Linux驱动开发常用调试工具---之内存读写工具devmem和devkmem
- Linux那些事儿之我是Block层(2)注册一个块设备驱动