Port a fix from FRR community (#3614)
Author: sudhanshukumar22 <sudhanshu.kumar@broadcom.com>
Date: Tue Oct 16 12:33:20 2019 -0700
39c93f379a
If we have a case where have created a fd for i/o and we have removed the
handling thread but still have the fd in the poll data structure, there
existed a case where we would get the handle this fd return from poll but we
would immediately do nothing with it because we didn't have a thread to hand
the event to.
This leads to an infinite loop. Prevent the infinite loop
from happening and log the problem.
Signed-off-by: Preetham Singh (preetham.singh@broadcom.com)
This commit is contained in:
parent
6ecec007e3
commit
5d9bd9c1ad
@ -0,0 +1,107 @@
|
|||||||
|
From e4225086634fb7ae7fa762f3a45af6ad39e78641 Mon Sep 17 00:00:00 2001
|
||||||
|
From: sudhanshukumar22 <sudhanshu.kumar@broadcom.com>
|
||||||
|
Date: Tue, 15 Oct 2019 02:17:00 -0700
|
||||||
|
Subject: [PATCH] Port a fix from FRR community
|
||||||
|
https://github.com/donaldsharp/frr/commit/39c93f379a5b57c56739a339ad75ec06e30daef3
|
||||||
|
If we have a case where have created a fd for i/o and we have removed the
|
||||||
|
handling thread but still have the fd in the poll data structure, there
|
||||||
|
existed a case where we would get the handle this fd return from poll but we
|
||||||
|
would immediately do nothing with it because we didn't have a thread to hand
|
||||||
|
the event to.
|
||||||
|
|
||||||
|
This leads to an infinite loop. Prevent the infinite loop
|
||||||
|
from happening and log the problem.
|
||||||
|
---
|
||||||
|
lib/lib_errors.c | 6 ++++++
|
||||||
|
lib/lib_errors.h | 1 +
|
||||||
|
lib/thread.c | 25 ++++++++++++++++++-------
|
||||||
|
3 files changed, 25 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/lib_errors.c b/lib/lib_errors.c
|
||||||
|
index b6c764d87..033f27e58 100644
|
||||||
|
--- a/lib/lib_errors.c
|
||||||
|
+++ b/lib/lib_errors.c
|
||||||
|
@@ -50,6 +50,12 @@ static struct log_ref ferr_lib_warn[] = {
|
||||||
|
.description = "The Event subsystem has detected a slow process, this typically indicates that FRR is having trouble completing work in a timely manner. This can be either a misconfiguration, bug, or some combination therof.",
|
||||||
|
.suggestion = "Gather log data and open an Issue",
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .code = EC_LIB_NO_THREAD,
|
||||||
|
+ .title = "The Event subsystem has detected an internal FD problem",
|
||||||
|
+ .description = "The Event subsystem has detected a file descriptor read/write event without an associated handling function. This is a bug, please collect log data and open an issue.",
|
||||||
|
+ .suggestion = "Gather log data and open an Issue",
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
.code = EC_LIB_RMAP_RECURSION_LIMIT,
|
||||||
|
.title = "Reached the Route-Map Recursion Limit",
|
||||||
|
diff --git a/lib/lib_errors.h b/lib/lib_errors.h
|
||||||
|
index 39b39fb06..996a16ba9 100644
|
||||||
|
--- a/lib/lib_errors.h
|
||||||
|
+++ b/lib/lib_errors.h
|
||||||
|
@@ -45,6 +45,7 @@ enum lib_log_refs {
|
||||||
|
EC_LIB_STREAM,
|
||||||
|
EC_LIB_LINUX_NS,
|
||||||
|
EC_LIB_SLOW_THREAD,
|
||||||
|
+ EC_LIB_NO_THREAD,
|
||||||
|
EC_LIB_RMAP_RECURSION_LIMIT,
|
||||||
|
EC_LIB_BACKUP_CONFIG,
|
||||||
|
EC_LIB_VRF_LENGTH,
|
||||||
|
diff --git a/lib/thread.c b/lib/thread.c
|
||||||
|
index 5ca859a74..82708557d 100644
|
||||||
|
--- a/lib/thread.c
|
||||||
|
+++ b/lib/thread.c
|
||||||
|
@@ -1235,12 +1235,26 @@ static struct thread *thread_run(struct thread_master *m, struct thread *thread,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int thread_process_io_helper(struct thread_master *m,
|
||||||
|
- struct thread *thread, short state, int pos)
|
||||||
|
+ struct thread *thread, short state, short actual_state, int pos)
|
||||||
|
{
|
||||||
|
struct thread **thread_array;
|
||||||
|
|
||||||
|
- if (!thread)
|
||||||
|
+ /*
|
||||||
|
+ * If another pthread scheduled this file descriptor for this event
|
||||||
|
+ * we're responding to, no problem, we're getting to it now.
|
||||||
|
+ * Additionally if !thread if we don't clear this now we'll
|
||||||
|
+ * infinaloop( which sucks )
|
||||||
|
+ */
|
||||||
|
+ m->handler.pfds[pos].events &= ~(state);
|
||||||
|
+
|
||||||
|
+ if (!thread) {
|
||||||
|
+ if ((actual_state & (POLLHUP | POLLIN)) != POLLHUP)
|
||||||
|
+ flog_err( EC_LIB_NO_THREAD,
|
||||||
|
+ "Attempting to process an I/O event but for fd: %d(%d) no thread to handle this!\n",
|
||||||
|
+ m->handler.pfds[pos].fd, actual_state);
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
if (thread->type == THREAD_READ)
|
||||||
|
thread_array = m->read;
|
||||||
|
@@ -1250,9 +1264,6 @@ static int thread_process_io_helper(struct thread_master *m,
|
||||||
|
thread_array[thread->u.fd] = NULL;
|
||||||
|
thread_list_add_tail(&m->ready, thread);
|
||||||
|
thread->type = THREAD_READY;
|
||||||
|
- /* if another pthread scheduled this file descriptor for the event we're
|
||||||
|
- * responding to, no problem; we're getting to it now */
|
||||||
|
- thread->master->handler.pfds[pos].events &= ~(state);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1290,10 +1301,10 @@ static void thread_process_io(struct thread_master *m, unsigned int num)
|
||||||
|
* should still be a valid index into the master's pfds. */
|
||||||
|
if (pfds[i].revents & (POLLIN | POLLHUP))
|
||||||
|
thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN,
|
||||||
|
- i);
|
||||||
|
+ pfds[i].revents,i);
|
||||||
|
if (pfds[i].revents & POLLOUT)
|
||||||
|
thread_process_io_helper(m, m->write[pfds[i].fd],
|
||||||
|
- POLLOUT, i);
|
||||||
|
+ POLLOUT, pfds[i].revents, i);
|
||||||
|
|
||||||
|
/* if one of our file descriptors is garbage, remove the same
|
||||||
|
* from
|
||||||
|
--
|
||||||
|
2.18.0
|
||||||
|
|
@ -3,3 +3,4 @@
|
|||||||
0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch
|
0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch
|
||||||
0005-Support-VRF.patch
|
0005-Support-VRF.patch
|
||||||
0006-changes-for-making-snmp-socket-non-blocking.patch
|
0006-changes-for-making-snmp-socket-non-blocking.patch
|
||||||
|
0007-prevent-dead-fd-poll-data-port-fix-from-frr.patch
|
||||||
|
Reference in New Issue
Block a user