2008年6月9日 星期一
荒漠甘泉06092008
2008年6月6日 星期五
荒漠甘泉06062008
「你們要....儆醒禱告。」(聖經彼得前書四章 7 節)
朋友,不要冒險和世界接觸,如果你還沒有禱告。當你晚上跪下禱告的
你一點都不儆醒禱告!你忽略了儆醒;這樣的忽略能不能補救的呢
你不儆醒禱告,是一件何等嚴重的事!試探在你面前,你無法對付
信徒們,不要作無謂的冒險,把儆醒禱告這件事忽略了
2008年6月5日 星期四
2008年6月3日 星期二
sk_buff->cb
sk_buff 這個恐怖的 structure. 其中有個 sk_buff->cb[64] 這個 64 bytes 的
東西, 專門拿來把一些 control information 放進去裡面的, 各層 protocol 都
可以拿來用, 但要小心別互相給蓋掉了...
看一下 definition:
include/linux/skbuff.h:
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
:
:
/*
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[64];
:
:
}
再來看一下 TCP layer 裡面有用到的部份...
include/net/tcp.h:
/* This is what the send packet queuing engine uses to pass
* TCP per-packet control information to the transmission
* code. We also store the host-order sequence numbers in
* here too. This is 36 bytes on 32-bit architectures,
* 40 bytes on 64-bit machines, if this grows please adjust
* skbuff.h:skbuff->cb[xxx] size appropriately.
*/
struct tcp_skb_cb {
union {
struct inet_skb_parm h4;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_skb_parm h6;
#endif
} header; /* For incoming frames */
__u32 seq; /* Starting sequence number */
__u32 end_seq; /* SEQ + FIN + SYN + datalen */
__u32 when; /* used to compute rtt's */
__u8 flags; /* TCP header flags. */
/* NOTE: These must match up to the flags byte in a
* real TCP header.
*/
:
:
__u8 sacked; /* State flags for SACK/FACK. */
:
:
__u16 urg_ptr; /* Valid w/URG flags is set. */
__u32 ack_seq; /* Sequence number ACK'd */
};
#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
struct inet_skb_parm 是啥鬼捏?
include/net/ip.h:
struct inet_skb_parm
{
struct ip_options opt; /* Compiled IP options
unsigned char flags;
:
:
};
哇靠, 又來一個 struct ip_options...
include/linux/ip.h:
struct ip_options {
__u32 faddr; /* Saved first hop address */
unsigned char optlen;
unsigned char srr;
unsigned char rr;
unsigned char ts;
unsigned char is_setbyuser:1, /* Set by setsockopt?
is_data:1, /* Options in __data, rather th
is_strictroute:1, /* Strict source route
srr_is_hit:1, /* Packet destination addr was
is_changed:1, /* IP checksum more not valid
rr_needaddr:1, /* Need to record addr of outgo
ts_needtime:1, /* Need to record timestamp
ts_needaddr:1; /* Need to record addr of outgo
unsigned char router_alert;
unsigned char __pad1;
unsigned char __pad2;
unsigned char __data[0];
};
Total 大約會用到 36 bytes (32bit machine), or 40 bytes (64bit machine)...
事實上在 protocol layer 裡還有其他幾個地方會用到 skb->cb 的咚咚:
[MVL4 include/net]$ grep "cb\[" *
ipx.h:#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
llc_conn.h: skb->cb[sizeof(skb->cb) - 1] = type;
llc_conn.h: return skb->cb[sizeof(skb->cb) - 1];
tcp.h: * skbuff.h:skbuff->cb[xxx] size appropriately.
tcp.h:#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
[MVL4 include/linux]$ grep "cb\[" *
if_vlan.h:#define VLAN_TX_SKB_CB(__skb) ((struct vlan_skb_tx_cookie *)&((__skb)->cb[0]))
if_vlan.h: * Puts the VLAN tag in @skb->cb[] and lets the device do the rest
if_vlan.h: * __vlan_hwaccel_get_tag - get the VLAN ID that is in @skb->cb[]
if_vlan.h: * Returns error if @skb->cb[] is not set correctly
llc.h:#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
所以盡量要使用 skb->cb[] 內容的話, 把它給擺在 cb[36] 以後吧, 反正有 64 bytes 可用...
... 這也難怪了... 先前把東西擺在 cb[0] & cb[1], 老是會不見 @_@ 唉啊, 真是沒看清楚啊~~~
likely & unlikely part II
1.2.9. Compile-Time Optimization for Condition Checks
Most of the time, when the kernel compares a variable against some external value to see whether a given condition is met, the result is extremely likely to be predictable. This is pretty common, for example, with code that enforces sanity checks. The kernel uses the likely and unlikely macros, respectively, to wrap comparisons that are likely to return a true (1) or false (0) result. Those macros take advantage of a feature of the gcc compiler that can optimize the compilation of the code based on that information.
Here is an example. Let's suppose you need to call the do_something function, and that in case of failure, you must handle it with the handle_error function:
err = do_something(x,y,z);
if (err)
handle_error(err);
Under the assumption that do_something rarely fails, you can rewrite the code as follows:
err = do_something(x,y,z);
if (unlikely(err))
handle_error(err);
An example of the optimization made possible by the likely and unlikely macros is in handling options in the IP header. The use of IP options is limited to very specific cases, and the kernel can safely assume that most IP packets do not carry IP options. When the kernel forwards an IP packet, it needs to take care of options according to the rules described in Chapter 18. The last stage of forwarding an IP packet is taken care of by ip_forward_finish. This function uses the unlikely macro to wrap the condition that checks whether there is any IP option to take care of. See the section "ip_forward_finish Function" in Chapter 20.
基本上跟先前的認知是一樣的, 但發覺 ARM, MIPS 跟 PowerPC 用的 GNU crosscompiler 似乎都不會去做這些個 optimization... x86 的就會...
2008年5月30日 星期五
荒漠甘泉 05302008
「除了從地上買來的那十四萬四千人以外,沒有人能學這歌。」
有一種歌,既非藝術所能教,也非樂理所能編,只有在患難中能學會的
沒有一個天使能唱得像我們這麼好聽。他們要唱,他們就必須走我們所
所以,我的己哪!你現在正在從父學習音樂功課。祂訓練你
你的父在訓練你擔任那天使所不能擔任的一部分;訓練你的學校就是苦
在黑雲中祂試你的聲音,在憂傷中祂教你唱歌的表情
荒漠甘泉 05292008
「我乃稱你們為朋友。」(聖經約翰福音十五章 15 節)
數年前某大學有一位年老的德文教授,他的生活是為全校學生所欽佩的
教授走進書室,時間已很遲了。看他的樣子似乎很累,但是他坐下來
與主歡聚是屬靈生活中的最高點;每一個基督人,該不惜任何代價