Author: | Michael Stone |
---|
First, I looked at some tools.
Cscope is very helpful for tracking down where a function is used. You can't do this from within VIM, however. The trick is to run Cscope from the command line, to perform your search, and then to hit '>' to save the results.
Next, I decided to track down some kernel memory.
As it turns out, there are only 19 calls to kmalloc in the entire program.
File | Function | Line | Code |
---|---|---|---|
lib/nswap_hashtable.c | <global> | 36 | htable_t ht = (htable_t)kmalloc(sizeof(htable_t), GFP_NSWAP); |
lib/nswap_hashtable.c | <global> | 40 | ht->table=(ht_list_t**)kmalloc(sizeof(ht_list_t*)*num_buckets, |
lib/nswap_hashtable.c | <global> | 49 | rsv_ptr=kmalloc(sizeof(ht_list_t), GFP_NSWAP); |
lib/nswap_threads.c | <global> | 81 | kmalloc(sizeof(nswap_thread_init_t), GFP_NSWAP); |
lib/nswap_hashtable.c | get_from_reserves | 15 | l = (ht_list_t*)kmalloc(sizeof(ht_list_t), GFP_NSWAP); |
lib/nswap_hashtable.c | ht_iter | 198 | cur=(ht_list_t*)kmalloc(sizeof(ht_list_t), |
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 24 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 56 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 61 | new_socket->addr = kmalloc(sizeof(struct sockaddr), GFP_NSWAP); |
src/nswap_iptable.c | nswap_iptable_init | 185 | nswap_iptable = kmalloc(sizeof(struct nswap_ipentry)*NSWAP_MAXHOSTS, |
src/nswapc_main.c | nswapc_init | 292 | io_request_sem = kmalloc(sizeof(struct semaphore), GFP_NSWAP); |
src/nswapc_main.c | nswapc_init | 319 | worker_args = kmalloc(sizeof(struct worker_thread_args), |
src/nswapd_mem.c | nswapd_mem_store | 91 | new_page = kmalloc(sizeof(page_data_t),(GFP_NSWAP)); |
src/nswapd_mem_mon.c | nswapd_mem_monitor_init | 91 | recent_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
src/nswapd_mem_mon.c | nswapd_mem_monitor_init | 92 | previous_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
src/nswapd_mem_mon_orig.c | nswapd_mem_monitor_init | 91 | recent_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
src/nswapd_mem_mon_orig.c | nswapd_mem_monitor_init | 92 | previous_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
src/nswapd_mem_monitor.c | nswapd_mem_monitor_init | 93 | recent_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
src/nswapd_mem_monitor.c | nswapd_mem_monitor_init | 94 | previous_monitor = kmalloc(sizeof(struct nswap_monitor_data), GFP_NSWAP); |
There are 22 calls to kfree.
File | Function | Line | Code |
---|---|---|---|
lib/nswap_hashtable.c | ht_destroy | 62 | kfree(ht->table); |
lib/nswap_hashtable.c | ht_destroy | 66 | kfree(rsv_ptr); |
lib/nswap_hashtable.c | ht_destroy | 69 | kfree(ht); |
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 34 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 73 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_tcp_close_socket | 88 | kfree(sock); |
lib/nswap_net_io.c | nswap_udp_close_socket | 99 | kfree(sock->addr); |
lib/nswap_net_io.c | nswap_udp_close_socket | 101 | kfree(sock); |
lib/nswap_threads.c | nswap_thread_wrapper | 47 | kfree(args); |
src/nswap_iptable.c | nswap_iptable_cleanup | 728 | kfree(nswap_iptable); |
src/nswapc_main.c | request_worker_thr | 448 | kfree(worker_args); |
src/nswapc_main.c | nswapc_cleanup | 1472 | kfree(io_request_sem); |
src/nswapd_mem.c | nswapd_page_unmap_and_unwire | 235 | kfree(old); |
src/nswapd_mem.c | nswapd_mem_release | 271 | kfree(old); |
src/nswapd_mem.c | nswapd_mem_cleanup | 470 | kfree(htlist->info); |
src/nswapd_mem.c | nswapd_mem_cleanup | 471 | kfree(htlist); |
src/nswapd_mem_mon.c | nswapd_mem_monitor_cleanup | 104 | kfree(recent_monitor); |
src/nswapd_mem_mon.c | nswapd_mem_monitor_cleanup | 105 | kfree(previous_monitor); |
src/nswapd_mem_mon_orig.c | nswapd_mem_monitor_cleanup | 104 | kfree(recent_monitor); |
src/nswapd_mem_mon_orig.c | nswapd_mem_monitor_cleanup | 105 | kfree(previous_monitor); |
src/nswapd_mem_monitor.c | nswapd_mem_monitor_cleanup | 106 | kfree(recent_monitor); |
src/nswapd_mem_monitor.c | nswapd_mem_monitor_cleanup | 107 | kfree(previous_monitor); |
ht_iter() only gets called once, in src/nswapd_mem.c:nswapd_mem_cleanup where its results are immediately deleted.
Likewise, nswapd_mem_monitor_init() is only called once in src/nswapd_mem.c:nswapd_mem_init() and its results are freed in the corresponding call nswapd_mem_cleanup()
That leaves us with 12 kmallocs:
File | Function | Line | Code |
---|---|---|---|
lib/nswap_hashtable.c | <global> | 36 | htable_t ht = (htable_t)kmalloc(sizeof(htable_t), GFP_NSWAP); |
lib/nswap_hashtable.c | <global> | 40 | ht->table=(ht_list_t**)kmalloc(sizeof(ht_list_t*)*num_buckets, |
lib/nswap_hashtable.c | <global> | 49 | rsv_ptr=kmalloc(sizeof(ht_list_t), GFP_NSWAP); |
lib/nswap_threads.c | <global> | 81 | kmalloc(sizeof(nswap_thread_init_t), GFP_NSWAP); |
lib/nswap_hashtable.c | get_from_reserves | 15 | l = (ht_list_t*)kmalloc(sizeof(ht_list_t), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 24 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 56 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 61 | new_socket->addr = kmalloc(sizeof(struct sockaddr), GFP_NSWAP); |
src/nswap_iptable.c | nswap_iptable_init | 185 | nswap_iptable = kmalloc(sizeof(struct nswap_ipentry)*NSWAP_MAXHOSTS, |
src/nswapc_main.c | nswapc_init | 292 | io_request_sem = kmalloc(sizeof(struct semaphore), GFP_NSWAP); |
src/nswapc_main.c | nswapc_init | 319 | worker_args = kmalloc(sizeof(struct worker_thread_args), |
src/nswapd_mem.c | nswapd_mem_store | 91 | new_page = kmalloc(sizeof(page_data_t),(GFP_NSWAP)); |
and 14 kfrees.
File | Function | Line | Code |
---|---|---|---|
lib/nswap_hashtable.c | ht_destroy | 62 | kfree(ht->table); |
lib/nswap_hashtable.c | ht_destroy | 66 | kfree(rsv_ptr); |
lib/nswap_hashtable.c | ht_destroy | 69 | kfree(ht); |
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 34 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 73 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_tcp_close_socket | 88 | kfree(sock); |
lib/nswap_net_io.c | nswap_udp_close_socket | 99 | kfree(sock->addr); |
lib/nswap_net_io.c | nswap_udp_close_socket | 101 | kfree(sock); |
lib/nswap_threads.c | nswap_thread_wrapper | 47 | kfree(args); |
src/nswap_iptable.c | nswap_iptable_cleanup | 728 | kfree(nswap_iptable); |
src/nswapc_main.c | request_worker_thr | 448 | kfree(worker_args); |
src/nswapc_main.c | nswapc_cleanup | 1472 | kfree(io_request_sem); |
src/nswapd_mem.c | nswapd_page_unmap_and_unwire | 235 | kfree(old); |
src/nswapd_mem.c | nswapd_mem_release | 271 | kfree(old); |
lib/nswap_hashtable.c:get_from_reserves() is only called once in lib/nswap_hashtable.c:ht_insert().
ht_insert() allocates the list element itself. This element is not freed in ht_remove() because ht_remove uses add_to_reserves() to return the newly empty list element to a pool of empty list elements.
The memory is actually freed in ht_destroy().
ht_reset() simply moves all the allocated list elements into the reserved pool.
Now memory that gets sent into the reserved pool will never be freed during the course of the program. However, it does look to me like the hashtable library is clean.
That leaves us with 8 kmallocs:
File | Function | Line | Code |
---|---|---|---|
lib/nswap_threads.c | nswap_thread | 81 | kmalloc(sizeof(nswap_thread_init_t), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 24 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 56 | new_socket = kmalloc(sizeof(struct nswap_socket), GFP_NSWAP); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 61 | new_socket->addr = kmalloc(sizeof(struct sockaddr), GFP_NSWAP); |
src/nswap_iptable.c | nswap_iptable_init | 185 | nswap_iptable = kmalloc(sizeof(struct nswap_ipentry)*NSWAP_MAXHOSTS, |
src/nswapc_main.c | nswapc_init | 292 | io_request_sem = kmalloc(sizeof(struct semaphore), GFP_NSWAP); |
src/nswapc_main.c | nswapc_init | 319 | worker_args = kmalloc(sizeof(struct worker_thread_args), |
src/nswapd_mem.c | nswapd_mem_store | 91 | new_page = kmalloc(sizeof(page_data_t),(GFP_NSWAP)); |
and 13 kfrees.
File | Function | Line | Code |
---|---|---|---|
lib/nswap_net_io.c | nswap_tcp_alloc_socket | 34 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_udp_alloc_socket | 73 | kfree(new_socket); |
lib/nswap_net_io.c | nswap_tcp_close_socket | 88 | kfree(sock); |
lib/nswap_net_io.c | nswap_udp_close_socket | 99 | kfree(sock->addr); |
lib/nswap_net_io.c | nswap_udp_close_socket | 101 | kfree(sock); |
lib/nswap_threads.c | nswap_thread_wrapper | 47 | kfree(args); |
src/nswap_iptable.c | nswap_iptable_cleanup | 728 | kfree(nswap_iptable); |
src/nswapc_main.c | request_worker_thr | 448 | kfree(worker_args); |
src/nswapc_main.c | nswapc_cleanup | 1472 | kfree(io_request_sem); |
src/nswapd_mem.c | nswapd_page_unmap_and_unwire | 235 | kfree(old); |
src/nswapd_mem.c | nswapd_mem_release | 271 | kfree(old); |