Put fault_fd into struct port

The fault timer file descriptor is a per port item, put it inside struct
port where other per port file descriptors are kept.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
master
Jiri Benc 2014-08-14 15:56:01 +02:00 committed by Richard Cochran
parent bdb6a35883
commit 2d1a88ca5d
3 changed files with 74 additions and 22 deletions

18
clock.c
View File

@ -82,7 +82,6 @@ struct clock {
struct ClockIdentity best_id; struct ClockIdentity best_id;
struct port *port[CLK_N_PORTS]; struct port *port[CLK_N_PORTS];
struct pollfd pollfd[CLK_N_PORTS*N_CLOCK_PFD]; struct pollfd pollfd[CLK_N_PORTS*N_CLOCK_PFD];
int fault_fd[CLK_N_PORTS];
int nports; /* does not include the UDS port */ int nports; /* does not include the UDS port */
int free_running; int free_running;
int freq_est_interval; int freq_est_interval;
@ -257,10 +256,8 @@ void clock_destroy(struct clock *c)
int i; int i;
clock_flush_subscriptions(c); clock_flush_subscriptions(c);
for (i = 0; i < c->nports; i++) { for (i = 0; i < c->nports; i++)
port_close(c->port[i]); port_close(c->port[i]);
close(c->fault_fd[i]);
}
port_close(c->port[i]); /*uds*/ port_close(c->port[i]); /*uds*/
if (c->clkid != CLOCK_REALTIME) { if (c->clkid != CLOCK_REALTIME) {
phc_close(c->clkid); phc_close(c->clkid);
@ -282,7 +279,7 @@ static int clock_fault_timeout(struct clock *c, int index, int set)
if (!set) { if (!set) {
pr_debug("clearing fault on port %d", index + 1); pr_debug("clearing fault on port %d", index + 1);
return set_tmo_lin(c->fault_fd[index], 0); return port_set_fault_timer_lin(c->port[index], 0);
} }
fault_interval(c->port[index], last_fault_type(c->port[index]), &i); fault_interval(c->port[index], last_fault_type(c->port[index]), &i);
@ -290,11 +287,11 @@ static int clock_fault_timeout(struct clock *c, int index, int set)
if (i.type == FTMO_LINEAR_SECONDS) { if (i.type == FTMO_LINEAR_SECONDS) {
pr_debug("waiting %d seconds to clear fault on port %d", pr_debug("waiting %d seconds to clear fault on port %d",
i.val, index + 1); i.val, index + 1);
return set_tmo_lin(c->fault_fd[index], i.val); return port_set_fault_timer_lin(c->port[index], i.val);
} else if (i.type == FTMO_LOG2_SECONDS) { } else if (i.type == FTMO_LOG2_SECONDS) {
pr_debug("waiting 2^{%d} seconds to clear fault on port %d", pr_debug("waiting 2^{%d} seconds to clear fault on port %d",
i.val, index + 1); i.val, index + 1);
return set_tmo_log(c->fault_fd[index], 1, i.val); return port_set_fault_timer_log(c->port[index], 1, i.val);
} }
pr_err("Unsupported fault interval type %d", i.type); pr_err("Unsupported fault interval type %d", i.type);
@ -863,12 +860,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count,
pr_err("failed to open port %s", iface[i].name); pr_err("failed to open port %s", iface[i].name);
return NULL; return NULL;
} }
c->fault_fd[i] = timerfd_create(CLOCK_MONOTONIC, 0); c->pollfd[N_CLOCK_PFD * i + N_POLLFD].fd = port_fault_fd(c->port[i]);
if (c->fault_fd[i] < 0) {
pr_err("timerfd_create failed: %m");
return NULL;
}
c->pollfd[N_CLOCK_PFD * i + N_POLLFD].fd = c->fault_fd[i];
c->pollfd[N_CLOCK_PFD * i + N_POLLFD].events = POLLIN|POLLPRI; c->pollfd[N_CLOCK_PFD * i + N_POLLFD].events = POLLIN|POLLPRI;
} }

49
port.c
View File

