[Click] About queues scheduling

Roberto Riggio roberto.riggio at create-net.org
Sun May 15 11:06:19 EDT 2011


Il 14/05/2011 06:26, Eddie Kohler ha scritto:
> If this works as I expect, you should see something like the 
> following, with _iters_per_os == 2:
>
> push
> pull
> pull
> pull
> push
> pull
> pull
> pull
Yes, it works as described.
>
> Nevertheless, though, adding BURST to KernelTun would help even more.
I'm attaching a patch that adds support for the BURST param. It defaults 
to 1
so the current behavior should not be affected.
>
> Any comments on if this helps?
With both patches the queue remains backlogged as I was expecting. Thanks.

> E

--

diff -urN -x .git -x diffserv -x wing -x secaggr -x click-align.cc -x 
availablechannels.cc -x availablechannels.hh -x devinfo.cc -x devinfo.hh 
click.upstream/elements/userlevel/kerneltun.cc 
click/elements/userlevel/kerneltun.cc
--- click.upstream/elements/userlevel/kerneltun.cc    2011-05-10 
10:22:19.915121002 +0200
+++ click/elements/userlevel/kerneltun.cc    2011-05-10 
21:13:08.943966002 +0200
@@ -94,10 +94,12 @@
      _adjust_headroom = false;
      _headroom += (4 - _headroom % 4) % 4; // default 4/0 alignment
      _mtu_out = DEFAULT_MTU;
