svn commit: r200029 - head/sys/netinet/ipfw
Luigi Rizzo
luigi at FreeBSD.org
Wed Dec 2 15:20:31 UTC 2009
Author: luigi
Date: Wed Dec 2 15:20:31 2009
New Revision: 200029
URL: http://svn.freebsd.org/changeset/base/200029
Log:
small changes for portability and diff reduction wrt/ FreeBSD 7.
No functional differences.
- use the div64() macro to wrap 64 bit divisions
(which almost always are 64 / 32 bits) so they are easier
to handle with compilers or OS that do not have native
support for 64bit divisions;
- use a local variable for p_numbytes even if not strictly
necessary on HEAD, as it reduces diffs with FreeBSD7
- in dummynet_send() check that a tag is present before
dereferencing the pointer.
- add a couple of blank lines for readability near the end of a function
MFC after: 3 days
Modified:
head/sys/netinet/ipfw/ip_dummynet.c
Modified: head/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- head/sys/netinet/ipfw/ip_dummynet.c Wed Dec 2 15:05:26 2009 (r200028)
+++ head/sys/netinet/ipfw/ip_dummynet.c Wed Dec 2 15:20:31 2009 (r200029)
@@ -570,7 +570,7 @@ compute_extra_bits(struct mbuf *pkt, str
if (!p->samples || p->samples_no == 0)
return 0;
index = random() % p->samples_no;
- extra_bits = ((dn_key)p->samples[index] * p->bandwidth) / 1000;
+ extra_bits = div64((dn_key)p->samples[index] * p->bandwidth, 1000);
if (index >= p->loss_level) {
struct dn_pkt_tag *dt = dn_tag_get(pkt);
if (dt)
@@ -696,11 +696,20 @@ ready_event_wfq(struct dn_pipe *p, struc
int p_was_empty = (p->head == NULL);
struct dn_heap *sch = &(p->scheduler_heap);
struct dn_heap *neh = &(p->not_eligible_heap);
+ int64_t p_numbytes = p->numbytes;
+
+ /*
+ * p->numbytes is only 32bits in FBSD7, but we might need 64 bits.
+ * Use a local variable for the computations, and write back the
+ * results when done, saturating if needed.
+ * The local variable has no impact on performance and helps
+ * reducing diffs between the various branches.
+ */
DUMMYNET_LOCK_ASSERT();
if (p->if_name[0] == 0) /* tx clock is simulated */
- p->numbytes += (curr_time - p->sched_time) * p->bandwidth;
+ p_numbytes += (curr_time - p->sched_time) * p->bandwidth;
else { /*
* tx clock is for real,
* the ifq must be empty or this is a NOP.
@@ -717,7 +726,7 @@ ready_event_wfq(struct dn_pipe *p, struc
* While we have backlogged traffic AND credit, we need to do
* something on the queue.
*/
- while (p->numbytes >= 0 && (sch->elements > 0 || neh->elements > 0)) {
+ while (p_numbytes >= 0 && (sch->elements > 0 || neh->elements > 0)) {
if (sch->elements > 0) {
/* Have some eligible pkts to send out. */
struct dn_flow_queue *q = sch->p[0].object;
@@ -727,10 +736,10 @@ ready_event_wfq(struct dn_pipe *p, struc
int len_scaled = p->bandwidth ? len * 8 * hz : 0;
heap_extract(sch, NULL); /* Remove queue from heap. */
- p->numbytes -= len_scaled;
+ p_numbytes -= len_scaled;
move_pkt(pkt, q, p, len);
- p->V += (len << MY_M) / p->sum; /* Update V. */
+ p->V += div64((len << MY_M), p->sum); /* Update V. */
q->S = q->F; /* Update start time. */
if (q->len == 0) {
/* Flow not backlogged any more. */
@@ -745,7 +754,7 @@ ready_event_wfq(struct dn_pipe *p, struc
* (we will fix this later).
*/
len = (q->head)->m_pkthdr.len;
- q->F += (len << MY_M) / (uint64_t)fs->weight;
+ q->F += div64((len << MY_M), fs->weight);
if (DN_KEY_LEQ(q->S, p->V))
heap_insert(neh, q->S, q);
else
@@ -768,11 +777,11 @@ ready_event_wfq(struct dn_pipe *p, struc
}
if (p->if_name[0] != '\0') { /* Tx clock is from a real thing */
- p->numbytes = -1; /* Mark not ready for I/O. */
+ p_numbytes = -1; /* Mark not ready for I/O. */
break;
}
}
- if (sch->elements == 0 && neh->elements == 0 && p->numbytes >= 0) {
+ if (sch->elements == 0 && neh->elements == 0 && p_numbytes >= 0) {
p->idle_time = curr_time;
/*
* No traffic and no events scheduled.
@@ -798,11 +807,11 @@ ready_event_wfq(struct dn_pipe *p, struc
* If we are under credit, schedule the next ready event.
* Also fix the delivery time of the last packet.
*/
- if (p->if_name[0]==0 && p->numbytes < 0) { /* This implies bw > 0. */
+ if (p->if_name[0]==0 && p_numbytes < 0) { /* This implies bw > 0. */
dn_key t = 0; /* Number of ticks i have to wait. */
if (p->bandwidth > 0)
- t = (p->bandwidth - 1 - p->numbytes) / p->bandwidth;
+ t = div64(p->bandwidth - 1 - p_numbytes, p->bandwidth);
dn_tag_get(p->tail)->output_time += t;
p->sched_time = curr_time;
heap_insert(&wfq_ready_heap, curr_time + t, (void *)p);
@@ -812,6 +821,9 @@ ready_event_wfq(struct dn_pipe *p, struc
*/
}
+ /* Write back p_numbytes (adjust 64->32bit if necessary). */
+ p->numbytes = p_numbytes;
+
/*
* If the delay line was empty call transmit_event() now.
* Otherwise, the scheduler will take care of it.
@@ -938,12 +950,20 @@ dummynet_send(struct mbuf *m)
struct dn_pkt_tag *pkt;
struct mbuf *n;
struct ip *ip;
+ int dst;
for (; m != NULL; m = n) {
n = m->m_nextpkt;
m->m_nextpkt = NULL;
- pkt = dn_tag_get(m);
- switch (pkt->dn_dir) {
+ if (m_tag_first(m) == NULL) {
+ pkt = NULL; /* probably unnecessary */
+ dst = DN_TO_DROP;
+ } else {
+ pkt = dn_tag_get(m);
+ dst = pkt->dn_dir;
+ }
+
+ switch (dst) {
case DN_TO_IP_OUT:
ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
break ;
@@ -1218,7 +1238,8 @@ red_drops(struct dn_flow_set *fs, struct
* XXX check wraps...
*/
if (q->avg) {
- u_int t = (curr_time - q->idle_time) / fs->lookup_step;
+ u_int t = div64(curr_time - q->idle_time,
+ fs->lookup_step);
q->avg = (t < fs->lookup_depth) ?
SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
@@ -1258,7 +1279,7 @@ red_drops(struct dn_flow_set *fs, struct
}
if (fs->flags_fs & DN_QSIZE_IS_BYTES)
- p_b = (p_b * len) / fs->max_pkt_size;
+ p_b = div64(p_b * len, fs->max_pkt_size);
if (++q->count == 0)
q->random = random() & 0xffff;
else {
@@ -1475,7 +1496,7 @@ dummynet_io(struct mbuf **m0, int dir, s
heap_extract(&(pipe->idle_heap), q);
q->S = MAX64(q->F, pipe->V);
}
- q->F = q->S + (len << MY_M) / (uint64_t)fs->weight;
+ q->F = q->S + div64(len << MY_M, fs->weight);
if (pipe->not_eligible_heap.elements == 0 &&
pipe->scheduler_heap.elements == 0)
@@ -2245,8 +2266,10 @@ ip_dn_ctl(struct sockopt *sopt)
error = delete_pipe(p);
break ;
}
+
if (p != NULL)
free(p, M_TEMP);
+
return error ;
}
More information about the svn-src-head
mailing list