Hi Richard,

Any comments for the new version patch?

On Mon, Apr 11, 2022 at 03:33:38PM +0800, Hangbin Liu wrote:
> Latest Linux kernel has supported getting PHC from bond directly. This
> would help topology like VLAN over bond to get PHC natively. To achieve
> this, the new hwtstamp flag is needed when passing hwtstamp_config to
> kernel. Let's supply the flag first, and fall back without flag if user
> run on old kernel.
> 
> Split port_change_phc() from function port_link_status() so the event
> functions could call it directly when find the phc changed.
> 
> Signed-off-by: Hangbin Liu <liuhang...@gmail.com>
> 
> v6: revert changes in clock_create(). Update ts_label by force and do
>     interface_get_tsinfo() only once.
> v5: no update
> v4: define HWTSTAMP_FLAG_BONDED_PHC_INDEX in missing.h
>     remove unneeded net_tstamp header files
> v3: remove ifdef in clock_create() and FD_RTNL event.
> v2: remove link state PHC_INDEX_CHANGED and use TS_LABEL_CHANGED only.
> ---
>  clock.c        |  3 ++
>  e2e_tc.c       |  7 ++++-
>  missing.h      |  6 ++++
>  p2p_tc.c       |  7 ++++-
>  port.c         | 74 +++++++++++++++++++++++++++++++-------------------
>  port_private.h |  1 +
>  sk.c           |  5 ++++
>  7 files changed, 73 insertions(+), 30 deletions(-)
> 
> diff --git a/clock.c b/clock.c
> index 7be021f..16ca6ed 100644
> --- a/clock.c
> +++ b/clock.c
> @@ -1767,6 +1767,9 @@ int clock_switch_phc(struct clock *c, int phc_index)
>       c->clkid = clkid;
>       c->servo = servo;
>       c->servo_state = SERVO_UNLOCKED;
> +
> +     pr_info("Switched to /dev/ptp%d as PTP clock", phc_index);
> +
>       return 0;
>  }
>  
> diff --git a/e2e_tc.c b/e2e_tc.c
> index 2f8e821..42baea3 100644
> --- a/e2e_tc.c
> +++ b/e2e_tc.c
> @@ -123,7 +123,12 @@ enum fsm_event e2e_event(struct port *p, int fd_index)
>  
>       case FD_RTNL:
>               pr_debug("%s: received link status notification", p->log_name);
> -             rtnl_link_status(fd, p->name, port_link_status, p);
> +             if (!interface_get_tsinfo(p->iface) &&
> +                 (p->phc_index != interface_phc_index(p->iface)))
> +                     port_change_phc(p);
> +             else
> +                     rtnl_link_status(fd, p->name, port_link_status, p);
> +
>               if (p->link_status == (LINK_UP|LINK_STATE_CHANGED)) {
>                       return EV_FAULT_CLEARED;
>               } else if ((p->link_status == (LINK_DOWN|LINK_STATE_CHANGED)) ||
> diff --git a/missing.h b/missing.h
> index 20f7193..4c7ac57 100644
> --- a/missing.h
> +++ b/missing.h
> @@ -73,6 +73,12 @@ struct so_timestamping {
>  };
>  #endif
>  
> +#ifndef HWTSTAMP_FLAG_BONDED_PHC_INDEX
> +enum {
> +     HWTSTAMP_FLAG_BONDED_PHC_INDEX = (1<<0),
> +};
> +#endif
> +
>  #ifdef PTP_EXTTS_REQUEST2
>  #define PTP_EXTTS_REQUEST_FAILED "PTP_EXTTS_REQUEST2 failed: %m"
>  #else
> diff --git a/p2p_tc.c b/p2p_tc.c
> index 75cb3b9..1164c9a 100644
> --- a/p2p_tc.c
> +++ b/p2p_tc.c
> @@ -126,7 +126,12 @@ enum fsm_event p2p_event(struct port *p, int fd_index)
>  
>       case FD_RTNL:
>               pr_debug("%s: received link status notification", p->log_name);
> -             rtnl_link_status(fd, p->name, port_link_status, p);
> +             if (!interface_get_tsinfo(p->iface) &&
> +                 (p->phc_index != interface_phc_index(p->iface)))
> +                     port_change_phc(p);
> +             else
> +                     rtnl_link_status(fd, p->name, port_link_status, p);
> +
>               if (p->link_status == (LINK_UP|LINK_STATE_CHANGED)) {
>                       return EV_FAULT_CLEARED;
>               } else if ((p->link_status == (LINK_DOWN|LINK_STATE_CHANGED)) ||
> diff --git a/port.c b/port.c
> index f2b666c..76e323f 100644
> --- a/port.c
> +++ b/port.c
> @@ -2636,10 +2636,48 @@ static void bc_dispatch(struct port *p, enum 
> fsm_event event, int mdiff)
>       }
>  }
>  
> +void port_change_phc(struct port *p)
> +{
> +     int required_modes;
> +
> +     /* Only switch phc with HW time stamping mode */
> +     if (!interface_tsinfo_valid(p->iface) ||
> +         interface_phc_index(p->iface) < 0)
> +             return;
> +
> +     required_modes = clock_required_modes(p->clock);
> +     if (!interface_tsmodes_supported(p->iface, required_modes)) {
> +             pr_err("interface '%s' does not support requested "
> +                    "timestamping mode, set link status down by force.",
> +                    interface_label(p->iface));
> +             p->link_status = LINK_DOWN | LINK_STATE_CHANGED;
> +     } else if (p->phc_from_cmdline) {
> +             pr_warning("%s: taking /dev/ptp%d from the "
> +                        "command line, not the attached ptp%d",
> +                        p->log_name, p->phc_index,
> +                        interface_phc_index(p->iface));
> +     } else if (p->phc_index != interface_phc_index(p->iface)) {
> +             p->phc_index = interface_phc_index(p->iface);
> +
> +             if (clock_switch_phc(p->clock, p->phc_index)) {
> +                     p->last_fault_type = FT_SWITCH_PHC;
> +                     port_dispatch(p, EV_FAULT_DETECTED, 0);
> +                     return;
> +             }
> +             clock_sync_interval(p->clock, p->log_sync_interval);
> +
> +             /* Ensure TS_LABEL_CHANGED is set for failover when
> +              * PHC changed as we may not call port_change_phc()
> +              * from port_link_status().
> +              */
> +             p->link_status |= TS_LABEL_CHANGED;
> +     }
> +}
> +
>  void port_link_status(void *ctx, int linkup, int ts_index)
>  {
>       char ts_label[MAX_IFNAME_SIZE + 1] = {0};
> -     int link_state, required_modes;
> +     int link_state;
>       const char *old_ts_label;
>       struct port *p = ctx;
>  
> @@ -2663,32 +2701,7 @@ void port_link_status(void *ctx, int linkup, int 
> ts_index)
>       if (p->link_status & LINK_UP &&
>           (p->link_status & LINK_STATE_CHANGED || p->link_status & 
> TS_LABEL_CHANGED)) {
>               interface_get_tsinfo(p->iface);
> -
> -             /* Only switch phc with HW time stamping mode */
> -             if (interface_tsinfo_valid(p->iface) &&
> -                 interface_phc_index(p->iface) >= 0) {
> -                     required_modes = clock_required_modes(p->clock);
> -                     if (!interface_tsmodes_supported(p->iface, 
> required_modes)) {
> -                             pr_err("interface '%s' does not support 
> requested "
> -                                    "timestamping mode, set link status down 
> by force.",
> -                                    interface_label(p->iface));
> -                             p->link_status = LINK_DOWN | LINK_STATE_CHANGED;
> -                     } else if (p->phc_from_cmdline) {
> -                             pr_warning("%s: taking /dev/ptp%d from the "
> -                                        "command line, not the attached 
> ptp%d",
> -                                        p->log_name, p->phc_index,
> -                                        interface_phc_index(p->iface));
> -                     } else if (p->phc_index != 
> interface_phc_index(p->iface)) {
> -                             p->phc_index = interface_phc_index(p->iface);
> -
> -                             if (clock_switch_phc(p->clock, p->phc_index)) {
> -                                     p->last_fault_type = FT_SWITCH_PHC;
> -                                     port_dispatch(p, EV_FAULT_DETECTED, 0);
> -                                     return;
> -                             }
> -                             clock_sync_interval(p->clock, 
> p->log_sync_interval);
> -                     }
> -             }
> +             port_change_phc(p);
>       }
>  
>       /*
> @@ -2802,7 +2815,12 @@ static enum fsm_event bc_event(struct port *p, int 
> fd_index)
>  
>       case FD_RTNL:
>               pr_debug("%s: received link status notification", p->log_name);
> -             rtnl_link_status(fd, p->name, port_link_status, p);
> +             if (!interface_get_tsinfo(p->iface) &&
> +                 (p->phc_index != interface_phc_index(p->iface)))
> +                     port_change_phc(p);
> +             else
> +                     rtnl_link_status(fd, p->name, port_link_status, p);
> +
>               if (p->link_status == (LINK_UP | LINK_STATE_CHANGED))
>                       return EV_FAULT_CLEARED;
>               else if ((p->link_status == (LINK_DOWN | LINK_STATE_CHANGED)) ||
> diff --git a/port_private.h b/port_private.h
> index d27dceb..2a800a9 100644
> --- a/port_private.h
> +++ b/port_private.h
> @@ -179,6 +179,7 @@ int port_delay_request(struct port *p);
>  void port_disable(struct port *p);
>  int port_initialize(struct port *p);
>  int port_is_enabled(struct port *p);
> +void port_change_phc(struct port *p);
>  void port_link_status(void *ctx, int index, int linkup);
>  int port_set_announce_tmo(struct port *p);
>  int port_set_delay_tmo(struct port *p);
> diff --git a/sk.c b/sk.c
> index b55d6b5..80075be 100644
> --- a/sk.c
> +++ b/sk.c
> @@ -66,6 +66,11 @@ static int hwts_init(int fd, const char *device, int 
> rx_filter,
>  
>       init_ifreq(&ifreq, &cfg, device);
>  
> +     cfg.flags = HWTSTAMP_FLAG_BONDED_PHC_INDEX;
> +     /* Fall back without flag if user run new build on old kernel */
> +     if (ioctl(fd, SIOCGHWTSTAMP, &ifreq) == -EINVAL)
> +             init_ifreq(&ifreq, &cfg, device);
> +
>       switch (sk_hwts_filter_mode) {
>       case HWTS_FILTER_CHECK:
>               err = ioctl(fd, SIOCGHWTSTAMP, &ifreq);
> -- 
> 2.35.1
> 


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

Reply via email to