<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.rt.user">
    <title>gmane.linux.rt.user</title>
    <link>http://blog.gmane.org/gmane.linux.rt.user</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3674"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3672"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3658"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3655"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3651"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3649"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3644"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3642"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3639"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3629"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3628"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3625"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3623"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3622"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3621"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3617"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3616"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3612"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3610"/>
        <rdf:li rdf:resource="http://comments.gmane.org/gmane.linux.rt.user/3609"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3674">
    <title>RFC: Latency reducing TCP modifications for thin-stream interactive applications</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3674</link>
    <description>A wide range of Internet-based services that use reliable transport 
protocols display what we call thin-stream properties. This means 
that the application sends data with such a low rate that the 
retransmission mechanisms of the transport protocol are not fully 
effective. In time-dependent scenarios (like online games, control 
systems or some sensor networks) where the user experience depends 
on the data delivery latency, packet loss can be devastating for 
the service quality. Extreme latencies are caused by TCP's 
dependency on the arrival of new data from the application to trigger 
retransmissions effectively through fast retransmit instead of 
waiting for long timeouts. After analyzing a large number of 
time-dependent interactive applications, we have seen that they 
often produce thin streams (as described above) and also stay with 
this traffic pattern throughout its entire lifespan. The 
combination of time-dependency and the fact that the streams 
provoke high latencies when using TCP is unfortunate.

In order to reduce application-layer latency when packets are lost, 
we have implemented modifications to the TCP retransmission 
mechanisms in the Linux kernel. We have also implemented a 
bundling mechanisms that introduces redundancy in order to 
preempt the experience of packet loss. In short, if the kernel 
detects a thin stream, we trade a small amount of bandwidth for 
latency reduction and apply:

Removal of exponential backoff: To prevent an exponential increase 
in retransmission delay for a repeatedly lost packet, we remove 
the exponential factor.

FASTER Fast Retransmit: Instead of waiting for 3 duplicate 
acknowledgments before sending a fast retransmission, we retransmit 
after receiving only one.

Redundant Data Bundling: We copy (bundle) data from the 
unacknowledged packets in the send buffer into the next packet if
 space is available.

These enhancements are applied only if the stream is detected as
thin. 
This is accomplished by defining thresholds for packet size and 
packets in flight. Also, we consider the redundancy introduced 
by our mechanisms acceptable because the streams are so thin 
that normal congestion mechanisms do not come into effect.

We have implemented these changes in the Linux kernel (2.6.23.8), 
and have tested the modifications on a wide range of different 
thin-stream applications (Skype, BZFlag, SSH, ...) under varying 
network conditions. Our results show that applications which use 
TCP for interactive time-dependent traffic will experience a 
reduction in both maximum and average latency, giving the users 
quicker feedback to their interactions.

Availability of this kind of mechanisms will help provide 
customizability for interactive network services. The quickly 
growing market for Linux gaming may benefit from lowered latency. 
As an example, most of the large MMORPG's today use TCP (like World 
of Warcraft and Age of Conan) and several multimedia applications 
(like Skype) use TCP fallback if UDP is blocked.

The modifications are all TCP standard compliant and transparent
to the receiver. As such, a game server could implement the 
modifications and get a one-way latency benefit without touching 
any of the clients.

In the following papers, we discuss the benefits and tradeoffs of 
the decribed mechanisms:
"The Fun of using TCP for an MMORPG": 
http://simula.no/research/networks/publications/Griwodz.2006.1
"TCP Enhancements For Interactive Thin-Stream Applications": 
http://simula.no/research/networks/publications/Simula.ND.83
"Improving application layer latency for reliable thin-stream game
traffic": http://simula.no/research/networks/publications/Simula.ND.185
"TCP mechanisms for improving the user experience for time-dependent 
thin-stream applications": 
http://simula.no/research/networks/publications/Simula.ND.159
Our presentation from the 2008 Linux-Kongress can be found here: 
http://data.guug.de/slides/lk2008/lk-2008-Andreas-Petlund.pdf

We have included a patch for the 2.6.23.8 kernel which implements the 
modifications. The patch is not properly segmented and formatted, but 
attached as a reference. We are currently working on an updated patch 
set which we hopefully will be able to post in a couple of weeks. This 
will also give us time to integrate any ideas that may arise from the 
discussions here.

We are happy for all feedback regarding this:
Is something like this viable to introduce into the kernel? Is the 
scheme for thin-stream detection mechanism acceptable. Any viewpoints 
on the architecture and design? 


diff -Nur linux-2.6.23.8.vanilla/include/linux/sysctl.h linux-2.6.23.8-tcp-thin/include/linux/sysctl.h
--- linux-2.6.23.8.vanilla/include/linux/sysctl.h2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/include/linux/sysctl.h2008-07-03 11:47:21.000000000 +0200
&lt; at &gt;&lt; at &gt; -355,6 +355,11 &lt; at &gt;&lt; at &gt;
 NET_IPV4_ROUTE=18,
 NET_IPV4_FIB_HASH=19,
 NET_IPV4_NETFILTER=20,
+
+NET_IPV4_TCP_FORCE_THIN_RDB=29,         /* Added &lt; at &gt; Simula */
+NET_IPV4_TCP_FORCE_THIN_RM_EXPB=30,     /* Added &lt; at &gt; Simula */
+NET_IPV4_TCP_FORCE_THIN_DUPACK=31,      /* Added &lt; at &gt; Simula */
+NET_IPV4_TCP_RDB_MAX_BUNDLE_BYTES=32,   /* Added &lt; at &gt; Simula */
 
 NET_IPV4_TCP_TIMESTAMPS=33,
 NET_IPV4_TCP_WINDOW_SCALING=34,
diff -Nur linux-2.6.23.8.vanilla/include/linux/tcp.h linux-2.6.23.8-tcp-thin/include/linux/tcp.h
--- linux-2.6.23.8.vanilla/include/linux/tcp.h2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/include/linux/tcp.h2008-07-02 15:17:38.000000000 +0200
&lt; at &gt;&lt; at &gt; -97,6 +97,10 &lt; at &gt;&lt; at &gt;
 #define TCP_CONGESTION13/* Congestion control algorithm */
 #define TCP_MD5SIG14/* TCP MD5 Signature (RFC2385) */
 
+#define TCP_THIN_RDB            15      /* Added &lt; at &gt; Simula - Enable redundant data bundling  */
+#define TCP_THIN_RM_EXPB        16      /* Added &lt; at &gt; Simula - Remove exponential backoff  */
+#define TCP_THIN_DUPACK         17      /* Added &lt; at &gt; Simula - Reduce number of dupAcks needed */
+
 #define TCPI_OPT_TIMESTAMPS1
 #define TCPI_OPT_SACK2
 #define TCPI_OPT_WSCALE4
&lt; at &gt;&lt; at &gt; -296,6 +300,10 &lt; at &gt;&lt; at &gt;
 u8nonagle;/* Disable Nagle algorithm?             */
 u8keepalive_probes; /* num of allowed keep alive probes*/
 
+u8      thin_rdb;       /* Enable RDB                           */
+u8      thin_rm_expb;   /* Remove exp. backoff                  */
+u8      thin_dupack;    /* Remove dupack                        */
+
 /* RTT measurement */
 u32srtt;/* smoothed round trip time &lt;&lt; 3*/
 u32mdev;/* medium deviation*/
diff -Nur linux-2.6.23.8.vanilla/include/net/sock.h linux-2.6.23.8-tcp-thin/include/net/sock.h
--- linux-2.6.23.8.vanilla/include/net/sock.h2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/include/net/sock.h2008-07-02 17:07:10.000000000 +0200
&lt; at &gt;&lt; at &gt; -462,7 +462,10 &lt; at &gt;&lt; at &gt;
 
 static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
 {
-skb_truesize_check(skb);
+/* Modified &lt; at &gt; Simula 
+   skb_truesize_check creates unnecessary 
+   noise when combined with RDB */
+//skb_truesize_check(skb);
 sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
 sk-&gt;sk_wmem_queued   -= skb-&gt;truesize;
 sk-&gt;sk_forward_alloc += skb-&gt;truesize;
diff -Nur linux-2.6.23.8.vanilla/include/net/tcp.h linux-2.6.23.8-tcp-thin/include/net/tcp.h
--- linux-2.6.23.8.vanilla/include/net/tcp.h2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/include/net/tcp.h2008-07-03 11:48:54.000000000 +0200
&lt; at &gt;&lt; at &gt; -188,9 +188,19 &lt; at &gt;&lt; at &gt;
 #define TCP_NAGLE_CORK2/* Socket is corked    */
 #define TCP_NAGLE_PUSH4/* Cork is overridden for already queued data */
 
+/* Added &lt; at &gt; Simula - Thin stream support */
+#define TCP_FORCE_THIN_RDB            0 /* Thin streams: exp. backoff   default off */
+#define TCP_FORCE_THIN_RM_EXPB        0 /* Thin streams: dynamic dupack default off */
+#define TCP_FORCE_THIN_DUPACK         0 /* Thin streams: smaller minRTO default off */
+#define TCP_RDB_MAX_BUNDLE_BYTES      0 /* Thin streams: Limit maximum bundled bytes */
+
 extern struct inet_timewait_death_row tcp_death_row;
 
 /* sysctl variables for tcp */
+extern int sysctl_tcp_force_thin_rdb;         /* Added &lt; at &gt; Simula */
+extern int sysctl_tcp_force_thin_rm_expb;     /* Added &lt; at &gt; Simula */
+extern int sysctl_tcp_force_thin_dupack;      /* Added &lt; at &gt; Simula */
+extern int sysctl_tcp_rdb_max_bundle_bytes;   /* Added &lt; at &gt; Simula */
 extern int sysctl_tcp_timestamps;
 extern int sysctl_tcp_window_scaling;
 extern int sysctl_tcp_sack;
&lt; at &gt;&lt; at &gt; -723,6 +733,16 &lt; at &gt;&lt; at &gt;
 return (tp-&gt;packets_out - tp-&gt;left_out + tp-&gt;retrans_out);
 }
 
+/* Added &lt; at &gt; Simula
+ *
+ * To determine whether a stream is thin or not
+ * return 1 if thin, 0 othervice 
+ */
+static inline unsigned int tcp_stream_is_thin(const struct tcp_sock *tp)
+{
+return (tp-&gt;packets_out &lt; 4 ? 1 : 0);
+}
+
 /* If cwnd &gt; ssthresh, we may raise ssthresh to be half-way to cwnd.
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
diff -Nur linux-2.6.23.8.vanilla/net/ipv4/sysctl_net_ipv4.c linux-2.6.23.8-tcp-thin/net/ipv4/sysctl_net_ipv4.c
--- linux-2.6.23.8.vanilla/net/ipv4/sysctl_net_ipv4.c2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/net/ipv4/sysctl_net_ipv4.c2008-07-03 11:49:59.000000000 +0200
&lt; at &gt;&lt; at &gt; -187,6 +187,38 &lt; at &gt;&lt; at &gt;
 }
 
 ctl_table ipv4_table[] = {
+{       /* Added &lt; at &gt; Simula for thin streams */
+                .ctl_name       = NET_IPV4_TCP_FORCE_THIN_RDB,
+                .procname       = "tcp_force_thin_rdb",
+                .data           = &amp;sysctl_tcp_force_thin_rdb,
+                .maxlen         = sizeof(int),
+                .mode           = 0644,
+                .proc_handler   = &amp;proc_dointvec
+        },
+{       /* Added &lt; at &gt; Simula for thin streams */
+                .ctl_name       = NET_IPV4_TCP_FORCE_THIN_RM_EXPB,
+                .procname       = "tcp_force_thin_rm_expb",
+                .data           = &amp;sysctl_tcp_force_thin_rm_expb,
+                .maxlen         = sizeof(int),
+                .mode           = 0644,
+                .proc_handler   = &amp;proc_dointvec
+        },
+{       /* Added &lt; at &gt; Simula for thin streams */
+                .ctl_name       = NET_IPV4_TCP_FORCE_THIN_DUPACK,
+                .procname       = "tcp_force_thin_dupack",
+                .data           = &amp;sysctl_tcp_force_thin_dupack,
+                .maxlen         = sizeof(int),
+                .mode           = 0644,
+                .proc_handler   = &amp;proc_dointvec
+        },
+{       /* Added &lt; at &gt; Simula for thin streams */
+                .ctl_name       = NET_IPV4_TCP_RDB_MAX_BUNDLE_BYTES,
+                .procname       = "tcp_rdb_max_bundle_bytes",
+                .data           = &amp;sysctl_tcp_rdb_max_bundle_bytes,
+                .maxlen         = sizeof(int),
+                .mode           = 0644,
+                .proc_handler   = &amp;proc_dointvec
+        },
 {
 .ctl_name= NET_IPV4_TCP_TIMESTAMPS,
 .procname= "tcp_timestamps",
diff -Nur linux-2.6.23.8.vanilla/net/ipv4/tcp.c linux-2.6.23.8-tcp-thin/net/ipv4/tcp.c
--- linux-2.6.23.8.vanilla/net/ipv4/tcp.c2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/net/ipv4/tcp.c2008-07-03 11:51:55.000000000 +0200
&lt; at &gt;&lt; at &gt; -270,6 +270,10 &lt; at &gt;&lt; at &gt;
 
 int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
 
+/* Added &lt; at &gt; Simula */
+int sysctl_tcp_force_thin_rdb __read_mostly = TCP_FORCE_THIN_RDB;
+int sysctl_tcp_rdb_max_bundle_bytes __read_mostly = TCP_RDB_MAX_BUNDLE_BYTES;
+
 DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics) __read_mostly;
 
 atomic_t tcp_orphan_count = ATOMIC_INIT(0);
&lt; at &gt;&lt; at &gt; -658,6 +662,167 &lt; at &gt;&lt; at &gt;
 return tmp;
 }
 
+/* Added at Simula to support RDB */
+static int tcp_trans_merge_prev(struct sock *sk, struct sk_buff *skb, int mss_now)
+{
+struct tcp_sock *tp = tcp_sk(sk);
+
+/* Make sure that this isn't referenced by somebody else */
+
+if(!skb_cloned(skb)){
+struct sk_buff *prev_skb = skb-&gt;prev;
+int skb_size = skb-&gt;len;
+int old_headlen = 0;
+int ua_data = 0;
+int uad_head = 0;
+int uad_frags = 0;
+int ua_nr_frags = 0;
+int ua_frags_diff = 0;
+
+/* Since this technique currently does not support SACK, I
+ * return -1 if the previous has been SACK'd. */
+if(TCP_SKB_CB(prev_skb)-&gt;sacked &amp; TCPCB_SACKED_ACKED){
+return -1;
+}
+
+/* Current skb is out of window. */
+if (after(TCP_SKB_CB(skb)-&gt;end_seq, tp-&gt;snd_una+tp-&gt;snd_wnd)){
+return -1;
+}
+
+/*TODO: Optimize this part with regards to how the 
+  variables are initialized */
+
+/*Calculates the ammount of unacked data that is available*/
+ua_data = (TCP_SKB_CB(prev_skb)-&gt;end_seq - tp-&gt;snd_una &gt; 
+   prev_skb-&gt;len ? prev_skb-&gt;len : 
+   TCP_SKB_CB(prev_skb)-&gt;end_seq - tp-&gt;snd_una);
+ua_frags_diff = ua_data - prev_skb-&gt;data_len;
+uad_frags = (ua_frags_diff &gt; 0 ? prev_skb-&gt;data_len : ua_data);
+uad_head = (ua_frags_diff &gt; 0 ? ua_data - uad_frags : 0);
+
+if(ua_data &lt;= 0)
+return -1;
+
+if(uad_frags &gt; 0){
+int i = 0;
+int bytes_frags = 0;
+
+if(uad_frags == prev_skb-&gt;data_len){
+ua_nr_frags = skb_shinfo(prev_skb)-&gt;nr_frags;
+} else{
+for(i=skb_shinfo(prev_skb)-&gt;nr_frags - 1; i&gt;=0; i--){
+if(skb_shinfo(prev_skb)-&gt;frags[i].size 
+   + bytes_frags == uad_frags){
+ua_nr_frags += 1;
+break;
+}   
+ua_nr_frags += 1;
+bytes_frags += skb_shinfo(prev_skb)-&gt;frags[i].size;
+}
+}
+}
+
+/*
+ * Do the diffrenet checks on size and content, and return if
+ * something will not work.
+ *
+ * TODO: Support copying some bytes
+ *
+ * 1. Larger than MSS.
+ * 2. Enough room for the stuff stored in the linear area
+ * 3. Enoug room for the pages
+ * 4. If both skbs have some data stored in the linear area, and prev_skb
+ * also has some stored in the paged area, they cannot be merged easily.
+ * 5. If prev_skb is linear, then this one has to be it as well.
+ */
+if ((sysctl_tcp_rdb_max_bundle_bytes == 0 &amp;&amp; ((skb_size + ua_data) &gt; mss_now))
+    || (sysctl_tcp_rdb_max_bundle_bytes &gt; 0 &amp;&amp; ((skb_size + ua_data) &gt;
+sysctl_tcp_rdb_max_bundle_bytes))){
+return -1;
+}
+
+/* We need to know tailroom, even if it is nonlinear */
+if(uad_head &gt; (skb-&gt;end - skb-&gt;tail)){
+return -1;
+}
+
+if(skb_is_nonlinear(skb) &amp;&amp; (uad_frags &gt; 0)){
+if((ua_nr_frags +
+    skb_shinfo(skb)-&gt;nr_frags) &gt; MAX_SKB_FRAGS){
+return -1;
+}
+
+if(skb_headlen(skb) &gt; 0){
+return -1;
+}
+}
+
+if((uad_frags &gt; 0) &amp;&amp; skb_headlen(skb) &gt; 0){
+return -1;
+}
+
+/* To avoid duplicate copies (and copies
+   where parts have been acked) */
+if(TCP_SKB_CB(skb)-&gt;seq &lt;= (TCP_SKB_CB(prev_skb)-&gt;end_seq - ua_data)){
+return -1;
+}
+
+/*SYN's are holy*/
+if(TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_SYN || TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_FIN){
+return -1;
+}
+
+/* Copy linear data */
+if(uad_head &gt; 0){
+
+/* Add required space to the header. Can't use put due to linearity */
+old_headlen = skb_headlen(skb);
+skb-&gt;tail += uad_head;
+skb-&gt;len += uad_head;
+
+if(skb_headlen(skb) &gt; 0){
+memmove(skb-&gt;data + uad_head, skb-&gt;data, old_headlen);
+}
+
+skb_copy_to_linear_data(skb, prev_skb-&gt;data + (skb_headlen(prev_skb) - uad_head), uad_head);
+}
+
+/*Copy paged data*/
+if(uad_frags &gt; 0){
+int i = 0;
+/*Must move data backwards in the array.*/
+if(skb_is_nonlinear(skb)){
+memmove(skb_shinfo(skb)-&gt;frags + ua_nr_frags,
+skb_shinfo(skb)-&gt;frags,
+skb_shinfo(skb)-&gt;nr_frags*sizeof(skb_frag_t));
+}
+
+/*Copy info and update pages*/
+memcpy(skb_shinfo(skb)-&gt;frags,
+       skb_shinfo(prev_skb)-&gt;frags + (skb_shinfo(prev_skb)-&gt;nr_frags - ua_nr_frags),
+       ua_nr_frags*sizeof(skb_frag_t));
+
+for(i=0; i&lt;ua_nr_frags;i++){
+get_page(skb_shinfo(skb)-&gt;frags[i].page);
+}
+
+skb_shinfo(skb)-&gt;nr_frags += ua_nr_frags;
+skb-&gt;data_len += uad_frags;
+skb-&gt;len += uad_frags;
+}
+
+TCP_SKB_CB(skb)-&gt;seq = TCP_SKB_CB(prev_skb)-&gt;end_seq - ua_data;
+
+if(skb-&gt;ip_summed == CHECKSUM_PARTIAL)
+skb-&gt;csum = CHECKSUM_PARTIAL;
+else
+skb-&gt;csum = skb_checksum(skb, 0, skb-&gt;len, 0);
+}
+
+return 1;
+}
+
 int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 size_t size)
 {
&lt; at &gt;&lt; at &gt; -825,6 +990,16 &lt; at &gt;&lt; at &gt;
 
 from += copy;
 copied += copy;
+
+/* Added at Simula to support RDB */
+if(((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb)) &amp;&amp; skb-&gt;len &lt; mss_now){
+if(skb-&gt;prev != (struct sk_buff*) &amp;(sk)-&gt;sk_write_queue
+   &amp;&amp; !(TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_SYN)
+   &amp;&amp; !(TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_FIN)){
+tcp_trans_merge_prev(sk, skb, mss_now);
+}
+} /* End - Simula */
+
 if ((seglen -= copy) == 0 &amp;&amp; iovlen == 0)
 goto out;
 
&lt; at &gt;&lt; at &gt; -1870,7 +2045,25 &lt; at &gt;&lt; at &gt;
 tcp_push_pending_frames(sk);
 }
 break;