+    _burst = 1;
      if (Args(conf, this, errh)
      .read_mp("ADDR", IPPrefixArg(), _near, _mask)
      .read_p("GATEWAY", _gw)
      .read("TAP", _tap)
+    .read("BURST", _burst)
      .read("HEADROOM", _headroom).read_status(_adjust_headroom)
      .read("ETHER", _macaddr)
      .read("IGNORE_QUEUE_OVERFLOWS", _ignore_q_errs)
@@ -504,65 +506,75 @@
  {
      if (fd != _fd)
      return;
-    WritablePacket *p = Packet::make(_headroom, 0, _mtu_in, 0);
-    if (!p) {
-    click_chatter("out of memory!");
-    return;
-    }

-    int cc = read(_fd, p->data(), _mtu_in);
-    if (cc > 0) {
-    p->take(_mtu_in - cc);
-    bool ok = false;
-
-    if (_tap) {
-        if (_type == LINUX_UNIVERSAL)
-        // 2-byte padding, 2-byte Ethernet type, then Ethernet header
-        p->pull(4);
-        else if (_type == LINUX_ETHERTAP)
-        // 2-byte padding, then Ethernet header
-        p->pull(2);
-        ok = true;
-    } else if (_type == LINUX_UNIVERSAL) {
-        // 2-byte padding followed by an Ethernet type
-        uint16_t etype = *(uint16_t *)(p->data() + 2);
-        p->pull(4);
-        if (etype != htons(ETHERTYPE_IP) && etype != htons(ETHERTYPE_IP6))
-        checked_output_push(1, p->clone());
-        else
-        ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
-    } else if (_type == BSD_TUN) {
-        // 4-byte address family followed by IP header
-        int af = ntohl(*(unsigned *)p->data());
-        p->pull(4);
-        if (af != AF_INET && af != AF_INET6) {
-        click_chatter("KernelTun(%s): don't know AF %d", 
_dev_name.c_str(), af);
-        checked_output_push(1, p->clone());
-        } else
-        ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
-    } else if (_type == OSX_TUN || _type == NETBSD_TUN) {
-        ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
-    } else { /* _type == LINUX_ETHERTAP */
-        // 2-byte padding followed by a mostly-useless Ethernet header
-        uint16_t etype = *(uint16_t *)(p->data() + 14);
-        p->pull(16);
-        if (etype != htons(ETHERTYPE_IP) && etype != htons(ETHERTYPE_IP6))
-        checked_output_push(1, p->clone());
-        else
-        ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
-    }
+    for (unsigned i = 0; i < _burst; i++) {

-    if (ok) {
-        p->timestamp_anno().assign_now();
-        output(0).push(p);
-    } else
-        checked_output_push(1, p);
-
-    } else {
-    if (!_ignore_q_errs || !_printed_read_err || (errno != ENOBUFS)) {
-        _printed_read_err = true;
-        perror("KernelTun read");
-    }
+        WritablePacket *p = Packet::make(_headroom, 0, _mtu_in, 0);
+        if (!p) {
+        click_chatter("out of memory!");
+        return;
+        }
+
+        int cc = read(_fd, p->data(), _mtu_in);
+
+        if ((cc == -1) && errno == EAGAIN) {
+            p->kill();
+            break;
+        }
+
+        if (cc > 0) {
+        p->take(_mtu_in - cc);
+        bool ok = false;
+
+        if (_tap) {
+            if (_type == LINUX_UNIVERSAL)
+            // 2-byte padding, 2-byte Ethernet type, then Ethernet header
+            p->pull(4);
+            else if (_type == LINUX_ETHERTAP)
+            // 2-byte padding, then Ethernet header
+            p->pull(2);
+            ok = true;
+        } else if (_type == LINUX_UNIVERSAL) {
+            // 2-byte padding followed by an Ethernet type
+            uint16_t etype = *(uint16_t *)(p->data() + 2);
+            p->pull(4);
+            if (etype != htons(ETHERTYPE_IP) && etype != 
htons(ETHERTYPE_IP6))
+            checked_output_push(1, p->clone());
+            else
+            ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+        } else if (_type == BSD_TUN) {
+            // 4-byte address family followed by IP header
+            int af = ntohl(*(unsigned *)p->data());
+            p->pull(4);
+            if (af != AF_INET && af != AF_INET6) {
+            click_chatter("KernelTun(%s): don't know AF %d", 
_dev_name.c_str(), af);
+            checked_output_push(1, p->clone());
+            } else
+            ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+        } else if (_type == OSX_TUN || _type == NETBSD_TUN) {
+            ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+        } else { /* _type == LINUX_ETHERTAP */
+            // 2-byte padding followed by a mostly-useless Ethernet header
+            uint16_t etype = *(uint16_t *)(p->data() + 14);
+            p->pull(16);
+            if (etype != htons(ETHERTYPE_IP) && etype != 
htons(ETHERTYPE_IP6))
+            checked_output_push(1, p->clone());
+            else
+            ok = fake_pcap_force_ip(p, FAKE_DLT_RAW);
+        }
+
+        if (ok) {
+            p->timestamp_anno().assign_now();
+            output(0).push(p);
+        } else
+            checked_output_push(1, p);
+
+        } else {
+        if (!_ignore_q_errs || !_printed_read_err || (errno != ENOBUFS)) {
+            _printed_read_err = true;
+            perror("KernelTun read");
+        }
+        }
      }
  }

diff -urN -x .git -x diffserv -x wing -x secaggr -x click-align.cc -x 
availablechannels.cc -x availablechannels.hh -x devinfo.cc -x devinfo.hh 
click.upstream/elements/userlevel/kerneltun.hh 
click/elements/userlevel/kerneltun.hh
--- click.upstream/elements/userlevel/kerneltun.hh    2011-05-10 
10:22:19.915121002 +0200
+++ click/elements/userlevel/kerneltun.hh    2011-04-27 
16:41:19.551880001 +0200
@@ -129,6 +129,7 @@
      enum Type { LINUX_UNIVERSAL, LINUX_ETHERTAP, BSD_TUN, BSD_TAP, 
OSX_TUN,
          NETBSD_TUN, NETBSD_TAP };

+    unsigned _burst;
      int _fd;
      int _mtu_in;
      int _mtu_out;



More information about the click mailing list