KernelStudy : 130 주차
일시 : 2016.01.16 (130 주차 스터디 진행)
모임명 : KernelStudy_ARM
장소 : 토즈 서현점
장소지원 : 공개 소프트웨어 개발자 커뮤니티 지원 프로그램
참여인원 : 3명
130 주차 진도
- 129 주차 진도를 복습하였습니다.
- vfs_caches_init()
- start_kernel 1 ~/kernel/iamroot/linux-stable/init/main.c
- vfs_caches_init 925 ~/kernel/iamroot/linux-stable/init/main.c
- mnt_init 3807 ~/kernel/iamroot/linux-stable/fs/dcache.c
- kobject_create_and_add 3926 ~/kernel/iamroot/linux-stable/fs/namespace.c
- kobject_add 828 retval = kobject_add(kobj, parent, "%s", name);
- kobject_add_varg 457 retval = kobject_add_varg(kobj, parent, fmt, args);
- kobject_set_name_vargs 395 retval = kobject_set_name_vargs(kobj, fmt, vargs);
- 129주차 함수 호출 구조
- call: start_kernel()->vfs_caches_init()
- vfs_caches_init()
- min()
- kmem_cache_create() : names_caches
- dcache_init()
- inode_init()
- files_init(): mempages
- mnt_init()
- kmem_cache_create(): mnt_cache
- alloc_large_system_hash() : Mount_cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create_and_add() : fs
- kobject_create()
- kzalloc()
- kobject_init()
- kobject_init_internal() : kobj
- kobject_add()
- va_start()
- kobject_add_vargs() : kobj, fs
- kobject_set_name_vargs()
- kvasprintf()
- va_copy()
- vsnprintf()
- format_decode()
- va_end()
- kmalloc_track_caller()
- vsnprintf()
- kvasprintf()
- kobject_set_name_vargs()
- kobject_create()
main.c::start_kernel()
- call: start_kernel()->vfs_caches_init()
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
// ATAG,DTB 정보로 사용
...
proc_caches_init();
// sighand_struct, signal_struct, files_struct, fs_struct, mm_struct, vm_area_struct, nsproxy
// 를 사용하기 위한 kmem_cache 할당자 및 percpu list 초기화 수행
buffer_init();
// buffer_head 를 사용하기 위한 kmem_cache 할당자 및 max_buffer_heads 값 초기화 수행
key_init(); // null funtion
security_init(); // null funtion
dbg_late_init(); // null funtion
// totalram_pages: 총 free된 page 수
vfs_caches_init(totalram_pages);
dcache.c::vfs_cache_init()
- call: start_kernel()
- vfs_caches_init()
// ARM10C 20151003
// totalram_pages: 총 free된 page 수
void __init vfs_caches_init(unsigned long mempages)
{
unsigned long reserve;
// mempages: 총 free된 page 수, nr_free_pages(): 현재의 free pages 수
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
// reserve: XXX
// mempages: 총 free된 page 수, reserve: XXX
mempages -= reserve;
// mempages: 총 free된 page 수 - XXX
// PATH_MAX: 4096
// SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
// kmem_cache_create("names_cache", 4096, 0, 0x42000, NULL): kmem_cache#6
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
// names_cachep: kmem_cache#6
dcache_init();
inode_init();
// mempages: 총 free된 page 수 - XXX
files_init(mempages);
mnt_init();
namespace.c::mnt_init()
- call: start_kernel()->vfs_caches_init()
- mnt_init()
// ARM10C 20151024
void __init mnt_init(void)
{
unsigned u;
int err;
// sizeof(struct mount): 152 bytes, SLAB_HWCACHE_ALIGN: 0x00002000UL, SLAB_PANIC: 0x00040000UL
// kmem_cache_create("mnt_cache", 152, 0, 0x42000, NULL): kmem_cache#2
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
// mnt_cache: kmem_cache#2
// sizeof(struct hlist_head): 4 bytes, mhash_entries: 0
// alloc_large_system_hash("Mount-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
mount_hashtable = alloc_large_system_hash("Mount-cache",
sizeof(struct hlist_head),
mhash_entries, 19,
0,
&m_hash_shift, &m_hash_mask, 0, 0);
// mount_hashtable: 16kB만큼 할당받은 메모리 주소
// sizeof(struct hlist_head): 4 bytes, mphash_entries: 0
// alloc_large_system_hash("Mountpoint-cache", 4, 0, 19, 0, &m_hash_shift, &m_hash_mask, 0, 0): 16kB만큼 할당받은 메모리 주소
mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
sizeof(struct hlist_head),
mphash_entries, 19,
0,
&mp_hash_shift, &mp_hash_mask, 0, 0);
// mountpoint_hashtable: 16kB만큼 할당받은 메모리 주소
// mount_hashtable: 16kB만큼 할당받은 메모리 주소, mountpoint_hashtable: 16kB만큼 할당받은 메모리 주소
if (!mount_hashtable || !mountpoint_hashtable)
panic("Failed to allocate mount hash table\n");
// m_hash_mask: 0xFFF
for (u = 0; u <= m_hash_mask; u++)
// u: 0
INIT_HLIST_HEAD(&mount_hashtable[u]);
// INIT_HLIST_HEAD 에서 한일:
// ((&mount_hashtable[0])->first = NULL)
// u: 1...4095 까지 loop 수행
// mp_hash_mask: 0xFFF
for (u = 0; u <= mp_hash_mask; u++)
// u: 0
INIT_HLIST_HEAD(&mountpoint_hashtable[u]);
// INIT_HLIST_HEAD 에서 한일:
// ((&mountpoint_hashtable[0])->first = NULL)
// u: 1...4095 까지 loop 수행
// sysfs_init(): 0
err = sysfs_init();
// err: 0
// err: 0
if (err)
printk(KERN_WARNING "%s: sysfs_init error: %d\n",
__func__, err);
fs_kobj = kobject_create_and_add("fs", NULL);
kobject.c::kobject_create_and_add()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
// ARM10C 20160109
// "fs", NULL
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
{
struct kobject *kobj;
int retval;
// kobject_create(): kmem_cache#30-oX (struct kobject)
kobj = kobject_create();
// kobj: kmem_cache#30-oX (struct kobject)
if (!kobj)
return NULL;
// kobj: kmem_cache#30-oX (struct kobject), parent: NULL, name: "fs"
retval = kobject_add(kobj, parent, "%s", name);
kobject.c::kobject_add()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_add()
// ARM10C 20160109
// kobj: kmem_cache#30-oX (struct kobject), parent: NULL, "%s", name: "fs"
int kobject_add(struct kobject *kobj, struct kobject *parent,
const char *fmt, ...)
{
va_list args;
int retval;
// kobj: kmem_cache#30-oX (struct kobject)
if (!kobj)
return -EINVAL;
// kobj->state_initialized: (kmem_cache#30-oX (struct kobject))->state_initialized: 1
if (!kobj->state_initialized) {
printk(KERN_ERR "kobject '%s' (%p): tried to add an "
"uninitialized object, something is seriously wrong.\n",
kobject_name(kobj), kobj);
dump_stack();
return -EINVAL;
}
// fmt: "%s"
va_start(args, fmt);
// va_start에서 한일:
// (args): (((char *) &("%s")) + 4): "fs"
// kobj: kmem_cache#30-oX (struct kobject), parent: NULL, fmt: "%s", args: "fs"
retval = kobject_add_varg(kobj, parent, fmt, args);
kobject.c::kobject_set_name_vargs()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_add()
- kobject_add_varg()
- kobject_add()
// ARM10C 20160109
// kobj: kmem_cache#30-oX (struct kobject), parent: NULL, fmt: "%s", args: "fs"
static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,
const char *fmt, va_list vargs)
{
int retval;
// kobj: kmem_cache#30-oX (struct kobject), fmt: "%s", vargs: "fs"
retval = kobject_set_name_vargs(kobj, fmt, vargs);
kobject.c::kobject_set_name_vargs()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_add()
- kobject_add_varg()
- kobject_add_vargs()
- kobject_add_varg()
- kobject_add()
// ARM10C 20160109
// kobj: kmem_cache#30-oX (struct kobject), fmt: "%s", vargs: "fs"
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: NULL
const char *old_name = kobj->name;
// old_name: NULL
char *s;
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: NULL, fmt: "%s"
if (kobj->name && !fmt)
return 0;
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: NULL
// GFP_KERNEL: 0xD0, fmt: "%s", vargs: "fs"
// kvasprintf(GFP_KERNEL: 0xD0, "%s", "fs"): kmem_cache#30-oX: "fs"
kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: kmem_cache#30-oX: "fs"
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: kmem_cache#30-oX: "fs"
if (!kobj->name)
return -ENOMEM;
// 2016/01/09 종료
/* ewww... some of these buggers have '/' in the name ... */
while ((s = strchr(kobj->name, '/')))
s[0] = '!';
kfree(old_name);
kobject.c::kobject_set_name_vargs()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_add()
- kobject_add_varg()
- kobject_add_vargs()
- kfree()
- kobject_add_vargs()
- kobject_add_varg()
- kobject_add()
void kfree(const void *x)
{
struct page *page;
// x: kmem_cache#30-o11
void *object = (void *)x;
// object: kmem_cache#30-o11
// _RET_IP_: __builtin_return_address(0), object: kmem_cache#30-o11
trace_kfree(_RET_IP_, x);
// x: kmem_cache#30-o11, ZERO_OR_NULL_PTR(kmem_cache#30-o11): 0
if (unlikely(ZERO_OR_NULL_PTR(x)))
return;
// x: kmem_cache#30-o11
// virt_to_head_page(kmem_cache#30-o11): kmem_cache#30-o11의 page 주소
page = virt_to_head_page(x);
// page: kmem_cache#30-o11의 page 주소
// page: kmem_cache#30-o11의 page 주소
// PageSlab(kmem_cache#30-o11의 page 주소): 1
if (unlikely(!PageSlab(page))) {
BUG_ON(!PageCompound(page));
kfree_hook(x);
__free_memcg_kmem_pages(page, compound_order(page));
return;
}
// 2014/11/29 종료
// 2014/12/06 시작
// page->slab_cache: (kmem_cache#30-o11의 page 주소)->slab_cache,
// page: kmem_cache#30-o11의 page 주소, object: kmem_cache#30-o11
slab_free(page->slab_cache, page, object, _RET_IP_);
// slab_free에서 한일:
// (kmem_cache#30)->cpu_slab: struct kmem_cache_cpu 자료구조를 사용하기 위해 할당받은 pcp 16 byte 메모리 공간을 구하여
// kmem_cache#30-o11의 freepointer의 값을
// ((kmem_cache#30)->cpu_slab + (pcpu_unit_offsets[0] + __per_cpu_start에서의pcpu_base_addr의 옵셋)->freelist 값으로 세팅
// 값 s->cpu_slab->freelist와 c->freelist를 비교, 값 s->cpu_slab->tid와 tid을 비교 하여
// 같을 경우에 s->cpu_slab->freelist와 s->cpu_slab->tid을 각각 object, next_tid(tid) 값으로 갱신하여
// freelist와 tid 값을 변경함
// kmem_cache_cpu의 freelist, tid 의 값을 변경함
}
EXPORT_SYMBOL(kfree);
kojbect.c::kobject_add_varg()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- kobject_set_name_vargs()
- kobject_add_varg()
static int kobject_add_internal(struct kobject *kobj)
{
int error = 0;
struct kobject *parent;
if (!kobj)
return -ENOENT;
if (!kobj->name || !kobj->name[0]) {
WARN(1, "kobject: (%p): attempted to be registered with empty "
"name!\n", kobj);
return -EINVAL;
}
parent = kobject_get(kobj->parent);
- kobject_get()
struct kobject *kobject_get(struct kobject *kobj)
{
if (kobj)
kref_get(&kobj->kref);
return kobj;
}
kobject.c::kobject_add()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- kobject_set_name_vargs()
- kobject_add_varg()
kobject.c::kobject_add_internal()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- kobject_set_name_vargs()
- kobject_add_varg()
// ARM10C 20160116
// kobj: kmem_cache#30-oX (struct kobject)
static int kobject_add_internal(struct kobject *kobj)
{
int error = 0;
// error: 0
struct kobject *parent;
// kobj: kmem_cache#30-oX (struct kobject)
if (!kobj)
return -ENOENT;
// kobj->name: (kmem_cache#30-oX (struct kobject))->name: "fs"
if (!kobj->name || !kobj->name[0]) {
WARN(1, "kobject: (%p): attempted to be registered with empty "
"name!\n", kobj);
return -EINVAL;
}
// kobj->parent: (kmem_cache#30-oX (struct kobject))->parent: NULL
// kobject_get(NULL): NULL
parent = kobject_get(kobj->parent);
// parent: NULL
/* join kset if set, use it as parent if we do not already have one */
// kobj->kset: (kmem_cache#30-oX (struct kobject))->kset: NULL
if (kobj->kset) {
if (!parent)
parent = kobject_get(&kobj->kset->kobj);
kobj_kset_join(kobj);
kobj->parent = parent;
}
// kobj: kmem_cache#30-oX (struct kobject),
// kobject_name(kmem_cache#30-oX (struct kobject)): "fs", parent: NULL,
// kobj->kset: (kmem_cache#30-oX (struct kobject))->kset: NULL
pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
kobject_name(kobj), kobj, __func__,
parent ? kobject_name(parent) : "<NULL>",
kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
// "kobject: 'fs' (kmem_cache#30-oX): kobject_add_internal: parent: '<NULL>', set: '<NULL>'\n"
// kobj: kmem_cache#30-oX (struct kobject)
error = create_dir(kobj);
dir.c::create_dir()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: carete_dir()
// ARM10C 20160116
// kobj: kmem_cache#30-oX (struct kobject), parent_sd: &sysfs_root, type: 0,
// kobject_name(kmem_cache#30-oX (struct kobject)): "fs", ns: NULL, &sd
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
enum kobj_ns_type type,
const char *name, const void *ns,
struct sysfs_dirent **p_sd)
{
// S_IFDIR: 0040000, S_IRWXU: 00700, S_IRUGO: 00444, S_IXUGO: 00111
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
// mode: 0x41ED
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
int rc;
/* allocate */
// name: "fs", mode: 0x41ED, SYSFS_DIR: 0x0001
// sysfs_new_dirent("fs", 0x41ED, 0x0001): kmem_cache#1-oX (struct sysfs_dirent)
sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
- sysfs_new_dirent에서 한일: // sysfs_dir_cachep: kmem_cache#1을 이용하여 struct sysfs_dirent 메모리를 할당받음 // kmem_cache#1-oX (struct sysfs_dirent) // // (&(&sysfs_ino_ida)->idr)->id_free: NULL // (&(&sysfs_ino_ida)->idr)->id_free_cnt: 6 // (&(&sysfs_ino_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer) // (&(&sysfs_ino_ida)->idr)->layers: 1 // (&sysfs_ino_ida)->free_bitmap: NULL // // (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL // (kmem_cache#21-o7 (struct idr_layer))->layer: 0 // (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap) // (kmem_cache#21-o7 (struct idr_layer))->count: 1 // // (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행 // // (kmem_cache#1-oX (struct sysfs_dirent))->s_ino: 2 // // (&(kmem_cache#1-oX (struct sysfs_dirent))->s_count)->counter: 1 // (&(kmem_cache#1-oX (struct sysfs_dirent))->s_active)->counter: 0 // (kmem_cache#1-oX (struct sysfs_dirent))->s_name: "fs" // (kmem_cache#1-oX (struct sysfs_dirent))->s_mode: 0x41ED // (kmem_cache#1-oX (struct sysfs_dirent))->s_flags: 0x2001
dir.c::create_dir()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: carete_dir()
// ARM10C 20160116
// kobj: kmem_cache#30-oX (struct kobject), parent_sd: &sysfs_root, type: 0,
// kobject_name(kmem_cache#30-oX (struct kobject)): "fs", ns: NULL, &sd
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
enum kobj_ns_type type,
const char *name, const void *ns,
struct sysfs_dirent **p_sd)
{
// S_IFDIR: 0040000, S_IRWXU: 00700, S_IRUGO: 00444, S_IXUGO: 00111
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
// mode: 0x41ED
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
int rc;
/* allocate */
// name: "fs", mode: 0x41ED, SYSFS_DIR: 0x0001
// sysfs_new_dirent("fs", 0x41ED, 0x0001): kmem_cache#1-oX (struct sysfs_dirent)
sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
- sysfs_new_dirent에서 한일: // sysfs_dir_cachep: kmem_cache#1을 이용하여 struct sysfs_dirent 메모리를 할당받음 // kmem_cache#1-oX (struct sysfs_dirent) // // (&(&sysfs_ino_ida)->idr)->id_free: NULL // (&(&sysfs_ino_ida)->idr)->id_free_cnt: 6 // (&(&sysfs_ino_ida)->idr)->top: kmem_cache#21-o7 (struct idr_layer) // (&(&sysfs_ino_ida)->idr)->layers: 1 // (&sysfs_ino_ida)->free_bitmap: NULL // // (kmem_cache#21-o7 (struct idr_layer))->ary[0]: NULL // (kmem_cache#21-o7 (struct idr_layer))->layer: 0 // (kmem_cache#21-o7 (struct idr_layer))->ary[0]: kmem_cache#27-oX (struct ida_bitmap) // (kmem_cache#21-o7 (struct idr_layer))->count: 1 // // (kmem_cache#27-oX (struct ida_bitmap))->bitmap 의 0 bit를 1로 set 수행 // // (kmem_cache#1-oX (struct sysfs_dirent))->s_ino: 2 // // (&(kmem_cache#1-oX (struct sysfs_dirent))->s_count)->counter: 1 // (&(kmem_cache#1-oX (struct sysfs_dirent))->s_active)->counter: 0 // (kmem_cache#1-oX (struct sysfs_dirent))->s_name: "fs" // (kmem_cache#1-oX (struct sysfs_dirent))->s_mode: 0x41ED // (kmem_cache#1-oX (struct sysfs_dirent))->s_flags: 0x2001
- configfs_attach_attr()
- sysfs_new_dirent()
- dir.c::sysfs_alloc_ino()
static int sysfs_alloc_ino(unsigned int *pino)
{
int ino, rc;
retry:
spin_lock(&sysfs_ino_lock);
rc = ida_get_new_above(&sysfs_ino_ida, 2, &ino);
spin_unlock(&sysfs_ino_lock);
if (rc == -EAGAIN) {
if (ida_pre_get(&sysfs_ino_ida, GFP_KERNEL))
goto retry;
rc = -ENOMEM;
}
*pino = ino;
return rc;
}
- return sysfs_alloc_ino() 가 한일.
dir.c::create_dir()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: carete_dir()
- sysfs_new_dirent()
- struct sysfs_dirent *sd
// sizeof(struct sysfs_dirent): 64 bytes
struct sysfs_dirent {
atomic_t s_count;
atomic_t s_active;
#ifdef CONFIG_DEBUG_LOCK_ALLOC // CONFIG_DEBUG_LOCK_ALLOC=n
struct lockdep_map dep_map;
#endif
struct sysfs_dirent *s_parent;
const char *s_name;
struct rb_node s_rb;
union {
struct completion *completion;
struct sysfs_dirent *removed_list;
} u;
const void *s_ns; /* namespace tag */
unsigned int s_hash; /* ns + name hash */
union {
struct sysfs_elem_dir s_dir;
struct sysfs_elem_symlink s_symlink;
struct sysfs_elem_attr s_attr;
};
unsigned short s_flags;
umode_t s_mode;
unsigned int s_ino;
struct sysfs_inode_attrs *s_iattr;
};
// ARM10C 20160116
// kobj: kmem_cache#30-oX (struct kobject), parent_sd: &sysfs_root, type: 0,
// kobject_name(kmem_cache#30-oX (struct kobject)): "fs", ns: NULL, &sd
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
enum kobj_ns_type type,
const char *name, const void *ns,
struct sysfs_dirent **p_sd)
{
// S_IFDIR: 0040000, S_IRWXU: 00700, S_IRUGO: 00444, S_IXUGO: 00111
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
// mode: 0x41ED
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
int rc;
/* allocate */
// name: "fs", mode: 0x41ED, SYSFS_DIR: 0x0001
// sysfs_new_dirent("fs", 0x41ED, 0x0001): kmem_cache#1-oX (struct sysfs_dirent)
sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
// sd: kmem_cache#1-oX (struct sysfs_dirent)
// sd: kmem_cache#1-oX (struct sysfs_dirent)
if (!sd)
return -ENOMEM;
sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);
sd->s_ns = ns;
sd->s_dir.kobj = kobj;
/* link in */
sysfs_addrm_start(&acxt);
dir.c::sysfs_addrm_start()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: carete_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
``dir.c void sysfs_addrm_start(struct sysfs_addrm_cxt acxt) __acquires(sysfs_mutex) { memset(acxt, 0, sizeof(acxt));
mutex_lock(&sysfs_mutex);
}
* sysfs_addrm_start()에서 한일
## dir.c::create_dir()
* call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
* call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
* call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
```dir.c
// ARM10C 20160116
// kobj: kmem_cache#30-oX (struct kobject), parent_sd: &sysfs_root, type: 0,
// kobject_name(kmem_cache#30-oX (struct kobject)): "fs", ns: NULL, &sd
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
enum kobj_ns_type type,
const char *name, const void *ns,
struct sysfs_dirent **p_sd)
{
// S_IFDIR: 0040000, S_IRWXU: 00700, S_IRUGO: 00444, S_IXUGO: 00111
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
// mode: 0x41ED
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
int rc;
/* allocate */
// name: "fs", mode: 0x41ED, SYSFS_DIR: 0x0001
// sysfs_new_dirent("fs", 0x41ED, 0x0001): kmem_cache#1-oX (struct sysfs_dirent)
sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
// sd: kmem_cache#1-oX (struct sysfs_dirent)
// sd: kmem_cache#1-oX (struct sysfs_dirent)
if (!sd)
return -ENOMEM;
sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT);
sd->s_ns = ns;
sd->s_dir.kobj = kobj;
/* link in */
sysfs_addrm_start(&acxt);
rc = sysfs_add_one(&acxt, sd, parent_sd);
dir.c::sysfs_add_one()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
- sysfs_add_one()
int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
struct sysfs_dirent *parent_sd)
{
int ret;
ret = __sysfs_add_one(acxt, sd, parent_sd);
if (ret == -EEXIST)
sysfs_warn_dup(parent_sd, sd->s_name);
return ret;
}
dir.c::__sysfs_add_one()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
- sysfs_add_one()
- sysfs_add_one()
- struct sysfs_inode_attrs
// ARM10C 20151205
struct sysfs_inode_attrs {
struct iattr ia_iattr;
void *ia_secdata;
u32 ia_secdata_len;
};
int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd,
struct sysfs_dirent *parent_sd)
{
struct sysfs_inode_attrs *ps_iattr;
int ret;
if (!!sysfs_ns_type(parent_sd) != !!sd->s_ns) {
WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
sysfs_ns_type(parent_sd) ? "required" : "invalid",
parent_sd->s_name, sd->s_name);
return -EINVAL;
}
sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
sd->s_parent = sysfs_get(parent_sd);
ret = sysfs_link_sibling(sd);
if (ret)
return ret;
/* Update timestamps on the parent */
ps_iattr = parent_sd->s_iattr;
if (ps_iattr) {
struct iattr *ps_iattrs = &ps_iattr->ia_iattr;
ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME;
}
/* Mark the entry added into directory tree */
sd->s_flags &= ~SYSFS_FLAG_REMOVED;
return 0;
}
- sysfs.h::sysfs_ns_type()
static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd)
{
return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT;
}
dir.c::__sysfs_add_one()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
- sysfs_add_one()
- sysfs_add_one()
- sysfs_ns_type()
- sysfs_name_hash()
- sysfs_add_one()
static unsigned int sysfs_name_hash(const char *name, const void *ns)
{
unsigned long hash = init_name_hash();
unsigned int len = strlen(name);
while (len--)
hash = partial_name_hash(*name++, hash);
hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
hash &= 0x7fffffffU;
/* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
if (hash < 1)
hash += 2;
if (hash >= INT_MAX)
hash = INT_MAX - 1;
return hash;
}
- partial_name_hash()
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
{
return (prevhash + (c << 4) + (c >> 4)) * 11;
}
- return 0x4662
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
- sysfs_add_one()
- sysfs_add_one()
- sysfs_ns_type()
- sysfs_name_hash()
- partial_name_hash()
- sysfs_get()
- sysfs_link_sibling()
- sysfs_add_one()
- sysfs_get()
// ARM10C 20151205
// sd: &sysfs_root
struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
{
// sd: &sysfs_root
// __sysfs_get(&sysfs_root): 2
return __sysfs_get(sd);
// return 2
// __sysfs_get에서 한일:
// (&sysfs_root)->s_count: 2
}
EXPORT_SYMBOL_GPL(sysfs_get);
dir.c::sysfs_link_sibling()
- call: start_kernel()->vfs_caches_init()->mnt_init()
- kmem_cache_create()
- alloc_large_system_hash() : mnt_cache
- alloc_large_system_hash() : Mount-cache
- alloc_large_system_hash() : Mountpoint-cache
- INIT_HLIST_HEAD() : &mount_hashtable[u]
- INIT_HLIST_HEAD() : &mountpoint_hashtable[u]
- sysfs_init()
- kobject_create_and_add() : fs
- kobject_create()
- kobject_add()
- call: kojbect_add()
- kobject_add_varg()
- kobject_set_name_vargs()
- kfree()
- kobject_add_internal()
- create_dir()
- kobject_set_name_vargs()
- kobject_add_varg()
- call: create_dir()
- sysfs_new_dirent()
- sysfs_addrm_start()
- sysfs_add_one()
- sysfs_add_one()
- sysfs_ns_type()
- sysfs_name_hash()
- partial_name_hash()
- sysfs_get()
- sysfs_link_sibling()
- sysfs_add_one()
static int sysfs_link_sibling(struct sysfs_dirent *sd)
{
struct rb_node **node = &sd->s_parent->s_dir.children.rb_node;
struct rb_node *parent = NULL;
if (sysfs_type(sd) == SYSFS_DIR)
sd->s_parent->s_dir.subdirs++;
while (*node) {
struct sysfs_dirent *pos;
int result;
pos = to_sysfs_dirent(*node);
parent = *node;
result = sysfs_sd_compare(sd, pos);
if (result < 0)
node = &pos->s_rb.rb_left;
else if (result > 0)
node = &pos->s_rb.rb_right;
else
return -EEXIST;
}
/* add new node and rebalance the tree */
rb_link_node(&sd->s_rb, parent, node);
rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children);
return 0;
}
log
- 1st log
f8705f2..87dee88 master -> origin/master
Updating f8705f2..87dee88
Fast-forward
arch/arm/include/asm/atomic.h | 4 +
fs/sysfs/dir.c | 168 ++++++++++++++++++++++++++++++++++
fs/sysfs/mount.c | 2 +
fs/sysfs/sysfs.h | 10 ++
include/asm-generic/bug.h | 1 +
include/linux/gfp.h | 1 +
include/linux/idr.h | 20 ++++
include/linux/kobject.h | 6 ++
include/linux/kobject_ns.h | 3 +
include/linux/slab.h | 5 +
include/linux/spinlock.h | 4 +
include/linux/spinlock_types.h | 12 +++
include/linux/stat.h | 2 +
include/linux/sysfs.h | 1 +
include/linux/types.h | 1 +
include/uapi/asm-generic/errno-base.h | 1 +
include/uapi/linux/stat.h | 3 +
lib/idr.c | 2 +
lib/kasprintf.c | 19 +++-
lib/kobject.c | 73 ++++++++++++++-
lib/string.c | 2 +
mm/slub.c | 2 +
22 files changed, 339 insertions(+), 3 deletions(-)
- 2nd log
87dee88..cc4b18b master -> origin/master
Updating 87dee88..cc4b18b
Fast-forward
fs/sysfs/dir.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/sysfs/mount.c | 12 ++++++++++--
fs/sysfs/sysfs.h | 17 +++++++++++++++++
include/linux/dcache.h | 13 +++++++++++++
include/linux/fs.h | 1 +
include/linux/hash.h | 9 +++++++++
include/linux/rbtree.h | 4 ++++
include/linux/sysfs.h | 1 +
kernel/locking/mutex.c | 2 ++
lib/rbtree.c | 2 ++
lib/string.c | 2 ++
11 files changed, 187 insertions(+), 2 deletions(-)
댓글 없음:
댓글 쓰기