-
+
+        /* Added &lt; at &gt; Simula. Support for thin streams */
+case TCP_THIN_RDB:
+if(val)
+tp-&gt;thin_rdb = 1;
+break;
+
+        /* Added &lt; at &gt; Simula. Support for thin streams */
+case TCP_THIN_RM_EXPB:
+if(val)
+tp-&gt;thin_rm_expb = 1;
+break;
+
+        /* Added &lt; at &gt; Simula. Support for thin streams */
+case TCP_THIN_DUPACK:
+if(val)
+tp-&gt;thin_dupack = 1;
+break;
+
 case TCP_KEEPIDLE:
 if (val &lt; 1 || val &gt; MAX_TCP_KEEPIDLE)
 err = -EINVAL;
diff -Nur linux-2.6.23.8.vanilla/net/ipv4/tcp_input.c linux-2.6.23.8-tcp-thin/net/ipv4/tcp_input.c
--- linux-2.6.23.8.vanilla/net/ipv4/tcp_input.c2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/net/ipv4/tcp_input.c2008-07-03 11:57:08.000000000 +0200
&lt; at &gt;&lt; at &gt; -89,6 +89,9 &lt; at &gt;&lt; at &gt;
 int sysctl_tcp_frto_response __read_mostly;
 int sysctl_tcp_nometrics_save __read_mostly;
 
+/* Added &lt; at &gt; Simula */
+int sysctl_tcp_force_thin_dupack __read_mostly = TCP_FORCE_THIN_DUPACK;
+
 int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
 int sysctl_tcp_abc __read_mostly;
 
&lt; at &gt;&lt; at &gt; -1709,6 +1712,12 &lt; at &gt;&lt; at &gt;
  */
 return 1;
 }
+
+/*Added at Simula to modify fast retransmit */
+if ((tp-&gt;thin_dupack || sysctl_tcp_force_thin_dupack) &amp;&amp;
+    tcp_fackets_out(tp) &gt; 1 &amp;&amp; tcp_stream_is_thin(tp)){
+  return 1;
+}
 
 return 0;
 }
