Fix the frequent, power consuming wake-ups
This commit is contained in:
parent
c639191703
commit
e9225f8d60
256
lldpad-0.9.41-reduce-number-of-select-timeouts-for-ECP.patch
Normal file
256
lldpad-0.9.41-reduce-number-of-select-timeouts-for-ECP.patch
Normal file
@ -0,0 +1,256 @@
|
||||
From aeb6d102f2b00c1799042cd02f079aa1f659d36c Mon Sep 17 00:00:00 2001
|
||||
From: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Date: Wed, 4 May 2011 08:21:45 -0700
|
||||
Subject: [PATCH 2/3] reduce number of select timeouts for ECP
|
||||
|
||||
A problem with the number of select timeouts has been reported in Redhat
|
||||
bugzilla #694639 (https://bugzilla.redhat.com/show_bug.cgi?id=694639) and
|
||||
by Will Cohen on the open-lldp mailing list.
|
||||
|
||||
The number of select timeouts for any running applications can be measured
|
||||
with 'stap -c "sleep 10" timeout.stp'.
|
||||
|
||||
The high number of select timeouts was caused by the timers used in the ECP
|
||||
code to control the timeout until when an ack has to be received and to
|
||||
determine wether there is any work pending (e.g. changed profiles).
|
||||
|
||||
This patch changes the timers from calling them at a regular interval to a
|
||||
demand based model. For this it is necessary to setup a short-running timer
|
||||
whenever work has been scheduled. This way the execution path returns to the
|
||||
event loop much more often leaving other modules a chance to get work done.
|
||||
|
||||
Signed-off-by: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
|
||||
Signed-off-by: Petr Sabata <psabata@redhat.com>
|
||||
---
|
||||
ecp/ecp.c | 104 ++++++++++++++++++++++++++++++++++++++++++++--------------
|
||||
ecp/ecp.h | 7 +++-
|
||||
ecp/ecp_tx.c | 8 ++++-
|
||||
3 files changed, 91 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/ecp/ecp.c b/ecp/ecp.c
|
||||
index ea3558d..b4d075e 100644
|
||||
--- a/ecp/ecp.c
|
||||
+++ b/ecp/ecp.c
|
||||
@@ -37,9 +37,65 @@
|
||||
#include "lldp/l2_packet.h"
|
||||
#include "ecp/ecp.h"
|
||||
|
||||
-static int ecp_start_timer(struct vdp_data *vd);
|
||||
+/* ecp_localchange_handler - triggers the processing of a local change
|
||||
+ * @eloop_data: data structure of event loop
|
||||
+ * @user_ctx: user context, vdp_data here
|
||||
+ *
|
||||
+ * no return value
|
||||
+ *
|
||||
+ * called from ecp_somethingchangedlocal when a change is pending. Calls
|
||||
+ * the ECP tx station state machine. A oneshot handler. This detour is taken
|
||||
+ * to not having to call the ecp code from the vdp state machine. Instead, we
|
||||
+ * return to the event loop, giving other code a chance to do work.
|
||||
+ */
|
||||
+void ecp_localchange_handler(void *eloop_data, void *user_ctx)
|
||||
+{
|
||||
+ struct vdp_data *vd;
|
||||
+
|
||||
+ vd = (struct vdp_data *) user_ctx;
|
||||
+
|
||||
+ if (vd->ecp.tx.localChange) {
|
||||
+ LLDPAD_DBG("%s(%i)-%s: ecp.tx.localChange %i!\n",
|
||||
+ __func__, __LINE__,
|
||||
+ vd->ifname, vd->ecp.tx.localChange);
|
||||
+ ecp_tx_run_sm(vd);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* ecp_start_localchange_timer - starts the ECP localchange timer
|
||||
+ * @vd: vdp_data for the interface
|
||||
+ *
|
||||
+ * returns 0 on success, -1 on error
|
||||
+ *
|
||||
+ * starts the ECP localchange timer when a localchange has been signaled from
|
||||
+ * the VDP state machine.
|
||||
+ */
|
||||
+int ecp_start_localchange_timer(struct vdp_data *vd)
|
||||
+{
|
||||
+ unsigned int usecs;
|
||||
+
|
||||
+ usecs = ECP_LOCALCHANGE_TIMEOUT;
|
||||
+
|
||||
+ return eloop_register_timeout(0, usecs, ecp_localchange_handler, NULL, (void *) vd);
|
||||
+}
|
||||
|
||||
-/* ecp_timeout_handler - handles the timer expiry
|
||||
+/* ecp_stop_localchange_timer - stop the ECP localchange timer
|
||||
+ * @vd: vdp_data for the interface
|
||||
+ *
|
||||
+ * returns the number of removed handlers
|
||||
+ *
|
||||
+ * stops the ECP localchange timer. Used e.g. when the host interface goes down.
|
||||
+ */
|
||||
+static int ecp_stop_localchange_timer(struct vdp_data *vd)
|
||||
+{
|
||||
+ LLDPAD_DBG("%s(%i)-%s: stopping ecp localchange timer\n", __func__, __LINE__,
|
||||
+ vd->ifname);
|
||||
+
|
||||
+ return eloop_cancel_timeout(ecp_localchange_handler, NULL, (void *) vd);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* ecp_ack_timeout_handler - handles the ack timer expiry
|
||||
* @eloop_data: data structure of event loop
|
||||
* @user_ctx: user context, vdp_data here
|
||||
*
|
||||
@@ -47,58 +103,55 @@ static int ecp_start_timer(struct vdp_data *vd);
|
||||
*
|
||||
* called when the ECP timer has expired. Calls the ECP station state machine.
|
||||
*/
|
||||
-void ecp_timeout_handler(void *eloop_data, void *user_ctx)
|
||||
+void ecp_ack_timeout_handler(void *eloop_data, void *user_ctx)
|
||||
{
|
||||
struct vdp_data *vd;
|
||||
|
||||
vd = (struct vdp_data *) user_ctx;
|
||||
|
||||
if (vd->ecp.ackTimer > 0)
|
||||
- vd->ecp.ackTimer--;
|
||||
+ vd->ecp.ackTimer -= ECP_ACK_TIMER_DEFAULT;
|
||||
|
||||
- if ((ecp_ackTimer_expired(vd) == true) ||
|
||||
- vd->ecp.tx.localChange) {
|
||||
+ if (ecp_ackTimer_expired(vd) == true) {
|
||||
LLDPAD_DBG("%s(%i)-%s: ecp_ackTimer_expired (%i) !\n",
|
||||
__func__, __LINE__, vd->ifname, vd->ecp.ackTimer);
|
||||
- LLDPAD_DBG("%s(%i)-%s: ecp.tx.localChange %i!\n",
|
||||
- __func__, __LINE__,
|
||||
- vd->ifname, vd->ecp.tx.localChange);
|
||||
ecp_tx_run_sm(vd);
|
||||
+ } else {
|
||||
+ LLDPAD_DBG("%s(%i)-%s: BUG ! handler called but"
|
||||
+ "vdp->ecp.ackTimer not expired (%i) !\n",
|
||||
+ __func__, __LINE__, vd->ecp.ackTimer);
|
||||
}
|
||||
-
|
||||
- ecp_start_timer(vd);
|
||||
}
|
||||
|
||||
-/* ecp_start_timer - starts the ECP timer
|
||||
+/* ecp_start_ack_timer - starts the ECP ack timer
|
||||
* @vd: vdp_data for the interface
|
||||
*
|
||||
* returns 0 on success, -1 on error
|
||||
*
|
||||
- * starts the ECP timer when the interface comes up.
|
||||
+ * starts the ECP ack timer when a frame has been sent out.
|
||||
*/
|
||||
-static int ecp_start_timer(struct vdp_data *vd)
|
||||
+int ecp_start_ack_timer(struct vdp_data *vd)
|
||||
{
|
||||
- unsigned int secs, usecs;
|
||||
+ unsigned int usecs;
|
||||
|
||||
- secs = 0;
|
||||
- usecs = ECP_TIMER_GRANULARITY;
|
||||
+ usecs = ECP_ACK_TIMER_DEFAULT;
|
||||
|
||||
- return eloop_register_timeout(secs, usecs, ecp_timeout_handler, NULL, (void *) vd);
|
||||
+ return eloop_register_timeout(0, usecs, ecp_ack_timeout_handler, NULL, (void *) vd);
|
||||
}
|
||||
|
||||
-/* ecp_stop_timer - stop the ECP timer
|
||||
+/* ecp_stop_ack_timer - stop the ECP ack timer
|
||||
* @vd: vdp_data for the interface
|
||||
*
|
||||
* returns the number of removed handlers
|
||||
*
|
||||
- * stops the ECP timer. Used e.g. when the host interface goes down.
|
||||
+ * stops the ECP ack timer. Used e.g. when the host interface goes down.
|
||||
*/
|
||||
-static int ecp_stop_timer(struct vdp_data *vd)
|
||||
+int ecp_stop_ack_timer(struct vdp_data *vd)
|
||||
{
|
||||
- LLDPAD_DBG("%s(%i)-%s: stopping ecp timer\n", __func__, __LINE__,
|
||||
+ LLDPAD_DBG("%s(%i)-%s: stopping ecp ack timer\n", __func__, __LINE__,
|
||||
vd->ifname);
|
||||
|
||||
- return eloop_cancel_timeout(ecp_timeout_handler, NULL, (void *) vd);
|
||||
+ return eloop_cancel_timeout(ecp_ack_timeout_handler, NULL, (void *) vd);
|
||||
}
|
||||
|
||||
/* ecp_init - initialize ecp module
|
||||
@@ -138,7 +191,7 @@ int ecp_init(char *ifname)
|
||||
ecp_rx_change_state(vd, ECP_RX_IDLE);
|
||||
ecp_rx_run_sm(vd);
|
||||
|
||||
- ecp_start_timer(vd);
|
||||
+ ecp_somethingChangedLocal(vd, true);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -159,7 +212,8 @@ int ecp_deinit(char *ifname)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- ecp_stop_timer(vd);
|
||||
+ ecp_stop_ack_timer(vd);
|
||||
+ ecp_stop_localchange_timer(vd);
|
||||
ecp_tx_stop_ackTimer(vd);
|
||||
|
||||
return 0;
|
||||
diff --git a/ecp/ecp.h b/ecp/ecp.h
|
||||
index c18b6d7..35fcf46 100644
|
||||
--- a/ecp/ecp.h
|
||||
+++ b/ecp/ecp.h
|
||||
@@ -34,8 +34,11 @@
|
||||
#define ECP_MAX_RETRIES 3
|
||||
#define ECP_SEQUENCE_NR_START 0x0
|
||||
|
||||
-#define ECP_ACK_TIMER_DEFAULT 50 /* 500 ms in 10 ms chunks */
|
||||
-#define ECP_TIMER_GRANULARITY 10000 /* 10 ms in us */
|
||||
+#define MSECS 1000
|
||||
+#define SECS 1000*MSECS
|
||||
+
|
||||
+#define ECP_ACK_TIMER_DEFAULT 500*MSECS /* 500 ms */
|
||||
+#define ECP_LOCALCHANGE_TIMEOUT 1*MSECS /* 1 ms */
|
||||
|
||||
#define ECP_ACK_TIMER_STOPPED -1
|
||||
|
||||
diff --git a/ecp/ecp_tx.c b/ecp/ecp_tx.c
|
||||
index ebf9e4b..ba96c6b 100644
|
||||
--- a/ecp/ecp_tx.c
|
||||
+++ b/ecp/ecp_tx.c
|
||||
@@ -53,11 +53,13 @@ void ecp_somethingChangedLocal(struct vdp_data *vd, bool flag)
|
||||
if (!vd)
|
||||
return;
|
||||
|
||||
- LLDPAD_DBG("%s(%i): vd->ecp.tx.localChange to %s.", __func__,
|
||||
+ LLDPAD_DBG("%s(%i): vd->ecp.tx.localChange to %s.\n", __func__,
|
||||
__LINE__, (flag == true) ? "true" : "false");
|
||||
|
||||
vd->ecp.tx.localChange = flag;
|
||||
|
||||
+ ecp_start_localchange_timer(vd);
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -288,6 +290,8 @@ void ecp_tx_stop_ackTimer(struct vdp_data *vd)
|
||||
|
||||
LLDPAD_DBG("%s(%i)-%s: stopped ecp ack timer\n", __func__, __LINE__,
|
||||
vd->ifname);
|
||||
+
|
||||
+ ecp_stop_ack_timer(vd);
|
||||
}
|
||||
|
||||
/* ecp_tx_start_ackTimer - starts the ECP ack timer
|
||||
@@ -303,6 +307,8 @@ static void ecp_tx_start_ackTimer(struct vdp_data *vd)
|
||||
|
||||
LLDPAD_DBG("%s(%i)-%s: starting ecp ack timer\n", __func__, __LINE__,
|
||||
vd->ifname);
|
||||
+
|
||||
+ ecp_start_ack_timer(vd);
|
||||
}
|
||||
|
||||
/* ecp_ackTimer_expired - checks for expired ack timer
|
||||
--
|
||||
1.7.4.4
|
||||
|
432
lldpad-0.9.41-reduce-number-of-select-timeouts-for-VDP.patch
Normal file
432
lldpad-0.9.41-reduce-number-of-select-timeouts-for-VDP.patch
Normal file
@ -0,0 +1,432 @@
|
||||
From 08a6ea57ef76248e439f94a77f74c80ab500d2db Mon Sep 17 00:00:00 2001
|
||||
From: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Date: Wed, 4 May 2011 08:23:19 -0700
|
||||
Subject: [PATCH 3/3] reduce number of select timeouts for VDP
|
||||
|
||||
A problem with the number of select timeouts has been reported in Redhat
|
||||
bugzilla #694639 (https://bugzilla.redhat.com/show_bug.cgi?id=694639) and
|
||||
by Will Cohen on the open-lldp mailing list.
|
||||
|
||||
The number of select timeouts for any running applications can be measured
|
||||
with 'stap -c "sleep 10" timeout.stp'.
|
||||
|
||||
The high number of select timeouts was caused by the timers used in the VDP
|
||||
code to control the ack and keepalive interval as well as to determine wether
|
||||
there is any work pending (e.g. changed profiles or received acks).
|
||||
|
||||
This patch changes the timers from calling them at a regular interval to a
|
||||
demand based model. For this it is necessary to setup a short-running timer
|
||||
whenever work has been scheduled. This way the execution path returns to the
|
||||
event loop much more often leaving other modules a chance to get work done.
|
||||
|
||||
Signed-off-by: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Signed-off-by: Petr Sabata <psabata@redhat.com>
|
||||
---
|
||||
include/lldp_vdp.h | 6 +-
|
||||
lldp_vdp.c | 234 ++++++++++++++++++++++++++++++++-------------------
|
||||
2 files changed, 150 insertions(+), 90 deletions(-)
|
||||
|
||||
diff --git a/include/lldp_vdp.h b/include/lldp_vdp.h
|
||||
index 4b7054b..947ae31 100644
|
||||
--- a/include/lldp_vdp.h
|
||||
+++ b/include/lldp_vdp.h
|
||||
@@ -64,11 +64,12 @@ static char *vsi_responses[] = {
|
||||
|
||||
#define VDP_MACVLAN_FORMAT_1 1
|
||||
|
||||
-#define VDP_TIMER_GRANULARITY 10000 /* 10 ms in us */
|
||||
-#define VDP_KEEPALIVE_TIMER_DEFAULT 1000 /* 10s in 10ms chunks */
|
||||
+#define VDP_TIMER_GRANULARITY 100*MSECS /* 100 ms */
|
||||
+#define VDP_KEEPALIVE_TIMER_DEFAULT 10*SECS /* 10s */
|
||||
#define VDP_ACK_TIMER_DEFAULT (2*ECP_ACK_TIMER_DEFAULT*ECP_MAX_RETRIES)
|
||||
#define VDP_KEEPALIVE_TIMER_STOPPED -1
|
||||
#define VDP_ACK_TIMER_STOPPED -1
|
||||
+#define VDP_LOCALCHANGE_TIMEOUT 1*MSECS /* 1 ms */
|
||||
|
||||
#define VDP_ROLE_STATION 0
|
||||
#define VDP_ROLE_BRIDGE 1
|
||||
@@ -155,7 +156,6 @@ struct packed_tlv *vdp_gettlv(struct vdp_data *vd, struct vsi_profile *profile);
|
||||
void vdp_vsi_sm_station(struct vsi_profile *profile);
|
||||
struct vsi_profile *vdp_add_profile(struct vsi_profile *profile);
|
||||
void vdp_somethingChangedLocal(struct vsi_profile *profile, bool mode);
|
||||
-static int vdp_start_timer(struct vdp_data *vd);
|
||||
|
||||
#define MAC_ADDR_STRLEN 18
|
||||
#define INSTANCE_STRLEN 36
|
||||
diff --git a/lldp_vdp.c b/lldp_vdp.c
|
||||
index 7be0b1c..4b2ce6a 100644
|
||||
--- a/lldp_vdp.c
|
||||
+++ b/lldp_vdp.c
|
||||
@@ -143,8 +143,10 @@ void vdp_ack_profiles(struct vdp_data *vd, int seqnr)
|
||||
struct vsi_profile *p;
|
||||
|
||||
LIST_FOREACH(p, &vd->profile_head, profile) {
|
||||
- if (p->seqnr == seqnr)
|
||||
+ if (p->seqnr == seqnr) {
|
||||
p->ackReceived = true;
|
||||
+ vdp_start_localchange_timer(p);
|
||||
+ }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -205,7 +207,13 @@ int vdp_vsis_pending(struct vdp_data *vd)
|
||||
*/
|
||||
void vdp_somethingChangedLocal(struct vsi_profile *profile, bool flag)
|
||||
{
|
||||
+ LLDPAD_DBG("%s(%i): setting profile->localChange to %s.\n",
|
||||
+ __func__, __LINE__, (flag == true) ? "true" : "false");
|
||||
+
|
||||
profile->localChange = flag;
|
||||
+
|
||||
+ if (flag == true)
|
||||
+ vdp_start_localchange_timer(profile);
|
||||
}
|
||||
|
||||
/* vdp_keepaliveTimer_expired - checks for expired ack timer
|
||||
@@ -234,147 +242,182 @@ static bool vdp_ackTimer_expired(struct vsi_profile *profile)
|
||||
return (profile->ackTimer == 0);
|
||||
}
|
||||
|
||||
-/* vdp_timeout_handler - handles the timer expiry
|
||||
+/* vdp_localchange_handler - triggers in case of ackReceived or on vdp localchange
|
||||
* @eloop_data: data structure of event loop
|
||||
* @user_ctx: user context, vdp_data here
|
||||
*
|
||||
* no return value
|
||||
*
|
||||
- * called when the VDP timer has expired. Decrements ack and keepaliveTimer
|
||||
- * and calls the VDP station state machine if necessary.
|
||||
+ * called from vdp_somethingchangedlocal or vdp_ack_profiles when a change is
|
||||
+ * pending. Calls the VDP station state machine. This detour is taken
|
||||
+ * to not having to call the vdp code from the ecp state machine. Instead, we
|
||||
+ * return to the event loop, giving other code a chance to do work.
|
||||
*/
|
||||
-void vdp_timeout_handler(void *eloop_data, void *user_ctx)
|
||||
+void vdp_localchange_handler(void *eloop_data, void *user_ctx)
|
||||
{
|
||||
- struct vdp_data *vd;
|
||||
struct vsi_profile *p;
|
||||
|
||||
- vd = (struct vdp_data *) user_ctx;
|
||||
-
|
||||
- vd->nroftimers--;
|
||||
+ p = (struct vsi_profile *) user_ctx;
|
||||
|
||||
- LIST_FOREACH(p, &vd->profile_head, profile) {
|
||||
- if (p->ackTimer > 0)
|
||||
- p->ackTimer--;
|
||||
-
|
||||
- if (p->keepaliveTimer > 0)
|
||||
- p->keepaliveTimer--;
|
||||
-
|
||||
- if (vdp_ackTimer_expired(p) ||
|
||||
- vdp_keepaliveTimer_expired(p) ||
|
||||
- p->ackReceived) {
|
||||
- LLDPAD_DBG("%s(%i): profile 0x%02x\n",
|
||||
- __func__, __LINE__, p->instance[15]);
|
||||
- LLDPAD_DBG("%s(%i): vdp_ackTimer_expired %i\n",
|
||||
- __func__, __LINE__, vdp_ackTimer_expired(p));
|
||||
- LLDPAD_DBG("%s(%i): p->ackReceived %i\n",
|
||||
- __func__, __LINE__, p->ackReceived);
|
||||
- LLDPAD_DBG("%s(%i): vdp_keepaliveTimer_expired %i\n",
|
||||
- __func__, __LINE__,
|
||||
- vdp_keepaliveTimer_expired(p));
|
||||
- vdp_vsi_sm_station(p);
|
||||
- }
|
||||
+ if ((p->ackReceived) || (p->localChange)) {
|
||||
+ LLDPAD_DBG("%s(%i): p->localChange %i!\n",
|
||||
+ __func__, __LINE__, p->localChange);
|
||||
+ LLDPAD_DBG("%s(%i): p->ackReceived %i!\n",
|
||||
+ __func__, __LINE__, p->ackReceived);
|
||||
+ vdp_vsi_sm_station(p);
|
||||
}
|
||||
-
|
||||
- vdp_start_timer(vd);
|
||||
}
|
||||
|
||||
-/* vdp_stop_timer - stop the VDP timer
|
||||
+/* vdp_start_localchange_timer - starts the VDP localchange timer
|
||||
* @vd: vdp_data for the interface
|
||||
*
|
||||
- * returns the number of removed handlers
|
||||
+ * returns 0 on success, -1 on error
|
||||
*
|
||||
- * stops the VDP timer. Used e.g. when the host interface goes down.
|
||||
+ * starts the VPP localchange timer when a localchange has been signaled from
|
||||
+ * the VDP state machine.
|
||||
*/
|
||||
-static int vdp_stop_timer(struct vdp_data *vd)
|
||||
+int vdp_start_localchange_timer(struct vsi_profile *p)
|
||||
{
|
||||
- LLDPAD_DBG("%s(%i)-%s: stopping vdp timer\n", __func__, __LINE__,
|
||||
- vd->ifname);
|
||||
+ unsigned int usecs;
|
||||
|
||||
- vd->nroftimers--;
|
||||
+ usecs = VDP_LOCALCHANGE_TIMEOUT;
|
||||
|
||||
- return eloop_cancel_timeout(vdp_timeout_handler, NULL, (void *) vd);
|
||||
+ return eloop_register_timeout(0, usecs, vdp_localchange_handler, NULL, (void *) p);
|
||||
}
|
||||
|
||||
-/* vdp_start_timer - starts the VDP timer
|
||||
- * @vd: vdp_data for the interface
|
||||
+/* vdp_ack_timeout_handler - handles the ack timer expiry
|
||||
+ * @eloop_data: data structure of event loop
|
||||
+ * @user_ctx: user context, vdp_data here
|
||||
*
|
||||
- * returns 0 on success, -1 on error
|
||||
+ * no return value
|
||||
*
|
||||
- * starts the VDP timer when the interface comes up.
|
||||
+ * called when the VDP ack timer for a profile has expired.
|
||||
+ * Calls the VDP station state machine for the profile.
|
||||
*/
|
||||
-static int vdp_start_timer(struct vdp_data *vd)
|
||||
+void vdp_ack_timeout_handler(void *eloop_data, void *user_ctx)
|
||||
{
|
||||
- unsigned int secs, usecs, rte;
|
||||
-
|
||||
- secs = 0;
|
||||
- usecs = VDP_TIMER_GRANULARITY;
|
||||
-
|
||||
- vd->nroftimers++;
|
||||
-
|
||||
- if (vd->nroftimers > 1) {
|
||||
- LLDPAD_WARN("%s(%i)-%s: nroftimers %i !\n", __func__, __LINE__,
|
||||
- vd->ifname, vd->nroftimers);
|
||||
- vd->nroftimers--;
|
||||
- return 0;
|
||||
+ struct vsi_profile *p = (struct vsi_profile *) user_ctx;
|
||||
+
|
||||
+ if (p->ackTimer > 0)
|
||||
+ p->ackTimer -= VDP_ACK_TIMER_DEFAULT;
|
||||
+
|
||||
+ if (vdp_ackTimer_expired(p)) {
|
||||
+ LLDPAD_DBG("%s(%i): profile 0x%02x\n",
|
||||
+ __func__, __LINE__, p->instance[15]);
|
||||
+ LLDPAD_DBG("%s(%i): vdp_ackTimer_expired %i\n",
|
||||
+ __func__, __LINE__, vdp_ackTimer_expired(p));
|
||||
+ LLDPAD_DBG("%s(%i): p->ackReceived %i\n",
|
||||
+ __func__, __LINE__, p->ackReceived);
|
||||
+ vdp_vsi_sm_station(p);
|
||||
}
|
||||
-
|
||||
- return eloop_register_timeout(secs, usecs, vdp_timeout_handler, NULL, (void *) vd);
|
||||
}
|
||||
|
||||
-/* vdp_start_ackTimer - starts the VDP ack timer
|
||||
- * @profile: profile to process
|
||||
+/* vdp_start_ack_timer - starts the VDP profile ack timer
|
||||
+ * @profile: vsi_profile
|
||||
+ *
|
||||
+ * returns 0 on success, -1 on error
|
||||
*
|
||||
- * starts the ack timer when a frame has been sent out.
|
||||
+ * starts the VDP profile ack timer when a profile has been handed to ecp for
|
||||
+ * transmission.
|
||||
*/
|
||||
-static void vdp_start_ackTimer(struct vsi_profile *profile)
|
||||
+static int vdp_start_ackTimer(struct vsi_profile *profile)
|
||||
{
|
||||
+ unsigned int usecs;
|
||||
+
|
||||
+ usecs = VDP_ACK_TIMER_DEFAULT;
|
||||
+
|
||||
profile->ackTimer = VDP_ACK_TIMER_DEFAULT;
|
||||
|
||||
LLDPAD_DBG("%s(%i)-%s: starting ack timer for 0x%02x (%i)\n",
|
||||
__func__, __LINE__, profile->port->ifname,
|
||||
profile->instance[15], profile->ackTimer);
|
||||
+
|
||||
+ return eloop_register_timeout(0, usecs, vdp_ack_timeout_handler, NULL, (void *) profile);
|
||||
}
|
||||
|
||||
-/* vdp_start_keepaliveTimer - starts the VDP keepalive timer for a profile
|
||||
- * @profile: profile to process
|
||||
+/* vdp_stop_ackTimer - stops the VDP profile ack timer
|
||||
+ * @vd: vdp_data for the interface
|
||||
+ *
|
||||
+ * returns the number of removed handlers
|
||||
*
|
||||
- * starts the keepalive timer when a frame has been sent out.
|
||||
+ * stops the VDP tck imer. Used e.g. when the host interface goes down.
|
||||
*/
|
||||
-static void vdp_start_keepaliveTimer(struct vsi_profile *profile)
|
||||
+static int vdp_stop_ackTimer(struct vsi_profile *profile)
|
||||
{
|
||||
- profile->keepaliveTimer = VDP_KEEPALIVE_TIMER_DEFAULT;
|
||||
-
|
||||
- LLDPAD_DBG("%s(%i)-%s: starting keepalive timer for 0x%02x (%i)\n",
|
||||
+ LLDPAD_DBG("%s(%i)-%s: stopping ack timer for 0x%02x (%i)\n",
|
||||
__func__, __LINE__, profile->port->ifname,
|
||||
- profile->instance[15], profile->keepaliveTimer);
|
||||
+ profile->instance[15], profile->ackTimer);
|
||||
+
|
||||
+ return eloop_cancel_timeout(vdp_ack_timeout_handler, NULL, (void *) profile);
|
||||
}
|
||||
|
||||
-/* vdp_stop_ackTimer - stops the VDP ack timer
|
||||
- * @profile: profile to process
|
||||
+/* vdp_keepalive_timeout_handler - handles the keepalive timer expiry
|
||||
+ * @eloop_data: data structure of event loop
|
||||
+ * @user_ctx: user context, vdp_data here
|
||||
+ *
|
||||
+ * no return value
|
||||
*
|
||||
- * stops the ack timer when a frame has been sent out.
|
||||
+ * called when the VDP keepalive timer for a profile has expired.
|
||||
+ * Calls the VDP station state machine for the profile.
|
||||
*/
|
||||
-static void vdp_stop_ackTimer(struct vsi_profile *profile)
|
||||
+void vdp_keepalive_timeout_handler(void *eloop_data, void *user_ctx)
|
||||
{
|
||||
- profile->ackTimer = VDP_ACK_TIMER_STOPPED;
|
||||
+ struct vsi_profile *p = (struct vsi_profile *) user_ctx;
|
||||
+
|
||||
+ if (p->keepaliveTimer > 0)
|
||||
+ p->keepaliveTimer -= VDP_KEEPALIVE_TIMER_DEFAULT;
|
||||
+
|
||||
+ if (vdp_keepaliveTimer_expired(p)) {
|
||||
+ LLDPAD_DBG("%s(%i): profile 0x%02x\n",
|
||||
+ __func__, __LINE__, p->instance[15]);
|
||||
+ LLDPAD_DBG("%s(%i): vdp_keepaliveTimer_expired %i\n",
|
||||
+ __func__, __LINE__, vdp_keepaliveTimer_expired(p));
|
||||
+ LLDPAD_DBG("%s(%i): p->ackReceived %i\n",
|
||||
+ __func__, __LINE__, p->ackReceived);
|
||||
+ vdp_vsi_sm_station(p);
|
||||
+ }
|
||||
+}
|
||||
|
||||
- LLDPAD_DBG("%s(%i)-%s: stopping ack timer for 0x%02x (%i)\n",
|
||||
+/* vdp_start_keepalive_timer - starts the VDP profile keepalive timer
|
||||
+ * @vd: vdp_data for the interface
|
||||
+ *
|
||||
+ * returns 0 on success, -1 on error
|
||||
+ *
|
||||
+ * starts the VDP profile keepalive timer when a profile has been handed to ecp for
|
||||
+ * transmission.
|
||||
+ */
|
||||
+static int vdp_start_keepaliveTimer(struct vsi_profile *profile)
|
||||
+{
|
||||
+ unsigned int usecs;
|
||||
+
|
||||
+ usecs = VDP_KEEPALIVE_TIMER_DEFAULT;
|
||||
+
|
||||
+ profile->keepaliveTimer = VDP_KEEPALIVE_TIMER_DEFAULT;
|
||||
+
|
||||
+ LLDPAD_DBG("%s(%i)-%s: starting keepalive timer for 0x%02x (%i)\n",
|
||||
__func__, __LINE__, profile->port->ifname,
|
||||
- profile->instance[15], profile->ackTimer);
|
||||
+ profile->instance[15], profile->keepaliveTimer);
|
||||
+
|
||||
+ return eloop_register_timeout(0, usecs, vdp_keepalive_timeout_handler,
|
||||
+ NULL, (void *) profile);
|
||||
}
|
||||
|
||||
-/* vdp_stop_keepaliveTimer - stops the VDP keepalive timer for a profile
|
||||
- * @profile: profile to process
|
||||
+/* vdp_stop_keepalive_timer - stops the VDP profile keepalive timer
|
||||
+ * @vd: vdp_data for the interface
|
||||
+ *
|
||||
+ * returns the number of removed handlers
|
||||
*
|
||||
- * stops the keepalive timer when a frame has been sent out.
|
||||
+ * stops the VDP tck imer. Used e.g. when the host interface goes down.
|
||||
*/
|
||||
-static void vdp_stop_keepaliveTimer(struct vsi_profile *profile)
|
||||
+static int vdp_stop_keepaliveTimer(struct vsi_profile *profile)
|
||||
{
|
||||
profile->keepaliveTimer = VDP_KEEPALIVE_TIMER_STOPPED;
|
||||
|
||||
LLDPAD_DBG("%s(%i)-%s: stopping keepalive timer for 0x%02x (%i)\n",
|
||||
__func__, __LINE__, profile->port->ifname,
|
||||
profile->instance[15], profile->keepaliveTimer);
|
||||
+
|
||||
+ return eloop_cancel_timeout(vdp_keepalive_timeout_handler, NULL, (void *) profile);
|
||||
}
|
||||
|
||||
static bool vdp_vsi_negative_response(struct vsi_profile *profile)
|
||||
@@ -560,6 +603,7 @@ void vdp_vsi_sm_station(struct vsi_profile *profile)
|
||||
profile->response = VDP_RESPONSE_NO_RESPONSE;
|
||||
if (profile->localChange) {
|
||||
ecp_somethingChangedLocal(vd, true);
|
||||
+ profile->ackReceived = false;
|
||||
vdp_start_ackTimer(profile);
|
||||
}
|
||||
break;
|
||||
@@ -573,6 +617,7 @@ void vdp_vsi_sm_station(struct vsi_profile *profile)
|
||||
vdp_stop_keepaliveTimer(profile);
|
||||
profile->response = VDP_RESPONSE_NO_RESPONSE;
|
||||
if (profile->localChange) {
|
||||
+ profile->ackReceived = false;
|
||||
ecp_somethingChangedLocal(vd, true);
|
||||
vdp_start_ackTimer(profile);
|
||||
}
|
||||
@@ -588,6 +633,7 @@ void vdp_vsi_sm_station(struct vsi_profile *profile)
|
||||
vdp_stop_keepaliveTimer(profile);
|
||||
profile->response = VDP_RESPONSE_NO_RESPONSE;
|
||||
if (profile->localChange) {
|
||||
+ profile->ackReceived = false;
|
||||
ecp_somethingChangedLocal(vd, true);
|
||||
vdp_start_ackTimer(profile);
|
||||
}
|
||||
@@ -1271,7 +1317,12 @@ void vdp_ifdown(char *ifname)
|
||||
if (ecp_deinit(ifname))
|
||||
goto out_err;
|
||||
|
||||
- vdp_stop_timer(vd);
|
||||
+ LIST_FOREACH(p, &vd->profile_head, profile) {
|
||||
+ if (p->ackTimer > 0)
|
||||
+ vdp_stop_ackTimer(p);
|
||||
+ if (p->keepaliveTimer > 0)
|
||||
+ vdp_stop_keepaliveTimer(p);
|
||||
+ }
|
||||
|
||||
LLDPAD_INFO("%s:%s vdp data removed\n", __func__, ifname);
|
||||
return;
|
||||
@@ -1291,10 +1342,11 @@ out_err:
|
||||
*/
|
||||
void vdp_ifup(char *ifname)
|
||||
{
|
||||
- char *p;
|
||||
+ char *string;
|
||||
struct vdp_data *vd;
|
||||
struct vdp_user_data *ud;
|
||||
struct port *port;
|
||||
+ struct vsi_profile *p;
|
||||
|
||||
LLDPAD_DBG("%s(%i): starting VDP for if %s !\n", __func__, __LINE__, ifname);
|
||||
|
||||
@@ -1315,9 +1367,9 @@ void vdp_ifup(char *ifname)
|
||||
|
||||
vd->role = VDP_ROLE_STATION;
|
||||
|
||||
- if (!get_cfg(ifname, "vdp.role", (void *)&p,
|
||||
+ if (!get_cfg(ifname, "vdp.role", (void *)&string,
|
||||
CONFIG_TYPE_STRING)) {
|
||||
- if (!strcasecmp(p, VAL_BRIDGE)) {
|
||||
+ if (!strcasecmp(string, VAL_BRIDGE)) {
|
||||
vd->role = VDP_ROLE_BRIDGE;
|
||||
}
|
||||
}
|
||||
@@ -1356,7 +1408,15 @@ out_start_again:
|
||||
|
||||
LLDPAD_DBG("%s(%i)-%s: starting vdp timer (%i)\n", __func__, __LINE__,
|
||||
vd->ifname, vd->nroftimers);
|
||||
- vdp_start_timer(vd);
|
||||
+
|
||||
+ LIST_FOREACH(p, &vd->profile_head, profile) {
|
||||
+ if (p->ackTimer > 0) {
|
||||
+ vdp_somethingChangedLocal(p, true);
|
||||
+ vdp_start_ackTimer(p);
|
||||
+ }
|
||||
+ if (p->keepaliveTimer > 0)
|
||||
+ vdp_start_keepaliveTimer(p);
|
||||
+ }
|
||||
|
||||
LLDPAD_DBG("%s:%s vdp added\n", __func__, ifname);
|
||||
return;
|
||||
--
|
||||
1.7.4.4
|
||||
|
71
lldpad-0.9.41-support-disabling-of-LLDP-on-switch-side.patch
Normal file
71
lldpad-0.9.41-support-disabling-of-LLDP-on-switch-side.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From 76dbd2e24ff64fe7ae1503c658614e44a0a4e2e4 Mon Sep 17 00:00:00 2001
|
||||
From: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Date: Wed, 4 May 2011 08:21:42 -0700
|
||||
Subject: [PATCH 1/3] support disabling of LLDP on switch side
|
||||
|
||||
In case LLDP is disabled on the switch side, the switch will send a LLDP
|
||||
frame with chassis, port and TTL with TTL set to 0.
|
||||
In this case evb_mibdelete is called to reset the previously negotiated EVB
|
||||
data.
|
||||
|
||||
Signed-off-by: Jens Osterkamp <jens@linux.vnet.ibm.com>
|
||||
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
|
||||
Signed-off-by: Petr Sabata <psabata@redhat.com>
|
||||
---
|
||||
lldp_evb.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 files changed, 33 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/lldp_evb.c b/lldp_evb.c
|
||||
index 0839054..b3d756b 100644
|
||||
--- a/lldp_evb.c
|
||||
+++ b/lldp_evb.c
|
||||
@@ -594,6 +594,38 @@ out_err:
|
||||
return;
|
||||
}
|
||||
|
||||
+u8 evb_mibdelete(struct port *port)
|
||||
+{
|
||||
+ struct evb_data *ed;
|
||||
+
|
||||
+ if (!is_tlv_txenabled(port->ifname, TLVID_8021Qbg(LLDP_EVB_SUBTYPE))) {
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+
|
||||
+ LLDPAD_DBG("%s(%i): mibdelete triggered for port %s.\n", __func__,
|
||||
+ __LINE__, port->ifname);
|
||||
+
|
||||
+ ed = evb_data(port->ifname);
|
||||
+ if (!ed) {
|
||||
+ LLDPAD_DBG("%s:%s does not exist.\n", __func__, port->ifname);
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+
|
||||
+ free(ed->tie);
|
||||
+ free(ed->last);
|
||||
+ free(ed->policy);
|
||||
+
|
||||
+ if (evb_init_cfg_tlv(ed)) {
|
||||
+ LLDPAD_ERR("%s:%s evb_init_cfg_tlv failed\n", __func__, port->ifname);
|
||||
+ goto out_err;
|
||||
+ }
|
||||
+
|
||||
+ evb_bld_tlv(ed);
|
||||
+
|
||||
+out_err:
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct lldp_mod_ops evb_ops = {
|
||||
.lldp_mod_register = evb_register,
|
||||
.lldp_mod_unregister = evb_unregister,
|
||||
@@ -601,6 +633,7 @@ static const struct lldp_mod_ops evb_ops = {
|
||||
.lldp_mod_rchange = evb_rchange,
|
||||
.lldp_mod_ifup = evb_ifup,
|
||||
.lldp_mod_ifdown = evb_ifdown,
|
||||
+ .lldp_mod_mibdelete = evb_mibdelete,
|
||||
.get_arg_handler = evb_get_arg_handlers,
|
||||
};
|
||||
|
||||
--
|
||||
1.7.4.4
|
||||
|
11
lldpad.spec
11
lldpad.spec
@ -1,6 +1,6 @@
|
||||
Name: lldpad
|
||||
Version: 0.9.41
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: Intel LLDP Agent
|
||||
|
||||
Group: System Environment/Daemons
|
||||
@ -64,6 +64,9 @@ Patch148: lldpad-0.9.41-lldpad-dormantTimer-should-not-be-touched-by-modul
|
||||
Patch149: lldpad-0.9.41-lldpad-dcbx-dropped-ifdown-messages-breaks-module.patch
|
||||
Patch150: lldpad-0.9.41-lldpad-DCB-remove-iSCSI-tc-qdisc-and-filters.patch
|
||||
Patch151: lldpad-0.9.41-lldpad-make-debug-messages-from-netlink-path-helpful.patch
|
||||
Patch152: lldpad-0.9.41-support-disabling-of-LLDP-on-switch-side.patch
|
||||
Patch153: lldpad-0.9.41-reduce-number-of-select-timeouts-for-ECP.patch
|
||||
Patch154: lldpad-0.9.41-reduce-number-of-select-timeouts-for-VDP.patch
|
||||
|
||||
Requires: kernel >= 2.6.32
|
||||
BuildRequires: libconfig-devel >= 1.3.2 kernel-headers >= 2.6.32
|
||||
@ -145,6 +148,9 @@ that use %{name}.
|
||||
%patch149 -p1
|
||||
%patch150 -p1
|
||||
%patch151 -p1
|
||||
%patch152 -p1
|
||||
%patch153 -p1
|
||||
%patch154 -p1
|
||||
# Fedora patches on top of that...
|
||||
%patch0 -p1 -b .make
|
||||
%patch1 -p1 -b .init
|
||||
@ -211,6 +217,9 @@ fi
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed May 4 2011 Petr Sabata <psabata@redhat.com> - 0.9.41-3
|
||||
- Fix the frequent, power consuming lldpad wake-ups (rhbz#701943)
|
||||
|
||||
* Thu Apr 21 2011 Petr Sabata <psabata@redhat.com> - 0.9.41-2
|
||||
- Bring in upstream 802.1Qbg bugfixes
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user