Commit b9f3fde4 authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'rubi-150821' into HEAD

Fix problem with hanging send in PPSI
parents ed2122f4 2f989cb5
...@@ -210,6 +210,11 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -210,6 +210,11 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len,
ppi->t_ops->get(ppi, t); ppi->t_ops->get(ppi, t);
ret = send(ch->fd, hdr, len, 0); ret = send(ch->fd, hdr, len, 0);
if (ret < 0) {
pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
return ret;
}
if (pp_diag_allow(ppi, frames, 2)) if (pp_diag_allow(ppi, frames, 2))
dump_1588pkt("send: ", pkt, len, t); dump_1588pkt("send: ", pkt, len, t);
return ret; return ret;
...@@ -228,9 +233,13 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -228,9 +233,13 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len,
ppi->t_ops->get(ppi, t); ppi->t_ops->get(ppi, t);
ret = send(ch->fd, vhdr, len, 0); ret = send(ch->fd, vhdr, len, 0);
if (ret < 0) {
pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
return ret;
}
if (pp_diag_allow(ppi, frames, 2)) if (pp_diag_allow(ppi, frames, 2))
dump_1588pkt("send: ", vhdr, len, t); dump_1588pkt("send: ", vhdr, len, t);
return ret;
case PPSI_PROTO_UDP: case PPSI_PROTO_UDP:
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
...@@ -243,8 +252,11 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -243,8 +252,11 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len,
ret = sendto(ppi->ch[chtype].fd, pkt, len, 0, ret = sendto(ppi->ch[chtype].fd, pkt, len, 0,
(struct sockaddr *)&addr, (struct sockaddr *)&addr,
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
if (pp_diag_allow(ppi, frames, 2)) if (ret < 0) {
dump_payloadpkt("send: ", pkt, len, t); pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
return ret;
}
return ret; return ret;
default: default:
...@@ -265,7 +277,7 @@ static int unix_open_ch_raw(struct pp_instance *ppi, char *ifname, int chtype) ...@@ -265,7 +277,7 @@ static int unix_open_ch_raw(struct pp_instance *ppi, char *ifname, int chtype)
/* open socket */ /* open socket */
context = "socket()"; context = "socket()";
sock = socket(PF_PACKET, SOCK_RAW, ETH_P_1588); sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK, ETH_P_1588);
if (sock < 0) if (sock < 0)
goto err_out; goto err_out;
...@@ -339,7 +351,7 @@ static int unix_open_ch_udp(struct pp_instance *ppi, char *ifname, int chtype) ...@@ -339,7 +351,7 @@ static int unix_open_ch_udp(struct pp_instance *ppi, char *ifname, int chtype)
char *context; char *context;
context = "socket()"; context = "socket()";
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); sock = socket(PF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
if (sock < 0) if (sock < 0)
goto err_out; goto err_out;
......
...@@ -349,7 +349,7 @@ static void poll_tx_timestamp(struct pp_instance *ppi, void *pkt, int len, ...@@ -349,7 +349,7 @@ static void poll_tx_timestamp(struct pp_instance *ppi, void *pkt, int len,
} control; } control;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct pollfd pfd; struct pollfd pfd;
int res, retry = 0;; int res, retry;
struct sock_extended_err *serr = NULL; struct sock_extended_err *serr = NULL;
struct scm_timestamping *sts = NULL; struct scm_timestamping *sts = NULL;
...@@ -368,33 +368,40 @@ static void poll_tx_timestamp(struct pp_instance *ppi, void *pkt, int len, ...@@ -368,33 +368,40 @@ static void poll_tx_timestamp(struct pp_instance *ppi, void *pkt, int len,
t->seconds = t->correct = 0; t->seconds = t->correct = 0;
pfd.fd = fd; pfd.fd = fd;
pfd.events = POLLIN; pfd.events = POLLERR;
while (1) { /* Not forever: we break after a few runs */
#define N_RETRY 3
for (retry = 0; retry < N_RETRY; retry++) {
errno = 0; errno = 0;
res = poll(&pfd, 1, 20 /* ms */); res = poll(&pfd, 1, 2 /* ms */);
if (res != 1) { if (res < 0 && errno != EAGAIN) {
pp_diag(ppi, time, 1, "%s: poll() = %i (%s)\n", pp_diag(ppi, time, 1, "%s: poll() = %i (%s)\n",
__func__, res, strerror(errno)); __func__, res, strerror(errno));
if (retry++ > 5)
return;
continue; continue;
} }
if (res < 1)
continue;
res = recvmsg(fd, &msg, MSG_ERRQUEUE); res = recvmsg(fd, &msg, MSG_ERRQUEUE);
if (res <= 0) { if (res <= 0) {
/* sometimes we got EAGAIN despite poll() = 1 */
pp_diag(ppi, time, 1, "%s: recvmsg() = %i (%s)\n", pp_diag(ppi, time, 1, "%s: recvmsg() = %i (%s)\n",
__func__, res, strerror(errno)); __func__, res, strerror(errno));
return; continue;
} }
/* Now, check if this frame is our frame. If not, retry */ /* Now, check if this frame is our frame. If not, retry */
if (!memcmp(data, pkt, len)) if (!memcmp(data, pkt, len))
break; break;
pp_diag(ppi, time, 1, "%s: recvmsg(): not our frame\n", pp_diag(ppi, time, 1, "%s: recvmsg(): not our frame\n",
__func__); __func__);
/* We won't pop out wrong stamps forever... */
if (retry++ > 5)
return;
} }
if (retry) {
pp_diag(ppi, time, 1, "%s: %i iterations. %s\n", __func__,
retry, errno ? strerror(errno) : "");
}
if (retry == N_RETRY) /* we got nothing */
return;
if (!t) /* maybe caller is not interested, though we popped it out */ if (!t) /* maybe caller is not interested, though we popped it out */
return; return;
...@@ -468,6 +475,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -468,6 +475,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
ppi->t_ops->get(ppi, t); ppi->t_ops->get(ppi, t);
ret = send(ch->fd, hdr, len, 0); ret = send(ch->fd, hdr, len, 0);
if (ret < 0) {
pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
break;
}
poll_tx_timestamp(ppi, pkt, len, s, ch->fd, t); poll_tx_timestamp(ppi, pkt, len, s, ch->fd, t);
if (drop) /* avoid messaging about stamps that are not used */ if (drop) /* avoid messaging about stamps that are not used */
...@@ -498,6 +510,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -498,6 +510,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
if (len < 64) if (len < 64)
len = 64; len = 64;
ret = send(ch->fd, vhdr, len, 0); ret = send(ch->fd, vhdr, len, 0);
if (ret < 0) {
pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
break;
}
poll_tx_timestamp(ppi, pkt, len, s, ch->fd, t); poll_tx_timestamp(ppi, pkt, len, s, ch->fd, t);
if (drop) /* avoid messaging about stamps that are not used */ if (drop) /* avoid messaging about stamps that are not used */
...@@ -519,6 +536,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len, ...@@ -519,6 +536,11 @@ int wrs_net_send(struct pp_instance *ppi, void *pkt, int len,
addr.sin_port = 3200; addr.sin_port = 3200;
ret = sendto(fd, pkt, len, 0, (struct sockaddr *)&addr, ret = sendto(fd, pkt, len, 0, (struct sockaddr *)&addr,
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
if (ret < 0) {
pp_diag(ppi, frames, 0, "send failed: %s\n",
strerror(errno));
break;
}
poll_tx_timestamp(ppi, pkt, len, s, fd, t); poll_tx_timestamp(ppi, pkt, len, s, fd, t);
if (drop) /* like above: skil messages about timestamps */ if (drop) /* like above: skil messages about timestamps */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment