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 ;
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to