ptp4l opens separate sockets for general and for event messages,
regardless of which PTP transport is being used. In the case of L4 PTP,
separate UDP ports are used (319 and 320) but in the case of L2 (raw)
PTP, there is no differentiation except for one bit in the messageType
field of the common PTP header. So to preserve that separation for L2,
ptp4l also opens 2 raw sockets, and adds 2 BPF filters on the same
interface, one matching on general messages and the other on events.

But having an ETH_P_ALL raw socket (in the kernel, a "ptype_all" handler)
is akin to having tcpdump open, which means that the kernel will need to
call:

        if (dev_nit_active(dev))
                dev_queue_xmit_nit(skb, dev);

for delivering skb's back to user space via a "network interface tap".
It also makes all traffic flowing through this interface be a candidate
for being delivered to the socket.

This means that all traffic on the interface will run through the BPF
filter installed by ptp4l. This might degrade performance quite visibly.
In the example below, ___bpf_prog_run is the #2 consumer in terms of CPU
cycles for an iperf3 TCP session, because ptp4l is running in the
background.

What we can do is to stop opening "packet type all" raw sockets, but
just open a raw socket for the EtherType we are interested in, which is
0x88f7 in the case of PTP. This is a well-known EtherType required by
IEEE 1588 as per Annex F.2 Ethertype. So we should not be expecting
various profiles to be able to change it.

Therefore, the BPF filter now runs on a lot less traffic, as can be seen
below, where the CPU usage has dropped so low that it is below the 1%
threshold used for my printing:

perf record -e cycles iperf3 -c 192.168.1.2 -t 10000

Before:

  Overhead  Command  Shared Object       Symbol
  ........  .......  ..................  ......................................

    49.62%  iperf3   [kernel.kallsyms]   [k] arm_copy_from_user
     2.63%  iperf3   [kernel.kallsyms]   [k] ___bpf_prog_run
     2.22%  iperf3   [kernel.kallsyms]   [k] tcp_ack
     2.19%  iperf3   [kernel.kallsyms]   [k] tcp_sendmsg_locked
     1.89%  iperf3   [kernel.kallsyms]   [k] get_page_from_freelist
     1.29%  iperf3   [kernel.kallsyms]   [k] kmem_cache_alloc
     1.08%  iperf3   [kernel.kallsyms]   [k] __kmalloc_track_caller
     1.07%  iperf3   [kernel.kallsyms]   [k] gfar_start_xmit
     1.00%  iperf3   [kernel.kallsyms]   [k] tcp_write_xmit

After:

  Overhead  Command  Shared Object       Symbol
  ........  .......  ..................  ......................................

    49.40%  iperf3   [kernel.kallsyms]   [k] arm_copy_from_user
     2.03%  iperf3   [kernel.kallsyms]   [k] tcp_sendmsg_locked
     2.00%  iperf3   [kernel.kallsyms]   [k] __softirqentry_text_start
     1.83%  iperf3   [kernel.kallsyms]   [k] get_page_from_freelist
     1.53%  iperf3   [kernel.kallsyms]   [k] tcp_ack
     1.42%  iperf3   [kernel.kallsyms]   [k] gfar_start_xmit
     1.16%  iperf3   [kernel.kallsyms]   [k] gfar_poll_tx_sq
     1.13%  iperf3   [kernel.kallsyms]   [k] __kmalloc_track_caller
     1.05%  iperf3   [kernel.kallsyms]   [k] kmem_cache_alloc
     1.01%  iperf3   [kernel.kallsyms]   [k] ipt_do_table

Signed-off-by: Vladimir Oltean <olte...@gmail.com>
---
 raw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/raw.c b/raw.c
index b933c4518ea6..a8fb473e0686 100644
--- a/raw.c
+++ b/raw.c
@@ -148,7 +148,7 @@ static int open_socket(const char *name, int event, 
unsigned char *ptp_dst_mac,
        struct sockaddr_ll addr;
        int fd, index;
 
-       fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+       fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_1588));
        if (fd < 0) {
                pr_err("socket failed: %m");
                goto no_socket;
@@ -160,7 +160,7 @@ static int open_socket(const char *name, int event, 
unsigned char *ptp_dst_mac,
        memset(&addr, 0, sizeof(addr));
        addr.sll_ifindex = index;
        addr.sll_family = AF_PACKET;
-       addr.sll_protocol = htons(ETH_P_ALL);
+       addr.sll_protocol = htons(ETH_P_1588);
        if (bind(fd, (struct sockaddr *) &addr, sizeof(addr))) {
                pr_err("bind failed: %m");
                goto no_option;
-- 
2.25.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to