e1000ドライバ探検隊〜その他 ささいなこと〜
Linuxデバドラ本勉強会で突っ込まれてたけど調べてなかった部分についてちょろりと
187 static struct pci_driver e1000_driver = { 188 .name = e1000_driver_name, 189 .id_table = e1000_pci_tbl, 190 .probe = e1000_probe, 191 .remove = __devexit_p(e1000_remove), 192 #ifdef CONFIG_PM 193 /* Power Managment Hooks */ 194 .suspend = e1000_suspend, 195 .resume = e1000_resume, 196 #endif 197 .shutdown = e1000_shutdown, 198 .err_handler = &e1000_err_handler 199 };
上記の構造体で"__devexit_p"って何ぞというお話があったのでここでまとめておく。
やってることは単純でNULLか、そのままかをCONFIG_HOTPLUGに応じて変えるだけ. e1000_remove()はホットプラグが有効になっている場合に、デバイスが取り除かれたことを検知した時呼び出される関数なのでなんとなくこうしている理由は分かる.
313 /* Functions marked as __devexit may be discarded at kernel link time, depending 314 on config options. Newer versions of binutils detect references from 315 retained sections to discarded sections and flag an error. Pointers to 316 __devexit functions must use __devexit_p(function_name), the wrapper will 317 insert either the function_name or NULL, depending on the config options. 318 */ 319 #if defined(MODULE) || defined(CONFIG_HOTPLUG) 320 #define __devexit_p(x) x 321 #else 322 #define __devexit_p(x) NULL 323 #endif
ただし"__devexit"とついている関数だけらしい
e1000_removeは以下のように宣言されている.
110 static void __devexit e1000_remove(struct pci_dev *pdev);
この__devexitの定義をおっていくと
include/linux/init.h 81 #define __devexit __section(.devexit.text) __exitused __cold
__sectionマクロは".devexit.text"セクションに宣言した関数を置く.
include/linux/compiler.h 260 #ifndef __section 261 # define __section(S) __attribute__ ((__section__(#S))) 262 #endif
__exitusedマクロは, gcc拡張の"__used". 関数が宣言されてて使われない場合, つまりCONFFIG_HOTPLUGが有効にされなかった場合に警告を抑制するようにする
include/linux/init.h 69 #ifdef MODULE 70 #define __exitused 71 #else 72 #define __exitused __used 73 #endif
__coldマクロ
include/linux/compiler-gcc4.h 23 #if __GNUC_MINOR__ >= 3 24 /* Mark functions as cold. gcc will assume any path leading to a call 25 to them will be unlikely. This means a lot of manual unlikely()s 26 are unnecessary now for any paths leading to the usual suspects 27 like BUG(), printk(), panic() etc. [but let's keep them for now for 28 older compilers] 29 30 Early snapshots of gcc 4.3 don't support this and we can't detect this 31 in the preprocessor, but we can live with this because they're unreleased. 32 Maketime probing would be overkill here. 33 34 gcc also has a __attribute__((__hot__)) to move hot functions into 35 a special section, but I don't see any sense in this right now in 36 the kernel context */ 37 #define __cold __attribute__((__cold__)) 38 39 #endif
これに関してGCCのマニュアルだと以下のようにcoldについての説明がある. unlikelyみたいなものらしい.
cold
The cold attribute is used to inform the compiler that a function is unlikely executed. The function is optimized for size rather than speed and on many targets it is placed into special subsection of the text section so all cold functions appears close together improving code locality of non-cold parts of program. The paths leading to call of cold functions within code are marked as unlikely by the branch prediction mechanism. It is thus useful to mark functions used to handle unlikely conditions, such as perror, as cold to improve optimization of hot functions that do call marked functions in rare occasions.When profile feedback is available, via -fprofile-use, hot functions are automatically detected and this attribute is ignored.
The cold attribute is not implemented in GCC versions earlier than 4.3.
これが有効になっているのはGCC 4.3以上らしいので、それ以外のバージョンについては単純に__coldを宣言するだけ.
include/linux/compiler.h 250 /* 251 * Tell gcc if a function is cold. The compiler will assume any path 252 * directly leading to the call is unlikely. 253 */ 254 255 #ifndef __cold 256 #define __cold 257 #endif