@ -65,6 +65,7 @@ struct port {
struct transport *trp; struct transport *trp;
enum timestamp_type timestamping; enum timestamp_type timestamping;
struct fdarray fda; struct fdarray fda;
int fault_fd;
struct foreign_clock *best; struct foreign_clock *best;
enum syfu_state syfu; enum syfu_state syfu;
struct ptp_message *last_syncfup; struct ptp_message *last_syncfup;
@ -193,6 +194,11 @@ int fault_interval(struct port *port, enum fault_type ft,
return 0; return 0;
} }
int port_fault_fd(struct port *port)
{
return port->fault_fd;
}
int set_tmo_log(int fd, unsigned int scale, int log_seconds) int set_tmo_log(int fd, unsigned int scale, int log_seconds)
{ {
struct itimerspec tmo = { struct itimerspec tmo = {
@ -253,6 +259,17 @@ int set_tmo_random(int fd, int min, int span, int log_seconds)
return timerfd_settime(fd, 0, &tmo, NULL); return timerfd_settime(fd, 0, &tmo, NULL);
} }
int port_set_fault_timer_log(struct port *port,
unsigned int scale, int log_seconds)
{
return set_tmo_log(port->fault_fd, scale, log_seconds);
}
int port_set_fault_timer_lin(struct port *port, int seconds)
{
return set_tmo_lin(port->fault_fd, seconds);
}
static void fc_clear(struct foreign_clock *fc) static void fc_clear(struct foreign_clock *fc)
{ {
struct ptp_message *m; struct ptp_message *m;
@ -1903,6 +1920,8 @@ void port_close(struct port *p)
} }
transport_destroy(p->trp); transport_destroy(p->trp);
filter_destroy(p->delay_filter); filter_destroy(p->delay_filter);
if (p->fault_fd >= 0)
close(p->fault_fd);
free(p); free(p);
} }
@ -2408,18 +2427,15 @@ struct port *port_open(int phc_index,
pr_err("port %d: PHC device mismatch", number); pr_err("port %d: PHC device mismatch", number);
pr_err("port %d: /dev/ptp%d requested, but /dev/ptp%d attached", pr_err("port %d: /dev/ptp%d requested, but /dev/ptp%d attached",
number, phc_index, interface->ts_info.phc_index); number, phc_index, interface->ts_info.phc_index);
free(p); goto err_port;
return NULL;
} }
p->pod = interface->pod; p->pod = interface->pod;
p->name = interface->name; p->name = interface->name;
p->clock = clock; p->clock = clock;
p->trp = transport_create(interface->transport); p->trp = transport_create(interface->transport);
if (!p->trp) { if (!p->trp)
free(p); goto err_port;
return NULL;
}
p->timestamping = timestamping; p->timestamping = timestamping;
p->portIdentity.clockIdentity = clock_identity(clock); p->portIdentity.clockIdentity = clock_identity(clock);
p->portIdentity.portNumber = number; p->portIdentity.portNumber = number;
@ -2431,12 +2447,27 @@ struct port *port_open(int phc_index,
interface->delay_filter_length); interface->delay_filter_length);
if (!p->delay_filter) { if (!p->delay_filter) {
pr_err("Failed to create delay filter"); pr_err("Failed to create delay filter");
transport_destroy(p->trp); goto err_transport;
free(p);
return NULL;
} }
p->nrate.ratio = 1.0; p->nrate.ratio = 1.0;
p->fault_fd = -1;
if (number) {
p->fault_fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (p->fault_fd < 0) {
pr_err("timerfd_create failed: %m");
goto err_filter;
}
}
return p; return p;
err_filter:
filter_destroy(p->delay_filter);
err_transport:
transport_destroy(p->trp);
err_port:
free(p);
return NULL;
} }
enum port_state port_state(struct port *port) enum port_state port_state(struct port *port)

29
port.h
View File

@ -200,6 +200,13 @@ struct port *port_open(int phc_index,
*/ */
enum port_state port_state(struct port *port); enum port_state port_state(struct port *port);
/**
* Return file descriptor of the port.
* @param port A port instance.
* @return File descriptor or -1 if not applicable.
*/
int port_fault_fd(struct port *port);
/** /**
* Utility function for setting or resetting a file descriptor timer. * Utility function for setting or resetting a file descriptor timer.
* *
@ -244,6 +251,28 @@ int set_tmo_random(int fd, int min, int span, int log_seconds);
*/ */
int set_tmo_lin(int fd, int seconds); int set_tmo_lin(int fd, int seconds);
/**
* Sets port's fault file descriptor timer.
* Passing both 'scale' and 'log_seconds' as zero disables the timer.
*
* @param fd A port instance.
* @param scale The multiplicative factor for the timer.
* @param log_seconds The exponential factor for the timer.
* @return Zero on success, non-zero otherwise.
*/
int port_set_fault_timer_log(struct port *port,
unsigned int scale, int log_seconds);
/**
* Sets port's fault file descriptor timer.
* Passing 'seconds' as zero disables the timer.
*
* @param fd A port instance.
* @param seconds The timeout value for the timer.
* @return Zero on success, non-zero otherwise.
*/
int port_set_fault_timer_lin(struct port *port, int seconds);
/** /**
* Returns a port's last fault type. * Returns a port's last fault type.
* *