struct tcphdr *th2;
        unsigned int thlen;
        unsigned int flags;
-       unsigned int total;
        unsigned int mss = 1;
        int flush = 1;
+       int i;
 
        th = skb_gro_header(skb, sizeof(*th));
        if (unlikely(!th))
 
                th2 = tcp_hdr(p);
 
-               if (th->source != th2->source || th->dest != th2->dest) {
+               if ((th->source ^ th2->source) | (th->dest ^ th2->dest)) {
                        NAPI_GRO_CB(p)->same_flow = 0;
                        continue;
                }
        flush |= flags & TCP_FLAG_CWR;
        flush |= (flags ^ tcp_flag_word(th2)) &
                  ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH);
-       flush |= th->ack_seq != th2->ack_seq || th->window != th2->window;
-       flush |= memcmp(th + 1, th2 + 1, thlen - sizeof(*th));
+       flush |= (th->ack_seq ^ th2->ack_seq) | (th->window ^ th2->window);
+       for (i = sizeof(*th); !flush && i < thlen; i += 4)
+               flush |= *(u32 *)((u8 *)th + i) ^
+                        *(u32 *)((u8 *)th2 + i);
 
-       total = skb_gro_len(p);
        mss = skb_shinfo(p)->gso_size;
 
-       flush |= skb_gro_len(skb) > mss || !skb_gro_len(skb);
-       flush |= ntohl(th2->seq) + total != ntohl(th->seq);
+       flush |= (skb_gro_len(skb) > mss) | !skb_gro_len(skb);
+       flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq);
 
        if (flush || skb_gro_receive(head, skb)) {
                mss = 1;