1bufmod(7M) STREAMS Modules bufmod(7M)
2
3
4
6 bufmod - STREAMS Buffer Module
7
9 #include <sys/bufmod.h>
10
11
12 ioctl(fd, I_PUSH, "bufmod");
13
14
16 bufmod is a STREAMS module that buffers incoming messages, reducing the
17 number of system calls and the associated overhead required to read and
18 process them. Although bufmod was originally designed to be used in
19 conjunction with STREAMS-based networking device drivers, the version
20 described here is general purpose so that it can be used anywhere
21 STREAMS input buffering is required.
22
23 Read-side Behavior
24 The behavior of bufmod depends on various parameters and flags that can
25 be set and queried as described below under IOCTLS. bufmod collects
26 incoming M_DATA messages into chunks, passing each chunk upstream when
27 the chunk becomes full or the current read timeout expires. It option‐
28 ally converts M_PROTO messages to M_DATA and adds them to chunks as
29 well. It also optionally adds to each message a header containing a
30 timestamp, and a cumulative count of messages dropped on the stream
31 read side due to resource exhaustion or flow control. Thedefault set‐
32 tings of bufmod allow it to drop messages when flow control sets in or
33 resources are exhausted; disabling headers and explicitly requesting no
34 drops makes bufmod pass all messages through. Finally, bufmod is capa‐
35 ble of truncating upstream messages to a fixed, programmable length.
36
37
38 When a message arrives, bufmod processes it in several steps. The fol‐
39 lowing paragraphs discuss each step in turn.
40
41
42 Upon receiving a message from below, if the SB_NO_HEADER flag is not
43 set, bufmod immediately timestamps it and saves the current time value
44 for later insertion in the header described below.
45
46
47 Next, if SB_NO_PROTO_CVT is not set, bufmod converts all leading
48 M_PROTO blocks in the message to M_DATA blocks, altering only the mes‐
49 sage type field and leaving the contents alone.
50
51
52 It then truncates the message to the current snapshot length, which is
53 set with the SBIOCSSNAP ioctl described below.
54
55
56 Afterwards, if SB_NO_HEADER is not set, bufmod prepends a header to the
57 converted message. This header is defined as follows.
58
59 struct sb_hdr {
60 uint_t sbh_origlen;
61 uint_t sbh_msglen;
62 uint_t sbh_totlen;
63 uint_t sbh_drops;
64 #if defined(_LP64) || defined(_I32LPx)
65 struct timeval32 sbh_timestamp;
66 #else
67 struct timeval sbh_timestamp;
68 #endif /* !_LP64 */
69 };
70
71
72
73 The sbh_origlen field gives the message's original length before trun‐
74 cation in bytes. The sbh_msglen field gives the length in bytes of the
75 message after the truncation has been done. sbh_totlen gives the dis‐
76 tance in bytes from the start of the truncated message in the current
77 chunk (described below) to the start of the next message in the chunk;
78 the value reflects any padding necessary to insure correct data align‐
79 ment for the host machine and includes the length of the header itself.
80 sbh_drops reports the cumulative number of input messages that this
81 instance of bufmod has dropped due to flow control or resource exhaus‐
82 tion. In the current implementation message dropping due to flow con‐
83 trol can occur only if the SB_NO_DROPS flag is not set. (Note: this
84 accounts only for events occurring within bufmod, and does not count
85 messages dropped by downstream or by upstream modules.) The sbh_time‐
86 stamp field contains the message arrival time expressed as a struct
87 timeval.
88
89
90 After preparing a message, bufmod attempts to add it to the end of the
91 current chunk, using the chunk size and timeout values to govern the
92 addition. The chunk size and timeout values are set and inspected using
93 the ioctl() calls described below. If adding the new message would make
94 the current chunk grow larger than the chunk size, bufmod closes off
95 the current chunk, passing it up to the next module in line, and starts
96 a new chunk. If adding the message would still make the new chunk over‐
97 flow, the module passes it upward in an over-size chunk of its own.
98 Otherwise, the module concatenates the message to the end of the cur‐
99 rent chunk.
100
101
102 To ensure that messages do not languish forever in an accumulating
103 chunk, bufmod maintains a read timeout. Whenever this timeout expires,
104 the module closes off the current chunk and passes it upward. The mod‐
105 ule restarts the timeout period when it receives a read side data mes‐
106 sage and a timeout is not currently active. These two rules insure that
107 bufmod minimizes the number of chunks it produces during periods of
108 intense message activity and that it periodically disposes of all mes‐
109 sages during slack intervals, but avoids any timeout overhead when
110 there is no activity.
111
112
113 bufmod handles other message types as follows. Upon receiving an
114 M_FLUSH message specifying that the read queue be flushed, the module
115 clears the currently accumulating chunk and passes the message on to
116 the module or driver above. (Note: bufmod uses zero length M_CTL mes‐
117 sages for internal synchronization and does not pass them through.)
118 bufmod passes all other messages through unaltered to its upper neigh‐
119 bor, maintaining message order for non high priority messages by pass‐
120 ing up any accumulated chunk first.
121
122
123 If the SB_DEFER_CHUNK flag is set, buffering does not begin until the
124 second message is received within the timeout window.
125
126
127 If the SB_SEND_ON_WRITE flag is set, bufmod passes up the read side any
128 buffered data when a message is received on the write side.
129 SB_SEND_ON_WRITE and SB_DEFER_CHUNK are often used together.
130
131 Write-side Behavior
132 bufmod intercepts M_IOCTL messages for the ioctls described below. The
133 module passes all other messages through unaltered to its lower neigh‐
134 bor. If SB_SEND_ON_WRITE is set, message arrival on the writer side
135 suffices to close and transmit the current read side chunk.
136
138 bufmod responds to the following ioctls.
139
140 SBIOCSTIME Set the read timeout value to the value referred to by
141 the struct timeval pointer given as argument. Setting
142 the timeout value to zero has the side-effect of forc‐
143 ing the chunk size to zero as well, so that the module
144 will pass all incoming messages upward immediately upon
145 arrival. Negative values are rejected with an EINVAL
146 error.
147
148
149 SBIOCGTIME Return the read timeout in the struct timeval pointed
150 to by the argument. If the timeout has been cleared
151 with the SBIOCCTIME ioctl, return with an ERANGE error.
152
153
154 SBIOCCTIME Clear the read timeout, effectively setting its value
155 to infinity. This results in no timeouts being active
156 and the chunk being delivered when it is full.
157
158
159 SBIOCSCHUNK Set the chunk size to the value referred to by the
160 uint_t pointer given as argument. See Notes for a
161 description of effect on stream head high water mark.
162
163
164 SBIOCGCHUNK Return the chunk size in the uint_t pointed to by the
165 argument.
166
167
168 SBIOCSSNAP Set the current snapshot length to the value given in
169 the uint_t pointed to by the ioctl's final argument.
170 bufmod interprets a snapshot length value of zero as
171 meaning infinity, so it will not alter the message. See
172 Notes for a description of effect on stream head high
173 water mark.
174
175
176 SBIOCGSNAP Returns the current snapshot length in the uint_t
177 pointed to by the ioctl's final argument.
178
179
180 SBIOCSFLAGS Set the current flags to the value given in the uint_t
181 pointed to by the ioctl's final argument. Possible val‐
182 ues are a combination of the following.
183
184 SB_SEND_ON_WRITE Transmit the read side chunk on
185 arrival of a message on the write
186 side.
187
188
189 SB_NO_HEADER Do not add headers to read side
190 messages.
191
192
193 SB_NO_DROPS Do not drop messages due to flow
194 control upstream.
195
196
197 SB_NO_PROTO_CVT Do not convert M_PROTO messages
198 into M_DATA.
199
200
201 SB_DEFER_CHUNK Begin buffering on arrival of the
202 second read side message in a
203 timeout interval.
204
205
206
207 SBIOCGFLAGS Returns the current flags in the uint_t pointed to by
208 the ioctl's final argument.
209
210
212 dlpi(7P), pfmod(7M)
213
215 Older versions of bufmod did not support the behavioral flexibility
216 controlled by the SBIOCSFLAGS ioctl. Applications that wish to take
217 advantage of this flexibility can guard themselves against old versions
218 of the module by invoking the SBIOCGFLAGS ioctl and checking for an
219 EINVAL error return.
220
221
222 When buffering is enabled by issuing an SBIOCSCHUNK ioctl to set the
223 chunk size to a non zero value, bufmod sends a SETOPTS message to
224 adjust the stream head high and low water marks to accommodate the
225 chunked messages.
226
227
228 When buffering is disabled by setting the chunk size to zero, message
229 truncation can have a significant influence on data traffic at the
230 stream head and therefore the stream head high and low water marks are
231 adjusted to new values appropriate for the smaller truncated message
232 sizes.
233
235 bufmod does not defend itself against allocation failures, so that it
236 is possible, although very unlikely, for the stream head to use inap‐
237 propriate high and low water marks after the chunk size or snapshot
238 length have changed.
239
240
241
242SunOS 5.11 11 Nov 1997 bufmod(7M)