全部博文(83)
分类: 系统运维
2009-06-06 18:44:17
《The Design and Implementation of the FreeBSD Operating System》
Part IV: Interprocess Communication
Chapter 11. Interprocess Communication
11.1. Interprocess-Communication Model
进程间通信和网络协议对内存管理的特殊要求有:
mbuf的定义是在mbuf.h中给出的:
_________________________________________________________________________________________
79 /*
80 * Header present at the beginning of every mbuf.
81 */
82 struct m_hdr {
83 struct mbuf *mh_next; /* next buffer in chain */
84 struct mbuf *mh_nextpkt; /* next chain in queue/record */
85 caddr_t mh_data; /* location of data */
86 int mh_len; /* amount of data in this mbuf */
87 int mh_flags; /* flags; see below */
88 short mh_type; /* type of data in this mbuf */
89 };
90
91 /*
92 * Packet tag structure (see below for details).
93 */
94 struct m_tag {
95 SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */
96 u_int16_t m_tag_id; /* Tag ID */
97 u_int16_t m_tag_len; /* Length of data */
98 u_int32_t m_tag_cookie; /* ABI/Module ID */
99 void (*m_tag_free)(struct m_tag *);
100 };
101
102 /*
103 * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
104 */
105 struct pkthdr {
106 struct ifnet *rcvif; /* rcv interface */
107 int len; /* total packet length */
108 /* variables for ip and tcp reassembly */
109 void *header; /* pointer to packet header */
110 /* variables for hardware checksum */
111 int csum_flags; /* flags regarding checksum */
112 int csum_data; /* data field used by csum routines */
113 SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
114 };
115
116 /*
117 * Description of external storage mapped into mbuf; valid only if M_EXT is set.
118 */
119 struct m_ext {
120 caddr_t ext_buf; /* start of buffer */
121 void (*ext_free) /* free routine if not the usual */
122 (void *, void *);
123 void *ext_args; /* optional argument pointer */
124 u_int ext_size; /* size of buffer, for ext_free */
125 volatile u_int *ref_cnt; /* pointer to ref count info */
126 int ext_type; /* type of external storage */
127 };
128
129 /*
130 * The core of the mbuf object along with some shortcut defines for
131 * practical purposes.
132 */
133 struct mbuf {
134 struct m_hdr m_hdr;
135 union {
136 struct {
137 struct pkthdr MH_pkthdr; /* M_PKTHDR set */
138 union {
139 struct m_ext MH_ext; /* M_EXT set */
140 char MH_databuf[MHLEN];
141 } MH_dat;
142 } MH;
143 char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
144 } M_dat;
145 };
146 #define m_next m_hdr.mh_next
147 #define m_len m_hdr.mh_len
148 #define m_data m_hdr.mh_data
149 #define m_type m_hdr.mh_type
150 #define m_flags m_hdr.mh_flags
151 #define m_nextpkt m_hdr.mh_nextpkt
152 #define m_act m_nextpkt
153 #define m_pkthdr M_dat.MH.MH_pkthdr
154 #define m_ext M_dat.MH.MH_dat.MH_ext
155 #define m_pktdat M_dat.MH.MH_dat.MH_databuf
156 #define m_dat M_dat.M_databuf
__________________________________________________________________/usr/src/sys/sys/mbuf.h
mbuf的典型内存布局如下图所示:
+----------------------------------------------------+
| mh_next |
| mh_nextpkt |
| mh_data (22 bytes) |
| mh_len |
| mh_flags |
| mh_type |
+-------------+--------------------------------------+
| M_databuf[] | rcvif |
| | len |
| | header (24 bytes) |
| (234 bytes) | csum_flags |
| | csum_data |
| | tags |
| +--------------+-----------------------+
| | MH_databuf[] | ext_buf |
| | | ext_free |
| | | ext_args (24 bytes) |
| | (210 bytes) | ext_size |
| | | ref_cnt |
| | | ext_type |
| | +-----------------------+
| | | |
... ... ...
| | | |
+-------------+--------------+-----------------------+
这是一个普通 这个mbuf是用来 这个mbuf使用了外部
的用于存储数 存储某个packet 存储空间,因此本身
据的mbuf 的多个mbuf中的 余下的内部存储空间
第一个 将废弃不用。(一个
mbuf可以既存储
packet头又使用外部
空间)
mbuf的大小甴MSIZE宏给出(当前为256字节),每个mbuf都有一个长度为22字节的头部,因此每个mbuf最多可存储234字节的数据。
除mbuf之外,还可申请外部存储空间,称为cluster,其大小甴MCLBYTES宏给出(当前为2048字节)。数据要么存储在mbuf的内部数据区中,
要么存储在外部cluster中。在mbuf的标准头中,有一个数据指针指向实际数据的起始位置,另外还有一个字段用于记录数据的长度,
这两个东西结合在一起就可以方便地在数据区地首部和尾部进行数据的增删操作。上述两个宏值的定义如下:
_________________________________________________________________________________________
134 /*
135 * Constants related to network buffer management.
136 * MCLBYTES must be no larger than PAGE_SIZE.
137 */
138 #ifndef MSIZE
139 #define MSIZE 256 /* size of an mbuf */
140 #endif /* MSIZE */
141
142 #ifndef MCLSHIFT
143 #define MCLSHIFT 11 /* convert bytes to mbuf clusters */
144 #endif /* MCLSHIFT */
145
146 #define MCLBYTES (1 << MCLSHIFT) /* size of an mbuf cluster */
_________________________________________________________________/usr/src/sys/sys/param.h
多个mbuf可通过m_next指针串在一起,用以存储任意长度的数据。按照惯例,以这种方式串起来的mbuf链是被当作一个单一的对象来处理的,
比如一个完整的packet。m_nextpkt指针则用于将上述对象链接成一个队列。下面图示了甴两个packet组成的队列的情况:
+-----------+ +-----------+ +-----------+
| m_next |------->| m_next |------->| m_next |-------> ...
+-----------+ +-----------+ +-----------+
----| m_nextpkt | | ... | | ... |
| +-----------+ | | | |
| | ... | | | | |
| +-----------+ +-----------+ +-----------+
|
| +-----------+ +-----------+
|-->| m_next |------->| m_next |-------> ...
+-----------+ +-----------+
--- | m_nextpkt | | ... |
| +-----------+ | |
| | ... | | |
| +-----------+ +-----------+
|
|--> ...
m_flags字段的取值是在mbuf.h中定义的,这些宏值被分为了两组,一组用于描述单个mbuf,一组用于描述整个packet:
_________________________________________________________________________________________
158 /*
159 * mbuf flags.
160 */
161 #define M_EXT 0x0001 /* has associated external storage */
162 #define M_PKTHDR 0x0002 /* start of record */
163 #define M_EOR 0x0004 /* end of record */
164 #define M_RDONLY 0x0008 /* associated data is marked read-only */
165 #define M_PROTO1 0x0010 /* protocol-specific */
166 #define M_PROTO2 0x0020 /* protocol-specific */
167 #define M_PROTO3 0x0040 /* protocol-specific */
168 #define M_PROTO4 0x0080 /* protocol-specific */
169 #define M_PROTO5 0x0100 /* protocol-specific */
170 #define M_SKIP_FIREWALL 0x4000 /* skip firewall processing */
171 #define M_FREELIST 0x8000 /* mbuf is on the free list */
172
173 /*
174 * mbuf pkthdr flags (also stored in m_flags).
175 */
176 #define M_BCAST 0x0200 /* send/received as link-level broadcast */
177 #define M_MCAST 0x0400 /* send/received as link-level multicast */
178 #define M_FRAG 0x0800 /* packet is a fragment of a larger packet */
179 #define M_FIRSTFRAG 0x1000 /* packet is first fragment */
180 #define M_LASTFRAG 0x2000 /* packet is last fragment */
181 #define M_VLANTAG 0x10000 /* packet has VLAN tag attached */
__________________________________________________________________/usr/src/sys/sys/mbuf.h
如果某个mbuf设置了M_PKTHDR标志,则表明:
如果某个mbuf设置了M_EXT标志,则表明:
注意,一个mbuf可以同时设置上述两个标志,这时在标准头之后是packet头,然后紧接着就是外部存储头。
mbuf大小固定的理由:
mbuf中的pakcet头中的tags用于携带一些关于packet的但又不能放在packet内部的信息。
存储管理算法:
========================================================================
==========嵌入式操作系统VxWorks中网络协议存储池原理及实现====================
VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS)。它以良好的持续能力、高性能的内核以及卓越的实时性被广泛的应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中。VxWorks操作系统有着优越的网络性能,而缓冲区的数据拷贝是影响网络性能的主要因素。
存储池在初始化后,由netPool结构组织几个下一级子池:一个mBlk池、一个clBlk池和一个cluster池。mBlk池就是由很多mBlk组成的一条mBlk链;clBlk池就是由很多clBlk组成的一条clBlk链。cluster池由很多的更下一级cluster子池构成,每一个cluster子池就是一个cluster链。每一个cluster链中的所有cluster的大小相同,不同链中的cluster大小不同。但要实现不同进程访问同一簇而不需要作数据的拷贝,还需要把mBlk结构,clBlk结构和簇结构链接在一起。创建这三级结构一般要遵循这样五步: