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