&lt; at &gt;&lt; at &gt; -2442,30 +2451,127 &lt; at &gt;&lt; at &gt;
 {
 struct tcp_sock *tp = tcp_sk(sk);
 const struct inet_connection_sock *icsk = inet_csk(sk);
-struct sk_buff *skb;
+struct sk_buff *skb = tcp_write_queue_head(sk);
+struct sk_buff *next_skb;
+
 __u32 now = tcp_time_stamp;
 int acked = 0;
 int prior_packets = tp-&gt;packets_out;
+
+/*Added at Simula for RDB support*/
+__u8 done = 0;
+int remove = 0;
+int remove_head = 0;
+int remove_frags = 0;
+int no_frags;
+int data_frags;
+int i;
+
 __s32 seq_rtt = -1;
 ktime_t last_ackt = net_invalid_timestamp();
-
-while ((skb = tcp_write_queue_head(sk)) &amp;&amp;
-       skb != tcp_send_head(sk)) {
+
+while (skb != NULL 
+       &amp;&amp; ((!(tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb) 
+    &amp;&amp; skb != tcp_send_head(sk) 
+    &amp;&amp; skb != (struct sk_buff *)&amp;sk-&gt;sk_write_queue) 
+   || ((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb) 
+       &amp;&amp; skb != (struct sk_buff *)&amp;sk-&gt;sk_write_queue))){
 struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
 __u8 sacked = scb-&gt;sacked;
-
+
+if(skb == NULL){
+break;
+}
+
+if(skb == tcp_send_head(sk)){
+break;
+}
+
+if(skb == (struct sk_buff *)&amp;sk-&gt;sk_write_queue){
+break;
+}
+
 /* If our packet is before the ack sequence we can
  * discard it as it's confirmed to have arrived at
  * the other end.
  */
 if (after(scb-&gt;end_seq, tp-&gt;snd_una)) {
-if (tcp_skb_pcount(skb) &gt; 1 &amp;&amp;
-    after(tp-&gt;snd_una, scb-&gt;seq))
-acked |= tcp_tso_acked(sk, skb,
-       now, &amp;seq_rtt);
-break;
+if (tcp_skb_pcount(skb) &gt; 1 &amp;&amp; after(tp-&gt;snd_una, scb-&gt;seq))
+acked |= tcp_tso_acked(sk, skb, now, &amp;seq_rtt);
+
+done = 1;
+
+/* Added at Simula for RDB support*/
+if ((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb) &amp;&amp; after(tp-&gt;snd_una, scb-&gt;seq)) {
+if (!skb_cloned(skb) &amp;&amp; !(scb-&gt;flags &amp; TCPCB_FLAG_SYN)){
+remove = tp-&gt;snd_una - scb-&gt;seq;
+remove_head = (remove &gt; skb_headlen(skb) ? 
+       skb_headlen(skb) : remove);
+remove_frags = (remove &gt; skb_headlen(skb) ? 
+remove - remove_head : 0);
+
+/* Has linear data */
+if(skb_headlen(skb) &gt; 0 &amp;&amp; remove_head &gt; 0){
+memmove(skb-&gt;data,
+skb-&gt;data + remove_head,
+skb_headlen(skb) - remove_head);
+
+skb-&gt;tail -= remove_head;
+}
+
+if(skb_is_nonlinear(skb) &amp;&amp; remove_frags &gt; 0){
+no_frags = 0;
+data_frags = 0;
+
+/*Remove unecessary pages*/
+for(i=0; i&lt;skb_shinfo(skb)-&gt;nr_frags; i++){
+if(data_frags + skb_shinfo(skb)-&gt;frags[i].size 
+   == remove_frags){
+put_page(skb_shinfo(skb)-&gt;frags[i].page);
+no_frags += 1;
+break;
+}
+put_page(skb_shinfo(skb)-&gt;frags[i].page);
+no_frags += 1;
+data_frags += skb_shinfo(skb)-&gt;frags[i].size;
+}
+
+if(skb_shinfo(skb)-&gt;nr_frags &gt; no_frags)
+memmove(skb_shinfo(skb)-&gt;frags,
+skb_shinfo(skb)-&gt;frags + no_frags,
+(skb_shinfo(skb)-&gt;nr_frags 
+ - no_frags)*sizeof(skb_frag_t));
+
+skb-&gt;data_len -= remove_frags;
+skb_shinfo(skb)-&gt;nr_frags -= no_frags;
+
+}
+
+scb-&gt;seq += remove;
+skb-&gt;len -= remove;
+
+if(skb-&gt;ip_summed == CHECKSUM_PARTIAL)
+skb-&gt;csum = CHECKSUM_PARTIAL;
+else
+skb-&gt;csum = skb_checksum(skb, 0, skb-&gt;len, 0);
+
+}
+
+/*Only move forward if data could be removed from this packet*/
+done = 2;
+
+}
+
+if(done == 1 || tcp_skb_is_last(sk,skb)){
+break;
+} else if(done == 2){
+skb = skb-&gt;next;
+done = 1;
+continue;
+}
+
 }
-
+
 /* Initial outgoing SYN's get put onto the write_queue
  * just like anything else we transmit.  It is not
  * true data, and if we misinform our callers that
&lt; at &gt;&lt; at &gt; -2479,14 +2585,14 &lt; at &gt;&lt; at &gt;
 acked |= FLAG_SYN_ACKED;
 tp-&gt;retrans_stamp = 0;
 }
-
+
 /* MTU probing checks */
 if (icsk-&gt;icsk_mtup.probe_size) {
 if (!after(tp-&gt;mtu_probe.probe_seq_end, TCP_SKB_CB(skb)-&gt;end_seq)) {
 tcp_mtup_probe_success(sk, skb);
 }
 }
-
+
 if (sacked) {
 if (sacked &amp; TCPCB_RETRANS) {
 if (sacked &amp; TCPCB_SACKED_RETRANS)
&lt; at &gt;&lt; at &gt; -2510,24 +2616,32 &lt; at &gt;&lt; at &gt;
 seq_rtt = now - scb-&gt;when;
 last_ackt = skb-&gt;tstamp;
 }
+
+if ((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb) &amp;&amp; skb == tcp_send_head(sk)) {
+tcp_advance_send_head(sk, skb);
+}
+
 tcp_dec_pcount_approx(&amp;tp-&gt;fackets_out, skb);
 tcp_packets_out_dec(tp, skb);
+next_skb = skb-&gt;next;
 tcp_unlink_write_queue(skb, sk);
 sk_stream_free_skb(sk, skb);
 clear_all_retrans_hints(tp);
+/* Added at Simula to support RDB */
+skb = next_skb;
 }
-
+
 if (acked&amp;FLAG_ACKED) {
 u32 pkts_acked = prior_packets - tp-&gt;packets_out;
 const struct tcp_congestion_ops *ca_ops
 = inet_csk(sk)-&gt;icsk_ca_ops;
-
+
 tcp_ack_update_rtt(sk, acked, seq_rtt);
 tcp_ack_packets_out(sk);
-
+
 if (ca_ops-&gt;pkts_acked) {
 s32 rtt_us = -1;
-
+
 /* Is the ACK triggering packet unambiguous? */
 if (!(acked &amp; FLAG_RETRANS_DATA_ACKED)) {
 /* High resolution needed and available? */
diff -Nur linux-2.6.23.8.vanilla/net/ipv4/tcp_output.c linux-2.6.23.8-tcp-thin/net/ipv4/tcp_output.c
--- linux-2.6.23.8.vanilla/net/ipv4/tcp_output.c2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/net/ipv4/tcp_output.c2008-07-03 11:55:45.000000000 +0200
&lt; at &gt;&lt; at &gt; -1653,7 +1653,7 &lt; at &gt;&lt; at &gt;
 
 BUG_ON(tcp_skb_pcount(skb) != 1 ||
        tcp_skb_pcount(next_skb) != 1);
-
+
 /* changing transmit queue under us so clear hints */
 clear_all_retrans_hints(tp);
 
&lt; at &gt;&lt; at &gt; -1702,6 +1702,166 &lt; at &gt;&lt; at &gt;
 }
 }
 
+/* Added at Simula. Variation of the regular collapse,
+   adapted to support RDB  */
+static void tcp_retrans_merge_redundant(struct sock *sk,
+struct sk_buff *skb,
+int mss_now)
+{
+struct tcp_sock *tp = tcp_sk(sk);
+struct sk_buff *next_skb = skb-&gt;next;
+int skb_size = skb-&gt;len;
+int new_data = 0;
+int new_data_head = 0;
+int new_data_frags = 0;
+int new_frags = 0;
+int old_headlen = 0;
+
+int i;
+int data_frags = 0;
+
+/* Loop through as many packets as possible
+ * (will create a lot of redundant data, but WHATEVER).
+ * The only packet this MIGHT be critical for is
+ * if this packet is the last in the retrans-queue.
+ *
+ * Make sure that the first skb isnt already in
+ * use by somebody else. */
+
+if (!skb_cloned(skb)) {
+/* Iterate through the retransmit queue */
+for (; (next_skb != (sk)-&gt;sk_send_head) &amp;&amp; 
+     (next_skb != (struct sk_buff *) &amp;(sk)-&gt;sk_write_queue); 
+     next_skb = next_skb-&gt;next) {
+
+/* Reset variables */
+new_frags = 0;
+data_frags = 0;
+new_data = TCP_SKB_CB(next_skb)-&gt;end_seq - TCP_SKB_CB(skb)-&gt;end_seq;
+
+/* New data will be stored at skb-&gt;start_add + some_offset, 
+   in other words the last N bytes */
+new_data_frags = (new_data &gt; next_skb-&gt;data_len ? 
+  next_skb-&gt;data_len : new_data);
+new_data_head = (new_data &gt; next_skb-&gt;data_len ? 
+ new_data - skb-&gt;data_len : 0);
+
+/*
+ * 1. Contains the same data
+ * 2. Size
+ * 3. Sack
+ * 4. Window
+ * 5. Cannot merge with a later packet that has linear data
+ * 6. The new number of frags will exceed the limit
+ * 7. Enough tailroom
+ */
+
+if(new_data &lt;= 0){
+return;
+}
+
+if ((sysctl_tcp_rdb_max_bundle_bytes == 0 &amp;&amp; ((skb_size + new_data) &gt; mss_now))
+    || (sysctl_tcp_rdb_max_bundle_bytes &gt; 0 &amp;&amp; ((skb_size + new_data) &gt;
+sysctl_tcp_rdb_max_bundle_bytes))){
+return;
+}
+
+if(TCP_SKB_CB(next_skb)-&gt;flags &amp; TCPCB_FLAG_FIN){
+return;
+}
+
+if((TCP_SKB_CB(skb)-&gt;sacked &amp; TCPCB_SACKED_ACKED) ||
+   (TCP_SKB_CB(next_skb)-&gt;sacked &amp; TCPCB_SACKED_ACKED)){
+return;
+}
+
+if(after(TCP_SKB_CB(skb)-&gt;end_seq + new_data, tp-&gt;snd_una + tp-&gt;snd_wnd)){
+return;
+}
+
+if(skb_shinfo(skb)-&gt;frag_list || skb_shinfo(skb)-&gt;frag_list){
+return;
+}
+
+/* Calculate number of new fragments. Any new data will be 
+   stored in the back. */
+if(skb_is_nonlinear(next_skb)){
+i = (skb_shinfo(next_skb)-&gt;nr_frags == 0 ? 
+     0 : skb_shinfo(next_skb)-&gt;nr_frags - 1);
+for( ; i&gt;=0;i--){
+if(data_frags + skb_shinfo(next_skb)-&gt;frags[i].size == 
+   new_data_frags){
+new_frags += 1;
+break;
+}
+
+data_frags += skb_shinfo(next_skb)-&gt;frags[i].size;
+new_frags += 1;
+}
+}
+
+/* If dealing with a fragmented skb, only merge 
+   with an skb that ONLY contain frags */
+if(skb_is_nonlinear(skb)){
+
+/*Due to the way packets are processed, no later data*/
+if(skb_headlen(next_skb) &amp;&amp; new_data_head &gt; 0){
+return;
+}
+
+if(skb_is_nonlinear(next_skb) &amp;&amp; (new_data_frags &gt; 0) &amp;&amp; 
+   ((skb_shinfo(skb)-&gt;nr_frags + new_frags) &gt; MAX_SKB_FRAGS)){
+return;
+}
+
+} else {
+if(skb_headlen(next_skb) &amp;&amp; (new_data_head &gt; (skb-&gt;end - skb-&gt;tail))){
+return;
+}
+}
+
+/*Copy linear data. This will only occur if both are linear, 
+  or only A is linear*/
+if(skb_headlen(next_skb) &amp;&amp; (new_data_head &gt; 0)){
+old_headlen = skb_headlen(skb);
+skb-&gt;tail += new_data_head;
+skb-&gt;len += new_data_head;
+
+/* The new data starts in the linear area, 
+   and the correct offset will then be given by 
+   removing new_data ammount of bytes from length. */
+skb_copy_to_linear_data_offset(skb, old_headlen, next_skb-&gt;tail - 
+       new_data_head, new_data_head);
+}
+
+if(skb_is_nonlinear(next_skb) &amp;&amp; (new_data_frags &gt; 0)){
+memcpy(skb_shinfo(skb)-&gt;frags + skb_shinfo(skb)-&gt;nr_frags, 
+       skb_shinfo(next_skb)-&gt;frags + 
+       (skb_shinfo(next_skb)-&gt;nr_frags - new_frags), 
+       new_frags*sizeof(skb_frag_t));
+
+for(i=skb_shinfo(skb)-&gt;nr_frags; 
+    i &lt; skb_shinfo(skb)-&gt;nr_frags + new_frags; i++)
+get_page(skb_shinfo(skb)-&gt;frags[i].page);
+
+skb_shinfo(skb)-&gt;nr_frags += new_frags;
+skb-&gt;data_len += new_data_frags;
+skb-&gt;len += new_data_frags;
+}
+
+TCP_SKB_CB(skb)-&gt;end_seq += new_data;
+
+if(skb-&gt;ip_summed == CHECKSUM_PARTIAL)
+skb-&gt;csum = CHECKSUM_PARTIAL;
+else
+skb-&gt;csum = skb_checksum(skb, 0, skb-&gt;len, 0);
+
+skb_size = skb-&gt;len;
+}
+
+}
+}
+
 /* Do a simple retransmit without using the backoff mechanisms in
  * tcp_timer. This is used for path mtu discovery.
  * The socket is already locked here.
&lt; at &gt;&lt; at &gt; -1756,6 +1916,8 &lt; at &gt;&lt; at &gt;
 /* This retransmits one SKB.  Policy decisions and retransmit queue
  * state updates are done by the caller.  Returns non-zero if an
  * error occurred which prevented the send.
+ * Modified at Simula to support thin stream optimizations
+ * TODO: Update to use new helpers (like tcp_write_queue_next())
  */
 int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
&lt; at &gt;&lt; at &gt; -1802,10 +1964,21 &lt; at &gt;&lt; at &gt;
     (skb-&gt;len &lt; (cur_mss &gt;&gt; 1)) &amp;&amp;
     (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &amp;&amp;
     (!tcp_skb_is_last(sk, skb)) &amp;&amp;
-    (skb_shinfo(skb)-&gt;nr_frags == 0 &amp;&amp; skb_shinfo(tcp_write_queue_next(sk, skb))-&gt;nr_frags == 0) &amp;&amp;
-    (tcp_skb_pcount(skb) == 1 &amp;&amp; tcp_skb_pcount(tcp_write_queue_next(sk, skb)) == 1) &amp;&amp;
-    (sysctl_tcp_retrans_collapse != 0))
+    (skb_shinfo(skb)-&gt;nr_frags == 0
+     &amp;&amp; skb_shinfo(tcp_write_queue_next(sk, skb))-&gt;nr_frags == 0)
+    &amp;&amp; (tcp_skb_pcount(skb) == 1
+&amp;&amp; tcp_skb_pcount(tcp_write_queue_next(sk, skb)) == 1)
+    &amp;&amp; (sysctl_tcp_retrans_collapse != 0)
+    &amp;&amp; !((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb))) {
 tcp_retrans_try_collapse(sk, skb, cur_mss);
+       } else if ((tp-&gt;thin_rdb || sysctl_tcp_force_thin_rdb)) {
+if (!(TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_SYN) &amp;&amp;
+    !(TCP_SKB_CB(skb)-&gt;flags &amp; TCPCB_FLAG_FIN) &amp;&amp;
+    (skb-&gt;next != tcp_send_head(sk)) &amp;&amp;
+    (skb-&gt;next != (struct sk_buff *) &amp;sk-&gt;sk_write_queue)) {
+tcp_retrans_merge_redundant(sk, skb, cur_mss);
+}
+}
 
 if (inet_csk(sk)-&gt;icsk_af_ops-&gt;rebuild_header(sk))
 return -EHOSTUNREACH; /* Routing failure or similar. */
diff -Nur linux-2.6.23.8.vanilla/net/ipv4/tcp_timer.c linux-2.6.23.8-tcp-thin/net/ipv4/tcp_timer.c
--- linux-2.6.23.8.vanilla/net/ipv4/tcp_timer.c2007-11-16 19:14:27.000000000 +0100
+++ linux-2.6.23.8-tcp-thin/net/ipv4/tcp_timer.c2008-07-02 15:17:38.000000000 +0200
&lt; at &gt;&lt; at &gt; -32,6 +32,9 &lt; at &gt;&lt; at &gt;
 int sysctl_tcp_retries2 __read_mostly = TCP_RETR2;
 int sysctl_tcp_orphan_retries __read_mostly;
 
+/* Added &lt; at &gt; Simula */
+int sysctl_tcp_force_thin_rm_expb __read_mostly = TCP_FORCE_THIN_RM_EXPB;
+
 static void tcp_write_timer(unsigned long);
 static void tcp_delack_timer(unsigned long);
 static void tcp_keepalive_timer (unsigned long data);
&lt; at &gt;&lt; at &gt; -368,13 +371,26 &lt; at &gt;&lt; at &gt;
  */
 icsk-&gt;icsk_backoff++;
 icsk-&gt;icsk_retransmits++;
-
+
 out_reset_timer:
-icsk-&gt;icsk_rto = min(icsk-&gt;icsk_rto &lt;&lt; 1, TCP_RTO_MAX);
+/* Added &lt; at &gt; Simula removal of exponential backoff for thin streams */
+if ((tp-&gt;thin_rm_expb || sysctl_tcp_force_thin_rm_expb) &amp;&amp; tcp_stream_is_thin(tp)) {
+/* Since 'icsk_backoff' is used to reset timer, set to 0
+ * Recalculate 'icsk_rto' as this might be increased if stream oscillates
+ * between thin and thick, thus the old value might already be too high
+ * compared to the value set by 'tcp_set_rto' in tcp_input.c which resets
+ * the rto without backoff. */
+icsk-&gt;icsk_backoff = 0;
+icsk-&gt;icsk_rto = min(((tp-&gt;srtt &gt;&gt; 3) + tp-&gt;rttvar), TCP_RTO_MAX);
+} else {
+/* Use normal backoff */
+icsk-&gt;icsk_rto = min(icsk-&gt;icsk_rto &lt;&lt; 1, TCP_RTO_MAX);
+}
+/* End Simula*/
 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk-&gt;icsk_rto, TCP_RTO_MAX);
 if (icsk-&gt;icsk_retransmits &gt; sysctl_tcp_retries1)
 __sk_dst_reset(sk);
</description>
    <dc:creator>Andreas Petlund</dc:creator>
    <dc:date>2008-11-27T13:39:41</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3672">
    <title>strange getrusage timer problem with rt-kernel</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3672</link>
    <description>I'm testing 2.6.26.6-rt11 (is that the latest?) kernel, using tiotest from tiobench
(http://sourceforge.net/projects/tiobench/), a classic multi-thread IO stress tool,

it reported a strange problem, with:

root:~/tiobench# time ./tiotest -R -d /dev/mapper/dg5-lv2 -t 1 -f 1000 -r 102400
tiotest: tiotest.c:609: add_timer: Assertion end_time-&gt;tv_sec &gt;= start_time-&gt;tv_sec' failed.?

this problem never happened in mainstream kernels.

Regards,

--
Cheng Renquan, Shenzhen, China

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>crquan&lt; at &gt;gmail.com</dc:creator>
    <dc:date>2008-11-26T03:52:28</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3658">
    <title>Strange device behavior on SMP system with CONFIG_PREEMPT_RT patch</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3658</link>
    <description>Hi everybody,
I noticed a strange behavior of my PCI-&gt;RS422 adapter (MOXA CP-132
using mxer kernel module) on SMP x86 system with kernel 2.6.26.6-rt11.
This PCI board has 2 RS422/RS485 ports. When I try to send cyclicaly
some ammount of data more than 16 bytes (it's internal buffer is 16
bytes) from the second port to the first the data is lost at random
iteration. If I try to send from first port to the second everything
works fine no matter which ammount of data I write to the port. It
seems that interrupts get lost.
Can somebody help me with this problem? What can cause such a behavior?

Thanks in advance,
Denis
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Denis Borisevich</dc:creator>
    <dc:date>2008-11-13T10:20:17</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3655">
    <title>config_preempt_RT patch platform support question.</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3655</link>
    <description>
Hi,
I work on a project which delivers low latency audio streaming via a Linux machine. I receive/send audio frames of 4 samples each per network frame (raw Ethernet) so I expect to have a network interrupt each 90 microseconds.
I use Linux 2.6.26.3-rt7 on different platforms; unfortunately we encountered problems such as kernel panics, depend on the platform running...

My questions are:
How can I have more details on the tests which where used to evaluate the platform running the config_preempt_RT (specifically on networking issues)? 
Does Intel Q6600 2.4GHz (quad core) has been tested? Are there known issues?
Does Xeon x5482 3.2GHz (x2 meaning octa core) has been tested? Are there known issues?


Thanks,
Amir.
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Amir Aharon</dc:creator>
    <dc:date>2008-11-12T14:30:45</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3651">
    <title>kernel modules and ftrace</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3651</link>
    <description>Hi list,

when I'm compiling in FTRACE support I get the following output, when I load
the first of a few modules:

-----------------------------------------------------------------------------
[...]
*****************************************************************************
*                                                                           *
*  REMINDER, the following debugging options are turned on in your .config: *
*                                                                           *
*        CONFIG_IRQSOFF_TRACER                                              *
*        CONFIG_FTRACE                                                      *
*                                                                           *
*  they may increase runtime overhead and latencies.                        *
*                                                                           *
*****************************************************************************
[...]
Freeing unused kernel memory: 132k init
[...]
of-gpio-wdt watchdog.1: gpio-watchdog driver started using gpio 211.
------------[ cut here ]------------
Badness at kernel/trace/ftrace.c:632
NIP: c00613a4 LR: c0061288 CTR: 00000000
REGS: c187bea0 TRAP: 0700   Not tainted  (2.6.26.7-rt11-ptx-trunk)
MSR: 00021032 &lt;ME,IR,DR&gt;  CR: 42002042  XER: 20000000
TASK = c1879ad0[19] 'ftraced' THREAD: c187a000
GPR00: 00000001 c187bf50 c1879ad0 00000002 c02d0118 c02b05ac c0053a60 18aaf80f
GPR08: c02d0000 c02d0000 4800015d c187bf50 0aeac2fc 1006d448 c02d0000 00000001
GPR16: 00000003 5b6cf500 c02e0000 c02d0000 c0260000 c0260000 00000001 c00128f0
GPR24: c02dd914 c02d0000 c02b05ac c18590f8 c02d0118 c185b0f8 c306e324 c187bf50
NIP [c00613a4] __ftrace_update_code+0x250/0x2d4
LR [c0061288] __ftrace_update_code+0x134/0x2d4
Call Trace:
[c187bf50] [c0061288] __ftrace_update_code+0x134/0x2d4 (unreliable)
[c187bfa0] [c006081c] ftrace_update_code+0x78/0xa4
[c187bfb0] [c00618f0] ftraced+0xa8/0x1bc
[c187bfd0] [c003d840] kthread+0x58/0x98
[c187bff0] [c0011e14] kernel_thread+0x44/0x60
Instruction dump:
7fc4f378 3875c248 4bfc2769 7fc4f378 38748e08 4bff6081 92d3f1bc 4bfffe54
3d20c02d 80090400 7c000034 5400d97e &lt;0f000000&gt; 2f800000 409e0074 3c60c026
ftrace failed to modify [&lt;c306e324&gt;] of_gpio_wdt_probe+0x8/0x294 [of_gpio_wdt]
 expected: 48:fa:45:cd actual: 48:00:01:5d replace: 60:00:00:00
-----------------------------------------------------------------------------

What does it mean? Anything wrong with my environment or my modules?

BTW: Kernel is 2.6.26-rt11.

Regards,
Juergen

</description>
    <dc:creator>Juergen Beisert</dc:creator>
    <dc:date>2008-11-11T17:56:30</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3649">
    <title>2.6.27.5 RT patch status (26rt11)</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3649</link>
    <description>I've updated from the 2.6.27-rc8 patch series based on 26rt9 to be
based on 2.6.27.5 kernel.org and 26rt11 preempt_rt.

I've done a successful boot to X11 on basic old P4 and it survived a
make -j20 of kernel.org git.  There is still work to be done in order to
stabilize more complex hardware (e.g. SMP etc) -- but I see this still
being the baseline for that 2.6.27.x based work.

The trees are where they were before, with the individual patches at:

git://opensource1.windriver.com/people/paulg/rt/patches

and the fully patched 2.6.27.5 git tree can be had from here:

git://opensource1.windriver.com/people/paulg/rt/linux-2.6

Note the patched tree is on the branch v2.6.27.5-26rt11 and that
master is just kernel.org master.

The patched trees are just the result of applying all the patches with
guilt, and so for those interested in the details of what changed in the
patches, looking at the patch repo is probably the most educational, i.e:

git whatchanged v2.6.27-rc8-26rt9..v2.6.27.5-26rt11

There are gitweb links too:

http://opensource1.windriver.com/gitweb/gitweb.cgi?p=people/paulg/rt/patches

http://opensource1.windriver.com/gitweb/gitweb.cgi?p=people/paulg/rt/linux-2.6

Both the patches repo and the pre-patched trees have some itermediary
branches as well, (rt9, rt10, 2.6.27.0, etc.)

Paul.
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Paul Gortmaker</dc:creator>
    <dc:date>2008-11-10T23:47:40</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3644">
    <title>[PATCH][RT] Trivial: Correctly dereference when clearing unusedvariable</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3644</link>
    <description>

From: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;
Subject:  Correctly dereference flags when clearing unused variable.

Its probably unsafe to set the flags pointer to 0, since this will oops,
if it is dereferenced elsewhere for some odd reason. 

Signed-off-by: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;

---
 mm/page_alloc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
&lt; at &gt;&lt; at &gt; -170,7 +170,7 &lt; at &gt;&lt; at &gt; static inline void __lock_cpu_pcp(unsign
 {
 #ifdef CONFIG_PREEMPT_RT
 spin_lock(&amp;__get_cpu_lock(pcp_locks, cpu));
-flags = 0;
+*flags = 0;
 #else
 local_irq_save(*flags);
 #endif
&lt; at &gt;&lt; at &gt; -180,7 +180,7 &lt; at &gt;&lt; at &gt; static inline void lock_cpu_pcp(unsigned
 {
 #ifdef CONFIG_PREEMPT_RT
 (void)get_cpu_var_locked(pcp_locks, this_cpu);
-flags = 0;
+*flags = 0;
 #else
 local_irq_save(*flags);
 *this_cpu = smp_processor_id();


--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Sven-Thorsten Dietrich</dc:creator>
    <dc:date>2008-11-07T21:19:42</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3642">
    <title>[PATCH][RT] Dereference pointer to cpu id, not to address of CPUID</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3642</link>
    <description>This patch applies to 2.6.25-rt, 2.6.26-rt and 2.6.27-rt


From: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;
Subject: Dereference pointer to cpu id, when evaluating condition.

Without dereferencing, the condition always evaluates to true.

Signed-off-by: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;
---
 mm/slab.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/mm/slab.c
+++ b/mm/slab.c
&lt; at &gt;&lt; at &gt; -2033,7 +2033,7 &lt; at &gt;&lt; at &gt; slab_destroy(struct kmem_cache *cachep,
 } else {
 kmem_freepages(cachep, addr);
 if (OFF_SLAB(cachep)) {
-if (this_cpu)
+if (*this_cpu)
 __cache_free(cachep-&gt;slabp_cache, slabp, this_cpu);
 else
 kmem_cache_free(cachep-&gt;slabp_cache, slabp);


--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Sven-Thorsten Dietrich</dc:creator>
    <dc:date>2008-11-07T21:13:27</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3639">
    <title>2.6.26.6-rt11  nanosleep() does have accurate behavior</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3639</link>
    <description>I recently started to study how nanosleep() behaves under 2.6.26.6-rt11 compiled in in FULL PREEMPT, uniprocessor mode. 
  I find that between 2.6.20-rt8 and this new kernel something has changed and nanosleep() is back to its old behavior 
or sleeping for next higher number of msec rather than carefully following the "y=x" line.

I don't follow the RT world closely enough, but is this a regression or an expected change in behavior? The link below 
show the results very clearly.

http://www.atl.external.lmco.com/projects/QoS/documents/nanosleep_1.png

Gautam
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Gautam Thaker</dc:creator>
    <dc:date>2008-11-07T15:56:02</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3629">
    <title>nohz=off</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3629</link>
    <description>Hi, 
When I have to boot with nohz=off , this could be a problem with rt
isn't it ? 
Who I could debug this problem ? 
This is a laptop with linux x86_64 ( I had try fedora 10 beta ) and
others kernel like 2.6.22 and 2.6.24 .

Can you point me some documentation about nohz=off , 
I try search a bit but don't found anything interesting.

Thanks,  
</description>
    <dc:creator>Sergio Monteiro Basto</dc:creator>
    <dc:date>2008-11-03T16:27:23</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3628">
    <title>Trouble compiling 2.6.26.6-rt11 for ARM</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3628</link>
    <description>Hello,

I am trying to compile 2.6.26.6-rt11 for an ARM-based board using
AT91RM9200,
but get the following error message when I compile:

  LD      .tmp_vmlinux1
kernel/built-in.o(.text+0xdf08): In function `$a':
: undefined reference to `wrong_size_cmpxchg'
kernel/built-in.o(.text+0xe05c): In function `$a':
: undefined reference to `wrong_size_cmpxchg'
kernel/built-in.o(.text+0xe32c): In function `$a':
: undefined reference to `wrong_size_cmpxchg'
make: *** [.tmp_vmlinux1] Error 1

I get the message both using my custom board and the EK-board from Atmel.
The cross-compiler is version 3.4.1.

Any ideas of what has gone wrong?


Best ragards,
Bo Hansen




</description>
    <dc:creator>Bo Hansen</dc:creator>
    <dc:date>2008-11-03T15:02:56</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3625">
    <title>rt-tests version 0.28 available</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3625</link>
    <description>-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

All,

The latest version of rt-tests (cyclictest, signaltest, pi_stress) is available at:

http://www.kernel.org/pub/linux//kernel/people/clrkwllms/rt-tests/rt-tests-0.28.tar.gz

as either a gziped or bziped tarball. This version has two new options added:

--histogramwhich dumps a histogram of latencies after the run
--duration which allows the run to be of a specific duration

Thanks to Sven for the very useful histogram code!

If you prefer, you can access the git tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git

Summary of git commits:

Clark Williams (3):
  add option to run for specified duration
  changed release target in Makefile
  told git to ignore tarballs and tmpdir

Sven-Thorsten Dietrich (1):
  Subject: Add histogram support to cyclictest

 .gitignore                  |    4 +-
 Makefile                    |    6 +-
 src/cyclictest/cyclictest.8 |   11 +++-
 src/cyclictest/cyclictest.c |  128 +++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 138 insertions(+), 11 deletions(-)


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEYEARECAAYFAkj/i54ACgkQHyuj/+TTEp3djwCfU1l91jtcU2O3PyA80E3fNhC/
ba4An2Mm8UKFaeAYxDUH5raWoOsFJNYt
=wMct
-----END PGP SIGNATURE-----
</description>
    <dc:creator>Clark Williams</dc:creator>
    <dc:date>2008-10-22T20:22:49</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3623">
    <title>[PATCH 2/2] netrate - network rate/rtt measurement utility</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3623</link>
    <description>-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


- From 1ecdeb7f48302a2ea8a37fd8aecd90081637e0dc Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Thu, 2 Oct 2008 17:26:05 -0500
Subject: [PATCH] consolidate into common

consolidated both rtt and transmit to use same socket setup function; added exchange code and daemon mode; removed --server and --receive; added versioning

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 common.c   |   82 +++++++++++++++++++++++++++++++++
 main.c     |  146 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 netrate.h  |   28 +++++++++---
 receive.c  |   71 +-----------------------------
 rtt.c      |   51 +--------------------
 server.c   |   74 +------------------------------
 transmit.c |   50 +--------------------
 7 files changed, 237 insertions(+), 265 deletions(-)

diff --git a/common.c b/common.c
index 48cd4e9..8ed0590 100644
- --- a/common.c
+++ b/common.c
&lt; at &gt;&lt; at &gt; -433,3 +433,85 &lt; at &gt;&lt; at &gt; free_histogram(struct histogram *h)
 free(h);
 }
 
+/*
+ ***********************************************************************
+ * socket stuff
+ ***********************************************************************
+ */
+
+int
+netrate_tx_socket(int protocol, int port, int request)
+{
+int ret;
+int sock;
+int val;
+char portstring[10];
+struct addrinfo *ai, hints;
+struct netrate_exchange ex;
+
+memset(&amp;hints, 0, sizeof(hints));
+hints.ai_flags = AI_CANONNAME;
+hints.ai_family = AF_INET;
+hints.ai_socktype = type;
+hints.ai_protocol = protocol;
+sprintf(portstring, "%d", port);
+
+ret = getaddrinfo(hostname, portstring, &amp;hints, &amp;ai);
+if (ret) {
+fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+return -ret;
+}
+
+sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
+if (sock &lt; 0) {
+perror("transmit socket()");
+return -(errno);
+}
+
+dprintf("calling connect\n");
+if (connect(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen) &lt; 0) {
+perror("connect");
+close(sock);
+return -(errno);
+}
+
+freeaddrinfo(ai);
+
+if (protocol == IPPROTO_TCP &amp;&amp; nodelay == TRUE) {
+/* set TCP_NODELAY */
+dprintf("setting TCP_NODELAY\n");
+val = 1;
+if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &amp;val, sizeof(val)) &lt; 0) {
+perror("setsockopt");
+ret = -errno;
+close(sock);
+return ret;
+}
+}
+memset(&amp;ex, 0, sizeof(ex));
+ex.major = MAJOR;
+ex.minor = MINOR;
+ex.request = request;
+ex.size = size;
+ret = write(sock, (void *) &amp;ex, sizeof(ex));
+if (ret &lt; 0) {
+fprintf(stderr, "Error sending exchange request: %s\n", strerror(errno));
+ret = -errno;
+close(sock);
+return ret;
+}
+ret = read(sock, (void *) &amp;ex, sizeof(ex));
+if (ret &lt; 0) {
+fprintf(stderr, "Error reading exchange ack: %s\n", strerror(errno));
+ret = -errno;
+close(sock);
+return ret;
+}
+if (ex.request != REQUEST_ACK) {
+fprintf(stderr, "Exchange ack not valid: %x\n", ex.request);
+ret = -errno;
+close(sock);
+return ret;
+}
+return sock;
+}
diff --git a/main.c b/main.c
index 838642c..a13f7f6 100644
- --- a/main.c
+++ b/main.c
&lt; at &gt;&lt; at &gt; -54,10 +54,9 &lt; at &gt;&lt; at &gt; char hostname[1024];/* host to connect to */
 static void interrupt(int sig);
 
 static struct option long_options[] = {
- -{"receive", 0, 0, RX},
 {"transmit", 0, 0, TX},
- -{"server", 0, 0, SERVER},
 {"rtt", 0, 0, RTT},
+{"daemon", 0, 0, DAEMON},
 {"rate", 1, 0, RATE},
 {"size", 1, 0, SIZE},
 {"tcp", 0, 0, TCP},
&lt; at &gt;&lt; at &gt; -75,7 +74,7 &lt; at &gt;&lt; at &gt; static struct option long_options[] = {
 
 void usage(void)
 {
- -fprintf(stderr, "usage: netrate {--transmit|--receive|--server|--rtt} [options]\n");
+fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n");
 fprintf(stderr, "   where options are:\n");
 fprintf(stderr, "        --rate=&lt;Inter-Packet Interval&gt;\n");
 fprintf(stderr, "        --size=&lt;packet size&gt;\n");
&lt; at &gt;&lt; at &gt; -92,6 +91,126 &lt; at &gt;&lt; at &gt; void usage(void)
 }
 
 
+int
+netrate_rx_socket(int protocol, int type)
+{
+int ret;
+int sock;
+char portstring[10];
+struct addrinfo hints, *ai;
+
+memset(&amp;hints, 0, sizeof(hints));
+hints.ai_flags = AI_PASSIVE;
+hints.ai_family = AF_INET;
+hints.ai_socktype = type;
+hints.ai_protocol = protocol;
+sprintf(portstring, "%d", port);
+
+dprintf("calling getaddrinfo\n");
+ret = getaddrinfo(NULL, portstring, &amp;hints, &amp;ai);
+if (ret) {
+fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+return -ret;
+}
+
+dprintf("calling socket\n");
+sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
+if (sock &lt; 0) {
+perror ("receive socket()");
+return -(errno);
+}
+
+dprintf("calling accept\n");
+ret = bind(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen);
+if (ret &lt; 0) {
+perror("bind");
+return -(errno);
+}
+
+if (protocol == IPPROTO_TCP) {
+dprintf("calling listen\n");
+ret = listen(sock, SOMAXCONN);
+if (ret &lt; 0) {
+perror("listen()");
+return -(errno);
+}
+}
+return sock;
+}
+
+int
+netrate_daemon(void)
+{
+int ret;
+int servsock, sock;
+socklen_t clientlen;
+struct sockaddr_in client;
+struct netrate_exchange ex, ack;
+
+dprintf("netrate_daemon: starting\n");
+servsock = netrate_rx_socket(protocol, type);
+
+if (protocol == IPPROTO_TCP) {
+dprintf("calling accept\n");
+sock = accept(servsock, (struct sockaddr *)&amp;client, &amp;clientlen);
+if (sock &lt; 0) {
+fprintf(stderr, "error from accept: %s\n", strerror(errno));
+close(servsock);
+exit(-1);
+}
+close(servsock);
+dprintf("out of accept\n");
+}
+else
+sock = servsock;
+
+dprintf("calling read for exchange\n");
+ret = read(sock, &amp;ex, sizeof(ex));
+if (ret &lt; 0) {
+fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+close(sock);
+exit(-2);
+}
+dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n",
+ex.major, ex.minor, ex.request, ex.size);
+
+if (ex.major != MAJOR || ex.minor != MINOR) {
+fprintf(stderr, "protocol mismatch us: (%d, %d), them:(%d, %d)\n",
+MAJOR, MINOR, ex.major, ex.minor);
+close(sock);
+exit(-3);
+}
+
+size = ex.size;
+
+ack = ex;
+ack.request = REQUEST_ACK;
+
+dprintf("ACK'ing exchange\n");
+ret = write(sock, &amp;ack, sizeof(ack));
+if (ret &lt; 0) {
+fprintf(stderr, "error acknowledging exchange request: %s\n",
+strerror(errno));
+close(sock);
+exit(-4);
+}
+
+switch (ex.request) {
+
+case SERVER:
+dprintf("calling netrate_server()\n");
+return netrate_server(sock);
+
+case RX:
+dprintf("calling netrate_receive()\n");
+return netrate_receive(sock);
+}
+fprintf(stderr, "Unknown exchange request: %d\n", ex.request);
+close(sock);
+return -1;
+}
+
+
 int main(int argc, char **argv)
 {
 int ret;
&lt; at &gt;&lt; at &gt; -107,18 +226,14 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 break;
 
 switch(opt) {
- -case RX:
- -role = RX;
- -dprintf("role == RX\n");
+case DAEMON:
+role = DAEMON;
+dprintf("role == DAEMON\n");
 break;
 case TX:
 role = TX;
 dprintf("role == TX\n");
 break;
- -case SERVER:
- -role = SERVER;
- -dprintf("role == SERVER\n");
- -break;
 case RTT:
 role = RTT;
 dprintf("role == RTT\n");
&lt; at &gt;&lt; at &gt; -193,8 +308,8 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 }
 }
 if (role == 0) {
- -fprintf(stderr, "Must specifiy either --transmit or "
- -"--receive options!\n");
+fprintf(stderr, "Must specifiy either --transmit, --daemon or "
+"--rtt options!\n");
 exit(-1);
 }
 
&lt; at &gt;&lt; at &gt; -218,11 +333,8 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 case TX:
 exit_val = netrate_transmit();
 break;
- -case RX:
- -exit_val = netrate_receive();
- -break;
- -case SERVER:
- -exit_val = netrate_server();
+case DAEMON:
+exit_val = netrate_daemon();
 break;
 case RTT:
 exit_val = netrate_rtt();
diff --git a/netrate.h b/netrate.h
index a0f79b5..c2aaba8 100644
- --- a/netrate.h
+++ b/netrate.h
&lt; at &gt;&lt; at &gt; -22,12 +22,18 &lt; at &gt;&lt; at &gt;
 #ifndef __NETRATE_H__
 #define __NETRATE_H__
 
+#define MAJOR 0
+#define MINOR 3
+
 #define TRUE  1
 #define FALSE 0
 
- -enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
- -      MULTI, PORT, HOST, DEBUG, HELP,
- -      SERVER, RTT, NODELAY, HISTOGRAM};
+enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
+       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
+       SERVER, RTT, NODELAY, HISTOGRAM,
+       NUM_OPT_VALS,
+};
+
 
 #define NS_PER_SEC1000000000
 #define US_PER_SEC1000000
&lt; at &gt;&lt; at &gt; -48,6 +54,16 &lt; at &gt;&lt; at &gt; enum optvals {RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define MAX_BUF_SIZE8192
 #define NETRATE_MSG_DATA 0xa5
 
+#include &lt;linux/types.h&gt;
+struct netrate_exchange {
+__u16 major;
+__u16 minor;
+__u16 request;
+__u16 size;
+};
+
+#define REQUEST_ACK0xffff
+
 struct netrate_message {
 unsigned long msg_len;/* message length (including header) */
 unsigned long msg_seq;/* sequence number */
&lt; at &gt;&lt; at &gt; -55,7 +71,6 &lt; at &gt;&lt; at &gt; struct netrate_message {
 char msg_data[]; /* body of message */
 };
 
- -
 extern int protocol;
 extern int type;
 extern int nodelay;
&lt; at &gt;&lt; at &gt; -70,9 +85,10 &lt; at &gt;&lt; at &gt; extern int interrupted;
 extern jmp_buf jmpbuf;
 
 int netrate_transmit(void);
- -int netrate_receive(void);
+int netrate_receive(int sock);
 int netrate_rtt(void);
- -int netrate_server(void);
+int netrate_server(int sock);
+int netrate_tx_socket(int protocol, int port, int request);
 void stop_execution(void);
 void dprintf(char *, ...);
 
diff --git a/receive.c b/receive.c
index ac145d5..b9a255a 100644
- --- a/receive.c
+++ b/receive.c
&lt; at &gt;&lt; at &gt; -36,60 +36,13 &lt; at &gt;&lt; at &gt;
  
 static struct statistics *stats;
 
- -static int
- -netrate_rx_socket(int protocol, int port, int multicast)
- -{
- -int ret;
- -int sock;
- -char portstring[10];
- -struct addrinfo hints, *ai;
- -
- -memset(&amp;hints, 0, sizeof(hints));
- -hints.ai_flags = AI_PASSIVE;
- -hints.ai_family = AF_INET;
- -hints.ai_socktype = type;
- -hints.ai_protocol = protocol;
- -sprintf(portstring, "%d", port);
- -
- -ret = getaddrinfo(NULL, portstring, &amp;hints, &amp;ai);
- -if (ret) {
- -fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -return -ret;
- -}
- -
- -sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
- -if (sock &lt; 0) {
- -perror ("receive socket()");
- -return -(errno);
- -}
- -
- -ret = bind(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen);
- -if (ret &lt; 0) {
- -perror("bind");
- -return -(errno);
- -}
- -
- -if (protocol == IPPROTO_TCP) {
- -ret = listen(sock, SOMAXCONN);
- -if (ret &lt; 0) {
- -perror("listen()");
- -return -(errno);
- -}
- -}
- -return sock;
- -}
- -
- -
 /*
  * main receiver routine
  */
 int
- -netrate_receive(void)
+netrate_receive(int consock)
 {
 int ret;
- -int servsock, consock;
- -socklen_t socklen;
- -struct sockaddr_in client;
 void *ptr;
 struct netrate_message *msg;
 long status;
&lt; at &gt;&lt; at &gt; -101,28 +54,6 &lt; at &gt;&lt; at &gt; netrate_receive(void)
 /* set up our ring buffers */
 r = setup_ring_buffers(10, bufsize);
 
- -/* setup a socket */
- -servsock = netrate_rx_socket(protocol, port, multicast);
- -if (servsock &lt; 0) {
- -perror("setting up recieve socket");
- -return servsock;
- -}
- -
- -/* if we're doing TCP, call accept */
- -if (protocol == IPPROTO_TCP) {
- -dprintf("calling accept\n");
- -consock = accept(servsock, (struct sockaddr *)&amp;client, &amp;socklen);
- -if (consock &lt; 0) {
- -perror("accept");
- -close(servsock);
- -return consock;
- -}
- -close(servsock);
- -dprintf("connection started\n");
- -}
- -else {
- -consock = servsock;
- -}
 
 /* allocate statistics space */
 stats = setup_statistics(MSEC);
diff --git a/rtt.c b/rtt.c
index 067d282..264a9a6 100644
- --- a/rtt.c
+++ b/rtt.c
&lt; at &gt;&lt; at &gt; -44,54 +44,6 &lt; at &gt;&lt; at &gt; static int stop_running = FALSE;
 
 static struct statistics *stats;
 
- -static int
- -setup_socket(int protocol, int port, int multicast)
- -{
- -int ret;
- -int val;
- -char portstring[10];
- -struct addrinfo hints, *ai;
- -
- -memset(&amp;hints, 0, sizeof(hints));
- -hints.ai_flags = AI_CANONNAME;
- -hints.ai_family = AF_INET;
- -hints.ai_socktype = type;
- -hints.ai_protocol = protocol;
- -sprintf(portstring, "%d", port);
- -       
- -ret = getaddrinfo(hostname, portstring, &amp;hints, &amp;ai);
- -if (ret) {
- -fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -return -ret;
- -}
- -
- -sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
- -if (sock &lt; 0) {
- -perror("transmit socket()");
- -return -(errno);
- -}
- -
- -dprintf("calling connect\n");
- -if (connect(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen) &lt; 0) {
- -perror("connect");
- -close(sock);
- -return -(errno);
- -}
- -
- -freeaddrinfo(ai);
- -
- -if (protocol == IPPROTO_TCP &amp;&amp; nodelay == TRUE) {
- -/* set TCP_NODELAY */
- -dprintf("setting TCP_NODELAY\n");
- -val = 1;
- -if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &amp;val, sizeof(val)) &lt; 0) {
- -perror("setsockopt");
- -close(sock);
- -return -(errno);
- -}
- -}
- -return sock;
- -}
 
 static void
 setup_buffers(struct ring_buffer **txring, struct ring_buffer **rxring)
&lt; at &gt;&lt; at &gt; -221,14 +173,13 &lt; at &gt;&lt; at &gt; int
 netrate_rtt(void)
 {
 int ret;
- -int sock;
 long val;
 struct netrate_message *msg;
 struct timespec ts;
 pthread_t thread_id;
 
 dprintf("setting up transmit socket\n");
- -sock = setup_socket(protocol, port, multicast);
+sock = netrate_tx_socket(protocol, port, SERVER);
 if (sock &lt; 0) {
 perror("transmit socket");
 return -(errno);
diff --git a/server.c b/server.c
index 8264b4e..9d205ba 100644
- --- a/server.c
+++ b/server.c
&lt; at &gt;&lt; at &gt; -34,61 +34,14 &lt; at &gt;&lt; at &gt; static int bufsize;
 
 #define RING_SIZE 10
 
- -static int
- -netrate_rx_socket(int protocol, int port, int multicast)
- -{
- -int ret;
- -int sock;
- -char portstring[10];
- -struct addrinfo hints, *ai;
- -
- -memset(&amp;hints, 0, sizeof(hints));
- -hints.ai_flags = AI_PASSIVE;
- -hints.ai_family = AF_INET;
- -hints.ai_socktype = type;
- -hints.ai_protocol = protocol;
- -sprintf(portstring, "%d", port);
- -       
- -ret = getaddrinfo(NULL, portstring, &amp;hints, &amp;ai);
- -if (ret) {
- -fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -return -ret;
- -}
- -
- -sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
- -if (sock &lt; 0) {
- -perror ("receive socket()");
- -return -(errno);
- -}
- -
- -ret = bind(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen);
- -if (ret &lt; 0) {
- -perror("bind");
- -return -(errno);
- -}
- -
- -freeaddrinfo(ai);
- -
- -if (protocol == IPPROTO_TCP) {
- -ret = listen(sock, SOMAXCONN);
- -if (ret &lt; 0) {
- -perror("listen()");
- -return -(errno);
- -}
- -}
- -return sock;
- -}
 
 /*
  * receive netrate messages and return them as quickly as possible
  */
 int
- -netrate_server(void)
+netrate_server(int consock)
 {
 int ret;
- -int servsock, consock;
- -socklen_t socklen;
- -struct sockaddr_in client;
 unsigned long packets = 0;
 struct ring_buffer *r;
 
&lt; at &gt;&lt; at &gt; -97,31 +50,6 &lt; at &gt;&lt; at &gt; netrate_server(void)
 /* setup receive ring */
 r = setup_ring_buffers(RING_SIZE, bufsize);
 
- -/* setup a socket */
- -servsock = netrate_rx_socket(protocol, port, multicast);
- -if (servsock &lt; 0) {
- -perror("setting up recieve socket");
- -free_ring_buffers(r);
- -return servsock;
- -}
- -
- -/* if we're doing TCP, call accept */
- -if (protocol == IPPROTO_TCP) {
- -dprintf("calling accept\n");
- -consock = accept(servsock, (struct sockaddr *)&amp;client, &amp;socklen);
- -if (consock &lt; 0) {
- -perror("accept");
- -close(servsock);
- -free_ring_buffers(r);
- -return consock;
- -}
- -close(servsock);
- -dprintf("connection started\n");
- -}
- -else {
- -consock = servsock;
- -}
- -
 dprintf("entering server loop\n");
 
 /* save our bailout point for SIGINT */
diff --git a/transmit.c b/transmit.c
index c134916..5e09bf6 100644
- --- a/transmit.c
+++ b/transmit.c
&lt; at &gt;&lt; at &gt; -31,54 +31,6 &lt; at &gt;&lt; at &gt;
 
 static unsigned long long sequence = 0;
 
- -static int
- -netrate_tx_socket(int protocol, int port, int multicast)
- -{
- -int ret;
- -int sock;
- -int val;
- -char portstring[10];
- -struct addrinfo *ai, hints;
- -
- -memset(&amp;hints, 0, sizeof(hints));
- -hints.ai_flags = AI_CANONNAME;
- -hints.ai_family = AF_INET;
- -hints.ai_socktype = type;
- -hints.ai_protocol = protocol;
- -sprintf(portstring, "%d", port);
- -
- -ret = getaddrinfo(hostname, portstring, &amp;hints, &amp;ai);
- -if (ret) {
- -fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -return -ret;
- -}
- -sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
- -if (sock &lt; 0) {
- -perror("transmit socket()");
- -return -(errno);
- -}
- -
- -dprintf("calling connect\n");
- -if (connect(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen) &lt; 0) {
- -perror("connect");
- -close(sock);
- -return -(errno);
- -}
- -freeaddrinfo(ai);
- -
- -if (protocol == IPPROTO_TCP) {
- -/* set TCP_NODELAY */
- -dprintf("setting TCP_NODELAY\n");
- -val = 1;
- -if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &amp;val, sizeof(val)) &lt; 0) {
- -perror("setsockopt");
- -close(sock);
- -return -(errno);
- -}
- -}
- -return sock;
- -}
- -
 int
 netrate_transmit(void)
 {
&lt; at &gt;&lt; at &gt; -94,7 +46,7 &lt; at &gt;&lt; at &gt; netrate_transmit(void)
 r = setup_ring_buffers(10, bufsize);
 
 dprintf("setting up transmit socket\n");
- -sock = netrate_tx_socket(protocol, port, multicast);
+sock = netrate_tx_socket(protocol, port, RX);
 if (sock &lt; 0) {
 perror("transmit socket");
 return -(errno);
- -- 
1.6.0.1


- From ed795f7a0c363b7ba2a05c487b5d7e12e80e9762 Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Wed, 8 Oct 2008 15:08:33 -0500
Subject: [PATCH] make use wildcards

modified Makefile targets to use wildcard builtin

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 Makefile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 7a5c25e..e9ad854 100644
- --- a/Makefile
+++ b/Makefile
&lt; at &gt;&lt; at &gt; -1,7 +1,7 &lt; at &gt;&lt; at &gt;
 CC:= gcc
 CFLAGS:= -g -O2 -Wall
- -SRC:= main.c receive.c transmit.c rtt.c server.c common.c
- -HDR:= netrate.h networking.h
+SRC:= $(wildcard *.c)
+HDR:= $(wildcard *.h)
 OBJ:= $(subst .c,.o,$(SRC))
 
 netrate:$(OBJ)
- -- 
1.6.0.1


- From c212089b4f3e751e7b5cb47a2a207d61af6f07a3 Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Wed, 8 Oct 2008 15:12:10 -0500
Subject: [PATCH] socket functions to common

moved tx and rx socket setup functions into common.c; changed to u64 type (from unsigned long long)

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 common.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 87 insertions(+), 11 deletions(-)

diff --git a/common.c b/common.c
index 8ed0590..a990e20 100644
- --- a/common.c
+++ b/common.c
&lt; at &gt;&lt; at &gt; -42,26 +42,26 &lt; at &gt;&lt; at &gt;
 /*
  * turn  a struct timespec into a long long of nanoseconds
  */
- -unsigned long long
+u64
 ts2ns(struct timespec *t)
 {
 return ((t-&gt;tv_sec * NS_PER_SEC) + t-&gt;tv_nsec);
 }
 
- -unsigned long
+u64
 ts2us(struct timespec *t)
 {
 return (t-&gt;tv_sec * US_PER_SEC) + NS_TO_US(t-&gt;tv_nsec);
 }
 
- -unsigned long
+u64
 ts2ms(struct timespec *t)
 {
 return (t-&gt;tv_sec * MS_PER_SEC) + NS_TO_MS(t-&gt;tv_nsec);
 }
 
 static unsigned long
- -ns2x(unsigned long ns, int units)
+ns2x(u64 ns, int units)
 {
 switch(units) {
 case MSEC:
&lt; at &gt;&lt; at &gt; -76,7 +76,7 &lt; at &gt;&lt; at &gt; ns2x(unsigned long ns, int units)
 return 0;
 }
 
- -unsigned long
+u64
 ts2x(struct timespec *ts, int units)
 {
 if (ts == NULL) {
&lt; at &gt;&lt; at &gt; -120,7 +120,7 &lt; at &gt;&lt; at &gt; tsnormalize(struct timespec *ts)
 }
 
 void
- -tsadd(struct timespec *ts, unsigned long ns)
+tsadd(struct timespec *ts, u64 ns)
 {
 ts-&gt;tv_nsec += ns;
 tsnormalize(ts);
&lt; at &gt;&lt; at &gt; -302,11 +302,29 &lt; at &gt;&lt; at &gt; update_statistics_time (struct statistics *s,
 s-&gt;end = *end;
 }
 
+void
+check_delta(struct statistics *s, struct timespec *delta)
+{
+u64 val;
+if (delta == NULL) {
+fprintf(stderr, "Invalid timespec pointer!\n");
+exit(-2);
+}
+
+val = ts2ns(delta);
+if (breakon &amp;&amp; val &gt; breakon) {
+fprintf(stderr, "breakon threshold exceeded!"
+" sample: %lu, value: %luns\n", 
+(unsigned long)s-&gt;samples, (unsigned long) val);
+exit(-1);
+}
+}
+
 /* note: raw values are kept in nanoseconds */
 void
 update_statistics_data (struct statistics *s, struct timespec *tsdelta)
 {
- -unsigned long long val;
+u64 val;
 
 if (s == NULL) {
 fprintf(stderr, "Invalid statistics structure!\n");
&lt; at &gt;&lt; at &gt; -344,13 +362,23 &lt; at &gt;&lt; at &gt; print_statistics(struct statistics *s)
        ns2x(runlen.tv_nsec, s-&gt;units), suffix);
 }
 printf("Run Statistics:\n");
- -printf("Number of Samples: %lu\n", s-&gt;samples);
+printf("Number of Samples: %lu\n", (unsigned long) s-&gt;samples);
 printf("Minumum:           %lu%s\n", ns2x(s-&gt;min, s-&gt;units), suffix);
 printf("Maximum:           %lu%s\n", ns2x(s-&gt;max, s-&gt;units), suffix);
 printf("Average:           %lu%s\n", 
        ns2x(s-&gt;accum / s-&gt;samples, s-&gt;units), suffix);
 }
 
+int
+missed_sequence(struct statistics *s, int expected, int got)
+{
+s-&gt;missed_sequence++;
+if (expected &lt; got)
+return got+1;
+return expected;
+}
+
+
 void
 free_statistics(struct statistics *s)
 {
&lt; at &gt;&lt; at &gt; -367,7 +395,7 &lt; at &gt;&lt; at &gt; struct histogram *
 setup_histogram (int units, int nbuckets, int bucketwidth, int base)
 {
 struct histogram *h;
- -int hsize = sizeof(struct histogram) + (nbuckets * sizeof(unsigned long)); 
+int hsize = sizeof(struct histogram) + (nbuckets * sizeof(u64)); 
 
 h = malloc(hsize);
 if (h == NULL) {
&lt; at &gt;&lt; at &gt; -385,7 +413,7 &lt; at &gt;&lt; at &gt; setup_histogram (int units, int nbuckets, int bucketwidth, int base)
 void
 histogram_record(struct histogram *h, struct timespec *ts)
 {
- -unsigned long long val;
+u64 val;
 
 if (h == NULL) {
 fprintf(stderr, "invalid histogram structure!\n");
&lt; at &gt;&lt; at &gt; -423,7 +451,8 &lt; at &gt;&lt; at &gt; histogram_print(struct histogram *h)
 printf("Histogram (%d  %d%s buckets)\n",
        h-&gt;nbuckets, h-&gt;bucketwidth, suffix);
 for (i = 0; i &lt; h-&gt;nbuckets; i++)
- -printf("%4.4d%s: %lu\n", i*h-&gt;bucketwidth, suffix, h-&gt;bucket[i]);
+printf("%4.4d%s: %lu\n", i*h-&gt;bucketwidth, suffix, 
+       (unsigned long)h-&gt;bucket[i]);
 
 }
 
&lt; at &gt;&lt; at &gt; -515,3 +544,50 &lt; at &gt;&lt; at &gt; netrate_tx_socket(int protocol, int port, int request)
 }
 return sock;
 }
+
+int
+netrate_rx_socket(int protocol, int type)
+{
+int ret;
+int sock;
+char portstring[10];
+struct addrinfo hints, *ai;
+
+memset(&amp;hints, 0, sizeof(hints));
+hints.ai_flags = AI_PASSIVE;
+hints.ai_family = AF_INET;
+hints.ai_socktype = type;
+hints.ai_protocol = protocol;
+sprintf(portstring, "%d", port);
+
+dprintf("calling getaddrinfo\n");
+ret = getaddrinfo(NULL, portstring, &amp;hints, &amp;ai);
+if (ret) {
+fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
+return -ret;
+}
+
+dprintf("calling socket\n");
+sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
+if (sock &lt; 0) {
+perror ("receive socket()");
+return -(errno);
+}
+
+dprintf("calling accept\n");
+ret = bind(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen);
+if (ret &lt; 0) {
+perror("bind");
+return -(errno);
+}
+
+if (protocol == IPPROTO_TCP) {
+dprintf("calling listen\n");
+ret = listen(sock, SOMAXCONN);
+if (ret &lt; 0) {
+perror("listen()");
+return -(errno);
+}
+}
+return sock;
+}
- -- 
1.6.0.1


- From fa8721403c9e3111ae236139414062868642514d Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Wed, 8 Oct 2008 15:12:53 -0500
Subject: [PATCH] add net exchange

removed netrate_rx_socket; added function exchange

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 main.c |  130 ++++++++++++++++++++++++++++-----------------------------------
 1 files changed, 58 insertions(+), 72 deletions(-)

diff --git a/main.c b/main.c
index a13f7f6..2ee5ad3 100644
- --- a/main.c
+++ b/main.c
&lt; at &gt;&lt; at &gt; -42,6 +42,7 &lt; at &gt;&lt; at &gt; int type= SOCK_STREAM;  /* type of socket */
 int nodelay= FALSE;/* use TCP_NODELAY for TCP sockets */
 int role = 0;/* should be either TX or RX */
 int rate = DEF_TX_RATE;/* transmit packet rate in nanoseconds */
+u64 breakon= 0;            /* stop if this threshold exceeded */
 int size = DEF_MSG_SIZE;/* size of message */
 int port = DEF_PORT;/* tx/rx port to use */
 int multicast = FALSE;/* are we multicasting? */
&lt; at &gt;&lt; at &gt; -69,6 +70,7 &lt; at &gt;&lt; at &gt; static struct option long_options[] = {
 {"help", 0, 0, HELP},
 {"nodelay", 0, 0, NODELAY},
 {"histogram", 0, 0, HISTOGRAM},
+{"breakon", 1, 0, BREAKON},
 {0, 0, 0, 0},
 };
 
&lt; at &gt;&lt; at &gt; -91,52 +93,6 &lt; at &gt;&lt; at &gt; void usage(void)
 }
 
 
- -int
- -netrate_rx_socket(int protocol, int type)
- -{
- -int ret;
- -int sock;
- -char portstring[10];
- -struct addrinfo hints, *ai;
- -
- -memset(&amp;hints, 0, sizeof(hints));
- -hints.ai_flags = AI_PASSIVE;
- -hints.ai_family = AF_INET;
- -hints.ai_socktype = type;
- -hints.ai_protocol = protocol;
- -sprintf(portstring, "%d", port);
- -
- -dprintf("calling getaddrinfo\n");
- -ret = getaddrinfo(NULL, portstring, &amp;hints, &amp;ai);
- -if (ret) {
- -fprintf(stderr, "Error from getaddrinfo: %s\n", strerror(ret));
- -return -ret;
- -}
- -
- -dprintf("calling socket\n");
- -sock = socket(ai-&gt;ai_family, ai-&gt;ai_socktype, ai-&gt;ai_protocol);
- -if (sock &lt; 0) {
- -perror ("receive socket()");
- -return -(errno);
- -}
- -
- -dprintf("calling accept\n");
- -ret = bind(sock, ai-&gt;ai_addr, ai-&gt;ai_addrlen);
- -if (ret &lt; 0) {
- -perror("bind");
- -return -(errno);
- -}
- -
- -if (protocol == IPPROTO_TCP) {
- -dprintf("calling listen\n");
- -ret = listen(sock, SOMAXCONN);
- -if (ret &lt; 0) {
- -perror("listen()");
- -return -(errno);
- -}
- -}
- -return sock;
- -}
 
 int
 netrate_daemon(void)
&lt; at &gt;&lt; at &gt; -145,7 +101,7 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 int servsock, sock;
 socklen_t clientlen;
 struct sockaddr_in client;
- -struct netrate_exchange ex, ack;
+struct netrate_exchange ex;
 
 dprintf("netrate_daemon: starting\n");
 servsock = netrate_rx_socket(protocol, type);
&lt; at &gt;&lt; at &gt; -183,18 +139,6 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 
 size = ex.size;
 
- -ack = ex;
- -ack.request = REQUEST_ACK;
- -
- -dprintf("ACK'ing exchange\n");
- -ret = write(sock, &amp;ack, sizeof(ack));
- -if (ret &lt; 0) {
- -fprintf(stderr, "error acknowledging exchange request: %s\n",
- -strerror(errno));
- -close(sock);
- -exit(-4);
- -}
- -
 switch (ex.request) {
 
 case SERVER:
&lt; at &gt;&lt; at &gt; -211,6 +155,47 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 }
 
 
+void
+netrate_sendack(int sock)
+{
+int ret;
+struct netrate_exchange ack;
+
+memset(&amp;ack, 0, sizeof(ack));
+ack.major = MAJOR;
+ack.minor = MINOR;
+ack.request = REQUEST_ACK;
+
+dprintf("ACK'ing exchange\n");
+ret = write(sock, &amp;ack, sizeof(ack));
+if (ret &lt; 0) {
+fprintf(stderr, "error acknowledging exchange request: %s\n",
+strerror(errno));
+close(sock);
+exit(-4);
+}
+}
+
+
+u64
+adjustns(char *suffix, u64 val)
+{
+u64 newval = val;
+if (suffix) {
+if (strcmp(suffix, "ms") == 0)
+newval = MS_TO_NS(val);
+else if (strcmp(suffix, "us") == 0)
+newval = US_TO_NS(val);
+else if (strcmp(suffix, "s"))
+newval = val * NS_PER_SEC;
+else {
+fprintf(stderr, "unknown time suffix: %s\n", suffix);
+exit(-1);
+}
+}
+return newval;
+}
+
 int main(int argc, char **argv)
 {
 int ret;
&lt; at &gt;&lt; at &gt; -220,7 +205,7 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 
 strcpy(hostname, "localhost");
 while (1) {
- -opt = getopt_long(argc, argv, "rta:z:cdmp", 
+opt = getopt_long(argc, argv, "rta:z:cdmpb:", 
   long_options, &amp;idx);
 if (opt == -1)
 break;
&lt; at &gt;&lt; at &gt; -240,23 +225,24 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 break;
 case RATE:
 rate = strtol(optarg, &amp;endptr, 10);
- -if (endptr) {
- -if (strcmp(endptr, "ms") == 0)
- -rate = MS_TO_NS(rate);
- -else if (strcmp(endptr, "us") == 0)
- -rate = US_TO_NS(rate);
- -else if (strcmp(endptr, "s"))
- -rate = rate * NS_PER_SEC;
- -else {
- -fprintf(stderr, "unknown time suffix: %s\n", endptr);
- -exit(-1);
- -}
- -}
+if (endptr)
+rate = adjustns(endptr, rate);
 /* default (no suffix) is milliseconds */
 else
 rate = MS_TO_NS(rate);
 dprintf("rate set to %dms\n", NS_TO_MS(rate));
 break;
+case BREAKON:
+breakon = strtol(optarg, &amp;endptr, 10);
+if (endptr)
+breakon = adjustns(endptr, breakon);
+else
+breakon = MS_TO_NS(breakon);
+dprintf("breakon set to %lums\n", 
+(unsigned long) NS_TO_MS(breakon));
+break;
+
+
 case SIZE:
 size = strtol(optarg, NULL, 10);
 dprintf("size set to %d\n", size);
- -- 
1.6.0.1


- From e5ce0e98fc81cbbfdb88cdd47902965b7d731d1b Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Wed, 8 Oct 2008 15:13:38 -0500
Subject: [PATCH] breakon and short typenames

added the BREAKON enumerated type and option to stop on a latency greater than X; changed to short typenames

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 netrate.h |   50 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/netrate.h b/netrate.h
index c2aaba8..9f073dd 100644
- --- a/netrate.h
+++ b/netrate.h
&lt; at &gt;&lt; at &gt; -30,7 +30,7 &lt; at &gt;&lt; at &gt;
 
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
        MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
- -       SERVER, RTT, NODELAY, HISTOGRAM,
+       SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
        NUM_OPT_VALS,
 };
 
&lt; at &gt;&lt; at &gt; -55,18 +55,22 &lt; at &gt;&lt; at &gt; enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define NETRATE_MSG_DATA 0xa5
 
 #include &lt;linux/types.h&gt;
+typedef __u16  u16;
+typedef __u32  u32;
+typedef __u64  u64;
+
 struct netrate_exchange {
- -__u16 major;
- -__u16 minor;
- -__u16 request;
- -__u16 size;
+u16 major;
+u16 minor;
+u16 request;
+u16 size;
 };
 
 #define REQUEST_ACK0xffff
 
 struct netrate_message {
- -unsigned long msg_len;/* message length (including header) */
- -unsigned long msg_seq;/* sequence number */
+u64 msg_len;/* message length (including header) */
+u64 msg_seq;/* sequence number */
 struct timespec msg_ts; /* time message was sent */
 char msg_data[]; /* body of message */
 };
&lt; at &gt;&lt; at &gt; -76,6 +80,7 &lt; at &gt;&lt; at &gt; extern int type;
 extern int nodelay;
 extern int role;
 extern int rate;
+extern u64 breakon;
 extern int size;
 extern int multicast;
 extern int port;
&lt; at &gt;&lt; at &gt; -89,17 +94,19 &lt; at &gt;&lt; at &gt; int netrate_receive(int sock);
 int netrate_rtt(void);
 int netrate_server(int sock);
 int netrate_tx_socket(int protocol, int port, int request);
+int netrate_rx_socket(int protocol, int type);
+void netrate_sendack(int sock);
 void stop_execution(void);
 void dprintf(char *, ...);
 
- -unsigned long long ts2ns(struct timespec *ts);
- -unsigned long ts2us(struct timespec *ts);
- -unsigned long ts2ms(struct timespec *ts);
+u64 ts2ns(struct timespec *ts);
+u64 ts2us(struct timespec *ts);
+u64 ts2ms(struct timespec *ts);
 void tsdelta(struct timespec *later, 
     struct timespec *earlier, 
     struct timespec *delta);
 void tsnormalize(struct timespec *ts);
- -void tsadd(struct timespec *ts, unsigned long ns);
+void tsadd(struct timespec *ts, u64 ns);
 
 
 struct ring_buffer {
&lt; at &gt;&lt; at &gt; -123,12 +130,13 &lt; at &gt;&lt; at &gt; enum units { SEC=1, MSEC, USEC, NSEC };
 struct statistics {
 struct timespec start;
 struct timespec end;
- -unsigned long min;
- -unsigned long max;
- -unsigned long average;
- -unsigned long long accum;
- -unsigned long samples;
- -unsigned int  units;
+u64 min;
+u64 max;
+u64 average;
+u64 accum;
+u64 samples;
+u32 units;
+u32 missed_sequence;
 };
 
 
&lt; at &gt;&lt; at &gt; -136,17 +144,19 &lt; at &gt;&lt; at &gt; struct statistics *setup_statistics(int units);
 void update_statistics_data(struct statistics *s, struct timespec *tsdelta);
 void update_statistics_time(struct statistics *s, 
     struct timespec *start, struct timespec *end);
+void check_delta(struct statistics *s, struct timespec *delta);
 void print_statistics(struct statistics *s);
 void free_statistics(struct statistics *s);
+int missed_sequence(struct statistics *s, int expected, int got);
 
 struct histogram {
 int units;
 int base;
 int nbuckets;
 int bucketwidth;
- -unsigned long underflow;
- -unsigned long overflow;
- -unsigned long bucket[];
+u64 underflow;
+u64 overflow;
+u64 bucket[];
 };
 
 struct histogram *setup_histogram (int units, int nbuckets, 
- -- 
1.6.0.1


- From 761d49f846e1947d708c3b2053b2f048562485bd Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Tue, 21 Oct 2008 20:45:48 -0500
Subject: [PATCH] keep going on sequence mismatch

dont exit on sequence mismatch; added exchange code

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 receive.c  |   27 +++++++++++++++++++--------
 rtt.c      |    2 +-
 server.c   |    5 ++++-
 transmit.c |    2 +-
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/receive.c b/receive.c
index b9a255a..798daff 100644
- --- a/receive.c
+++ b/receive.c
&lt; at &gt;&lt; at &gt; -54,26 +54,36 &lt; at &gt;&lt; at &gt; netrate_receive(int consock)
 /* set up our ring buffers */
 r = setup_ring_buffers(10, bufsize);
 
- -
 /* allocate statistics space */
 stats = setup_statistics(MSEC);
 
+/* mark our start time */
+status = clock_gettime(CLOCK_MONOTONIC, &amp;current);
+if (status &lt; 0) {
+fprintf(stderr, "error from clock_gettime: %s\n", 
+strerror(abs(status)));
+return (int) status;
+}
+update_statistics_time(stats, &amp;current, NULL);
+
+/* ack the request so the transmitter starts */
+netrate_sendack(consock);
+
+/* get a valid "last" time */
 status = clock_gettime(CLOCK_MONOTONIC, &amp;last);
 if (status &lt; 0) {
 fprintf(stderr, "error from clock_gettime: %s\n", 
 strerror(abs(status)));
 return (int) status;
 }
- -update_statistics_time(stats, &amp;last, NULL);
 
 /* save our bailout point for SIGINT */
 setjmp(jmpbuf);
- -
 dprintf("entering receive loop\n");
 
 /* loop until done */
 while(!interrupted) {
- -ptr = get_next_ring_buffer(r);
+msg = ptr = get_next_ring_buffer(r);
 ret = read_message(consock, ptr, bufsize);
 if (ret &lt;= 0)
 break;
&lt; at &gt;&lt; at &gt; -87,15 +97,16 &lt; at &gt;&lt; at &gt; netrate_receive(int consock)
 }
 if (sequence++) {
 tsdelta(&amp;current, &amp;last, &amp;delta);
+check_delta(stats, &amp;delta);
 update_statistics_data(stats, &amp;delta);
 }
- -msg = ptr;
+else
+dprintf("skipped first packet\n");
 if (msg-&gt;msg_seq != sequence) {
 fprintf(stderr, "sequence number wrong!\n"
 "    calculated: %lu, received: %lu\n", 
- -sequence, msg-&gt;msg_seq);
- -close(consock);
- -break;
+sequence, (unsigned long) msg-&gt;msg_seq);
+sequence = missed_sequence(stats, sequence, msg-&gt;msg_seq);
 }
 last = current;
 }
diff --git a/rtt.c b/rtt.c
index 264a9a6..5f9d052 100644
- --- a/rtt.c
+++ b/rtt.c
&lt; at &gt;&lt; at &gt; -36,7 +36,7 &lt; at &gt;&lt; at &gt; static struct ring_buffer *tx_ring;
 static struct ring_buffer *rx_ring;
 static int bufsize;
 
- -static unsigned long long sequence = 0;
+static u64 sequence = 0;
 
 static int sock = -1;
 
diff --git a/server.c b/server.c
index 9d205ba..f4c9508 100644
- --- a/server.c
+++ b/server.c
&lt; at &gt;&lt; at &gt; -42,7 +42,7 &lt; at &gt;&lt; at &gt; int
 netrate_server(int consock)
 {
 int ret;
- -unsigned long packets = 0;
+u64 packets = 0;
 struct ring_buffer *r;
 
 bufsize = sizeof(struct netrate_message) + size;
&lt; at &gt;&lt; at &gt; -52,6 +52,9 &lt; at &gt;&lt; at &gt; netrate_server(int consock)
 
 dprintf("entering server loop\n");
 
+/* send the ack to start the transmitter */
+netrate_sendack(consock);
+
 /* save our bailout point for SIGINT */
 setjmp(jmpbuf);
 
diff --git a/transmit.c b/transmit.c
index 5e09bf6..f0db186 100644
- --- a/transmit.c
+++ b/transmit.c
&lt; at &gt;&lt; at &gt; -29,7 +29,7 &lt; at &gt;&lt; at &gt;
 #include "networking.h"
 
 
- -static unsigned long long sequence = 0;
+static u64 sequence = 0;
 
 int
 netrate_transmit(void)
- -- 
1.6.0.1


- From e6e0454a1b8b7c57c1459c3498bf5bd8e37118a3 Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Tue, 21 Oct 2008 20:52:24 -0500
Subject: [PATCH] packet skip and connected UDP

added logic to put UDP socket in connected mode; added packet skip option
added versioning in the Makefile

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 .gitignore |    1 +
 Makefile   |    7 +++++--
 main.c     |   41 +++++++++++++++++++++++++++++++++--------
 netrate.h  |   11 +++++++++--
 receive.c  |    9 +++++++--
 rtt.c      |    9 +++++++++
 server.c   |    9 +++++++--
 transmit.c |   10 ++++++++++
 8 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2e01fe3..d056f27 100644
- --- a/.gitignore
+++ b/.gitignore
&lt; at &gt;&lt; at &gt; -1,3 +1,4 &lt; at &gt;&lt; at &gt;
 *.o
 *~
 netrate
+*.bz2
diff --git a/Makefile b/Makefile
index e9ad854..d75f741 100644
- --- a/Makefile
+++ b/Makefile
&lt; at &gt;&lt; at &gt; -3,6 +3,9 &lt; at &gt;&lt; at &gt; CFLAGS:= -g -O2 -Wall
 SRC:= $(wildcard *.c)
 HDR:= $(wildcard *.h)
 OBJ:= $(subst .c,.o,$(SRC))
+MAJOR:= $(shell awk '/MAJOR/ {print $$3}' netrate.h)
+MINOR:= $(shell awk '/MINOR/ {print $$3}' netrate.h)
+VERSION:= $(MAJOR).$(MINOR)
 
 netrate:$(OBJ)
 $(CC) $(CFLAGS) -o netrate $(OBJ) -lrt
&lt; at &gt;&lt; at &gt; -15,5 +18,5 &lt; at &gt;&lt; at &gt; clean:
 tarball:  clean
 mkdir -p tmp/netrate
 cp Makefile $(SRC) $(HDR) tmp/netrate
- -(cd tmp &amp;&amp; tar -cjvf netrate.tar.bz2 netrate)
- -mv tmp/netrate.tar.bz2 .
+(cd tmp &amp;&amp; tar -cjvf netrate-$(VERSION).tar.bz2 netrate)
+mv tmp/netrate-$(VERSION).tar.bz2 .
diff --git a/main.c b/main.c
index 2ee5ad3..0293a1b 100644
- --- a/main.c
+++ b/main.c
&lt; at &gt;&lt; at &gt; -50,6 +50,7 &lt; at &gt;&lt; at &gt; int debugging = FALSE;/* Are we edbugging? */
 int interrupted = FALSE;/* have we been interrupted? */
 jmp_buf jmpbuf;/* bailout state for being interrupted */
 int histogram   = FALSE;/* keep a histogram of time values */
+int skip= 0;/* number of packets to skip before measuring */
 char hostname[1024];/* host to connect to */
 
 static void interrupt(int sig);
&lt; at &gt;&lt; at &gt; -71,6 +72,7 &lt; at &gt;&lt; at &gt; static struct option long_options[] = {
 {"nodelay", 0, 0, NODELAY},
 {"histogram", 0, 0, HISTOGRAM},
 {"breakon", 1, 0, BREAKON},
+{"skip", 1, 0, SKIP},
 {0, 0, 0, 0},
 };
 
&lt; at &gt;&lt; at &gt; -116,16 +118,35 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 }
 close(servsock);
 dprintf("out of accept\n");
+dprintf("calling read for exchange\n");
+ret = read(sock, &amp;ex, sizeof(ex));
+if (ret &lt; 0) {
+fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+close(sock);
+exit(-2);
+}
 }
- -else
- -sock = servsock;
+else {
+struct sockaddr_in addr;
+socklen_t addrlen;
 
- -dprintf("calling read for exchange\n");
- -ret = read(sock, &amp;ex, sizeof(ex));
- -if (ret &lt; 0) {
- -fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
- -close(sock);
- -exit(-2);
+sock = servsock;
+dprintf("Calling recvfrom for exchange\n");
+ret = recvfrom(sock, &amp;ex, sizeof(ex), 0, 
+       (struct sockaddr *) &amp;addr, 
+       (socklen_t *) &amp;addrlen);
+if (ret == -1) {
+fprintf(stderr, "error receiving exchange data: %s\n",
+strerror(errno));
+close(sock);
+exit(-2);
+}
+if (connect(sock, (struct sockaddr *) &amp;addr, addrlen) &lt; 0) {
+fprintf(stderr, "error connecting UDP socket: %s\n",
+strerror(errno));
+close(sock);
+exit(-2);
+}
 }
 dprintf("got exchange: major: %d, minor: %d, request: %d, size: %d\n",
 ex.major, ex.minor, ex.request, ex.size);
&lt; at &gt;&lt; at &gt; -287,6 +308,10 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 histogram = TRUE;
 dprintf("histogram set to true\n");
 break;
+case SKIP:
+skip = strtol(optarg, NULL, 10);
+dprintf("packet skip set to %d\n", skip);
+break;
 case HELP:
 default:
 usage();
diff --git a/netrate.h b/netrate.h
index 9f073dd..8186dc4 100644
- --- a/netrate.h
+++ b/netrate.h
&lt; at &gt;&lt; at &gt; -23,7 +23,7 &lt; at &gt;&lt; at &gt;
 #define __NETRATE_H__
 
 #define MAJOR 0
- -#define MINOR 3
+#define MINOR 4
 
 #define TRUE  1
 #define FALSE 0
&lt; at &gt;&lt; at &gt; -31,7 +31,7 &lt; at &gt;&lt; at &gt;
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
        MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
        SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
- -       NUM_OPT_VALS,
+       SKIP, NUM_OPT_VALS,
 };
 
 
&lt; at &gt;&lt; at &gt; -54,6 +54,9 &lt; at &gt;&lt; at &gt; enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define MAX_BUF_SIZE8192
 #define NETRATE_MSG_DATA 0xa5
 
+/* number of packets to skip before starting measurements */
+#define STEADY_STATE_DELAY 1
+
 #include &lt;linux/types.h&gt;
 typedef __u16  u16;
 typedef __u32  u32;
&lt; at &gt;&lt; at &gt; -68,7 +71,10 &lt; at &gt;&lt; at &gt; struct netrate_exchange {
 
 #define REQUEST_ACK0xffff
 
+enum msg_types { MSG_DATA=1, MSG_EOF=0xffffffff};
+
 struct netrate_message {
+u32 msg_type;
 u64 msg_len;/* message length (including header) */
 u64 msg_seq;/* sequence number */
 struct timespec msg_ts; /* time message was sent */
&lt; at &gt;&lt; at &gt; -85,6 +91,7 &lt; at &gt;&lt; at &gt; extern int size;
 extern int multicast;
 extern int port;
 extern int histogram;
+extern int skip;
 extern char hostname[];
 extern int interrupted;
 extern jmp_buf jmpbuf;
diff --git a/receive.c b/receive.c
index 798daff..edadc02 100644
- --- a/receive.c
+++ b/receive.c
&lt; at &gt;&lt; at &gt; -88,6 +88,10 &lt; at &gt;&lt; at &gt; netrate_receive(int consock)
 if (ret &lt;= 0)
 break;
 
+/* bail out if the other end going away */
+if (msg-&gt;msg_type == MSG_EOF)
+break;
+
 //dprintf(".");
 status = clock_gettime(CLOCK_MONOTONIC, &amp;current);
 if (status &lt; 0) {
&lt; at &gt;&lt; at &gt; -95,13 +99,13 &lt; at &gt;&lt; at &gt; netrate_receive(int consock)
 strerror(abs(status)));
 return (int) status;
 }
- -if (sequence++) {
+if (sequence++ &gt; skip) { 
 tsdelta(&amp;current, &amp;last, &amp;delta);
 check_delta(stats, &amp;delta);
 update_statistics_data(stats, &amp;delta);
 }
 else
- -dprintf("skipped first packet\n");
+dprintf("skipped packet %d\n", sequence);
 if (msg-&gt;msg_seq != sequence) {
 fprintf(stderr, "sequence number wrong!\n"
 "    calculated: %lu, received: %lu\n", 
&lt; at &gt;&lt; at &gt; -111,6 +115,7 &lt; at &gt;&lt; at &gt; netrate_receive(int consock)
 last = current;
 }
 dprintf("out of receive loop\n");
+close(consock);
 status = clock_gettime(CLOCK_MONOTONIC, &amp;last);
 if (status &lt; 0) {
 fprintf(stderr, "error from clock_gettime: %s\n", 
diff --git a/rtt.c b/rtt.c
index 5f9d052..d9b563e 100644
- --- a/rtt.c
+++ b/rtt.c
&lt; at &gt;&lt; at &gt; -104,6 +104,7 &lt; at &gt;&lt; at &gt; setup_message(int sequence, struct netrate_message *m)
 fprintf(stderr, "invalid buffer pointer!\n");
 exit(-1);
 }
+m-&gt;msg_type = MSG_DATA;
 m-&gt;msg_seq = sequence;
 m-&gt;msg_len = size;
 ret = clock_gettime(CLOCK_MONOTONIC, &amp;m-&gt;msg_ts);
&lt; at &gt;&lt; at &gt; -229,6 +230,14 &lt; at &gt;&lt; at &gt; netrate_rtt(void)
 }
 }
 dprintf("out of transmit loop (%lu messages transmitted)\n", sequence);
+if (protocol == IPPROTO_UDP) {
+msg = (struct netrate_message *) get_next_ring_buffer(tx_ring);
+msg-&gt;msg_type = MSG_EOF;
+msg-&gt;msg_seq = sequence;
+msg-&gt;msg_len = size;
+write_message(msg);
+}
+close(sock);
 dprintf("freeing transmit ring\n");
 free_ring_buffers(tx_ring);
 dprintf("freeing receive ring\n");
diff --git a/server.c b/server.c
index f4c9508..4f0e1bb 100644
- --- a/server.c
+++ b/server.c
&lt; at &gt;&lt; at &gt; -44,7 +44,8 &lt; at &gt;&lt; at &gt; netrate_server(int consock)
 int ret;
 u64 packets = 0;
 struct ring_buffer *r;
- -
+struct netrate_message *m;
+
 bufsize = sizeof(struct netrate_message) + size;
 
 /* setup receive ring */
&lt; at &gt;&lt; at &gt; -60,11 +61,14 &lt; at &gt;&lt; at &gt; netrate_server(int consock)
 
 /* loop until done */
 while(!interrupted) {
- -char *buf = get_next_ring_buffer(r);
+void *buf = get_next_ring_buffer(r);
 
+m = buf;
 if ((ret = read_message(consock, buf, bufsize)) &lt;= 0)
 break;
 
+if (m-&gt;msg_type == MSG_EOF)
+break;
 if ((ret = write(consock, buf, bufsize)) &lt; 0) {
 fprintf(stderr, "Error echoing packet: %s\n",
 strerror(errno));
&lt; at &gt;&lt; at &gt; -73,6 +77,7 &lt; at &gt;&lt; at &gt; netrate_server(int consock)
 packets++;
 }
 dprintf("out of receive loop (processed %d packets)\n", packets);
+close(consock);
 
 free_ring_buffers(r);
 return 0;
diff --git a/transmit.c b/transmit.c
index f0db186..dd90fab 100644
- --- a/transmit.c
+++ b/transmit.c
&lt; at &gt;&lt; at &gt; -61,6 +61,7 &lt; at &gt;&lt; at &gt; netrate_transmit(void)
 setjmp(jmpbuf);
 while(!interrupted) {
 msg = (struct netrate_message *) get_next_ring_buffer(r);
+msg-&gt;msg_type = MSG_DATA;
 msg-&gt;msg_seq = ++sequence;
 msg-&gt;msg_len = size;
 
&lt; at &gt;&lt; at &gt; -81,6 +82,15 &lt; at &gt;&lt; at &gt; netrate_transmit(void)
 }
 }
 dprintf("out of transmit loop (%lu messages transmitted)\n", sequence);
+if (protocol == IPPROTO_UDP) {
+msg = (struct netrate_message *) get_next_ring_buffer(r);
+msg-&gt;msg_type = MSG_EOF;
+msg-&gt;msg_seq = ++sequence;
+msg-&gt;msg_len = size;
+
+if ((ret = write(sock, msg, bufsize)) &lt; 0)
+perror("transmit");
+}
 close(sock);
 free_ring_buffers(r);
 return ret;
- -- 
1.6.0.1


- From 1abef56d17e4a081db2b73fdbfe3c8d228c38a5e Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Thu, 16 Oct 2008 12:12:25 -0500
Subject: [PATCH] fixed nodelay option setting


Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 common.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/common.c b/common.c
index a990e20..5302785 100644
- --- a/common.c
+++ b/common.c
&lt; at &gt;&lt; at &gt; -473,7 +473,6 &lt; at &gt;&lt; at &gt; netrate_tx_socket(int protocol, int port, int request)
 {
 int ret;
 int sock;
- -int val;
 char portstring[10];
 struct addrinfo *ai, hints;
 struct netrate_exchange ex;
&lt; at &gt;&lt; at &gt; -506,15 +505,18 &lt; at &gt;&lt; at &gt; netrate_tx_socket(int protocol, int port, int request)
 
 freeaddrinfo(ai);
 
- -if (protocol == IPPROTO_TCP &amp;&amp; nodelay == TRUE) {
+if (protocol == IPPROTO_TCP) {
+int val;
 /* set TCP_NODELAY */
- -dprintf("setting TCP_NODELAY\n");
- -val = 1;
- -if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &amp;val, sizeof(val)) &lt; 0) {
- -perror("setsockopt");
- -ret = -errno;
- -close(sock);
- -return ret;
+if (nodelay == TRUE) {
+dprintf("setting TCP_NODELAY\n");
+val = 1;
+if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, &amp;val, sizeof(val)) &lt; 0) {
+perror("setsockopt");
+ret = -errno;
+close(sock);
+return ret;
+}
 }
 }
 memset(&amp;ex, 0, sizeof(ex));
- -- 
1.6.0.1


- From 2bdbd044f1d1fd94f565e812b2bffdad5147087e Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Tue, 21 Oct 2008 20:54:33 -0500
Subject: [PATCH] renamed daemon option to listen

changed DAEMON to LISTEN; changed default msg size to 536

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 main.c    |   27 ++++++++++++++-------------
 netrate.h |    4 ++--
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/main.c b/main.c
index 0293a1b..aa41637 100644
- --- a/main.c
+++ b/main.c
&lt; at &gt;&lt; at &gt; -58,7 +58,7 &lt; at &gt;&lt; at &gt; static void interrupt(int sig);
 static struct option long_options[] = {
 {"transmit", 0, 0, TX},
 {"rtt", 0, 0, RTT},
- -{"daemon", 0, 0, DAEMON},
+{"listen", 0, 0, LISTEN},
 {"rate", 1, 0, RATE},
 {"size", 1, 0, SIZE},
 {"tcp", 0, 0, TCP},
&lt; at &gt;&lt; at &gt; -78,7 +78,7 &lt; at &gt;&lt; at &gt; static struct option long_options[] = {
 
 void usage(void)
 {
- -fprintf(stderr, "usage: netrate {--transmit|--rtt|--daemon} [options]\n");
+fprintf(stderr, "usage: netrate {--transmit|--rtt|--listen} [options]\n");
 fprintf(stderr, "   where options are:\n");
 fprintf(stderr, "        --rate=&lt;Inter-Packet Interval&gt;\n");
 fprintf(stderr, "        --size=&lt;packet size&gt;\n");
&lt; at &gt;&lt; at &gt; -97,7 +97,7 &lt; at &gt;&lt; at &gt; void usage(void)
 
 
 int
- -netrate_daemon(void)
+netrate_listen(void)
 {
 int ret;
 int servsock, sock;
&lt; at &gt;&lt; at &gt; -105,7 +105,7 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 struct sockaddr_in client;
 struct netrate_exchange ex;
 
- -dprintf("netrate_daemon: starting\n");
+dprintf("netrate_listen: starting\n");
 servsock = netrate_rx_socket(protocol, type);
 
 if (protocol == IPPROTO_TCP) {
&lt; at &gt;&lt; at &gt; -121,7 +121,8 &lt; at &gt;&lt; at &gt; netrate_daemon(void)
 dprintf("calling read for exchange\n");
 ret = read(sock, &amp;ex, sizeof(ex));
 if (ret &lt; 0) {
- -fprintf(stderr, "error reading exchange message: %s\n", strerror(errno));
+fprintf(stderr, "error reading exchange message: %s\n",
+strerror(errno));
 close(sock);
 exit(-2);
 }
&lt; at &gt;&lt; at &gt; -232,9 +233,9 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 break;
 
 switch(opt) {
- -case DAEMON:
- -role = DAEMON;
- -dprintf("role == DAEMON\n");
+case LISTEN:
+role = LISTEN;
+dprintf("role == LISTEN\n");
 break;
 case TX:
 role = TX;
&lt; at &gt;&lt; at &gt; -305,6 +306,8 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 dprintf("setting nodelay\n");
 break;
 case HISTOGRAM:
+fprintf(stderr, "histogram option not supported yet\n");
+exit(-1);
 histogram = TRUE;
 dprintf("histogram set to true\n");
 break;
&lt; at &gt;&lt; at &gt; -319,7 +322,7 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 }
 }
 if (role == 0) {
- -fprintf(stderr, "Must specifiy either --transmit, --daemon or "
+fprintf(stderr, "Must specifiy either --transmit, --listen or "
 "--rtt options!\n");
 exit(-1);
 }
&lt; at &gt;&lt; at &gt; -338,14 +341,12 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 }
 signal(SIGINT, interrupt);
 
- -dprintf("startup up with message size == %d\n", size);
- -
 switch(role) {
 case TX:
 exit_val = netrate_transmit();
 break;
- -case DAEMON:
- -exit_val = netrate_daemon();
+case LISTEN:
+exit_val = netrate_listen();
 break;
 case RTT:
 exit_val = netrate_rtt();
diff --git a/netrate.h b/netrate.h
index 8186dc4..88a2f6d 100644
- --- a/netrate.h
+++ b/netrate.h
&lt; at &gt;&lt; at &gt; -29,7 +29,7 &lt; at &gt;&lt; at &gt;
 #define FALSE 0
 
 enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP, 
- -       MULTI, PORT, HOST, DEBUG, HELP, DAEMON,
+       MULTI, PORT, HOST, DEBUG, HELP, LISTEN,
        SERVER, RTT, NODELAY, HISTOGRAM, BREAKON,
        SKIP, NUM_OPT_VALS,
 };
&lt; at &gt;&lt; at &gt; -49,7 +49,7 &lt; at &gt;&lt; at &gt; enum optvals { RX=1, TX, RATE, SIZE, TCP, UDP, SCTP,
 #define NS_TO_MS(n)(NS_TO_US(n) / 1000)
 
 #define DEF_TX_RATE MS_TO_NS(100)
- -#define DEF_MSG_SIZE 50
+#define DEF_MSG_SIZE 536
 #define DEF_PORT 5001 /* steal the ttcp port :) */
 #define MAX_BUF_SIZE8192
 #define NETRATE_MSG_DATA 0xa5
- -- 
1.6.0.1


- From bdc0d3f6e90c97927a6aa736d9321b975d3b3c51 Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Thu, 16 Oct 2008 12:34:23 -0500
Subject: [PATCH] rearranged includes

Changed order of socket includes

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 networking.h |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/networking.h b/networking.h
index db08758..e870591 100644
- --- a/networking.h
+++ b/networking.h
&lt; at &gt;&lt; at &gt; -22,13 +22,15 &lt; at &gt;&lt; at &gt;
 #define __NETWORKING_H__
 #include &lt;sys/types.h&gt;
 #include &lt;sys/socket.h&gt;
+#include &lt;netinet/in.h&gt;
+#include &lt;netinet/ip.h&gt;
+#include &lt;linux/tcp.h&gt;
 #include &lt;sys/time.h&gt;
 #include &lt;time.h&gt;
- -#include &lt;netinet/in.h&gt;
- -#include &lt;fcntl.h&gt;
- -#include &lt;signal.h&gt;
 #include &lt;sys/un.h&gt;
 #include &lt;sys/wait.h&gt;
 #include &lt;netdb.h&gt;
- -#include &lt;linux/tcp.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;signal.h&gt;
+
 #endif
- -- 
1.6.0.1


- From 8a2c923b7345c64543e4cd4d8a19f4ca64494e1a Mon Sep 17 00:00:00 2001
From: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
Date: Thu, 16 Oct 2008 12:35:18 -0500
Subject: [PATCH] move tx buffer setup

don't setup tx buffers until we know we're connected

Signed-off-by: Clark Williams &lt;williams&lt; at &gt;redhat.com&gt;
- ---
 transmit.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/transmit.c b/transmit.c
index dd90fab..0bd414a 100644
- --- a/transmit.c
+++ b/transmit.c
&lt; at &gt;&lt; at &gt; -40,10 +40,7 &lt; at &gt;&lt; at &gt; netrate_transmit(void)
 struct netrate_message *msg;
 struct timespec ts;
 struct ring_buffer *r;
- -int bufsize = sizeof(struct netrate_message) + size;
- -
- -/* setup transmit buffers */
- -r = setup_ring_buffers(10, bufsize);
+int bufsize = sizeof(struct netrate_message) + size;;
 
 dprintf("setting up transmit socket\n");
 sock = netrate_tx_socket(protocol, port, RX);
&lt; at &gt;&lt; at &gt; -52,6 +49,9 &lt; at &gt;&lt; at &gt; netrate_transmit(void)
 return -(errno);
 }
 
+/* setup transmit buffers */
+r = setup_ring_buffers(10, bufsize);
+
 dprintf("entering transmit loop (IPI == %dms)\n", NS_TO_MS(rate));
 if (clock_gettime(CLOCK_MONOTONIC, &amp;ts)) {
 fprintf(stderr, "clock_gettime failed\n");
- -- 
1.6.0.1

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEUEARECAAYFAkj+oLEACgkQqA4JVb61b9dBoACYtn9gXlCGv4N9SKifK4UDSMsJ
tACeJ6gQ05BJMzqqOvk8C5oUEXWFfIY=
=VZTH
-----END PGP SIGNATURE-----
N</description>
    <dc:creator>Clark Williams</dc:creator>
    <dc:date>2008-10-22T03:40:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3622">
    <title>[PATCH 0/2] netrate - network rate/rtt measurement utility</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3622</link>
    <description>-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Thomas,

The patch series that follows is for a program called 'netrate'. It's a utility
I wrote recently to prove to a customer (and myself) that we were 
receiving data on a TCP socket at the same rate as it was being sent
from another system. Since I did that, I've added a round-trip-time
measurement as well. Nothing in netrate is specific to the -rt kernel, since I tried 
to ensure I only used posix interfaces. So if you spot something which breaks that, please let me know. 

The default host address is localhost, so you can test this quite easily on the same system.

$ netrate --help
usage: netrate {--transmit|--rtt|--listen} [options]
   where options are:
        --rate=&lt;Inter-Packet Interval&gt;
        --size=&lt;packet size&gt;
        --tcp
        --udp
        --sctp
        --nodelay
        --multicast
        --port=&lt;port number&gt;
        --host=&lt;hostname or IP address&gt;
        --debug
        --histogram
        --help

Currently histogram, multicast and sctp aren't functional. 

Typical usage:

&lt;server&gt;
$ netrate --listen

&lt;client&gt;
$ netrate --transmit --host=&lt;server&gt;
^C

&lt;server&gt;
Run Length: 2s:575ms
Run Statistics:
Number of Samples: 25
Minumum:           99ms
Maximum:           100ms
Average:           100ms

As you can see the default transmit rate is 100ms. Additionally, you
can run it to measure the round-trip-time of a connection with:

&lt;server&gt;
$ netrate --listen

&lt;client&gt;
$ netrate --rtt --host=&lt;server&gt;
^C
Run Statistics:
Number of Samples: 37
Minumum:           641us
Maximum:           1569us
Average:           1141us

It's nowhere near completely cooked, but I though I'd get you (and the folks
on the rt-list) to try it out and see if it was generally useful. If
so, I'll add it to the repository with cyclictest/signaltest/pi_stress
and continue to try and flesh it out.

Questions, comments, snide remarks welcome

Clark
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEYEARECAAYFAkj+oJEACgkQqA4JVb61b9coeACfZ/PvVGzZXQIteIhmX1cQbYr7
ZmQAoJNwBJi/B607omP0+Ek/I9sqZ38W
=ZvUv
-----END PGP SIGNATURE-----
</description>
    <dc:creator>Clark Williams</dc:creator>
    <dc:date>2008-10-22T03:39:50</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3621">
    <title>[PATCH] Cyclictest Hiistogram Support</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3621</link>
    <description>

Subject: Add histogram support to cyclictest
From: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;

Add -h &lt;size&gt; parameter and functionality to log histograms of latencies
in cyclictest.

Signed-off-by: Sven-Thorsten Dietrich &lt;sdietrich&lt; at &gt;suse.de&gt;

diff --git a/src/cyclictest/cyclictest.8 b/src/cyclictest/cyclictest.8
index 9827458..82c2c43 100644
--- a/src/cyclictest/cyclictest.8
+++ b/src/cyclictest/cyclictest.8
&lt; at &gt;&lt; at &gt; -16,7 +16,7 &lt; at &gt;&lt; at &gt;
 cyclictest \- High resolution test program
 .SH SYNOPSIS
 .B cyclictest
-.RI "[ \-hfmnqrsv ] [\-a " proc " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] [\-i " intv " ] [\-l " loop " ] [\-o " red " ] [\-p " prio " ] [\-t " num " ]"
+.RI "[ \-hfmnqrsv ] [\-a " proc " ] [\-b " usec " ] [\-c " clock " ] [\-d " dist " ] [\-h " histogram " ] [\-i " intv " ] [\-l " loop " ] [\-o " red " ] [\-p " prio " ] [\-t " num " ]"
 .\" .SH DESCRIPTION
 .\" This manual page documents briefly the
 .\" .B cyclictest commands.
&lt; at &gt;&lt; at &gt; -81,6 +81,9 &lt; at &gt;&lt; at &gt; Set the distance of thread intervals in microseconds (default is 500us). When cy
 .B \-f, \-\-ftrace
 Enable function tracing using ftrace as tracer. This option is available only with \-b.
 .TP
+.B \-h=MAXLATENCYINUS
+Dump latency histogram to stdout.
+.TP
 .B \-i, \-\-interval=INTV
 Set the base interval of the thread(s) in microseconds (default is 1000us). This sets the interval of the first thread. See also \-d.
 .TP
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 149c2ec..c604131 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
&lt; at &gt;&lt; at &gt; -93,6 +93,8 &lt; at &gt;&lt; at &gt; enum {
 IRQPREEMPTOFF,
 };
 
+#define HIST_MAX1000000
+
 /* Struct to transfer parameters to the thread */
 struct thread_param {
 int prio;
&lt; at &gt;&lt; at &gt; -116,6 +118,7 &lt; at &gt;&lt; at &gt; struct thread_stat {
 long act;
 double avg;
 long *values;
+long *hist_array;
 pthread_t thread;
 int threadstarted;
 int tid;
&lt; at &gt;&lt; at &gt; -132,6 +135,7 &lt; at &gt;&lt; at &gt; static int verbose = 0;
 static int oscope_reduction = 1;
 static int tracetype;
 static int lockall = 0;
+static int histogram = 0;
 
 /* Backup of kernel variables that we modify */
 static struct kvars {
&lt; at &gt;&lt; at &gt; -536,6 +540,9 &lt; at &gt;&lt; at &gt; void *timerthread(void *param)
 
 if (par-&gt;bufmsk)
 stat-&gt;values[stat-&gt;cycles &amp; par-&gt;bufmsk] = diff;
+
+if (histogram &amp;&amp; (diff &lt; histogram))
+stat-&gt;hist_array[diff] += 1;
 
 next.tv_sec += interval.tv_sec;
 next.tv_nsec += interval.tv_nsec;
&lt; at &gt;&lt; at &gt; -582,6 +589,7 &lt; at &gt;&lt; at &gt; static void display_help(void)
        "                           1 = CLOCK_REALTIME\n"
        "-d DIST  --distance=DIST   distance of thread intervals in us default=500\n"
        "-f       --ftrace          function trace (when -b is active)\n"
+        "-h H_MAX                   latency histogram size in us default 0 (off)\n"
        "-i INTV  --interval=INTV   base interval of thread in us default=1000\n"
        "-I       --irqsoff         Irqsoff tracing (used with -b)\n"
        "-l LOOPS --loops=LOOPS     number of loops: default=0(endless)\n"
&lt; at &gt;&lt; at &gt; -642,6 +650,7 &lt; at &gt;&lt; at &gt; static void process_options (int argc, char *argv[])
 {"clock", required_argument, NULL, 'c'},
 {"distance", required_argument, NULL, 'd'},
 {"ftrace", no_argument, NULL, 'f'},
+{"histogram", required_argument, NULL, 'h'},
 {"interval", required_argument, NULL, 'i'},
 {"irqsoff", no_argument, NULL, 'I'},
 {"loops", required_argument, NULL, 'l'},
&lt; at &gt;&lt; at &gt; -658,7 +667,7 &lt; at &gt;&lt; at &gt; static void process_options (int argc, char *argv[])
 {"help", no_argument, NULL, '?'},
 {NULL, 0, NULL, 0}
 };
-int c = getopt_long (argc, argv, "a::b:Bc:d:fi:Il:nmo:p:Pqrst::v",
+int c = getopt_long (argc, argv, "a::b:Bc:d:fh:i:Il:nmo:p:Pqrst::v",
 long_options, &amp;option_index);
 if (c == -1)
 break;
&lt; at &gt;&lt; at &gt; -679,6 +688,7 &lt; at &gt;&lt; at &gt; static void process_options (int argc, char *argv[])
 case 'c': clocksel = atoi(optarg); break;
 case 'd': distance = atoi(optarg); break;
 case 'f': ftrace = 1; break;
+ case 'h': histogram = atoi(optarg); break;
 case 'i': interval = atoi(optarg); break;
 case 'I': tracetype = IRQSOFF; break;
 case 'l': max_cycles = atoi(optarg); break;
&lt; at &gt;&lt; at &gt; -724,6 +734,9 &lt; at &gt;&lt; at &gt; static void process_options (int argc, char *argv[])
 error = 1;
 }
 
+if (histogram &lt; 0)
+error = 1;
+
 if (priority &lt; 0 || priority &gt; 99)
 error = 1;
 
&lt; at &gt;&lt; at &gt; -776,6 +789,36 &lt; at &gt;&lt; at &gt; static void sighand(int sig)
 tracing(0);
 }
 
+static void print_hist(struct thread_param *par, int nthreads)
+{
+int i, j;
+unsigned long long log_entries[nthreads];
+unsigned long max_latency = 0;
+
+bzero(log_entries, sizeof(log_entries));
+
+printf("# Histogram\n");
+for (i = 0; i &lt; histogram; i++) {
+
+printf("%05d ", i);
+
+for (j = 0; j &lt; nthreads; j++) {
+unsigned long curr_latency=par[j].stats-&gt;hist_array[i];
+printf("%06lu\t", curr_latency);
+log_entries[j] += curr_latency;
+if (curr_latency &amp;&amp; max_latency &lt; i)
+max_latency = i;
+}
+printf("\n");
+
+}
+printf("# Total:");
+for (j = 0; j &lt; nthreads; j++)
+printf(" %09llu", log_entries[j]);
+printf("\n");
+printf("# Max Latency: %lu / %d\n", max_latency, histogram);
+}
+
 static void print_stat(struct thread_param *par, int index, int verbose)
 {
 struct thread_stat *stat = par-&gt;stats;
&lt; at &gt;&lt; at &gt; -874,6 +917,12 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 goto outpar;
 
 for (i = 0; i &lt; num_threads; i++) {
+if (histogram) {
+if (histogram &gt; HIST_MAX)
+histogram = HIST_MAX;
+stat[i].hist_array = calloc(histogram, sizeof(long));
+}
+
 if (verbose) {
 stat[i].values = calloc(VALBUF_SIZE, sizeof(long));
 if (!stat[i].values)
&lt; at &gt;&lt; at &gt; -882,14 +931,17 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 }
 
 par[i].prio = priority;
-if (priority)
+if (priority &amp;&amp; !histogram)
 priority--;
 par[i].clock = clocksources[clocksel];
 par[i].mode = mode;
 par[i].timermode = timermode;
 par[i].signal = signum;
 par[i].interval = interval;
-interval += distance;
+if (!histogram) /* histogram requires same interval on CPUs*/
+interval += distance;
+if (verbose)
+printf("Thread %d Interval: %d\n", i, interval);
 par[i].max_cycles = max_cycles;
 par[i].stats = &amp;stat[i];
 switch (setaffinity) {
&lt; at &gt;&lt; at &gt; -932,6 +984,7 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
  outall:
 shutdown = 1;
 usleep(50000);
+
 if (quiet)
 quiet = 2;
 for (i = 0; i &lt; num_threads; i++) {
&lt; at &gt;&lt; at &gt; -939,12 +992,19 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 pthread_kill(stat[i].thread, SIGTERM);
 if (stat[i].threadstarted) {
 pthread_join(stat[i].thread, NULL);
-if (quiet)
+if (quiet &amp;&amp; !histogram)
 print_stat(&amp;par[i], i, 0);
 }
 if (stat[i].values)
 free(stat[i].values);
 }
+
+if (histogram) {
+print_hist(par, num_threads);
+for (i = 0; i &lt; num_threads; i++) 
+free (stat[i].hist_array);
+}
+
 free(stat);
  outpar:
 free(par);


--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Sven-Thorsten Dietrich</dc:creator>
    <dc:date>2008-10-21T20:19:56</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3617">
    <title>[-rt] 2.6.26.6-rt11: Another sleeping function called from invalid context</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3617</link>
    <description>Hi,

when I boot the 2.6.26.6-rt11 kernel, I get another of these 'sleeping
function called from invalid context' error messages:

BUG: sleeping function called from invalid context IRQ-15(75) at
arch/x86/mm/highmem_32.c:8
in_atomic():0 [00000000], irqs_disabled():1
Pid: 75, comm: IRQ-15 Not tainted 2.6.26.6-rt11-HWS #2
 [&lt;c01155ce&gt;] __might_sleep+0xd4/0xdb
 [&lt;c0113da9&gt;] kmap+0x42/0x55
 [&lt;f8cb7969&gt;] ata_sff_hsm_move+0x3ca/0x671 [libata]
 [&lt;f8cb8865&gt;] ata_sff_interrupt+0x141/0x1c0 [libata]
 [&lt;c014a1e6&gt;] handle_IRQ_event+0x45/0xb6
 [&lt;c014ac23&gt;] do_irqd+0x126/0x223
 [&lt;c014aafd&gt;] ? do_irqd+0x0/0x223
 [&lt;c012b8c5&gt;] kthread+0x39/0x60
 [&lt;c012b88c&gt;] ? kthread+0x0/0x60
 [&lt;c0104507&gt;] kernel_thread_helper+0x7/0x10

Hardware is a Pentium-M Processor on an industrial PC mainboard with
Intel chip set, 1GB RAM, HDD + DVD ROM drives.
Software is OpenSUSE 10.3 with KDE 3.5.

The message comes up twice during start of the system and will be
repeated indefintely if there is a CD or DVD in the drive.

Bye,
            Jürgen

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Jürgen Mell</dc:creator>
    <dc:date>2008-10-18T20:17:40</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3616">
    <title>[PATCH -rt] sched: remove unneeded #if directive</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3616</link>
    <description>From: Hiroshi Shimamoto &lt;h-shimamoto&lt; at &gt;ct.jp.nec.com&gt;

__cond_resched_spinlock() is in #ifdef CONFIG_PREEMPT_RT.
So the following line always true.
#if (defined(CONFIG_SMP) &amp;&amp; defined(CONFIG_PREEMPT)) || defined(CONFIG_PREEMPT_RT)

Signed-off-by: Hiroshi Shimamoto &lt;h-shimamoto&lt; at &gt;ct.jp.nec.com&gt;
---
 kernel/sched.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index 0d68e79..2b34f00 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
&lt; at &gt;&lt; at &gt; -5841,7 +5841,6 &lt; at &gt;&lt; at &gt; EXPORT_SYMBOL(__cond_resched_raw_spinlock);
 
 int __cond_resched_spinlock(spinlock_t *lock)
 {
-#if (defined(CONFIG_SMP) &amp;&amp; defined(CONFIG_PREEMPT)) || defined(CONFIG_PREEMPT_RT)
 if (lock-&gt;break_lock) {
 lock-&gt;break_lock = 0;
 spin_unlock_no_resched(lock);
&lt; at &gt;&lt; at &gt; -5849,7 +5848,7 &lt; at &gt;&lt; at &gt; int __cond_resched_spinlock(spinlock_t *lock)
 spin_lock(lock);
 return 1;
 }
-#endif
+
 return 0;
 }
 EXPORT_SYMBOL(__cond_resched_spinlock);
</description>
    <dc:creator>Hiroshi Shimamoto</dc:creator>
    <dc:date>2008-10-18T01:21:29</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3612">
    <title>New rt-tests maintainer</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3612</link>
    <description>Hi everyone,

I'm handing over the maintainership of rt-tests (cyclictest,
signaltest, pi_stress) to Clark Williams.

rt-tests started with cyclictest, a test program I wrote for
validating the high resolution timers implementation. In hindsight I'm
still surprised that cyclictest became a defacto standard for
benchmarking preempt-rt, but on the technical side it's quite clear as
it tests the whole chain: interrupt -&gt; wakeup -&gt; scheduler -&gt;
userspace.

I never expected that cyclictest might ship with distros and I'm very
grateful to all the people who contributed and helped to bring it and
the whole rt-tests package into shape. I know that I'm a lousy user
space programmer :)

&lt; at &gt;Clark, thanks for taking over. It takes away my permanent guilty
conscience of not caring about rt-tests enough.

&lt; at &gt;all, please support Clark with his new project as you supported
me. Thanks for all the support and help again !

Thanks,

tglx

P.S.: If you really need to add autocrap^H^H^H^Htools please do it in
      a way so I still can hack on it :)
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Thomas Gleixner</dc:creator>
    <dc:date>2008-10-13T20:23:18</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3610">
    <title>[PATCH 2/2] add function_trace_stop</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3610</link>
    <description>
2.6.26.6-rt10 added /debug/tracing/function_trace_stop which is a very 
quick way of starting and stopping the tracer. It does not disable the 
mcount call, but just sets a variable in the mcount call to return.

This patch tries to open the function_trace_stop file and if it succeeds
it will use the trace stop to start and stop the tracer an keep the ftrace 
enabled the entire time.

Signed-off-by: Steven Rostedt &lt;srostedt&lt; at &gt;redhat.com&gt;
---
 src/cyclictest/cyclictest.c |   37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

Index: rt-tests.git/src/cyclictest/cyclictest.c
===================================================================
--- rt-tests.git.orig/src/cyclictest/cyclictest.c2008-10-13 15:04:11.000000000 -0400
+++ rt-tests.git/src/cyclictest/cyclictest.c2008-10-13 15:13:36.000000000 -0400
&lt; at &gt;&lt; at &gt; -134,6 +134,7 &lt; at &gt;&lt; at &gt; static int tracetype;
 static int lockall = 0;
 
 static int traceenable_fd = -1;
+static int funcstop_fd = -1;
 
 /* Backup of kernel variables that we modify */
 static struct kvars {
&lt; at &gt;&lt; at &gt; -153,7 +154,8 &lt; at &gt;&lt; at &gt; enum kernelversion {
 KV_NOT_26,
 KV_26_LT18,
 KV_26_LT24,
-KV_26_CURR
+KV_26_CURR,
+KV_26_QUICKSTOP,
 };
 
 enum {
&lt; at &gt;&lt; at &gt; -223,7 +225,7 &lt; at &gt;&lt; at &gt; static void setkernvar(const char *name,
 int i;
 char oldvalue[KVALUELEN];
 
-if (kernelversion != KV_26_CURR) {
+if (kernelversion &lt; KV_26_CURR) {
 if (kernvar(O_RDONLY, name, oldvalue, sizeof(oldvalue)))
 fprintf(stderr, "could not retrieve %s\n", name);
 else {
&lt; at &gt;&lt; at &gt; -283,6 +285,11 &lt; at &gt;&lt; at &gt; void set_trace_enable(char val)
 write(traceenable_fd, &amp;val, 1);
 }
 
+static void setfuncstop(char val)
+{
+write(funcstop_fd, &amp;val, 1);
+}
+
 void tracing(int on)
 {
 if (on) {
&lt; at &gt;&lt; at &gt; -290,6 +297,7 &lt; at &gt;&lt; at &gt; void tracing(int on)
 case KV_26_LT18: gettimeofday(0,(struct timezone *)1); break;
 case KV_26_LT24: prctl(0, 1); break;
 case KV_26_CURR: set_trace_enable('1'); break;
+case KV_26_QUICKSTOP: setfuncstop('0'); break;
 default: break;
 }
 } else {
&lt; at &gt;&lt; at &gt; -297,6 +305,7 &lt; at &gt;&lt; at &gt; void tracing(int on)
 case KV_26_LT18: gettimeofday(0,0); break;
 case KV_26_LT24: prctl(0, 0); break;
 case KV_26_CURR: set_trace_enable('0'); break;
+case KV_26_QUICKSTOP: setfuncstop('1'); break;
 default: break;
 }
 }
&lt; at &gt;&lt; at &gt; -378,7 +387,7 &lt; at &gt;&lt; at &gt; void *timerthread(void *param)
 interval.tv_nsec = (par-&gt;interval % USEC_PER_SEC) * 1000;
 
 if (tracelimit) {
-if (kernelversion == KV_26_CURR) {
+if (kernelversion &gt;= KV_26_CURR) {
 char buffer[32];
 int ret;
 
&lt; at &gt;&lt; at &gt; -858,6 +867,19 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 fprintf(stderr, "ERROR: %s not found\n"
     "debug fs not mounted, "
     "TRACERs not configured?\n", testname);
+} else {
+char *name = "function_trace_stop";
+
+strncpy(testname, fileprefix, sizeof(testname));
+strncat(testname, name, sizeof(testname) - strlen(fileprefix));
+funcstop_fd = open(testname, O_RDWR);
+if (funcstop_fd &gt;= 0) {
+/* enable tracing */
+tracing(1);
+kernelversion = KV_26_QUICKSTOP;
+/* stop it */
+tracing(0);
+}
 }
 } else if (tracelimit)
 fileprefix = procfileprefix;
&lt; at &gt;&lt; at &gt; -963,9 +985,16 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 munlockall();
 
 /* Be a nice program, cleanup */
-if (kernelversion != KV_26_CURR)
+if (kernelversion &lt; KV_26_CURR)
 restorekernvars();
 
+if (funcstop_fd &gt;= 0) {
+/* disable tracing */
+kernelversion = KV_26_CURR;
+tracing(0);
+close(funcstop_fd);
+}
+
 if (traceenable_fd &gt;= 0)
 close(traceenable_fd);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Steven Rostedt</dc:creator>
    <dc:date>2008-10-13T19:16:34</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3609">
    <title>[PATCH 1/2] cyclictest: preopen trace_enabled</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3609</link>
    <description>
The conversion to use kernvar caused an open and close at every iteration,
which is very expensive. This patch opens the file at start up and closes
it at exit.

Signed-off-by: Steven Rostedt &lt;srostedt&lt; at &gt;redhat.com&gt;
---
 src/cyclictest/cyclictest.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

Index: rt-tests.git/src/cyclictest/cyclictest.c
===================================================================
--- rt-tests.git.orig/src/cyclictest/cyclictest.c2008-10-13 13:01:59.000000000 -0400
+++ rt-tests.git/src/cyclictest/cyclictest.c2008-10-13 15:01:00.000000000 -0400
&lt; at &gt;&lt; at &gt; -133,6 +133,8 &lt; at &gt;&lt; at &gt; static int oscope_reduction = 1;
 static int tracetype;
 static int lockall = 0;
 
+static int traceenable_fd = -1;
+
 /* Backup of kernel variables that we modify */
 static struct kvars {
 char name[KVARNAMELEN];
&lt; at &gt;&lt; at &gt; -276,20 +278,25 &lt; at &gt;&lt; at &gt; static inline long calcdiff(struct times
 return diff;
 }
 
+void set_trace_enable(char val)
+{
+write(traceenable_fd, &amp;val, 1);
+}
+
 void tracing(int on)
 {
 if (on) {
 switch (kernelversion) {
 case KV_26_LT18: gettimeofday(0,(struct timezone *)1); break;
 case KV_26_LT24: prctl(0, 1); break;
-case KV_26_CURR: setkernvar("tracing_enabled", "1"); break;
+case KV_26_CURR: set_trace_enable('1'); break;
 default: break;
 }
 } else {
 switch (kernelversion) {
 case KV_26_LT18: gettimeofday(0,0); break;
 case KV_26_LT24: prctl(0, 0); break;
-case KV_26_CURR: setkernvar("tracing_enabled", "0"); break;
+case KV_26_CURR: set_trace_enable('0'); break;
 default: break;
 }
 }
&lt; at &gt;&lt; at &gt; -846,7 +853,8 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 
 strcpy(testname, debugfileprefix);
 strcat(testname, "tracing_enabled");
-if (access(testname, R_OK)) {
+traceenable_fd = open(testname, O_RDWR);
+if (traceenable_fd &lt; 0) {
 fprintf(stderr, "ERROR: %s not found\n"
     "debug fs not mounted, "
     "TRACERs not configured?\n", testname);
&lt; at &gt;&lt; at &gt; -958,5 +966,8 &lt; at &gt;&lt; at &gt; int main(int argc, char **argv)
 if (kernelversion != KV_26_CURR)
 restorekernvars();
 
+if (traceenable_fd &gt;= 0)
+close(traceenable_fd);
+
 exit(ret);
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo&lt; at &gt;vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

</description>
    <dc:creator>Steven Rostedt</dc:creator>
    <dc:date>2008-10-13T19:09:14</dc:date>
  </item>
  <item rdf:about="http://comments.gmane.org/gmane.linux.rt.user/3606">
    <title>2.6.26.6-rt10</title>
    <link>http://comments.gmane.org/gmane.linux.rt.user/3606</link>
    <description>We are pleased to announce the 2.6.26.6-rt10 tree, which can be
downloaded from the location:

  http://rt.et.redhat.com/download/

Information on the RT patch can be found at:

  http://rt.wiki.kernel.org/index.php/Main_Page

Changes since 2.6.26.5-rt9

  - ported to 2.6.26.6

  - rwlock to handle unnested order unlocks (Steven Rostedt)

  - rwlock update torture test to test unnested unlocks (Steven Rostedt)

  - remove rt push comment (Gregory Haskins)

  - rt sched fix to handle dequeue (Gregory Haskins)

  - PPC: remove duplicate stack trace code (Robert Schwebel)

  - ARM: ftrace event IRQ call fix (Alexander Pazdnikov)

  - fair sched not to resched RT tasks (Peter Zijlstra)

  - ftrace quick stop (Steven Rostedt)

  - event trace of resched (Steven Rostedt)


to build a 2.6.26.6-rt10 tree, the following patches should be applied:

  http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2
  http://kernel.org/pub/linux/kernel/v2.6/patch-2.6.26.6.bz2
  http://rt.et.redhat.com/download/patch-2.6.26.6-rt10.bz2



And like always, my RT version of Matt Mackall's ketchup will get this
for you nicely:

  http://people.redhat.com/srostedt/rt/tools/ketchup-0.9.8-rt3


The broken out patches are also available.


</description>
    <dc:creator>Steven Rostedt</dc:creator>
    <dc:date>2008-10-12T19:30:14</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.rt.user">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.rt.user</link>
  </textinput>
</rdf:RDF>
