summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command.c2
-rw-r--r--lib/distribute.c25
-rw-r--r--lib/hash.c11
-rw-r--r--lib/hash.h2
-rw-r--r--lib/if.c16
-rw-r--r--lib/if_rmap.c12
-rw-r--r--lib/memory.c10
-rw-r--r--lib/memtypes.c1
-rw-r--r--lib/prefix.c15
-rw-r--r--lib/prefix.h20
-rw-r--r--lib/sockunion.c40
-rw-r--r--lib/sockunion.h2
-rw-r--r--lib/table.c14
-rw-r--r--lib/thread.c146
-rw-r--r--lib/thread.h3
-rw-r--r--lib/vty.c3
-rw-r--r--lib/workqueue.c19
-rw-r--r--lib/zclient.c23
18 files changed, 265 insertions, 99 deletions
diff --git a/lib/command.c b/lib/command.c
index ebb50b40..4f6d184d 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -3648,6 +3648,8 @@ cmd_init (int terminal)
install_element (VIEW_NODE, &show_thread_cpu_cmd);
install_element (ENABLE_NODE, &show_thread_cpu_cmd);
install_element (RESTRICTED_NODE, &show_thread_cpu_cmd);
+
+ install_element (ENABLE_NODE, &clear_thread_cpu_cmd);
install_element (VIEW_NODE, &show_work_queues_cmd);
install_element (ENABLE_NODE, &show_work_queues_cmd);
}
diff --git a/lib/distribute.c b/lib/distribute.c
index 7f84b80e..04889030 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -114,16 +114,11 @@ distribute_get (const char *ifname)
}
static unsigned int
-distribute_hash_make (struct distribute *dist)
+distribute_hash_make (void *arg)
{
- unsigned int i, key;
+ const struct distribute *dist = arg;
- key = 0;
- if (dist->ifname)
- for (i = 0; i < strlen (dist->ifname); i++)
- key += dist->ifname[i];
-
- return key;
+ return dist->ifname ? string_hash_make (dist->ifname) : 0;
}
/* If two distribute-list have same value then return 1 else return
@@ -304,7 +299,6 @@ DEFUN (distribute_list_all,
"Filter outgoing routing updates\n")
{
enum distribute_type type;
- struct distribute *dist;
/* Check of distribute list type. */
if (strncmp (argv[1], "i", 1) == 0)
@@ -319,7 +313,7 @@ DEFUN (distribute_list_all,
}
/* Get interface name corresponding distribute list. */
- dist = distribute_list_set (NULL, type, argv[0]);
+ distribute_list_set (NULL, type, argv[0]);
return CMD_SUCCESS;
}
@@ -384,7 +378,6 @@ DEFUN (distribute_list,
"Interface name\n")
{
enum distribute_type type;
- struct distribute *dist;
/* Check of distribute list type. */
if (strncmp (argv[1], "i", 1) == 0)
@@ -398,7 +391,7 @@ DEFUN (distribute_list,
}
/* Get interface name corresponding distribute list. */
- dist = distribute_list_set (argv[2], type, argv[0]);
+ distribute_list_set (argv[2], type, argv[0]);
return CMD_SUCCESS;
}
@@ -463,7 +456,6 @@ DEFUN (distribute_list_prefix_all,
"Filter outgoing routing updates\n")
{
enum distribute_type type;
- struct distribute *dist;
/* Check of distribute list type. */
if (strncmp (argv[1], "i", 1) == 0)
@@ -478,7 +470,7 @@ DEFUN (distribute_list_prefix_all,
}
/* Get interface name corresponding distribute list. */
- dist = distribute_list_prefix_set (NULL, type, argv[0]);
+ distribute_list_prefix_set (NULL, type, argv[0]);
return CMD_SUCCESS;
}
@@ -546,7 +538,6 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
"Interface name\n")
{
enum distribute_type type;
- struct distribute *dist;
/* Check of distribute list type. */
if (strncmp (argv[1], "i", 1) == 0)
@@ -561,7 +552,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd,
}
/* Get interface name corresponding distribute list. */
- dist = distribute_list_prefix_set (argv[2], type, argv[0]);
+ distribute_list_prefix_set (argv[2], type, argv[0]);
return CMD_SUCCESS;
}
@@ -763,7 +754,7 @@ distribute_list_reset ()
void
distribute_list_init (int node)
{
- disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make,
+ disthash = hash_create (distribute_hash_make,
(int (*) (const void *, const void *)) distribute_cmp);
if(node==RIP_NODE) {
diff --git a/lib/hash.c b/lib/hash.c
index 672327ec..6db79ea7 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -101,6 +101,17 @@ hash_lookup (struct hash *hash, void *data)
return hash_get (hash, data, NULL);
}
+/* Simple Bernstein hash which is simple and fast for common case */
+unsigned int string_hash_make (const char *str)
+{
+ unsigned int hash = 0;
+
+ while (*str)
+ hash = (hash * 33) ^ (unsigned int) *str++;
+
+ return hash;
+}
+
/* This function release registered value from specified hash. When
release is successfully finished, return the data pointer in the
hash backet. */
diff --git a/lib/hash.h b/lib/hash.h
index f4b1c23e..4cb772e5 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -70,4 +70,6 @@ extern void hash_iterate (struct hash *,
extern void hash_clean (struct hash *, void (*) (void *));
extern void hash_free (struct hash *);
+extern unsigned int string_hash_make (const char *);
+
#endif /* _ZEBRA_HASH_H */
diff --git a/lib/if.c b/lib/if.c
index 31c60e3f..1e99ffbc 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -426,16 +426,20 @@ if_flag_dump (unsigned long flag)
static void
if_dump (const struct interface *ifp)
{
- zlog_info ("Interface %s index %d metric %d mtu %d "
+ struct listnode *node;
+ struct connected *c;
+
+ for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c))
+ zlog_info ("Interface %s index %d metric %d mtu %d "
#ifdef HAVE_IPV6
- "mtu6 %d "
+ "mtu6 %d "
#endif /* HAVE_IPV6 */
- "%s",
- ifp->name, ifp->ifindex, ifp->metric, ifp->mtu,
+ "%s",
+ ifp->name, ifp->ifindex, ifp->metric, ifp->mtu,
#ifdef HAVE_IPV6
- ifp->mtu6,
+ ifp->mtu6,
#endif /* HAVE_IPV6 */
- if_flag_dump (ifp->flags));
+ if_flag_dump (ifp->flags));
}
/* Interface printing for all interface. */
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index ddc62fd5..7d049b87 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -109,14 +109,9 @@ if_rmap_get (const char *ifname)
static unsigned int
if_rmap_hash_make (void *data)
{
- struct if_rmap *if_rmap = data;
- unsigned int i, key;
+ const struct if_rmap *if_rmap = data;
- key = 0;
- for (i = 0; i < strlen (if_rmap->ifname); i++)
- key += if_rmap->ifname[i];
-
- return key;
+ return string_hash_make (if_rmap->ifname);
}
static int
@@ -212,7 +207,6 @@ DEFUN (if_rmap,
"Route map interface name\n")
{
enum if_rmap_type type;
- struct if_rmap *if_rmap;
if (strncmp (argv[1], "i", 1) == 0)
type = IF_RMAP_IN;
@@ -224,7 +218,7 @@ DEFUN (if_rmap,
return CMD_WARNING;
}
- if_rmap = if_rmap_set (argv[2], type, argv[0]);
+ if_rmap_set (argv[2], type, argv[0]);
return CMD_SUCCESS;
}
diff --git a/lib/memory.c b/lib/memory.c
index 4bac31db..4090fd90 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -111,6 +111,9 @@ zrealloc (int type, void *ptr, size_t size)
memory = realloc (ptr, size);
if (memory == NULL)
zerror ("realloc", type, size);
+ if (ptr == NULL)
+ alloc_inc (type);
+
return memory;
}
@@ -123,8 +126,11 @@ zrealloc (int type, void *ptr, size_t size)
void
zfree (int type, void *ptr)
{
- alloc_dec (type);
- free (ptr);
+ if (ptr != NULL)
+ {
+ alloc_dec (type);
+ free (ptr);
+ }
}
/*
diff --git a/lib/memtypes.c b/lib/memtypes.c
index d0ce8c5e..d2bc1c62 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -106,6 +106,7 @@ struct memory_list memory_list_bgp[] =
{ MTYPE_BGP_NODE, "BGP node" },
{ MTYPE_BGP_ROUTE, "BGP route" },
{ MTYPE_BGP_ROUTE_EXTRA, "BGP ancillary route info" },
+ { MTYPE_BGP_CONN, "BGP connected" },
{ MTYPE_BGP_STATIC, "BGP static" },
{ MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" },
{ MTYPE_BGP_ADVERTISE, "BGP adv" },
diff --git a/lib/prefix.c b/lib/prefix.c
index ceda08de..5e8cff04 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -2317,6 +2317,21 @@ static const char map64kto17_nbo[0xffff + 1] =
#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
+unsigned int
+prefix_bit (const u_char *prefix, const u_char prefixlen)
+{
+ unsigned int offset = prefixlen / 8;
+ unsigned int shift = 7 - (prefixlen % 8);
+
+ return (prefix[offset] >> shift) & 1;
+}
+
+unsigned int
+prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
+{
+ return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
+}
+
/* Address Famiy Identifier to Address Family converter. */
int
afi2family (afi_t afi)
diff --git a/lib/prefix.h b/lib/prefix.h
index dab4202e..7f0d3607 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -128,26 +128,14 @@ struct prefix_rd
/* Prefix's family member. */
#define PREFIX_FAMILY(p) ((p)->family)
-/* Check bit of the prefix. */
-static inline unsigned int
-prefix_bit (const u_char *prefix, const u_char prefixlen)
-{
- unsigned int offset = prefixlen / 8;
- unsigned int shift = 7 - (prefixlen % 8);
-
- return (prefix[offset] >> shift) & 1;
-}
-
-static inline unsigned int
-prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen)
-{
- return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen);
-}
-
/* Prototypes. */
extern int afi2family (afi_t);
extern afi_t family2afi (int);
+/* Check bit of the prefix. */
+extern unsigned int prefix_bit (const u_char *prefix, const u_char prefixlen);
+extern unsigned int prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen);
+
extern struct prefix *prefix_new (void);
extern void prefix_free (struct prefix *);
extern const char *prefix_family_str (const struct prefix *);
diff --git a/lib/sockunion.c b/lib/sockunion.c
index 10224a05..59770529 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -527,6 +527,46 @@ sockopt_ttl (int family, int sock, int ttl)
}
int
+sockopt_cork (int sock, int onoff)
+{
+#ifdef TCP_CORK
+ return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff));
+#else
+ return 0;
+#endif
+}
+
+int
+sockopt_minttl (int family, int sock, int minttl)
+{
+#ifdef IP_MINTTL
+ if (family == AF_INET)
+ {
+ int ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl));
+ if (ret < 0)
+ zlog (NULL, LOG_WARNING,
+ "can't set sockopt IP_MINTTL to %d on socket %d: %s",
+ minttl, sock, safe_strerror (errno));
+ return ret;
+ }
+#endif /* IP_MINTTL */
+#ifdef IPV6_MINHOPCNT
+ if (family == AF_INET6)
+ {
+ int ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MINHOPCNT, &minttl, sizeof(minttl));
+ if (ret < 0)
+ zlog (NULL, LOG_WARNING,
+ "can't set sockopt IPV6_MINHOPCNT to %d on socket %d: %s",
+ minttl, sock, safe_strerror (errno));
+ return ret;
+ }
+#endif
+
+ errno = EOPNOTSUPP;
+ return -1;
+}
+
+int
sockopt_v6only (int family, int sock)
{
int ret, on = 1;
diff --git a/lib/sockunion.h b/lib/sockunion.h
index db145cf2..4531f620 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -103,6 +103,8 @@ extern int sockopt_v6only (int family, int sock);
extern int sockunion_bind (int sock, union sockunion *,
unsigned short, union sockunion *);
extern int sockopt_ttl (int family, int sock, int ttl);
+extern int sockopt_minttl (int family, int sock, int minttl);
+extern int sockopt_cork (int sock, int onoff);
extern int sockunion_socket (union sockunion *su);
extern const char *inet_sutop (union sockunion *su, char *str);
extern enum connect_result sockunion_connect (int fd, union sockunion *su,
diff --git a/lib/table.c b/lib/table.c
index 04df3af5..e40e6707 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -209,6 +209,10 @@ route_node_match (const struct route_table *table, const struct prefix *p)
{
if (node->info)
matched = node;
+
+ if (node->p.prefixlen == p->prefixlen)
+ break;
+
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -260,8 +264,8 @@ route_node_lookup (struct route_table *table, struct prefix *p)
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
- if (node->p.prefixlen == p->prefixlen && node->info)
- return route_lock_node (node);
+ if (node->p.prefixlen == p->prefixlen)
+ return node->info ? route_lock_node (node) : NULL;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
@@ -283,10 +287,8 @@ route_node_get (struct route_table *table, struct prefix *p)
prefix_match (&node->p, p))
{
if (node->p.prefixlen == p->prefixlen)
- {
- route_lock_node (node);
- return node;
- }
+ return route_lock_node (node);
+
match = node;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
diff --git a/lib/thread.c b/lib/thread.c
index e89af541..6d3c3cb3 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -248,7 +248,7 @@ cpu_record_hash_free (void *a)
XFREE (MTYPE_THREAD_STATS, hist);
}
-static inline void
+static void
vty_out_cpu_thread_history(struct vty* vty,
struct cpu_thread_history *a)
{
@@ -303,7 +303,7 @@ cpu_record_print(struct vty *vty, thread_type filter)
void *args[3] = {&tmp, vty, &filter};
memset(&tmp, 0, sizeof tmp);
- tmp.funcname = "TOTAL";
+ tmp.funcname = (char *)"TOTAL";
tmp.types = filter;
#ifdef HAVE_RUSAGE
@@ -382,6 +382,89 @@ DEFUN(show_thread_cpu,
cpu_record_print(vty, filter);
return CMD_SUCCESS;
}
+
+static void
+cpu_record_hash_clear (struct hash_backet *bucket,
+ void *args)
+{
+ thread_type *filter = args;
+ struct cpu_thread_history *a = bucket->data;
+
+ a = bucket->data;
+ if ( !(a->types & *filter) )
+ return;
+
+ hash_release (cpu_record, bucket->data);
+}
+
+static void
+cpu_record_clear (thread_type filter)
+{
+ thread_type *tmp = &filter;
+ hash_iterate (cpu_record,
+ (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear,
+ tmp);
+}
+
+DEFUN(clear_thread_cpu,
+ clear_thread_cpu_cmd,
+ "clear thread cpu [FILTER]",
+ "Clear stored data\n"
+ "Thread information\n"
+ "Thread CPU usage\n"
+ "Display filter (rwtexb)\n")
+{
+ int i = 0;
+ thread_type filter = (thread_type) -1U;
+
+ if (argc > 0)
+ {
+ filter = 0;
+ while (argv[0][i] != '\0')
+ {
+ switch ( argv[0][i] )
+ {
+ case 'r':
+ case 'R':
+ filter |= (1 << THREAD_READ);
+ break;
+ case 'w':
+ case 'W':
+ filter |= (1 << THREAD_WRITE);
+ break;
+ case 't':
+ case 'T':
+ filter |= (1 << THREAD_TIMER);
+ break;
+ case 'e':
+ case 'E':
+ filter |= (1 << THREAD_EVENT);
+ break;
+ case 'x':
+ case 'X':
+ filter |= (1 << THREAD_EXECUTE);
+ break;
+ case 'b':
+ case 'B':
+ filter |= (1 << THREAD_BACKGROUND);
+ break;
+ default:
+ break;
+ }
+ ++i;
+ }
+ if (filter == 0)
+ {
+ vty_out(vty, "Invalid filter \"%s\" specified,"
+ " must contain at least one of 'RWTEXB'%s",
+ argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ cpu_record_clear (filter);
+ return CMD_SUCCESS;
+}
/* List allocation and head/tail print out. */
static void
@@ -525,7 +608,7 @@ thread_master_free (struct thread_master *m)
}
/* Thread list is empty or not. */
-static inline int
+static int
thread_empty (struct thread_list *list)
{
return list->head ? 0 : 1;
@@ -903,6 +986,24 @@ thread_timer_process (struct thread_list *list, struct timeval *timenow)
return ready;
}
+/* process a list en masse, e.g. for event thread lists */
+static unsigned int
+thread_process (struct thread_list *list)
+{
+ struct thread *thread;
+ unsigned int ready = 0;
+
+ for (thread = list->head; thread; thread = thread->next)
+ {
+ thread_list_delete (list, thread);
+ thread->type = THREAD_READY;
+ thread_list_add (&thread->master->ready, thread);
+ ready++;
+ }
+ return ready;
+}
+
+
/* Fetch next ready thread. */
struct thread *
thread_fetch (struct thread_master *m, struct thread *fetch)
@@ -911,41 +1012,48 @@ thread_fetch (struct thread_master *m, struct thread *fetch)
fd_set readfd;
fd_set writefd;
fd_set exceptfd;
- struct timeval timer_val;
+ struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 };
struct timeval timer_val_bg;
- struct timeval *timer_wait;
+ struct timeval *timer_wait = &timer_val;
struct timeval *timer_wait_bg;
while (1)
{
int num = 0;
- /* Signals are highest priority */
+ /* Signals pre-empt everything */
quagga_sigevent_process ();
- /* Normal event are the next highest priority. */
- if ((thread = thread_trim_head (&m->event)) != NULL)
- return thread_run (m, thread, fetch);
-
- /* If there are any ready threads from previous scheduler runs,
- * process top of them.
+ /* Drain the ready queue of already scheduled jobs, before scheduling
+ * more.
*/
if ((thread = thread_trim_head (&m->ready)) != NULL)
return thread_run (m, thread, fetch);
+ /* To be fair to all kinds of threads, and avoid starvation, we
+ * need to be careful to consider all thread types for scheduling
+ * in each quanta. I.e. we should not return early from here on.
+ */
+
+ /* Normal event are the next highest priority. */
+ thread_process (&m->event);
+
/* Structure copy. */
readfd = m->readfd;
writefd = m->writefd;
exceptfd = m->exceptfd;
/* Calculate select wait timer if nothing else to do */
- quagga_get_relative (NULL);
- timer_wait = thread_timer_wait (&m->timer, &timer_val);
- timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
-
- if (timer_wait_bg &&
- (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
- timer_wait = timer_wait_bg;
+ if (m->ready.count == 0)
+ {
+ quagga_get_relative (NULL);
+ timer_wait = thread_timer_wait (&m->timer, &timer_val);
+ timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg);
+
+ if (timer_wait_bg &&
+ (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0)))
+ timer_wait = timer_wait_bg;
+ }
num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait);
diff --git a/lib/thread.h b/lib/thread.h
index b52bc541..978aa6b0 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -82,7 +82,7 @@ struct thread
struct cpu_thread_history
{
int (*func)(struct thread *);
- const char *funcname;
+ char *funcname;
unsigned int total_calls;
struct time_stats
{
@@ -197,6 +197,7 @@ extern int thread_should_yield (struct thread *);
/* Internal libzebra exports */
extern void thread_getrusage (RUSAGE_T *);
extern struct cmd_element show_thread_cpu_cmd;
+extern struct cmd_element clear_thread_cpu_cmd;
/* replacements for the system gettimeofday(), clock_gettime() and
* time() functions, providing support for non-decrementing clock on
diff --git a/lib/vty.c b/lib/vty.c
index d9eb921e..83bd6785 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1685,7 +1685,6 @@ static int
vty_accept (struct thread *thread)
{
int vty_sock;
- struct vty *vty;
union sockunion su;
int ret;
unsigned int on;
@@ -1770,7 +1769,7 @@ vty_accept (struct thread *thread)
if (bufp)
XFREE (MTYPE_TMP, bufp);
- vty = vty_create (vty_sock, &su);
+ vty_create (vty_sock, &su);
return 0;
}
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 7c811edd..61643bf8 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -103,7 +103,7 @@ work_queue_free (struct work_queue *wq)
return;
}
-static inline int
+static int
work_queue_schedule (struct work_queue *wq, unsigned int delay)
{
/* if appropriate, schedule work queue thread */
@@ -341,7 +341,7 @@ work_queue_run (struct thread *thread)
stats:
-#define WQ_HYSTERIS_FACTOR 2
+#define WQ_HYSTERESIS_FACTOR 4
/* we yielded, check whether granularity should be reduced */
if (yielded && (cycles < wq->cycles.granularity))
@@ -349,17 +349,18 @@ stats:
wq->cycles.granularity = ((cycles > 0) ? cycles
: WORK_QUEUE_MIN_GRANULARITY);
}
-
- if (cycles >= (wq->cycles.granularity))
+ /* otherwise, should granularity increase? */
+ else if (cycles >= (wq->cycles.granularity))
{
if (cycles > wq->cycles.best)
wq->cycles.best = cycles;
- /* along with yielded check, provides hysteris for granularity */
- if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR * 2))
- wq->cycles.granularity *= WQ_HYSTERIS_FACTOR; /* quick ramp-up */
- else if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR))
- wq->cycles.granularity += WQ_HYSTERIS_FACTOR;
+ /* along with yielded check, provides hysteresis for granularity */
+ if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR
+ * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity *= WQ_HYSTERESIS_FACTOR; /* quick ramp-up */
+ else if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR))
+ wq->cycles.granularity += WQ_HYSTERESIS_FACTOR;
}
#undef WQ_HYSTERIS_FACTOR
diff --git a/lib/zclient.c b/lib/zclient.c
index 37ee2420..12d113e7 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -837,7 +837,6 @@ zebra_interface_address_read (int type, struct stream *s)
static int
zclient_read (struct thread *thread)
{
- int ret;
size_t already;
uint16_t length, command;
uint8_t marker, version;
@@ -932,47 +931,47 @@ zclient_read (struct thread *thread)
{
case ZEBRA_ROUTER_ID_UPDATE:
if (zclient->router_id_update)
- ret = (*zclient->router_id_update) (command, zclient, length);
+ (*zclient->router_id_update) (command, zclient, length);
break;
case ZEBRA_INTERFACE_ADD:
if (zclient->interface_add)
- ret = (*zclient->interface_add) (command, zclient, length);
+ (*zclient->interface_add) (command, zclient, length);
break;
case ZEBRA_INTERFACE_DELETE:
if (zclient->interface_delete)
- ret = (*zclient->interface_delete) (command, zclient, length);
+ (*zclient->interface_delete) (command, zclient, length);
break;
case ZEBRA_INTERFACE_ADDRESS_ADD:
if (zclient->interface_address_add)
- ret = (*zclient->interface_address_add) (command, zclient, length);
+ (*zclient->interface_address_add) (command, zclient, length);
break;
case ZEBRA_INTERFACE_ADDRESS_DELETE:
if (zclient->interface_address_delete)
- ret = (*zclient->interface_address_delete) (command, zclient, length);
+ (*zclient->interface_address_delete) (command, zclient, length);
break;
case ZEBRA_INTERFACE_UP:
if (zclient->interface_up)
- ret = (*zclient->interface_up) (command, zclient, length);
+ (*zclient->interface_up) (command, zclient, length);
break;
case ZEBRA_INTERFACE_DOWN:
if (zclient->interface_down)
- ret = (*zclient->interface_down) (command, zclient, length);
+ (*zclient->interface_down) (command, zclient, length);
break;
case ZEBRA_IPV4_ROUTE_ADD:
if (zclient->ipv4_route_add)
- ret = (*zclient->ipv4_route_add) (command, zclient, length);
+ (*zclient->ipv4_route_add) (command, zclient, length);
break;
case ZEBRA_IPV4_ROUTE_DELETE:
if (zclient->ipv4_route_delete)
- ret = (*zclient->ipv4_route_delete) (command, zclient, length);
+ (*zclient->ipv4_route_delete) (command, zclient, length);
break;
case ZEBRA_IPV6_ROUTE_ADD:
if (zclient->ipv6_route_add)
- ret = (*zclient->ipv6_route_add) (command, zclient, length);
+ (*zclient->ipv6_route_add) (command, zclient, length);
break;
case ZEBRA_IPV6_ROUTE_DELETE:
if (zclient->ipv6_route_delete)
- ret = (*zclient->ipv6_route_delete) (command, zclient, length);
+ (*zclient->ipv6_route_delete) (command, zclient, length);
break;
default:
break;