* Re: [PATCH] net/bonding: bonding: Adjust coding style for bond_3ad files.
From: Rafael Aquini @ 2011-05-06 1:05 UTC (permalink / raw)
To: kernel-janitors
Cc: Joe Perches, Jay Vosburgh, Andy Gospodarek, netdev, shemminger
In-Reply-To: <1304549184.1788.128.camel@Joe-Laptop>
Howdy,
Thanks to Joe Perches & Stephen Hemminger for
taking time and proving valuable feedback.
Resubmitting the proposed patch.
---
drivers/net/bonding/bond_3ad.c | 836 +++++++++++++++++++++++-----------------
drivers/net/bonding/bond_3ad.h | 195 +++++-----
2 files changed, 579 insertions(+), 452 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 31912f1..fdb07be 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -34,14 +34,14 @@
#include "bonding.h"
#include "bond_3ad.h"
-// General definitions
+/* General definitions */
#define AD_SHORT_TIMEOUT 1
#define AD_LONG_TIMEOUT 0
#define AD_STANDBY 0x2
#define AD_MAX_TX_IN_SECOND 3
#define AD_COLLECTOR_MAX_DELAY 0
-// Timer definitions(43.4.4 in the 802.3ad standard)
+/* Timer definitions (43.4.4 in the 802.3ad standard) */
#define AD_FAST_PERIODIC_TIME 1
#define AD_SLOW_PERIODIC_TIME 30
#define AD_SHORT_TIMEOUT_TIME (3*AD_FAST_PERIODIC_TIME)
@@ -49,7 +49,7 @@
#define AD_CHURN_DETECTION_TIME 60
#define AD_AGGREGATE_WAIT_TIME 2
-// Port state definitions(43.4.2.2 in the 802.3ad standard)
+/* Port state definitions (43.4.2.2 in the 802.3ad standard) */
[raquini@x61 linux-2.6 (bond-patch %)]$ git format-patch --no-renames -k --stdout 5895198c56d131cc696556a45f7ff0ea99ac297b > ../../patches/linux-2.6-net-bonding-Adjust-codingstyle-for-bond_3ad-files.patch
[raquini@x61 linux-2.6 (bond-patch %)]$ vim ../../patches/linux-2.6-net-bonding-Adjust-codingstyle-for-bond_3ad-files.patch
[raquini@x61 linux-2.6 (bond-patch %)]$ cat ../../patches/linux-2.6-net-bonding-Adjust-codingstyle-for-bond_3ad-files.patch
>From 0784cebed3e82f2448492a17688b400c91408ecf Mon Sep 17 00:00:00 2001
From: Rafael Aquini <aquini@redhat.com>
Date: Thu, 5 May 2011 21:47:00 -0300
Subject: [net] bonding: Adjust coding style for bond_3ad files.
---
drivers/net/bonding/bond_3ad.c | 836 +++++++++++++++++++++++-----------------
drivers/net/bonding/bond_3ad.h | 195 +++++-----
2 files changed, 579 insertions(+), 452 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 31912f1..fdb07be 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -34,14 +34,14 @@
#include "bonding.h"
#include "bond_3ad.h"
-// General definitions
+/* General definitions */
#define AD_SHORT_TIMEOUT 1
#define AD_LONG_TIMEOUT 0
#define AD_STANDBY 0x2
#define AD_MAX_TX_IN_SECOND 3
#define AD_COLLECTOR_MAX_DELAY 0
-// Timer definitions(43.4.4 in the 802.3ad standard)
+/* Timer definitions (43.4.4 in the 802.3ad standard) */
#define AD_FAST_PERIODIC_TIME 1
#define AD_SLOW_PERIODIC_TIME 30
#define AD_SHORT_TIMEOUT_TIME (3*AD_FAST_PERIODIC_TIME)
@@ -49,7 +49,7 @@
#define AD_CHURN_DETECTION_TIME 60
#define AD_AGGREGATE_WAIT_TIME 2
-// Port state definitions(43.4.2.2 in the 802.3ad standard)
+/* Port state definitions (43.4.2.2 in the 802.3ad standard) */
#define AD_STATE_LACP_ACTIVITY 0x1
#define AD_STATE_LACP_TIMEOUT 0x2
#define AD_STATE_AGGREGATION 0x4
@@ -59,7 +59,9 @@
#define AD_STATE_DEFAULTED 0x40
#define AD_STATE_EXPIRED 0x80
-// Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard)
+/* Port Variables definitions used by the State Machines
+ * (43.4.7 in the 802.3ad standard)
+ */
#define AD_PORT_BEGIN 0x1
#define AD_PORT_LACP_ENABLED 0x2
#define AD_PORT_ACTOR_CHURN 0x4
@@ -71,27 +73,23 @@
#define AD_PORT_SELECTED 0x100
#define AD_PORT_MOVED 0x200
-// Port Key definitions
-// key is determined according to the link speed, duplex and
-// user key(which is yet not supported)
-// ------------------------------------------------------------
-// Port key : | User key | Speed |Duplex|
-// ------------------------------------------------------------
-// 16 6 1 0
+/* Port Key definitions:
+ * key is determined according to the link speed, duplex and
+ * user key (which is yet not supported)
+ * ------------------------------------------------------------
+ * Port key: | User key | Speed |Duplex|
+ * ------------------------------------------------------------
+ * 16 6 1 0
+ */
#define AD_DUPLEX_KEY_BITS 0x1
#define AD_SPEED_KEY_BITS 0x3E
#define AD_USER_KEY_BITS 0xFFC0
-//dalloun
#define AD_LINK_SPEED_BITMASK_1MBPS 0x1
#define AD_LINK_SPEED_BITMASK_10MBPS 0x2
#define AD_LINK_SPEED_BITMASK_100MBPS 0x4
#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8
#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10
-//endalloun
-
-// compare MAC addresses
-#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN)
static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } };
static u16 ad_ticks_per_sec;
@@ -99,7 +97,7 @@ static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
static const u8 lacpdu_mcast_addr[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-// ================= main 802.3ad protocol functions ==================
+/* ================= main 802.3ad protocol functions ================== */
static int ad_lacpdu_send(struct port *port);
static int ad_marker_send(struct port *port, struct bond_marker *marker);
static void ad_mux_machine(struct port *port);
@@ -113,14 +111,12 @@ static void ad_initialize_agg(struct aggregator *aggregator);
static void ad_initialize_port(struct port *port, int lacp_fast);
static void ad_enable_collecting_distributing(struct port *port);
static void ad_disable_collecting_distributing(struct port *port);
-static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port);
-static void ad_marker_response_received(struct bond_marker *marker, struct port *port);
-
-
-/////////////////////////////////////////////////////////////////////////////////
-// ================= api to bonding and kernel code ==================
-/////////////////////////////////////////////////////////////////////////////////
+static void ad_marker_info_received(struct bond_marker *marker_info,
+ struct port *port);
+static void ad_marker_response_received(struct bond_marker *marker,
+ struct port *port);
+/* ================= api to bonding and kernel code ================== */
/**
* __get_bond_by_port - get the port's bonding struct
* @port: the port we're looking at
@@ -161,7 +157,7 @@ static inline struct port *__get_next_port(struct port *port)
struct bonding *bond = __get_bond_by_port(port);
struct slave *slave = port->slave;
- // If there's no bond for this port, or this is the last slave
+ /* If there's no bond for this port, or this is the last slave */
if ((bond == NULL) || (slave->next == bond->first_slave))
return NULL;
@@ -179,7 +175,7 @@ static inline struct aggregator *__get_first_agg(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
- // If there's no bond for this port, or bond has no slaves
+ /* If there's no bond for this port, or bond has no slaves */
if ((bond == NULL) || (bond->slave_cnt == 0))
return NULL;
@@ -198,7 +194,7 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
struct slave *slave = aggregator->slave;
struct bonding *bond = bond_get_bond_by_slave(slave);
- // If there's no bond for this aggregator, or this is the last slave
+ /* If there's no bond for this aggregator, or this is the last slave */
if ((bond == NULL) || (slave->next == bond->first_slave))
return NULL;
@@ -316,10 +312,9 @@ static u16 __get_link_speed(struct port *port)
struct slave *slave = port->slave;
u16 speed;
- /* this if covers only a special case: when the configuration starts with
- * link down, it sets the speed to 0.
- * This is done in spite of the fact that the e100 driver reports 0 to be
- * compatible with MVT in the future.*/
+ /* handling a special case:
+ * when the configuration starts with link down, it sets the speed to 0
+ */
if (slave->link != BOND_LINK_UP)
speed = 0;
else {
@@ -341,7 +336,8 @@ static u16 __get_link_speed(struct port *port)
break;
default:
- speed = 0; // unknown speed value from ethtool. shouldn't happen
+ /* unknown speed value from ethtool. shouldn't happen */
+ speed = 0;
break;
}
}
@@ -365,8 +361,9 @@ static u8 __get_duplex(struct port *port)
u8 retval;
- // handling a special case: when the configuration starts with
- // link down, it sets the duplex to 0.
+ /* handling a special case:
+ * when the configuration starts with link down, it sets the duplex to 0
+ */
if (slave->link != BOND_LINK_UP)
retval = 0x0;
else {
@@ -394,12 +391,10 @@ static u8 __get_duplex(struct port *port)
*/
static inline void __initialize_port_locks(struct port *port)
{
- // make sure it isn't called twice
+ /* make sure it isn't called twice */
spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock));
}
-//conversions
-
/**
* __ad_timer_to_ticks - convert a given timer type to AD module ticks
* @timer_type: which timer to operate
@@ -411,36 +406,32 @@ static inline void __initialize_port_locks(struct port *port)
*/
static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
{
- u16 retval = 0; /* to silence the compiler */
+ u16 retval = 0;
switch (timer_type) {
- case AD_CURRENT_WHILE_TIMER: // for rx machine usage
+ case AD_CURRENT_WHILE_TIMER: /* for rx machine usage */
if (par)
- retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout
+ retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec);
else
- retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout
+ retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec);
break;
- case AD_ACTOR_CHURN_TIMER: // for local churn machine
+ case AD_ACTOR_CHURN_TIMER: /* for local churn machine */
retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
break;
- case AD_PERIODIC_TIMER: // for periodic machine
- retval = (par*ad_ticks_per_sec); // long timeout
+ case AD_PERIODIC_TIMER: /* for periodic machine */
+ retval = (par*ad_ticks_per_sec);
break;
- case AD_PARTNER_CHURN_TIMER: // for remote churn machine
+ case AD_PARTNER_CHURN_TIMER: /* for remote churn machine */
retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
break;
- case AD_WAIT_WHILE_TIMER: // for selection machine
+ case AD_WAIT_WHILE_TIMER: /* for selection machine */
retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec);
break;
}
return retval;
}
-
-/////////////////////////////////////////////////////////////////////////////////
-// ================= ad_rx_machine helper functions ==================
-/////////////////////////////////////////////////////////////////////////////////
-
+/* ================= ad_rx_machine helper functions ================== */
/**
* __choose_matched - update a port's matched variable from a received lacpdu
* @lacpdu: the lacpdu we've received
@@ -466,17 +457,17 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
*/
static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
{
- // check if all parameters are alike
+ /* check if all parameters are alike */
if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
(ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
- !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
+ !compare_ether_addr((const u8 *)&(lacpdu->partner_system), (const u8 *)&(port->actor_system)) &&
(ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
(ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
- // or this is individual link(aggregation == FALSE)
+ /* or this is individual link(aggregation == FALSE) */
((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
) {
- // update the state machine Matched variable
+ /* update the state machine Matched variable */
port->sm_vars |= AD_PORT_MATCHED;
} else {
port->sm_vars &= ~AD_PORT_MATCHED;
@@ -498,7 +489,7 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
struct port_params *partner = &port->partner_oper;
__choose_matched(lacpdu, port);
- // record the new parameter values for the partner operational
+ /* record the new values for the operational partner */
partner->port_number = ntohs(lacpdu->actor_port);
partner->port_priority = ntohs(lacpdu->actor_port_priority);
partner->system = lacpdu->actor_system;
@@ -506,12 +497,14 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
partner->key = ntohs(lacpdu->actor_key);
partner->port_state = lacpdu->actor_state;
- // set actor_oper_port_state.defaulted to FALSE
+ /* set actor_oper_port_state.defaulted to FALSE */
port->actor_oper_port_state &= ~AD_STATE_DEFAULTED;
- // set the partner sync. to on if the partner is sync. and the port is matched
- if ((port->sm_vars & AD_PORT_MATCHED)
- && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION))
+ /* set the partner sync to on if the partner is sync
+ * and the port is matched.
+ */
+ if ((port->sm_vars & AD_PORT_MATCHED) &&
+ (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION))
partner->port_state |= AD_STATE_SYNCHRONIZATION;
else
partner->port_state &= ~AD_STATE_SYNCHRONIZATION;
@@ -529,11 +522,8 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
static void __record_default(struct port *port)
{
if (port) {
- // record the partner admin parameters
memcpy(&port->partner_oper, &port->partner_admin,
sizeof(struct port_params));
-
- // set actor_oper_port_state.defaulted to true
port->actor_oper_port_state |= AD_STATE_DEFAULTED;
}
}
@@ -556,14 +546,14 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port)
if (lacpdu && port) {
const struct port_params *partner = &port->partner_oper;
- // check if any parameter is different
+ /* check if any parameter is different */
if (ntohs(lacpdu->actor_port) != partner->port_number ||
ntohs(lacpdu->actor_port_priority) != partner->port_priority ||
- MAC_ADDRESS_COMPARE(&lacpdu->actor_system, &partner->system) ||
+ compare_ether_addr((const u8 *)&lacpdu->actor_system, (const u8 *)&partner->system) ||
ntohs(lacpdu->actor_system_priority) != partner->system_priority ||
ntohs(lacpdu->actor_key) != partner->key ||
(lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) {
- // update the state machine Selected variable
+ /* update the state machine Selected variable */
port->sm_vars &= ~AD_PORT_SELECTED;
}
}
@@ -587,15 +577,15 @@ static void __update_default_selected(struct port *port)
const struct port_params *admin = &port->partner_admin;
const struct port_params *oper = &port->partner_oper;
- // check if any parameter is different
if (admin->port_number != oper->port_number ||
admin->port_priority != oper->port_priority ||
- MAC_ADDRESS_COMPARE(&admin->system, &oper->system) ||
+ compare_ether_addr((const u8 *)&admin->system,
+ (const u8 *)&oper->system) ||
admin->system_priority != oper->system_priority ||
admin->key != oper->key ||
(admin->port_state & AD_STATE_AGGREGATION)
!= (oper->port_state & AD_STATE_AGGREGATION)) {
- // update the state machine Selected variable
+ /* update the state machine Selected variable */
port->sm_vars &= ~AD_PORT_SELECTED;
}
}
@@ -615,12 +605,12 @@ static void __update_default_selected(struct port *port)
*/
static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
{
- // validate lacpdu and port
+ /* validate lacpdu and port */
if (lacpdu && port) {
- // check if any parameter is different
+ /* check if any parameter is different */
if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
(ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
- MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) ||
+ compare_ether_addr((const u8 *)&(lacpdu->partner_system), (const u8 *)&(port->actor_system)) ||
(ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
(ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
@@ -628,7 +618,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION))
) {
-
+ /* set port ntt */
port->ntt = true;
}
}
@@ -644,9 +634,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
*/
static void __attach_bond_to_agg(struct port *port)
{
- port = NULL; /* just to satisfy the compiler */
- // This function does nothing since the parser/multiplexer of the receive
- // and the parser/multiplexer of the aggregator are already combined
+ port = NULL;
}
/**
@@ -659,9 +647,7 @@ static void __attach_bond_to_agg(struct port *port)
*/
static void __detach_bond_from_agg(struct port *port)
{
- port = NULL; /* just to satisfy the compiler */
- // This function does nothing sience the parser/multiplexer of the receive
- // and the parser/multiplexer of the aggregator are already combined
+ port = NULL;
}
/**
@@ -675,7 +661,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator)
int retval = 1;
if (aggregator) {
- // scan all ports in this aggregator to verfy if they are all ready
+ /* scan all ports in this aggregator
+ * to verfy if they are all ready.
+ */
for (port = aggregator->lag_ports;
port;
port = port->next_port_in_aggregator) {
@@ -737,7 +725,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
bandwidth = aggregator->num_of_ports * 10000;
break;
default:
- bandwidth = 0; /*to silence the compiler ....*/
+ bandwidth = 0;
}
}
return bandwidth;
@@ -809,10 +797,7 @@ static inline void __update_lacpdu_from_port(struct port *port)
*/
}
-//////////////////////////////////////////////////////////////////////////////////////
-// ================= main 802.3ad protocol code ======================================
-//////////////////////////////////////////////////////////////////////////////////////
-
+/* ================= main 802.3ad protocol code ================= */
/**
* ad_lacpdu_send - send out a lacpdu packet on a given port
* @port: the port we're looking at
@@ -841,11 +826,12 @@ static int ad_lacpdu_send(struct port *port)
memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN);
/* Note: source address is set to be the member's PERMANENT address,
- because we use it to identify loopback lacpdus in receive. */
+ * because we use it to identify loopback lacpdus in receive.
+ */
memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN);
lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU;
- lacpdu_header->lacpdu = port->lacpdu; // struct copy
+ lacpdu_header->lacpdu = port->lacpdu;
dev_queue_xmit(skb);
@@ -886,7 +872,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN);
marker_header->hdr.h_proto = PKT_TYPE_LACPDU;
- marker_header->marker = *marker; // struct copy
+ marker_header->marker = *marker;
dev_queue_xmit(skb);
@@ -902,80 +888,101 @@ static void ad_mux_machine(struct port *port)
{
mux_states_t last_state;
- // keep current State Machine state to compare later if it was changed
last_state = port->sm_mux_state;
if (port->sm_vars & AD_PORT_BEGIN) {
- port->sm_mux_state = AD_MUX_DETACHED; // next state
+ port->sm_mux_state = AD_MUX_DETACHED;
} else {
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
- if ((port->sm_vars & AD_PORT_SELECTED)
- || (port->sm_vars & AD_PORT_STANDBY))
+ if ((port->sm_vars & AD_PORT_SELECTED) ||
+ (port->sm_vars & AD_PORT_STANDBY))
/* if SELECTED or STANDBY */
- port->sm_mux_state = AD_MUX_WAITING; // next state
+ port->sm_mux_state = AD_MUX_WAITING;
break;
case AD_MUX_WAITING:
- // if SELECTED == FALSE return to DETACH state
- if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED
+ /* if SELECTED == FALSE return to DETACH state */
+ if (!(port->sm_vars & AD_PORT_SELECTED)) {
port->sm_vars &= ~AD_PORT_READY_N;
- // in order to withhold the Selection Logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
- __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
- port->sm_mux_state = AD_MUX_DETACHED; // next state
+ /* in order to withhold the Selection Logic
+ * to check all ports READY_N value at every
+ * callback cycle to update ready variable,
+ * we check READY_N and update READY here
+ */
+ __set_agg_ports_ready(port->aggregator,
+ __agg_ports_are_ready(port->aggregator));
+ port->sm_mux_state = AD_MUX_DETACHED;
break;
}
- // check if the wait_while_timer expired
- if (port->sm_mux_timer_counter
- && !(--port->sm_mux_timer_counter))
+ /* check if the wait_while_timer expired */
+ if (port->sm_mux_timer_counter &&
+ !(--port->sm_mux_timer_counter))
port->sm_vars |= AD_PORT_READY_N;
- // in order to withhold the selection logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
- __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
-
- // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state
- if ((port->sm_vars & AD_PORT_READY)
- && !port->sm_mux_timer_counter)
- port->sm_mux_state = AD_MUX_ATTACHED; // next state
+ /* in order to withhold the selection logic
+ * to check all ports READY_N value at every
+ * callback cycle to update ready variable,
+ * we check READY_N and update READY here
+ */
+ __set_agg_ports_ready(port->aggregator,
+ __agg_ports_are_ready(port->aggregator));
+
+ /* if the wait_while_timer expired, and the port
+ * is in READY state, move to ATTACHED state
+ */
+ if ((port->sm_vars & AD_PORT_READY) &&
+ !port->sm_mux_timer_counter)
+ port->sm_mux_state = AD_MUX_ATTACHED;
break;
case AD_MUX_ATTACHED:
- // check also if agg_select_timer expired(so the edable port will take place only after this timer)
- if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) {
- port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state
- } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if UNSELECTED or STANDBY
+ /* check also if agg_select_timer expired
+ * so the enable port will take place
+ * only after this timer
+ */
+ if ((port->sm_vars & AD_PORT_SELECTED) &&
+ (port->partner_oper.port_state &
+ AD_STATE_SYNCHRONIZATION) &&
+ !__check_agg_selection_timer(port)) {
+ port->sm_mux_state =
+ AD_MUX_COLLECTING_DISTRIBUTING;
+ } else if (!(port->sm_vars & AD_PORT_SELECTED) ||
+ (port->sm_vars & AD_PORT_STANDBY)) {
+ /* if UNSELECTED or STANDBY */
port->sm_vars &= ~AD_PORT_READY_N;
- // in order to withhold the selection logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
- __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
- port->sm_mux_state = AD_MUX_DETACHED;// next state
+ /* in order to withhold the Selection Logic
+ * to check all ports READY_N value at every
+ * callback cycle to update ready variable,
+ * we check READY_N and update READY here
+ */
+ __set_agg_ports_ready(port->aggregator,
+ __agg_ports_are_ready(port->aggregator));
+ port->sm_mux_state = AD_MUX_DETACHED;
}
break;
case AD_MUX_COLLECTING_DISTRIBUTING:
- if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) ||
- !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION)
- ) {
- port->sm_mux_state = AD_MUX_ATTACHED;// next state
-
+ if (!(port->sm_vars & AD_PORT_SELECTED) ||
+ (port->sm_vars & AD_PORT_STANDBY) ||
+ !(port->partner_oper.port_state &
+ AD_STATE_SYNCHRONIZATION)) {
+ port->sm_mux_state = AD_MUX_ATTACHED;
} else {
- // if port state hasn't changed make
- // sure that a collecting distributing
- // port in an active aggregator is enabled
+ /* if port state hasn't changed make
+ * sure that a collecting distributing
+ * port in an active aggregator is enabled
+ */
if (port->aggregator &&
port->aggregator->is_active &&
- !__port_is_enabled(port)) {
-
+ !__port_is_enabled(port))
__enable_port(port);
- }
}
break;
- default: //to silence the compiler
+ default:
break;
}
}
- // check if the state machine was changed
+ /* check if the state machine was changed */
if (port->sm_mux_state != last_state) {
pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n",
port->actor_port_number, last_state,
@@ -983,14 +990,16 @@ static void ad_mux_machine(struct port *port)
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
__detach_bond_from_agg(port);
- port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
+ port->actor_oper_port_state &=
+ ~AD_STATE_SYNCHRONIZATION;
ad_disable_collecting_distributing(port);
port->actor_oper_port_state &= ~AD_STATE_COLLECTING;
port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;
port->ntt = true;
break;
case AD_MUX_WAITING:
- port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0);
+ port->sm_mux_timer_counter =
+ __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0);
break;
case AD_MUX_ATTACHED:
__attach_bond_to_agg(port);
@@ -1006,7 +1015,7 @@ static void ad_mux_machine(struct port *port)
ad_enable_collecting_distributing(port);
port->ntt = true;
break;
- default: //to silence the compiler
+ default:
break;
}
}
@@ -1025,59 +1034,62 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
{
rx_states_t last_state;
- // keep current State Machine state to compare later if it was changed
last_state = port->sm_rx_state;
- // check if state machine should change state
- // first, check if port was reinitialized
+ /* check if state machine should change state
+ * first, check if port was reinitialized
+ */
if (port->sm_vars & AD_PORT_BEGIN)
/* next state */
port->sm_rx_state = AD_RX_INITIALIZE;
- // check if port is not enabled
- else if (!(port->sm_vars & AD_PORT_BEGIN)
- && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
+ /* check if port is not enabled */
+ else if (!(port->sm_vars & AD_PORT_BEGIN) &&
+ !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
/* next state */
port->sm_rx_state = AD_RX_PORT_DISABLED;
- // check if new lacpdu arrived
- else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) {
- port->sm_rx_timer_counter = 0; // zero timer
+ /* check if new lacpdu arrived */
+ else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) ||
+ (port->sm_rx_state == AD_RX_DEFAULTED) ||
+ (port->sm_rx_state == AD_RX_CURRENT))) {
+ port->sm_rx_timer_counter = 0; /* zero timer */
port->sm_rx_state = AD_RX_CURRENT;
} else {
- // if timer is on, and if it is expired
- if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) {
+ /* if timer is on, and if it is expired */
+ if (port->sm_rx_timer_counter &&
+ !(--port->sm_rx_timer_counter)) {
switch (port->sm_rx_state) {
case AD_RX_EXPIRED:
- port->sm_rx_state = AD_RX_DEFAULTED; // next state
+ port->sm_rx_state = AD_RX_DEFAULTED;
break;
case AD_RX_CURRENT:
- port->sm_rx_state = AD_RX_EXPIRED; // next state
+ port->sm_rx_state = AD_RX_EXPIRED;
break;
- default: //to silence the compiler
+ default:
break;
}
} else {
- // if no lacpdu arrived and no timer is on
+ /* if no lacpdu arrived and no timer is on */
switch (port->sm_rx_state) {
case AD_RX_PORT_DISABLED:
if (port->sm_vars & AD_PORT_MOVED)
- port->sm_rx_state = AD_RX_INITIALIZE; // next state
- else if (port->is_enabled
- && (port->sm_vars
- & AD_PORT_LACP_ENABLED))
- port->sm_rx_state = AD_RX_EXPIRED; // next state
- else if (port->is_enabled
- && ((port->sm_vars
- & AD_PORT_LACP_ENABLED) == 0))
- port->sm_rx_state = AD_RX_LACP_DISABLED; // next state
+ port->sm_rx_state = AD_RX_INITIALIZE;
+ else if (port->is_enabled &&
+ (port->sm_vars &
+ AD_PORT_LACP_ENABLED))
+ port->sm_rx_state = AD_RX_EXPIRED;
+ else if (port->is_enabled &&
+ ((port->sm_vars &
+ AD_PORT_LACP_ENABLED) == 0))
+ port->sm_rx_state = AD_RX_LACP_DISABLED;
break;
- default: //to silence the compiler
+ default:
break;
}
}
}
- // check if the State machine was changed or new lacpdu arrived
+ /* check if the State machine was changed or new lacpdu arrived */
if ((port->sm_rx_state != last_state) || (lacpdu)) {
pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n",
port->actor_port_number, last_state,
@@ -1092,7 +1104,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
__record_default(port);
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
port->sm_vars &= ~AD_PORT_MOVED;
- port->sm_rx_state = AD_RX_PORT_DISABLED; // next state
+ port->sm_rx_state = AD_RX_PORT_DISABLED;
/*- Fall Through -*/
@@ -1107,14 +1119,20 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break;
case AD_RX_EXPIRED:
- //Reset of the Synchronization flag. (Standard 43.4.12)
- //This reset cause to disable this port in the COLLECTING_DISTRIBUTING state of the
- //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port.
- port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
+ /* Reset of the Synchronization flag. (Standard 43.4.12)
+ * This reset cause to disable this port in the
+ * COLLECTING_DISTRIBUTING state of the mux machine
+ * in case of EXPIRED even if LINK_DOWN didn't arrive
+ * for the port.
+ */
+ port->partner_oper.port_state &=
+ ~AD_STATE_SYNCHRONIZATION;
port->sm_vars &= ~AD_PORT_MATCHED;
port->partner_oper.port_state |=
AD_STATE_LACP_ACTIVITY;
- port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
+ port->sm_rx_timer_counter =
+ __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER,
+ (u16)(AD_SHORT_TIMEOUT));
port->actor_oper_port_state |= AD_STATE_EXPIRED;
break;
case AD_RX_DEFAULTED:
@@ -1124,12 +1142,13 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break;
case AD_RX_CURRENT:
- // detect loopback situation
- if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
- // INFO_RECEIVED_LOOPBACK_FRAMES
+ /* detect loopback situation */
+ if (!compare_ether_addr((const u8 *)&(lacpdu->actor_system), (const u8 *)&(port->actor_system))) {
+ /* INFO_RECEIVED_LOOPBACK_FRAMES */
pr_err("%s: An illegal loopback occurred on adapter (%s).\n"
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
- port->slave->dev->master->name, port->slave->dev->name);
+ port->slave->dev->master->name,
+ port->slave->dev->name);
return;
}
__update_selected(lacpdu, port);
@@ -1137,15 +1156,19 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
__record_pdu(lacpdu, port);
port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT));
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
- // verify that if the aggregator is enabled, the port is enabled too.
- //(because if the link goes down for a short time, the 802.3ad will not
- // catch it, and the port will continue to be disabled)
+
+ /* verify that if the aggregator is enabled,
+ * so the port is enabled too.
+ * because if the link goes down for a short time,
+ * the 802.3ad will not catch it,
+ * and the port will continue to be disabled
+ */
if (port->aggregator
&& port->aggregator->is_active
&& !__port_is_enabled(port))
__enable_port(port);
break;
- default: //to silence the compiler
+ default:
break;
}
}
@@ -1158,9 +1181,11 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
*/
static void ad_tx_machine(struct port *port)
{
- // check if tx timer expired, to verify that we do not send more than 3 packets per second
+ /* check if tx timer has expired,
+ * to verify that we do not send more than 3 packets per second
+ */
if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) {
- // check if there is something to send
+ /* check if there is something to send */
if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
__update_lacpdu_from_port(port);
@@ -1168,14 +1193,17 @@ static void ad_tx_machine(struct port *port)
pr_debug("Sent LACPDU on port %d\n",
port->actor_port_number);
- /* mark ntt as false, so it will not be sent again until
- demanded */
+ /* mark ntt as false,
+ * so it won't be sent again until demanded
+ */
port->ntt = false;
}
}
- // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND
+ /* restart tx timer
+ * to verify that we won't exceed AD_MAX_TX_IN_SECOND
+ */
port->sm_tx_timer_counter =
- ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
+ ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
}
}
@@ -1189,76 +1217,87 @@ static void ad_periodic_machine(struct port *port)
{
periodic_states_t last_state;
- // keep current state machine state to compare later if it was changed
+ /* keep current state machine state to compare later if it was changed*/
last_state = port->sm_periodic_state;
- // check if port was reinitialized
- if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) ||
- (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & AD_STATE_LACP_ACTIVITY))
- ) {
- port->sm_periodic_state = AD_NO_PERIODIC; // next state
+ /* check if port was reinitialized */
+ if (((port->sm_vars & AD_PORT_BEGIN) ||
+ !(port->sm_vars & AD_PORT_LACP_ENABLED) ||
+ !port->is_enabled) ||
+ (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) &&
+ !(port->partner_oper.port_state & AD_STATE_LACP_ACTIVITY))) {
+ port->sm_periodic_state = AD_NO_PERIODIC; /* next state */
}
- // check if state machine should change state
+ /* check if state machine should change state */
else if (port->sm_periodic_timer_counter) {
- // check if periodic state machine expired
+ /* check if periodic state machine expired */
if (!(--port->sm_periodic_timer_counter)) {
- // if expired then do tx
- port->sm_periodic_state = AD_PERIODIC_TX; // next state
+ /* if expired then do tx, next state */
+ port->sm_periodic_state = AD_PERIODIC_TX;
} else {
- // If not expired, check if there is some new timeout parameter from the partner state
+ /* If not expired, check if there is some
+ * new timeout parameter from the partner state
+ */
switch (port->sm_periodic_state) {
case AD_FAST_PERIODIC:
if (!(port->partner_oper.port_state
& AD_STATE_LACP_TIMEOUT))
- port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
+ port->sm_periodic_state = AD_SLOW_PERIODIC;
break;
case AD_SLOW_PERIODIC:
- if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) {
- // stop current timer
+ if ((port->partner_oper.port_state &
+ AD_STATE_LACP_TIMEOUT)) {
+ /* stop current timer */
port->sm_periodic_timer_counter = 0;
- port->sm_periodic_state = AD_PERIODIC_TX; // next state
+ port->sm_periodic_state = AD_PERIODIC_TX;
}
break;
- default: //to silence the compiler
+ default:
break;
}
}
} else {
switch (port->sm_periodic_state) {
case AD_NO_PERIODIC:
- port->sm_periodic_state = AD_FAST_PERIODIC; // next state
+ port->sm_periodic_state = AD_FAST_PERIODIC;
break;
case AD_PERIODIC_TX:
- if (!(port->partner_oper.port_state
- & AD_STATE_LACP_TIMEOUT))
- port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
+ if (!(port->partner_oper.port_state &
+ AD_STATE_LACP_TIMEOUT))
+ port->sm_periodic_state = AD_SLOW_PERIODIC;
else
- port->sm_periodic_state = AD_FAST_PERIODIC; // next state
+ port->sm_periodic_state = AD_FAST_PERIODIC;
break;
- default: //to silence the compiler
+ default:
break;
}
}
- // check if the state machine was changed
+ /* check if the state machine was changed */
if (port->sm_periodic_state != last_state) {
pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n",
port->actor_port_number, last_state,
port->sm_periodic_state);
switch (port->sm_periodic_state) {
case AD_NO_PERIODIC:
- port->sm_periodic_timer_counter = 0; // zero timer
+ port->sm_periodic_timer_counter = 0;
break;
case AD_FAST_PERIODIC:
- port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
+ /* decrement 1 tick we lost in PERIODIC_TX cycle */
+ port->sm_periodic_timer_counter =
+ __ad_timer_to_ticks(AD_PERIODIC_TIMER,
+ (u16)(AD_FAST_PERIODIC_TIME))-1;
break;
case AD_SLOW_PERIODIC:
- port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
+ /* decrement 1 tick we lost in PERIODIC_TX cycle */
+ port->sm_periodic_timer_counter =
+ __ad_timer_to_ticks(AD_PERIODIC_TIMER,
+ (u16)(AD_SLOW_PERIODIC_TIME))-1;
break;
case AD_PERIODIC_TX:
port->ntt = true;
break;
- default: //to silence the compiler
+ default:
break;
}
}
@@ -1274,46 +1313,58 @@ static void ad_periodic_machine(struct port *port)
*/
static void ad_port_selection_logic(struct port *port)
{
- struct aggregator *aggregator, *free_aggregator = NULL, *temp_aggregator;
+ struct aggregator *aggregator, *temp_aggregator;
+ struct aggregator *free_aggregator = NULL;
struct port *last_port = NULL, *curr_port;
int found = 0;
- // if the port is already Selected, do nothing
+ /* if the port is already Selected, do nothing */
if (port->sm_vars & AD_PORT_SELECTED)
return;
- // if the port is connected to other aggregator, detach it
+ /* if the port is connected to other aggregator, detach it */
if (port->aggregator) {
- // detach the port from its former aggregator
+ /* detach the port from its former aggregator */
temp_aggregator = port->aggregator;
for (curr_port = temp_aggregator->lag_ports; curr_port;
last_port = curr_port,
curr_port = curr_port->next_port_in_aggregator) {
if (curr_port == port) {
temp_aggregator->num_of_ports--;
- if (!last_port) {// if it is the first port attached to the aggregator
+ if (!last_port) {
+ /* if it is the first port attached
+ to the aggregator */
temp_aggregator->lag_ports =
port->next_port_in_aggregator;
- } else {// not the first port attached to the aggregator
+ } else {
+ /* not the first port attached
+ to the aggregator */
last_port->next_port_in_aggregator =
port->next_port_in_aggregator;
}
- // clear the port's relations to this aggregator
+ /* clear the port's relations
+ to this aggregator */
port->aggregator = NULL;
port->next_port_in_aggregator = NULL;
port->actor_port_aggregator_identifier = 0;
pr_debug("Port %d left LAG %d\n",
- port->actor_port_number,
- temp_aggregator->aggregator_identifier);
- // if the aggregator is empty, clear its parameters, and set it ready to be attached
+ port->actor_port_number,
+ temp_aggregator->aggregator_identifier);
+ /* if the aggregator is empty,
+ * clear its parameters, and set it ready
+ * to be attached
+ */
if (!temp_aggregator->lag_ports)
ad_clear_agg(temp_aggregator);
break;
}
}
- if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
+ if (!curr_port) {
+ /* meaning: the port was related to an aggregator
+ * but was not on the aggregator port list.
+ */
pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
port->slave->dev->master->name,
port->actor_port_number,
@@ -1321,27 +1372,34 @@ static void ad_port_selection_logic(struct port *port)
port->aggregator->aggregator_identifier);
}
}
- // search on all aggregators for a suitable aggregator for this port
+ /* search on all aggregators for a suitable aggregator for this port */
for (aggregator = __get_first_agg(port); aggregator;
aggregator = __get_next_agg(aggregator)) {
- // keep a free aggregator for later use(if needed)
+ /* keep a free aggregator for later use (if needed) */
if (!aggregator->lag_ports) {
if (!free_aggregator)
free_aggregator = aggregator;
continue;
}
- // check if current aggregator suits us
- if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && // if all parameters match AND
- !MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(port->partner_oper.system)) &&
+
+ /* check if current aggregator suits us
+ * a suitable aggregator must fit the following requirements,
+ * tested here:
+ * i. match all parameters;
+ * ii. has partner answers;
+ * iii. it is not individual
+ */
+ if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) &&
+ !compare_ether_addr((const u8 *)&(aggregator->partner_system), (const u8 *)&(port->partner_oper.system)) &&
(aggregator->partner_system_priority == port->partner_oper.system_priority) &&
(aggregator->partner_oper_aggregator_key == port->partner_oper.key)
) &&
- ((MAC_ADDRESS_COMPARE(&(port->partner_oper.system), &(null_mac_addr)) && // partner answers
- !aggregator->is_individual) // but is not individual OR
+ ((compare_ether_addr((const u8 *)&(port->partner_oper.system), (const u8 *)&(null_mac_addr)) &&
+ !aggregator->is_individual)
)
) {
- // attach to the founded aggregator
+ /* attach to the founded aggregator */
port->aggregator = aggregator;
port->actor_port_aggregator_identifier =
port->aggregator->aggregator_identifier;
@@ -1352,42 +1410,45 @@ static void ad_port_selection_logic(struct port *port)
port->actor_port_number,
port->aggregator->aggregator_identifier);
- // mark this port as selected
+ /* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
found = 1;
break;
}
}
- // the port couldn't find an aggregator - attach it to a new aggregator
+ /* the port couldn't find an aggregator, attach it to a new aggregator*/
if (!found) {
if (free_aggregator) {
- // assign port a new aggregator
+ /* assign port a new aggregator */
port->aggregator = free_aggregator;
port->actor_port_aggregator_identifier =
port->aggregator->aggregator_identifier;
- // update the new aggregator's parameters
- // if port was responsed from the end-user
+ /* update the new aggregator's parameters
+ if port was responsed from the end-user */
if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)
/* if port is full duplex */
port->aggregator->is_individual = false;
else
port->aggregator->is_individual = true;
- port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key;
- port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key;
+ port->aggregator->actor_admin_aggregator_key =
+ port->actor_admin_port_key;
+ port->aggregator->actor_oper_aggregator_key =
+ port->actor_oper_port_key;
port->aggregator->partner_system =
- port->partner_oper.system;
+ port->partner_oper.system;
port->aggregator->partner_system_priority =
- port->partner_oper.system_priority;
- port->aggregator->partner_oper_aggregator_key = port->partner_oper.key;
+ port->partner_oper.system_priority;
+ port->aggregator->partner_oper_aggregator_key =
+ port->partner_oper.key;
port->aggregator->receive_state = 1;
port->aggregator->transmit_state = 1;
port->aggregator->lag_ports = port;
port->aggregator->num_of_ports++;
- // mark this port as selected
+ /* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
pr_debug("Port %d joined LAG %d(new LAG)\n",
@@ -1399,16 +1460,18 @@ static void ad_port_selection_logic(struct port *port)
port->actor_port_number, port->slave->dev->name);
}
}
- // if all aggregator's ports are READY_N == TRUE, set ready=TRUE in all aggregator's ports
- // else set ready=FALSE in all aggregator's ports
- __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
+ /* if all aggregator's ports are READY_N == TRUE,
+ * set ready=TRUE in all aggregator's ports
+ * else set ready=FALSE in all aggregator's ports
+ */
+ __set_agg_ports_ready(port->aggregator,
+ __agg_ports_are_ready(port->aggregator));
aggregator = __get_first_agg(port);
ad_agg_selection_logic(aggregator);
}
-/*
- * Decide if "agg" is a better choice for the new active aggregator that
+/* Decide if "agg" is a better choice for the new active aggregator that
* the current best, according to the ad_select policy.
*/
static struct aggregator *ad_agg_selection_test(struct aggregator *best,
@@ -1533,16 +1596,15 @@ static void ad_agg_selection_logic(struct aggregator *agg)
if (best &&
__get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) {
- /*
- * For the STABLE policy, don't replace the old active
- * aggregator if it's still active (it has an answering
- * partner) or if both the best and active don't have an
- * answering partner.
+
+ /* For the STABLE policy, don't replace the old active
+ * aggregator if it's still active (it has an answering partner)
+ * or if both the best and active don't have answering partners
*/
if (active && active->lag_ports &&
active->lag_ports->is_enabled &&
(__agg_has_partner(active) ||
- (!__agg_has_partner(active) && !__agg_has_partner(best)))) {
+ (!__agg_has_partner(active) && !__agg_has_partner(best)))) {
if (!(!active->actor_oper_aggregator_key &&
best->actor_oper_aggregator_key)) {
best = NULL;
@@ -1556,7 +1618,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
active->is_active = 1;
}
- // if there is new best aggregator, activate it
+ /* if there is new best aggregator, activate it */
if (best) {
pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
best->aggregator_identifier, best->num_of_ports,
@@ -1577,7 +1639,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
agg->is_individual, agg->is_active);
}
- // check if any partner replys
+ /* check if any partner replys */
if (best->is_individual) {
pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
best->slave ? best->slave->dev->master->name : "NULL");
@@ -1592,7 +1654,9 @@ static void ad_agg_selection_logic(struct aggregator *agg)
best->partner_oper_aggregator_key,
best->is_individual, best->is_active);
- // disable the ports that were related to the former active_aggregator
+ /* disable the ports that were related to
+ * the former active_aggregator
+ */
if (active) {
for (port = active->lag_ports; port;
port = port->next_port_in_aggregator) {
@@ -1601,8 +1665,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
}
}
- /*
- * if the selected aggregator is of join individuals
+ /* if the selected aggregator is of join individuals
* (partner_system is NULL), enable their ports
*/
active = __get_active_agg(origin);
@@ -1701,8 +1764,10 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
port->ntt = false;
port->actor_admin_port_key = 1;
port->actor_oper_port_key = 1;
- port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
- port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
+ port->actor_admin_port_state =
+ AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
+ port->actor_oper_port_state =
+ AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
if (lacp_fast)
port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
@@ -1711,7 +1776,7 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
memcpy(&port->partner_oper, &tmpl, sizeof(tmpl));
port->is_enabled = true;
- // ****** private parameters ******
+ /* ****** private parameters ****** */
port->sm_vars = 0x3;
port->sm_rx_state = 0;
port->sm_rx_timer_counter = 0;
@@ -1753,7 +1818,9 @@ static void ad_enable_collecting_distributing(struct port *port)
*/
static void ad_disable_collecting_distributing(struct port *port)
{
- if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
+ if (port->aggregator &&
+ compare_ether_addr((const u8 *)&(port->aggregator->partner_system),
+ (const u8 *)&(null_mac_addr))) {
pr_debug("Disabling port %d(LAG %d)\n",
port->actor_port_number,
port->aggregator->aggregator_identifier);
@@ -1775,27 +1842,28 @@ static void ad_marker_info_send(struct port *port)
struct bond_marker marker;
u16 index;
- // fill the marker PDU with the appropriate values
+ /* fill the marker PDU with the appropriate values */
marker.subtype = 0x02;
marker.version_number = 0x01;
marker.tlv_type = AD_MARKER_INFORMATION_SUBTYPE;
marker.marker_length = 0x16;
- // convert requester_port to Big Endian
- marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8));
+ /* convert requester_port to Big Endian */
+ marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |
+ ((u16)(port->actor_port_number & 0xFF00) >> 8));
marker.requester_system = port->actor_system;
- // convert requester_port(u32) to Big Endian
+ /* convert requester_port(u32) to Big Endian */
marker.requester_transaction_id =
- (((++port->transaction_id & 0xFF) << 24)
- | ((port->transaction_id & 0xFF00) << 8)
- | ((port->transaction_id & 0xFF0000) >> 8)
- | ((port->transaction_id & 0xFF000000) >> 24));
+ (((++port->transaction_id & 0xFF) << 24) |
+ ((port->transaction_id & 0xFF00) << 8) |
+ ((port->transaction_id & 0xFF0000) >> 8) |
+ ((port->transaction_id & 0xFF000000) >> 24));
marker.pad = 0;
marker.tlv_type_terminator = 0x00;
marker.terminator_length = 0x00;
for (index = 0; index < 90; index++)
marker.reserved_90[index] = 0;
- // send the marker information
+ /* send the marker information */
if (ad_marker_send(port, &marker) >= 0) {
pr_debug("Sent Marker Information on port %d\n",
port->actor_port_number);
@@ -1814,12 +1882,13 @@ static void ad_marker_info_received(struct bond_marker *marker_info,
{
struct bond_marker marker;
- // copy the received marker data to the response marker
- //marker = *marker_info;
+ /* copy the received marker data to the response marker
+ * marker = *marker_info;
+ */
memcpy(&marker, marker_info, sizeof(struct bond_marker));
- // change the marker subtype to marker response
+ /* change the marker subtype to marker response */
marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE;
- // send the marker response
+ /* send the marker response */
if (ad_marker_send(port, &marker) >= 0) {
pr_debug("Sent Marker Response on port %d\n",
@@ -1839,16 +1908,13 @@ static void ad_marker_info_received(struct bond_marker *marker_info,
static void ad_marker_response_received(struct bond_marker *marker,
struct port *port)
{
- marker = NULL; /* just to satisfy the compiler */
- port = NULL; /* just to satisfy the compiler */
- // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW
+ marker = NULL;
+ port = NULL;
}
-//////////////////////////////////////////////////////////////////////////////////////
-// ================= AD exported functions to the main bonding code ==================
-//////////////////////////////////////////////////////////////////////////////////////
+/* ============= AD exported functions to the main bonding code ============ */
-// Check aggregators status in team every T seconds
+/* Check aggregators status in team every T seconds */
#define AD_AGGREGATOR_SELECTION_TIMER 8
/*
@@ -1876,17 +1942,20 @@ static u16 aggregator_identifier;
*/
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
{
- // check that the bond is not initialized yet
- if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
+ /* check that the bond is not initialized yet */
+ if (compare_ether_addr((const u8 *)&(BOND_AD_INFO(bond).system.sys_mac_addr),
bond->dev->dev_addr)) {
aggregator_identifier = 0;
BOND_AD_INFO(bond).lacp_fast = lacp_fast;
BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
- BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
+ BOND_AD_INFO(bond).system.sys_mac_addr =
+ *((struct mac_addr *)bond->dev->dev_addr);
- // initialize how many times this module is called in one second(should be about every 100ms)
+ /* initialize how many times this module is
+ * called in one second(should be about every 100ms)
+ */
ad_ticks_per_sec = tick_resolution;
bond_3ad_initiate_agg_selection(bond,
@@ -1914,31 +1983,37 @@ int bond_3ad_bind_slave(struct slave *slave)
return -1;
}
- //check that the slave has not been initialized yet.
+ /* check that the slave has not been initialized yet. */
if (SLAVE_AD_INFO(slave).port.slave != slave) {
- // port initialization
+ /* port initialization */
port = &(SLAVE_AD_INFO(slave).port);
ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast);
port->slave = slave;
port->actor_port_number = SLAVE_AD_INFO(slave).id;
- // key is determined according to the link speed, duplex and user key(which is yet not supported)
- // ------------------------------------------------------------
- // Port key : | User key | Speed |Duplex|
- // ------------------------------------------------------------
- // 16 6 1 0
- port->actor_admin_port_key = 0; // initialize this parameter
+ /* key is determined according to the link speed,
+ * duplex and user key(which is yet not supported)
+ * Port key:
+ * ------------------------------------------------------------
+ * | User key | Speed |Duplex|
+ * ------------------------------------------------------------
+ * 16 6 1 0
+ */
+ port->actor_admin_port_key = 0; /* initialize this parameter */
port->actor_admin_port_key |= __get_duplex(port);
port->actor_admin_port_key |= (__get_link_speed(port) << 1);
port->actor_oper_port_key = port->actor_admin_port_key;
- // if the port is not full duplex, then the port should be not lacp Enabled
+ /* if the port is not full duplex,
+ * then the port should be not lacp Enabled
+ */
if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED;
- // actor system is the bond's system
+ /* actor system is the bond's system */
port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
- // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second)
+
+ /* certify that no more than MAX_TX_IN_SECOND lacpdu sent/sec */
port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
port->aggregator = NULL;
port->next_port_in_aggregator = NULL;
@@ -1947,12 +2022,13 @@ int bond_3ad_bind_slave(struct slave *slave)
__initialize_port_locks(port);
- // aggregator initialization
+ /* aggregator initialization */
aggregator = &(SLAVE_AD_INFO(slave).aggregator);
ad_initialize_agg(aggregator);
- aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
+ aggregator->aggregator_mac_address =
+ *((struct mac_addr *)bond->dev->dev_addr);
aggregator->aggregator_identifier = (++aggregator_identifier);
aggregator->slave = slave;
aggregator->is_active = 0;
@@ -1976,13 +2052,13 @@ void bond_3ad_unbind_slave(struct slave *slave)
struct aggregator *aggregator, *new_aggregator, *temp_aggregator;
int select_new_active_agg = 0;
- // find the aggregator related to this slave
+ /* find the aggregator related to this slave */
aggregator = &(SLAVE_AD_INFO(slave).aggregator);
- // find the port related to this slave
+ /* find the port related to this slave */
port = &(SLAVE_AD_INFO(slave).port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n",
slave->dev->master->name, slave->dev->name);
@@ -1997,32 +2073,43 @@ void bond_3ad_unbind_slave(struct slave *slave)
__update_lacpdu_from_port(port);
ad_lacpdu_send(port);
- // check if this aggregator is occupied
+ /* check if this aggregator is occupied */
if (aggregator->lag_ports) {
- // check if there are other ports related to this aggregator except
- // the port related to this slave(thats ensure us that there is a
- // reason to search for new aggregator, and that we will find one
- if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) {
- // find new aggregator for the related port(s)
+ /* check if there are other ports related to this aggregator
+ * except the port related to this slave
+ * (thats ensure us that there is a reason to search for
+ * new aggregator, and that we will find one)
+ */
+ if ((aggregator->lag_ports != port) ||
+ (aggregator->lag_ports->next_port_in_aggregator)) {
+ /* find new aggregator for the related port(s) */
new_aggregator = __get_first_agg(port);
- for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) {
- // if the new aggregator is empty, or it is connected to our port only
- if (!new_aggregator->lag_ports
- || ((new_aggregator->lag_ports == port)
- && !new_aggregator->lag_ports->next_port_in_aggregator))
+ for (; new_aggregator;
+ new_aggregator = __get_next_agg(new_aggregator)) {
+ /* if the new aggregator is empty,
+ or it is connected to our port only */
+ if (!new_aggregator->lag_ports ||
+ ((new_aggregator->lag_ports == port) &&
+ !new_aggregator->lag_ports->next_port_in_aggregator))
break;
}
- // if new aggregator found, copy the aggregator's parameters
- // and connect the related lag_ports to the new aggregator
- if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
+ /* if new aggregator found, copy the aggregator's
+ * parameters and connect the related lag_ports to the
+ * new aggregator
+ */
+ if ((new_aggregator) &&
+ ((!new_aggregator->lag_ports) ||
+ ((new_aggregator->lag_ports == port) &&
+ !new_aggregator->lag_ports->next_port_in_aggregator))) {
pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n",
aggregator->aggregator_identifier,
new_aggregator->aggregator_identifier);
- if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
+ if ((new_aggregator->lag_ports == port) &&
+ new_aggregator->is_active) {
pr_info("%s: Removing an active aggregator\n",
aggregator->slave->dev->master->name);
- // select new active aggregator
+ /* select new active aggregator */
select_new_active_agg = 1;
}
@@ -2038,14 +2125,15 @@ void bond_3ad_unbind_slave(struct slave *slave)
new_aggregator->is_active = aggregator->is_active;
new_aggregator->num_of_ports = aggregator->num_of_ports;
- // update the information that is written on the ports about the aggregator
- for (temp_port = aggregator->lag_ports; temp_port;
- temp_port = temp_port->next_port_in_aggregator) {
+ /* update the information that is written on
+ * the ports about the aggregator
+ */
+ for (temp_port = aggregator->lag_ports; temp_port; temp_port = temp_port->next_port_in_aggregator) {
temp_port->aggregator = new_aggregator;
temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier;
}
- // clear the aggregator
+ /* clear the aggregator */
ad_clear_agg(aggregator);
if (select_new_active_agg)
@@ -2054,42 +2142,50 @@ void bond_3ad_unbind_slave(struct slave *slave)
pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
slave->dev->master->name);
}
- } else { // in case that the only port related to this aggregator is the one we want to remove
+ } else {
+ /* in case that the only port related to this
+ * aggregator is the one we want to remove
+ */
select_new_active_agg = aggregator->is_active;
- // clear the aggregator
+ /* clear the aggregator */
ad_clear_agg(aggregator);
if (select_new_active_agg) {
pr_info("%s: Removing an active aggregator\n",
slave->dev->master->name);
- // select new active aggregator
+ /* select new active aggregator */
ad_agg_selection_logic(__get_first_agg(port));
}
}
}
pr_debug("Unbinding port %d\n", port->actor_port_number);
- // find the aggregator that this port is connected to
+ /* find the aggregator that this port is connected to */
temp_aggregator = __get_first_agg(port);
- for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
+ for (; temp_aggregator;
+ temp_aggregator = __get_next_agg(temp_aggregator)) {
prev_port = NULL;
- // search the port in the aggregator's related ports
+ /* search the port in the aggregator's related ports */
for (temp_port = temp_aggregator->lag_ports; temp_port;
prev_port = temp_port,
temp_port = temp_port->next_port_in_aggregator) {
- if (temp_port == port) { // the aggregator found - detach the port from this aggregator
+ if (temp_port == port) {
+ /* the aggregator found
+ detach the port from this aggregator */
if (prev_port)
- prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator;
+ prev_port->next_port_in_aggregator =
+ temp_port->next_port_in_aggregator;
else
- temp_aggregator->lag_ports = temp_port->next_port_in_aggregator;
+ temp_aggregator->lag_ports =
+ temp_port->next_port_in_aggregator;
temp_aggregator->num_of_ports--;
if (temp_aggregator->num_of_ports == 0) {
select_new_active_agg = temp_aggregator->is_active;
- // clear the aggregator
+ /* clear the aggregator */
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
pr_info("%s: Removing an active aggregator\n",
slave->dev->master->name);
- // select new active aggregator
+ /* select new active aggreg */
ad_agg_selection_logic(__get_first_agg(port));
}
}
@@ -2125,13 +2221,14 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
if (bond->kill_timers)
goto out;
- //check if there are any slaves
+ /* check if there are any slaves */
if (bond->slave_cnt == 0)
goto re_arm;
- // check if agg_select_timer timer after initialize is timed out
- if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) {
- // select the active aggregator for the bond
+ /* check if agg_select_timer timer after initialize is timed out */
+ if (BOND_AD_INFO(bond).agg_select_timer &&
+ !(--BOND_AD_INFO(bond).agg_select_timer)) {
+ /* select the active aggregator for the bond */
if ((port = __get_first_port(bond))) {
if (!port->slave) {
pr_warning("%s: Warning: bond's first port is uninitialized\n",
@@ -2145,17 +2242,18 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
bond_3ad_set_carrier(bond);
}
- // for each port run the state machines
- for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
+ /* for each port run the state machines */
+ for (port = __get_first_port(bond); port;
+ port = __get_next_port(port)) {
if (!port->slave) {
pr_warning("%s: Warning: Found an uninitialized port\n",
bond->dev->name);
goto re_arm;
}
- /* Lock around state machines to protect data accessed
- * by all (e.g., port->sm_vars). ad_rx_machine may run
- * concurrently due to incoming LACPDU.
+ /* Lock around state machines to protect data accessed by all
+ * (e.g., port->sm_vars).
+ * ad_rx_machine may run concurrently due to incoming LACPDU.
*/
__get_state_machine_lock(port);
@@ -2165,7 +2263,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
ad_mux_machine(port);
ad_tx_machine(port);
- // turn off the BEGIN bit, since we already handled it
+ /* turn off the BEGIN bit, since we already handled it */
if (port->sm_vars & AD_PORT_BEGIN)
port->sm_vars &= ~AD_PORT_BEGIN;
@@ -2198,7 +2296,8 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
if (!port->slave) {
pr_warning("%s: Warning: port of slave %s is uninitialized\n",
- slave->dev->name, slave->dev->master->name);
+ slave->dev->name,
+ slave->dev->master->name);
return;
}
@@ -2213,7 +2312,9 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
break;
case AD_TYPE_MARKER:
- // No need to convert fields to Little Endian since we don't use the marker's fields.
+ /* No need to convert fields to Little Endian
+ * since we don't use the marker's fields.
+ */
switch (((struct bond_marker *)lacpdu)->tlv_type) {
case AD_MARKER_INFORMATION_SUBTYPE:
@@ -2248,19 +2349,22 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
port = &(SLAVE_AD_INFO(slave).port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
pr_warning("Warning: %s: speed changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->dev->master->name,
+ slave->dev->name);
return;
}
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
port->actor_oper_port_key = port->actor_admin_port_key |=
(__get_link_speed(port) << 1);
+
pr_debug("Port %d changed speed\n", port->actor_port_number);
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+ /* there is no need to reselect a new aggregator,
+ * just signal the state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
}
@@ -2276,19 +2380,22 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
port = &(SLAVE_AD_INFO(slave).port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->dev->master->name,
+ slave->dev->name);
return;
}
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
port->actor_oper_port_key = port->actor_admin_port_key |=
__get_duplex(port);
+
pr_debug("Port %d changed duplex\n", port->actor_port_number);
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+ /* there is no need to reselect a new aggregator,
+ * just signal the state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
}
@@ -2305,15 +2412,19 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
port = &(SLAVE_AD_INFO(slave).port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
pr_warning("Warning: %s: link status changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ slave->dev->master->name,
+ slave->dev->name);
return;
}
- // on link down we are zeroing duplex and speed since some of the adaptors(ce1000.lan) report full duplex/speed instead of N/A(duplex) / 0(speed)
- // on link up we are forcing recheck on the duplex and speed since some of he adaptors(ce1000.lan) report
+ /* on link down we are zeroing duplex and speed
+ * since some of the adaptors (ce1000.lan) report full duplex/speed
+ * instead of N/A (duplex) / 0(speed)
+ * on link up we are forcing recheck on the duplex and speed
+ */
if (link == BOND_LINK_UP) {
port->is_enabled = true;
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
@@ -2329,9 +2440,15 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
port->actor_oper_port_key = (port->actor_admin_port_key &=
~AD_SPEED_KEY_BITS);
}
- //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN")));
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+
+ /* BOND_PRINT_DBG(("Port %d changed link status to %s",
+ * port->actor_port_number,
+ * ((link == BOND_LINK_UP)?"UP":"DOWN")));
+ */
+
+ /* there is no need to reselect a new aggregator,
+ * just signal the state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
}
@@ -2387,7 +2504,8 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
ad_info->ports = aggregator->num_of_ports;
ad_info->actor_key = aggregator->actor_oper_aggregator_key;
ad_info->partner_key = aggregator->partner_oper_aggregator_key;
- memcpy(ad_info->partner_system, aggregator->partner_system.mac_addr_value, ETH_ALEN);
+ memcpy(ad_info->partner_system,
+ aggregator->partner_system.mac_addr_value, ETH_ALEN);
return 0;
}
@@ -2405,9 +2523,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
struct ad_info ad_info;
int res = 1;
- /* make sure that the slaves list will
- * not change during tx
- */
+ /* make sure that the slaves list will not change during tx */
read_lock(&bond->lock);
if (!BOND_IS_OK(bond))
@@ -2442,7 +2558,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slave_agg_no >= 0) {
pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n",
- dev->name, agg_id);
+ dev->name, agg_id);
goto out;
}
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index b28baff..83b0961 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -28,7 +28,7 @@
#include <linux/netdevice.h>
#include <linux/if_ether.h>
-// General definitions
+/* General definitions */
#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
#define AD_TIMER_INTERVAL 100 /*msec*/
@@ -47,54 +47,54 @@ enum {
BOND_AD_COUNT = 2,
};
-// rx machine states(43.4.11 in the 802.3ad standard)
+/* rx machine states (43.4.11 in the 802.3ad standard) */
typedef enum {
AD_RX_DUMMY,
- AD_RX_INITIALIZE, // rx Machine
- AD_RX_PORT_DISABLED, // rx Machine
- AD_RX_LACP_DISABLED, // rx Machine
- AD_RX_EXPIRED, // rx Machine
- AD_RX_DEFAULTED, // rx Machine
- AD_RX_CURRENT // rx Machine
+ AD_RX_INITIALIZE,
+ AD_RX_PORT_DISABLED,
+ AD_RX_LACP_DISABLED,
+ AD_RX_EXPIRED,
+ AD_RX_DEFAULTED,
+ AD_RX_CURRENT
} rx_states_t;
-// periodic machine states(43.4.12 in the 802.3ad standard)
+/* periodic machine states (43.4.12 in the 802.3ad standard) */
typedef enum {
AD_PERIODIC_DUMMY,
- AD_NO_PERIODIC, // periodic machine
- AD_FAST_PERIODIC, // periodic machine
- AD_SLOW_PERIODIC, // periodic machine
- AD_PERIODIC_TX // periodic machine
+ AD_NO_PERIODIC,
+ AD_FAST_PERIODIC,
+ AD_SLOW_PERIODIC,
+ AD_PERIODIC_TX
} periodic_states_t;
-// mux machine states(43.4.13 in the 802.3ad standard)
+/* mux machine states (43.4.13 in the 802.3ad standard) */
typedef enum {
AD_MUX_DUMMY,
- AD_MUX_DETACHED, // mux machine
- AD_MUX_WAITING, // mux machine
- AD_MUX_ATTACHED, // mux machine
- AD_MUX_COLLECTING_DISTRIBUTING // mux machine
+ AD_MUX_DETACHED,
+ AD_MUX_WAITING,
+ AD_MUX_ATTACHED,
+ AD_MUX_COLLECTING_DISTRIBUTING
} mux_states_t;
-// tx machine states(43.4.15 in the 802.3ad standard)
+/* tx machine states (43.4.15 in the 802.3ad standard) */
typedef enum {
AD_TX_DUMMY,
- AD_TRANSMIT // tx Machine
+ AD_TRANSMIT
} tx_states_t;
-// rx indication types
+/* rx indication types */
typedef enum {
- AD_TYPE_LACPDU = 1, // type lacpdu
- AD_TYPE_MARKER // type marker
+ AD_TYPE_LACPDU = 1,
+ AD_TYPE_MARKER
} pdu_type_t;
-// rx marker indication types
+/* rx marker indication types */
typedef enum {
- AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
- AD_MARKER_RESPONSE_SUBTYPE // marker response subtype
+ AD_MARKER_INFORMATION_SUBTYPE = 1,
+ AD_MARKER_RESPONSE_SUBTYPE
} bond_marker_subtype_t;
-// timers types(43.4.9 in the 802.3ad standard)
+/* timers types (43.4.9 in the 802.3ad standard) */
typedef enum {
AD_CURRENT_WHILE_TIMER,
AD_ACTOR_CHURN_TIMER,
@@ -105,35 +105,37 @@ typedef enum {
#pragma pack(1)
-// Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard)
+/* Link Aggregation Control Protocol (LACP) data unit structure
+ * (43.4.2.2 in the 802.3ad standard)
+ */
typedef struct lacpdu {
- u8 subtype; // = LACP(= 0x01)
+ u8 subtype; /* = LACP(= 0x01) */
u8 version_number;
- u8 tlv_type_actor_info; // = actor information(type/length/value)
- u8 actor_information_length; // = 20
+ u8 tlv_type_actor_info; /* = actor info(type/length/value)*/
+ u8 actor_information_length; /* = 20 */
__be16 actor_system_priority;
struct mac_addr actor_system;
__be16 actor_key;
__be16 actor_port_priority;
__be16 actor_port;
u8 actor_state;
- u8 reserved_3_1[3]; // = 0
- u8 tlv_type_partner_info; // = partner information
- u8 partner_information_length; // = 20
+ u8 reserved_3_1[3]; /* = 0 */
+ u8 tlv_type_partner_info; /* = partner information */
+ u8 partner_information_length; /* = 20 */
__be16 partner_system_priority;
struct mac_addr partner_system;
__be16 partner_key;
__be16 partner_port_priority;
__be16 partner_port;
u8 partner_state;
- u8 reserved_3_2[3]; // = 0
- u8 tlv_type_collector_info; // = collector information
- u8 collector_information_length; // = 16
+ u8 reserved_3_2[3]; /* = 0 */
+ u8 tlv_type_collector_info; /* = collector information */
+ u8 collector_information_length; /* = 16 */
__be16 collector_max_delay;
u8 reserved_12[12];
- u8 tlv_type_terminator; // = terminator
- u8 terminator_length; // = 0
- u8 reserved_50[50]; // = 0
+ u8 tlv_type_terminator; /* = terminator */
+ u8 terminator_length; /* = 0 */
+ u8 reserved_50[50]; /* = 0 */
} lacpdu_t;
typedef struct lacpdu_header {
@@ -141,20 +143,22 @@ typedef struct lacpdu_header {
struct lacpdu lacpdu;
} lacpdu_header_t;
-// Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
+/* Marker Protocol Data Unit(PDU) structure
+ * (43.5.3.2 in the 802.3ad standard)
+ */
typedef struct bond_marker {
- u8 subtype; // = 0x02 (marker PDU)
- u8 version_number; // = 0x01
- u8 tlv_type; // = 0x01 (marker information)
- // = 0x02 (marker response information)
- u8 marker_length; // = 0x16
- u16 requester_port; // The number assigned to the port by the requester
- struct mac_addr requester_system; // The requester's system id
- u32 requester_transaction_id; // The transaction id allocated by the requester,
- u16 pad; // = 0
- u8 tlv_type_terminator; // = 0x00
- u8 terminator_length; // = 0x00
- u8 reserved_90[90]; // = 0
+ u8 subtype; /* = 0x02 (marker PDU) */
+ u8 version_number; /* = 0x01 */
+ u8 tlv_type; /* = 0x01 (marker information)
+ * = 0x02 (marker response info */
+ u8 marker_length; /* = 0x16 */
+ u16 requester_port;
+ struct mac_addr requester_system; /* The requester's system id */
+ u32 requester_transaction_id;
+ u16 pad; /* = 0 */
+ u8 tlv_type_terminator; /* = 0x00 */
+ u8 terminator_length; /* = 0x00 */
+ u8 reserved_90[90]; /* = 0 */
} bond_marker_t;
typedef struct bond_marker_header {
@@ -173,7 +177,7 @@ struct port;
#pragma pack(8)
#endif
-// aggregator structure(43.4.5 in the 802.3ad standard)
+/* aggregator structure (43.4.5 in the 802.3ad standard) */
typedef struct aggregator {
struct mac_addr aggregator_mac_address;
u16 aggregator_identifier;
@@ -183,12 +187,13 @@ typedef struct aggregator {
struct mac_addr partner_system;
u16 partner_system_priority;
u16 partner_oper_aggregator_key;
- u16 receive_state; // BOOLEAN
- u16 transmit_state; // BOOLEAN
+ u16 receive_state; /* BOOLEAN */
+ u16 transmit_state; /* BOOLEAN */
struct port *lag_ports;
- // ****** PRIVATE PARAMETERS ******
- struct slave *slave; // pointer to the bond slave that this aggregator belongs to
- u16 is_active; // BOOLEAN. Indicates if this aggregator is active
+ /* ****** PRIVATE PARAMETERS ****** */
+ struct slave *slave; /* poiter to the bond slave
+ that this aggregator belongs to */
+ u16 is_active; /* BOOLEAN. Indicates if the aggregator is active*/
u16 num_of_ports;
} aggregator_t;
@@ -201,12 +206,18 @@ struct port_params {
u16 port_state;
};
-// port structure(43.4.6 in the 802.3ad standard)
+/* port structure (43.4.6 in the 802.3ad standard) */
typedef struct port {
u16 actor_port_number;
u16 actor_port_priority;
- struct mac_addr actor_system; // This parameter is added here although it is not specified in the standard, just for simplification
- u16 actor_system_priority; // This parameter is added here although it is not specified in the standard, just for simplification
+
+ /* in a attempt to simplify operations the
+ * following two elements were included here
+ * despite they are not specified in the standard
+ */
+ struct mac_addr actor_system;
+ u16 actor_system_priority;
+
u16 actor_port_aggregator_identifier;
bool ntt;
u16 actor_admin_port_key;
@@ -219,21 +230,21 @@ typedef struct port {
bool is_enabled;
- // ****** PRIVATE PARAMETERS ******
- u16 sm_vars; // all state machines variables for this port
- rx_states_t sm_rx_state; // state machine rx state
- u16 sm_rx_timer_counter; // state machine rx timer counter
- periodic_states_t sm_periodic_state;// state machine periodic state
- u16 sm_periodic_timer_counter; // state machine periodic timer counter
- mux_states_t sm_mux_state; // state machine mux state
- u16 sm_mux_timer_counter; // state machine mux timer counter
- tx_states_t sm_tx_state; // state machine tx state
- u16 sm_tx_timer_counter; // state machine tx timer counter(allways on - enter to transmit state 3 time per second)
- struct slave *slave; // pointer to the bond slave that this port belongs to
- struct aggregator *aggregator; // pointer to an aggregator that this port related to
- struct port *next_port_in_aggregator; // Next port on the linked list of the parent aggregator
- u32 transaction_id; // continuous number for identification of Marker PDU's;
- struct lacpdu lacpdu; // the lacpdu that will be sent for this port
+ /* ****** PRIVATE PARAMETERS ****** */
+ u16 sm_vars;
+ rx_states_t sm_rx_state;
+ u16 sm_rx_timer_counter;
+ periodic_states_t sm_periodic_state;
+ u16 sm_periodic_timer_counter;
+ mux_states_t sm_mux_state;
+ u16 sm_mux_timer_counter;
+ tx_states_t sm_tx_state;
+ u16 sm_tx_timer_counter;
+ struct slave *slave;
+ struct aggregator *aggregator;
+ struct port *next_port_in_aggregator;
+ u32 transaction_id;
+ struct lacpdu lacpdu;
} port_t;
// system structure
@@ -246,41 +257,41 @@ struct ad_system {
#pragma pack()
#endif
#define BOND_AD_INFO(bond) ((bond)->ad_info)
#define SLAVE_AD_INFO(slave) ((slave)->ad_info)
struct ad_bond_info {
struct ad_system system; /* 802.3ad system structure */
- u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes
- u32 agg_select_mode; // Mode of selection of active aggregator(bandwidth/count)
- int lacp_fast; /* whether fast periodic tx should be
- * requested
- */
+ u32 agg_select_timer; /* aggregator's selected timer */
+ u32 agg_select_mode; /* aggregator's selected mode */
+ int lacp_fast;
struct timer_list ad_timer;
struct packet_type ad_pkt_type;
};
struct ad_slave_info {
- struct aggregator aggregator; // 802.3ad aggregator structure
- struct port port; // 802.3ad port structure
- spinlock_t state_machine_lock; /* mutex state machines vs.
- incoming LACPDU */
+ struct aggregator aggregator; /* 802.3ad aggregator structure */
+ struct port port; /* 802.3ad port structure */
+ spinlock_t state_machine_lock; /* mutex state machines vs.
+ * incoming LACPDU */
u16 id;
};
-// ================= AD Exported functions to the main bonding code ==================
-void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast);
-int bond_3ad_bind_slave(struct slave *slave);
+/* ========= AD Exported functions to the main bonding code ========== */
+void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution,
+ int lacp_fast);
+int bond_3ad_bind_slave(struct slave *slave);
void bond_3ad_unbind_slave(struct slave *slave);
void bond_3ad_state_machine_handler(struct work_struct *);
void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
void bond_3ad_adapter_speed_changed(struct slave *slave);
void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
-int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
+int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
+int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type* ptype, struct net_device *orig_dev);
int bond_3ad_set_carrier(struct bonding *bond);
#endif //__BOND_3AD_H__
--
1.7.4.4
^ permalink raw reply related
* RE: Question for canutils
From: Tomoya MORINAGA @ 2011-05-06 0:37 UTC (permalink / raw)
To: 'Marc Kleine-Budde'
Cc: 'Wolfgang Grandegger', socketcan-core, netdev,
linux-kernel, toshiharu-linux
In-Reply-To: <4DB81F2E.4050802@pengutronix.de>
Hi Marc,
On Wednesday, April 27, 2011 10:51 PM, Marc Kleine-Budde wrote:
> Into which location?
>
> Please send me the output of:
>
> ls -l /usr/local/lib
> ls -l /usr/local/lib/pkgconfig
[morinaga@localhost ~]$
[morinaga@localhost ~]$ ls -l /usr/local/lib
合計 1412
-rw-r--r--. 1 root root 103226 2011-01-13 16:56 libhistory.a
lrwxrwxrwx. 1 root root 15 2011-01-13 16:56 libhistory.so -> libhistory.so.6
lrwxrwxrwx. 1 root root 17 2011-01-13 16:56 libhistory.so.6 -> libhistory.so.6.0
-r-xr-xr-x. 1 root root 80204 2011-01-13 16:56 libhistory.so.6.0
-rw-r--r--. 1 root root 686760 2011-01-13 16:56 libreadline.a
lrwxrwxrwx. 1 root root 16 2011-01-13 16:56 libreadline.so -> libreadline.so.6
lrwxrwxrwx. 1 root root 18 2011-01-13 16:56 libreadline.so.6 -> libreadline.so.6.0
-r-xr-xr-x. 1 root root 498839 2011-01-13 16:56 libreadline.so.6.0
-rw-r--r--. 1 root root 28718 2011-04-27 15:40 libsocketcan.a
-rwxr-xr-x. 1 root root 843 2011-04-27 15:40 libsocketcan.la
lrwxrwxrwx. 1 root root 21 2011-04-27 15:40 libsocketcan.so -> libsocketcan.so.2.2.0
lrwxrwxrwx. 1 root root 21 2011-04-27 15:40 libsocketcan.so.2 -> libsocketcan.so.2.2.0
-rwxr-xr-x. 1 root root 27835 2011-04-27 15:40 libsocketcan.so.2.2.0
drwxr-xr-x. 2 root root 4096 2011-04-27 15:53 pkgconfig
[morinaga@localhost ~]$ ls -l /usr/local/lib/pkgconfig/
合計 8
-rw-r--r--. 1 root root 198 2011-04-27 15:53 canutils.pc
-rw-r--r--. 1 root root 300 2011-04-27 15:40 libsocketcan.pc
[morinaga@localhost ~]$
> First build the canutils, then configure the bitrate, e.g. 250 kbit/s:
> $ canconfig can0 bitrate 250000
> $ ifconfig can0 up
The above commands failed.
[root@localhost can]#
[root@localhost can]# canconfig can0 bitrate 250000
opening CAN interface 'can0' in sysfs failed, maybe not a CAN interface
No such file or directory
[root@localhost ~]# ifconfig can0 up
SIOCSIFFLAGS: Invalid argument
[root@localhost ~]#
Thanks,
-----------------------------------------
Tomoya MORINAGA
OKI SEMICONDUCTOR CO., LTD.
^ permalink raw reply
* [PATCH net-next-2.6] sfc: Implement NETIF_F_LOOPBACK
From: Ben Hutchings @ 2011-05-06 0:12 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-net-drivers, Mahesh Bandewar,
Michał Mirosław
In-Reply-To: <1304559011-15983-1-git-send-email-maheshb@google.com>
We already have comprehensive support for loopback testing, so pick
the nearest mode and run with it.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
David, this depends on Mahesh's patch to define NETIF_F_LOOPBACK
<http://patchwork.ozlabs.org/patch/94190/>. Although you've marked that
as RFC, I think it is ready to apply.
Ben.
drivers/net/sfc/efx.c | 24 ++++++++++++++++++++++--
1 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 38a55e9..b7bfb49 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1884,6 +1884,25 @@ static int efx_set_features(struct net_device *net_dev, u32 data)
if (net_dev->features & ~data & NETIF_F_NTUPLE)
efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
+ /* Toggle loopback if required */
+ if ((net_dev->features ^ data) & NETIF_F_LOOPBACK) {
+ enum efx_loopback_mode old_mode;
+ int rc;
+
+ mutex_lock(&efx->mac_lock);
+ old_mode = efx->loopback_mode;
+ if (data & NETIF_F_LOOPBACK)
+ efx->loopback_mode = __ffs(efx->loopback_modes);
+ else
+ efx->loopback_mode = LOOPBACK_NONE;
+ rc = __efx_reconfigure_port(efx);
+ if (rc)
+ efx->loopback_mode = old_mode;
+ mutex_unlock(&efx->mac_lock);
+ if (rc)
+ return rc;
+ }
+
return 0;
}
@@ -2472,8 +2491,9 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
NETIF_F_RXCSUM);
- /* All offloads can be toggled */
- net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
+ /* All offloads can be toggled, and so can loopback */
+ net_dev->hw_features = ((net_dev->features & ~NETIF_F_HIGHDMA) |
+ NETIF_F_LOOPBACK);
efx = netdev_priv(net_dev);
pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
--
1.7.4
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply related
* [PATCH v6 BONUS 4/3] ipv4: Store rtable entries directly in FIB
From: David Miller @ 2011-05-05 23:36 UTC (permalink / raw)
To: netdev; +Cc: tgraf, jpirko, herbert, eric.dumazet
Ok, here is the fun patch showing the scheme I'm working on. Two
things going on here.
First, we store pre-constructed rtable entries, on demand, inside of
the routing table objects themselves.
Second, we get rid of RT_TABLE_LOCAL and load all routes equally
into RT_TABLE_MAIN.
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 10422ef..f3c9598 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -44,6 +44,7 @@ struct fib_config {
};
struct fib_info;
+struct rtable;
struct fib_nh {
struct net_device *nh_dev;
@@ -62,6 +63,7 @@ struct fib_nh {
__be32 nh_gw;
__be32 nh_saddr;
int nh_saddr_genid;
+ struct rtable *nh_rtable;
};
/*
@@ -200,10 +202,6 @@ static inline int fib_lookup(struct net *net, const struct flowi4 *flp,
{
struct fib_table *table;
- table = fib_get_table(net, RT_TABLE_LOCAL);
- if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
- return 0;
-
table = fib_get_table(net, RT_TABLE_MAIN);
if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF))
return 0;
diff --git a/include/net/route.h b/include/net/route.h
index 70155fb..04e7197 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -109,6 +109,7 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
+extern struct rtable *ip_route_output_new(struct net *, struct flowi4 *flp);
extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 33bbbda..24e67d8 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -155,7 +155,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net,
res.r = NULL;
#endif
- local_table = fib_get_table(net, RT_TABLE_LOCAL);
+ local_table = fib_get_table(net, RT_TABLE_MAIN);
if (local_table) {
ret = RTN_UNICAST;
rcu_read_lock();
@@ -662,11 +662,7 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
},
};
- if (type == RTN_UNICAST)
- tb = fib_new_table(net, RT_TABLE_MAIN);
- else
- tb = fib_new_table(net, RT_TABLE_LOCAL);
-
+ tb = fib_new_table(net, RT_TABLE_MAIN);
if (tb == NULL)
return;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 641a5a2..c37ebd3 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -148,6 +148,10 @@ static void free_fib_info_rcu(struct rcu_head *head)
{
struct fib_info *fi = container_of(head, struct fib_info, rcu);
+ change_nexthops(fi) {
+ ip_rt_put(nexthop_nh->nh_rtable);
+ nexthop_nh->nh_rtable = NULL;
+ } endfor_nexthops(fi);
if (fi->fib_metrics != (u32 *) dst_default_metrics)
kfree(fi->fib_metrics);
kfree(fi);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1e67624..2f77d28 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1861,6 +1861,68 @@ out:
}
EXPORT_SYMBOL_GPL(__ip_route_output_key);
+struct rtable *ip_route_output_new(struct net *net, struct flowi4 *fl4)
+{
+ struct net_device *dev_out = NULL;
+ u32 tos = RT_FL_TOS(fl4);
+ unsigned int flags = 0;
+ struct fib_result res;
+ struct rtable *rth;
+ int orig_oif;
+
+ res.fi = NULL;
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+ res.r = NULL;
+#endif
+
+ orig_oif = fl4->flowi4_oif;
+
+ fl4->flowi4_iif = net->loopback_dev->ifindex;
+ fl4->flowi4_tos = tos & IPTOS_RT_MASK;
+ fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
+
+ rcu_read_lock();
+ if (fib_lookup(net, fl4, &res)) {
+ rth = ERR_PTR(-ENETUNREACH);
+ goto out;
+ }
+
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+ if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0)
+ fib_select_multipath(&res);
+ else
+#endif
+ if (!res.prefixlen && res.table->tb_num_default > 1 &&
+ res.type == RTN_UNICAST && !fl4->flowi4_oif)
+ fib_select_default(&res);
+
+ if (!fl4->saddr)
+ fl4->saddr = FIB_RES_PREFSRC(net, res);
+
+ dev_out = FIB_RES_DEV(res);
+ fl4->flowi4_oif = dev_out->ifindex;
+
+ rth = FIB_RES_NH(res).nh_rtable;
+ if (!rth) {
+ if (res.type == RTN_LOCAL)
+ flags |= RTCF_LOCAL;
+ rth = __mkroute_output(&res, fl4, orig_oif, dev_out, flags);
+ if (!IS_ERR(rth))
+ rth = rt_finalize(rth, NULL);
+ if (!IS_ERR(rth))
+ FIB_RES_NH(res).nh_rtable = rth;
+ }
+
+ if (!IS_ERR(rth))
+ atomic_inc(&rth->dst.__refcnt);
+
+out:
+ rcu_read_unlock();
+ return rth;
+}
+EXPORT_SYMBOL_GPL(ip_route_output_new);
+
static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie)
{
return NULL;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 544f435..9bb827e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -929,7 +929,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
faddr, saddr, dport, inet->inet_sport);
security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
- rt = ip_route_output_flow(net, &fl4, sk);
+ rt = ip_route_output_new(net, &fl4);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
rt = NULL;
^ permalink raw reply related
* [PATCH v6 3/3] ipv4: Remove rt_key_{src,dst,tos} from struct rtable.
From: David Miller @ 2011-05-05 23:36 UTC (permalink / raw)
To: netdev; +Cc: tgraf, jpirko, herbert, eric.dumazet
They are always used in contexts where they can be reconstituted,
or where the finally resolved rt->rt_{src,dst} is semantically
equivalent.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 7 +-----
net/ipv4/ip_options.c | 10 ++++----
net/ipv4/route.c | 49 +++++++++++++---------------------------------
net/ipv4/xfrm4_policy.c | 3 --
4 files changed, 20 insertions(+), 49 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index ef20edc..70155fb 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -45,14 +45,9 @@ struct fib_info;
struct rtable {
struct dst_entry dst;
- /* Lookup key. */
- __be32 rt_key_dst;
- __be32 rt_key_src;
-
int rt_genid;
unsigned rt_flags;
__u16 rt_type;
- __u8 rt_key_tos;
__be32 rt_dst; /* Path destination */
__be32 rt_src; /* Path source */
@@ -176,7 +171,7 @@ extern unsigned inet_addr_type(struct net *net, __be32 addr);
extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
extern void ip_rt_multicast_event(struct in_device *);
extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
-extern void ip_rt_get_source(u8 *src, struct rtable *rt);
+extern void ip_rt_get_source(struct iphdr *iph, u8 *src, struct rtable *rt);
extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
struct in_ifaddr;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 01fc409..4dc0f22 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
if (!is_frag) {
if (opt->rr_needaddr)
- ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt);
+ ip_rt_get_source(ip_hdr(skb), iph+opt->rr+iph[opt->rr+2]-5, rt);
if (opt->ts_needaddr)
- ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
+ ip_rt_get_source(ip_hdr(skb), iph+opt->ts+iph[opt->ts+2]-9, rt);
if (opt->ts_needtime) {
struct timespec tv;
__be32 midtime;
@@ -553,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb)
if (opt->rr_needaddr) {
optptr = (unsigned char *)raw + opt->rr;
- ip_rt_get_source(&optptr[optptr[2]-5], rt);
+ ip_rt_get_source(ip_hdr(skb), &optptr[optptr[2]-5], rt);
opt->is_changed = 1;
}
if (opt->srr_is_hit) {
@@ -572,14 +572,14 @@ void ip_forward_options(struct sk_buff *skb)
}
if (srrptr + 3 <= srrspace) {
opt->is_changed = 1;
- ip_rt_get_source(&optptr[srrptr-1], rt);
+ ip_rt_get_source(ip_hdr(skb), &optptr[srrptr-1], rt);
ip_hdr(skb)->daddr = rt->rt_dst;
optptr[2] = srrptr+4;
} else if (net_ratelimit())
printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
if (opt->ts_needaddr) {
optptr = raw + opt->ts;
- ip_rt_get_source(&optptr[optptr[2]-9], rt);
+ ip_rt_get_source(ip_hdr(skb), &optptr[optptr[2]-9], rt);
opt->is_changed = 1;
}
}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index be5976a..1e67624 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -628,8 +628,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
ret = NULL;
} else if (rt->rt_flags & RTCF_REDIRECTED) {
#if RT_CACHE_DEBUG >= 1
- printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n",
- &rt->rt_dst, rt->rt_key_tos);
+ printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4 dropped\n",
+ &rt->rt_dst);
#endif
ip_rt_put(rt);
ret = NULL;
@@ -979,7 +979,7 @@ static int ip_rt_bug(struct sk_buff *skb)
in IP options!
*/
-void ip_rt_get_source(u8 *addr, struct rtable *rt)
+void ip_rt_get_source(struct iphdr *iph, u8 *addr, struct rtable *rt)
{
__be32 src;
struct fib_result res;
@@ -988,9 +988,9 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
src = rt->rt_src;
else {
struct flowi4 fl4 = {
- .daddr = rt->rt_key_dst,
- .saddr = rt->rt_key_src,
- .flowi4_tos = rt->rt_key_tos,
+ .daddr = rt->rt_dst,
+ .saddr = rt->rt_src,
+ .flowi4_tos = iph->tos,
.flowi4_oif = rt->rt_oif,
.flowi4_iif = rt->rt_iif,
.flowi4_mark = rt->rt_mark,
@@ -1160,12 +1160,9 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
#endif
rth->dst.output = ip_rt_bug;
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(dev_net(dev));
rth->rt_flags = RTCF_MULTICAST;
rth->rt_type = RTN_MULTICAST;
- rth->rt_key_tos = tos;
rth->rt_dst = daddr;
rth->rt_src = saddr;
rth->rt_route_iif = dev->ifindex;
@@ -1296,12 +1293,9 @@ static int __mkroute_input(struct sk_buff *skb,
goto cleanup;
}
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(dev_net(rth->dst.dev));
rth->rt_flags = flags;
rth->rt_type = res->type;
- rth->rt_key_tos = tos;
rth->rt_dst = daddr;
rth->rt_src = saddr;
rth->rt_route_iif = in_dev->dev->ifindex;
@@ -1471,12 +1465,9 @@ local_input:
rth->dst.tclassid = itag;
#endif
- rth->rt_key_dst = daddr;
- rth->rt_key_src = saddr;
rth->rt_genid = rt_genid(net);
rth->rt_flags = flags|RTCF_LOCAL;
rth->rt_type = res.type;
- rth->rt_key_tos = tos;
rth->rt_dst = daddr;
rth->rt_src = saddr;
#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -1589,12 +1580,10 @@ EXPORT_SYMBOL(ip_route_input);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
const struct flowi4 *fl4,
- __be32 orig_daddr, __be32 orig_saddr,
int orig_oif, struct net_device *dev_out,
unsigned int flags)
{
struct fib_info *fi = res->fi;
- u32 tos = RT_FL_TOS(fl4);
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
@@ -1640,12 +1629,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth->dst.output = ip_output;
- rth->rt_key_dst = orig_daddr;
- rth->rt_key_src = orig_saddr;
rth->rt_genid = rt_genid(dev_net(dev_out));
rth->rt_flags = flags;
rth->rt_type = type;
- rth->rt_key_tos = tos;
rth->rt_dst = fl4->daddr;
rth->rt_src = fl4->saddr;
rth->rt_route_iif = 0;
@@ -1698,8 +1684,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
unsigned int flags = 0;
struct fib_result res;
struct rtable *rth;
- __be32 orig_daddr;
- __be32 orig_saddr;
int orig_oif;
res.fi = NULL;
@@ -1707,8 +1691,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
res.r = NULL;
#endif
- orig_daddr = fl4->daddr;
- orig_saddr = fl4->saddr;
orig_oif = fl4->flowi4_oif;
fl4->flowi4_iif = net->loopback_dev->ifindex;
@@ -1869,8 +1851,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
make_route:
- rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif,
- dev_out, flags);
+ rth = __mkroute_output(&res, fl4, orig_oif, dev_out, flags);
if (!IS_ERR(rth))
rth = rt_finalize(rth, NULL);
@@ -1928,9 +1909,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
if (new->dev)
dev_hold(new->dev);
- rt->rt_key_dst = ort->rt_key_dst;
- rt->rt_key_src = ort->rt_key_src;
- rt->rt_key_tos = ort->rt_key_tos;
rt->rt_route_iif = ort->rt_route_iif;
rt->rt_iif = ort->rt_iif;
rt->rt_oif = ort->rt_oif;
@@ -1975,7 +1953,7 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
}
EXPORT_SYMBOL_GPL(ip_route_output_flow);
-static int rt_fill_info(struct net *net,
+static int rt_fill_info(struct net *net, __be32 src, u8 tos,
struct sk_buff *skb, u32 pid, u32 seq, int event,
int nowait, unsigned int flags)
{
@@ -1993,7 +1971,7 @@ static int rt_fill_info(struct net *net,
r->rtm_family = AF_INET;
r->rtm_dst_len = 32;
r->rtm_src_len = 0;
- r->rtm_tos = rt->rt_key_tos;
+ r->rtm_tos = tos;
r->rtm_table = RT_TABLE_MAIN;
NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
r->rtm_type = rt->rt_type;
@@ -2005,9 +1983,9 @@ static int rt_fill_info(struct net *net,
NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
- if (rt->rt_key_src) {
+ if (src) {
r->rtm_src_len = 32;
- NLA_PUT_BE32(skb, RTA_SRC, rt->rt_key_src);
+ NLA_PUT_BE32(skb, RTA_SRC, src);
}
if (rt->dst.dev)
NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex);
@@ -2017,7 +1995,7 @@ static int rt_fill_info(struct net *net,
#endif
if (rt_is_input_route(rt))
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
- else if (rt->rt_src != rt->rt_key_src)
+ else if (rt->rt_src != src)
NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
if (rt->rt_dst != rt->rt_gateway)
@@ -2158,7 +2136,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
if (rtm->rtm_flags & RTM_F_NOTIFY)
rt->rt_flags |= RTCF_NOTIFY;
- err = rt_fill_info(net, skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+ err = rt_fill_info(net, src, rtm->rtm_tos, skb,
+ NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
RTM_NEWROUTE, 0, 0);
if (err <= 0)
goto errout_free;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7ff973b..bfe3d50 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -71,9 +71,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
struct rtable *rt = (struct rtable *)xdst->route;
const struct flowi4 *fl4 = &fl->u.ip4;
- rt->rt_key_dst = fl4->daddr;
- rt->rt_key_src = fl4->saddr;
- rt->rt_key_tos = fl4->flowi4_tos;
rt->rt_route_iif = fl4->flowi4_iif;
rt->rt_iif = fl4->flowi4_iif;
rt->rt_oif = fl4->flowi4_oif;
--
1.7.5.1
^ permalink raw reply related
* [PATCH v6 2/3] ipv4: Kill ip_route_input_noref().
From: David Miller @ 2011-05-05 23:36 UTC (permalink / raw)
To: netdev; +Cc: tgraf, jpirko, herbert, eric.dumazet
The "noref" argument to ip_route_input_common() is now always ignored
because we do not cache routes, and in that case we must always grab
a reference to the resulting 'dst'.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 16 ++--------------
net/ipv4/arp.c | 2 +-
net/ipv4/ip_fragment.c | 4 ++--
net/ipv4/ip_input.c | 4 ++--
net/ipv4/route.c | 6 +++---
net/ipv4/xfrm4_input.c | 4 ++--
6 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index f6d7673..ef20edc 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -165,20 +165,8 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4
return ip_route_output_key(net, fl4);
}
-extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin, bool noref);
-
-static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin)
-{
- return ip_route_input_common(skb, dst, src, tos, devin, false);
-}
-
-static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin)
-{
- return ip_route_input_common(skb, dst, src, tos, devin, true);
-}
+extern int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
+ u8 tos, struct net_device *devin);
extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph,
unsigned short new_mtu, struct net_device *dev);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 1b74d3b..ef44a91 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -875,7 +875,7 @@ static int arp_process(struct sk_buff *skb)
}
if (arp->ar_op == htons(ARPOP_REQUEST) &&
- ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {
+ ip_route_input(skb, tip, sip, 0, dev) == 0) {
rt = skb_rtable(skb);
addr_type = rt->rt_type;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index b1d282f..ebe8bd3 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -234,8 +234,8 @@ static void ip_expire(unsigned long arg)
/* skb dst is stale, drop it, and perform route lookup again */
skb_dst_drop(head);
iph = ip_hdr(head);
- err = ip_route_input_noref(head, iph->daddr, iph->saddr,
- iph->tos, head->dev);
+ err = ip_route_input(head, iph->daddr, iph->saddr,
+ iph->tos, head->dev);
if (err)
goto out_rcu_unlock;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index c8f48ef..c21ff9b 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -324,8 +324,8 @@ static int ip_rcv_finish(struct sk_buff *skb)
* how the packet travels inside Linux networking.
*/
if (skb_dst(skb) == NULL) {
- int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev);
+ int err = ip_route_input(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev);
if (unlikely(err)) {
if (err == -EHOSTUNREACH)
IP_INC_STATS_BH(dev_net(skb->dev),
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f3f4037..be5976a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1540,8 +1540,8 @@ martian_source_keep_err:
goto out;
}
-int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- u8 tos, struct net_device *dev, bool noref)
+int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
+ u8 tos, struct net_device *dev)
{
int res;
@@ -1584,7 +1584,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rcu_read_unlock();
return res;
}
-EXPORT_SYMBOL(ip_route_input_common);
+EXPORT_SYMBOL(ip_route_input);
/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 06814b6..58d23a5 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
if (skb_dst(skb) == NULL) {
const struct iphdr *iph = ip_hdr(skb);
- if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev))
+ if (ip_route_input(skb, iph->daddr, iph->saddr,
+ iph->tos, skb->dev))
goto drop;
}
return dst_input(skb);
--
1.7.5.1
^ permalink raw reply related
* [PATCH v6 1/3] ipv4: Delete routing cache.
From: David Miller @ 2011-05-05 23:36 UTC (permalink / raw)
To: netdev; +Cc: tgraf, jpirko, herbert, eric.dumazet
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/route.h | 1 -
net/ipv4/fib_frontend.c | 5 -
net/ipv4/route.c | 910 +---------------------------------------------
3 files changed, 20 insertions(+), 896 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index 9f8070b..f6d7673 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -114,7 +114,6 @@ extern int ip_rt_init(void);
extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
-extern void rt_cache_flush_batch(struct net *net);
extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
struct sock *sk);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 2252471..33bbbda 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1022,11 +1022,6 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
rt_cache_flush(dev_net(dev), 0);
break;
case NETDEV_UNREGISTER_BATCH:
- /* The batch unregister is only called on the first
- * device in the list of devices being unregistered.
- * Therefore we should not pass dev_net(dev) in here.
- */
- rt_cache_flush_batch(NULL);
break;
}
return NOTIFY_DONE;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 6a83840..f3f4037 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -129,7 +129,6 @@ static int ip_rt_gc_elasticity __read_mostly = 8;
static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;
static int ip_rt_min_pmtu __read_mostly = 512 + 20 + 20;
static int ip_rt_min_advmss __read_mostly = 256;
-static int rt_chain_length_max __read_mostly = 20;
/*
* Interface to generic destination cache.
@@ -142,7 +141,6 @@ static void ipv4_dst_destroy(struct dst_entry *dst);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
-static int rt_garbage_collect(struct dst_ops *ops);
static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
int how)
@@ -187,7 +185,6 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
static struct dst_ops ipv4_dst_ops = {
.family = AF_INET,
.protocol = cpu_to_be16(ETH_P_IP),
- .gc = rt_garbage_collect,
.check = ipv4_dst_check,
.default_advmss = ipv4_default_advmss,
.default_mtu = ipv4_default_mtu,
@@ -222,184 +219,30 @@ const __u8 ip_tos2prio[16] = {
};
-/*
- * Route cache.
- */
-
-/* The locking scheme is rather straight forward:
- *
- * 1) Read-Copy Update protects the buckets of the central route hash.
- * 2) Only writers remove entries, and they hold the lock
- * as they look at rtable reference counts.
- * 3) Only readers acquire references to rtable entries,
- * they do so with atomic increments and with the
- * lock held.
- */
-
-struct rt_hash_bucket {
- struct rtable __rcu *chain;
-};
-
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || \
- defined(CONFIG_PROVE_LOCKING)
-/*
- * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks
- * The size of this table is a power of two and depends on the number of CPUS.
- * (on lockdep we have a quite big spinlock_t, so keep the size down there)
- */
-#ifdef CONFIG_LOCKDEP
-# define RT_HASH_LOCK_SZ 256
-#else
-# if NR_CPUS >= 32
-# define RT_HASH_LOCK_SZ 4096
-# elif NR_CPUS >= 16
-# define RT_HASH_LOCK_SZ 2048
-# elif NR_CPUS >= 8
-# define RT_HASH_LOCK_SZ 1024
-# elif NR_CPUS >= 4
-# define RT_HASH_LOCK_SZ 512
-# else
-# define RT_HASH_LOCK_SZ 256
-# endif
-#endif
-
-static spinlock_t *rt_hash_locks;
-# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
-
-static __init void rt_hash_lock_init(void)
-{
- int i;
-
- rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ,
- GFP_KERNEL);
- if (!rt_hash_locks)
- panic("IP: failed to allocate rt_hash_locks\n");
-
- for (i = 0; i < RT_HASH_LOCK_SZ; i++)
- spin_lock_init(&rt_hash_locks[i]);
-}
-#else
-# define rt_hash_lock_addr(slot) NULL
-
-static inline void rt_hash_lock_init(void)
-{
-}
-#endif
-
-static struct rt_hash_bucket *rt_hash_table __read_mostly;
-static unsigned rt_hash_mask __read_mostly;
-static unsigned int rt_hash_log __read_mostly;
-
static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
#define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field)
-static inline unsigned int rt_hash(__be32 daddr, __be32 saddr, int idx,
- int genid)
-{
- return jhash_3words((__force u32)daddr, (__force u32)saddr,
- idx, genid)
- & rt_hash_mask;
-}
-
static inline int rt_genid(struct net *net)
{
return atomic_read(&net->ipv4.rt_genid);
}
#ifdef CONFIG_PROC_FS
-struct rt_cache_iter_state {
- struct seq_net_private p;
- int bucket;
- int genid;
-};
-
-static struct rtable *rt_cache_get_first(struct seq_file *seq)
-{
- struct rt_cache_iter_state *st = seq->private;
- struct rtable *r = NULL;
-
- for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
- if (!rcu_dereference_raw(rt_hash_table[st->bucket].chain))
- continue;
- rcu_read_lock_bh();
- r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
- while (r) {
- if (dev_net(r->dst.dev) == seq_file_net(seq) &&
- r->rt_genid == st->genid)
- return r;
- r = rcu_dereference_bh(r->dst.rt_next);
- }
- rcu_read_unlock_bh();
- }
- return r;
-}
-
-static struct rtable *__rt_cache_get_next(struct seq_file *seq,
- struct rtable *r)
-{
- struct rt_cache_iter_state *st = seq->private;
-
- r = rcu_dereference_bh(r->dst.rt_next);
- while (!r) {
- rcu_read_unlock_bh();
- do {
- if (--st->bucket < 0)
- return NULL;
- } while (!rcu_dereference_raw(rt_hash_table[st->bucket].chain));
- rcu_read_lock_bh();
- r = rcu_dereference_bh(rt_hash_table[st->bucket].chain);
- }
- return r;
-}
-
-static struct rtable *rt_cache_get_next(struct seq_file *seq,
- struct rtable *r)
-{
- struct rt_cache_iter_state *st = seq->private;
- while ((r = __rt_cache_get_next(seq, r)) != NULL) {
- if (dev_net(r->dst.dev) != seq_file_net(seq))
- continue;
- if (r->rt_genid == st->genid)
- break;
- }
- return r;
-}
-
-static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
-{
- struct rtable *r = rt_cache_get_first(seq);
-
- if (r)
- while (pos && (r = rt_cache_get_next(seq, r)))
- --pos;
- return pos ? NULL : r;
-}
-
static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct rt_cache_iter_state *st = seq->private;
if (*pos)
- return rt_cache_get_idx(seq, *pos - 1);
- st->genid = rt_genid(seq_file_net(seq));
+ return NULL;
return SEQ_START_TOKEN;
}
static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct rtable *r;
-
- if (v == SEQ_START_TOKEN)
- r = rt_cache_get_first(seq);
- else
- r = rt_cache_get_next(seq, v);
++*pos;
- return r;
+ return NULL;
}
static void rt_cache_seq_stop(struct seq_file *seq, void *v)
{
- if (v && v != SEQ_START_TOKEN)
- rcu_read_unlock_bh();
}
static int rt_cache_seq_show(struct seq_file *seq, void *v)
@@ -409,29 +252,6 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
"Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\t"
"Metric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\t"
"HHUptod\tSpecDst");
- else {
- struct rtable *r = v;
- int len;
-
- seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
- "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
- r->dst.dev ? r->dst.dev->name : "*",
- (__force u32)r->rt_dst,
- (__force u32)r->rt_gateway,
- r->rt_flags, atomic_read(&r->dst.__refcnt),
- r->dst.__use, 0, (__force u32)r->rt_src,
- dst_metric_advmss(&r->dst) + 40,
- dst_metric(&r->dst, RTAX_WINDOW),
- (int)((dst_metric(&r->dst, RTAX_RTT) >> 3) +
- dst_metric(&r->dst, RTAX_RTTVAR)),
- r->rt_key_tos,
- r->dst.hh ? atomic_read(&r->dst.hh->hh_refcnt) : -1,
- r->dst.hh ? (r->dst.hh->hh_output ==
- dev_queue_xmit) : 0,
- r->rt_spec_dst, &len);
-
- seq_printf(seq, "%*s\n", 127 - len, "");
- }
return 0;
}
@@ -444,8 +264,7 @@ static const struct seq_operations rt_cache_seq_ops = {
static int rt_cache_seq_open(struct inode *inode, struct file *file)
{
- return seq_open_net(inode, file, &rt_cache_seq_ops,
- sizeof(struct rt_cache_iter_state));
+ return seq_open(file, &rt_cache_seq_ops);
}
static const struct file_operations rt_cache_seq_fops = {
@@ -453,7 +272,7 @@ static const struct file_operations rt_cache_seq_fops = {
.open = rt_cache_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release_net,
+ .release = seq_release,
};
@@ -643,184 +462,12 @@ static inline int ip_rt_proc_init(void)
}
#endif /* CONFIG_PROC_FS */
-static inline void rt_free(struct rtable *rt)
-{
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
-static inline void rt_drop(struct rtable *rt)
-{
- ip_rt_put(rt);
- call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
-}
-
-static inline int rt_fast_clean(struct rtable *rth)
-{
- /* Kill broadcast/multicast entries very aggresively, if they
- collide in hash table with more useful entries */
- return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) &&
- rt_is_input_route(rth) && rth->dst.rt_next;
-}
-
-static inline int rt_valuable(struct rtable *rth)
-{
- return (rth->rt_flags & (RTCF_REDIRECTED | RTCF_NOTIFY)) ||
- (rth->peer && rth->peer->pmtu_expires);
-}
-
-static int rt_may_expire(struct rtable *rth, unsigned long tmo1, unsigned long tmo2)
-{
- unsigned long age;
- int ret = 0;
-
- if (atomic_read(&rth->dst.__refcnt))
- goto out;
-
- age = jiffies - rth->dst.lastuse;
- if ((age <= tmo1 && !rt_fast_clean(rth)) ||
- (age <= tmo2 && rt_valuable(rth)))
- goto out;
- ret = 1;
-out: return ret;
-}
-
-/* Bits of score are:
- * 31: very valuable
- * 30: not quite useless
- * 29..0: usage counter
- */
-static inline u32 rt_score(struct rtable *rt)
-{
- u32 score = jiffies - rt->dst.lastuse;
-
- score = ~score & ~(3<<30);
-
- if (rt_valuable(rt))
- score |= (1<<31);
-
- if (rt_is_output_route(rt) ||
- !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL)))
- score |= (1<<30);
-
- return score;
-}
-
-static inline bool rt_caching(const struct net *net)
-{
- return net->ipv4.current_rt_cache_rebuild_count <=
- net->ipv4.sysctl_rt_cache_rebuild_count;
-}
-
-static inline bool compare_hash_inputs(const struct rtable *rt1,
- const struct rtable *rt2)
-{
- return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |
- ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
- (rt1->rt_iif ^ rt2->rt_iif)) == 0);
-}
-
-static inline int compare_keys(struct rtable *rt1, struct rtable *rt2)
-{
- return (((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) |
- ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
- (rt1->rt_mark ^ rt2->rt_mark) |
- (rt1->rt_key_tos ^ rt2->rt_key_tos) |
- (rt1->rt_oif ^ rt2->rt_oif) |
- (rt1->rt_iif ^ rt2->rt_iif)) == 0;
-}
-
-static inline int compare_netns(struct rtable *rt1, struct rtable *rt2)
-{
- return net_eq(dev_net(rt1->dst.dev), dev_net(rt2->dst.dev));
-}
-
static inline int rt_is_expired(struct rtable *rth)
{
return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
}
/*
- * Perform a full scan of hash table and free all entries.
- * Can be called by a softirq or a process.
- * In the later case, we want to be reschedule if necessary
- */
-static void rt_do_flush(struct net *net, int process_context)
-{
- unsigned int i;
- struct rtable *rth, *next;
-
- for (i = 0; i <= rt_hash_mask; i++) {
- struct rtable __rcu **pprev;
- struct rtable *list;
-
- if (process_context && need_resched())
- cond_resched();
- rth = rcu_dereference_raw(rt_hash_table[i].chain);
- if (!rth)
- continue;
-
- spin_lock_bh(rt_hash_lock_addr(i));
-
- list = NULL;
- pprev = &rt_hash_table[i].chain;
- rth = rcu_dereference_protected(*pprev,
- lockdep_is_held(rt_hash_lock_addr(i)));
-
- while (rth) {
- next = rcu_dereference_protected(rth->dst.rt_next,
- lockdep_is_held(rt_hash_lock_addr(i)));
-
- if (!net ||
- net_eq(dev_net(rth->dst.dev), net)) {
- rcu_assign_pointer(*pprev, next);
- rcu_assign_pointer(rth->dst.rt_next, list);
- list = rth;
- } else {
- pprev = &rth->dst.rt_next;
- }
- rth = next;
- }
-
- spin_unlock_bh(rt_hash_lock_addr(i));
-
- for (; list; list = next) {
- next = rcu_dereference_protected(list->dst.rt_next, 1);
- rt_free(list);
- }
- }
-}
-
-/*
- * While freeing expired entries, we compute average chain length
- * and standard deviation, using fixed-point arithmetic.
- * This to have an estimation of rt_chain_length_max
- * rt_chain_length_max = max(elasticity, AVG + 4*SD)
- * We use 3 bits for frational part, and 29 (or 61) for magnitude.
- */
-
-#define FRACT_BITS 3
-#define ONE (1UL << FRACT_BITS)
-
-/*
- * Given a hash chain and an item in this hash chain,
- * find if a previous entry has the same hash_inputs
- * (but differs on tos, mark or oif)
- * Returns 0 if an alias is found.
- * Returns ONE if rth has no alias before itself.
- */
-static int has_noalias(const struct rtable *head, const struct rtable *rth)
-{
- const struct rtable *aux = head;
-
- while (aux != rth) {
- if (compare_hash_inputs(aux, rth))
- return 0;
- aux = rcu_dereference_protected(aux->dst.rt_next, 1);
- }
- return ONE;
-}
-
-/*
* Perturbation of rt_genid by a small quantity [1..256]
* Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
* many times (2^24) without giving recent rt_genid.
@@ -841,364 +488,20 @@ static void rt_cache_invalidate(struct net *net)
void rt_cache_flush(struct net *net, int delay)
{
rt_cache_invalidate(net);
- if (delay >= 0)
- rt_do_flush(net, !in_softirq());
-}
-
-/* Flush previous cache invalidated entries from the cache */
-void rt_cache_flush_batch(struct net *net)
-{
- rt_do_flush(net, !in_softirq());
-}
-
-static void rt_emergency_hash_rebuild(struct net *net)
-{
- if (net_ratelimit())
- printk(KERN_WARNING "Route hash chain too long!\n");
- rt_cache_invalidate(net);
-}
-
-/*
- Short description of GC goals.
-
- We want to build algorithm, which will keep routing cache
- at some equilibrium point, when number of aged off entries
- is kept approximately equal to newly generated ones.
-
- Current expiration strength is variable "expire".
- We try to adjust it dynamically, so that if networking
- is idle expires is large enough to keep enough of warm entries,
- and when load increases it reduces to limit cache size.
- */
-
-static int rt_garbage_collect(struct dst_ops *ops)
-{
- static unsigned long expire = RT_GC_TIMEOUT;
- static unsigned long last_gc;
- static int rover;
- static int equilibrium;
- struct rtable *rth;
- struct rtable __rcu **rthp;
- unsigned long now = jiffies;
- int goal;
- int entries = dst_entries_get_fast(&ipv4_dst_ops);
-
- /*
- * Garbage collection is pretty expensive,
- * do not make it too frequently.
- */
-
- RT_CACHE_STAT_INC(gc_total);
-
- if (now - last_gc < ip_rt_gc_min_interval &&
- entries < ip_rt_max_size) {
- RT_CACHE_STAT_INC(gc_ignored);
- goto out;
- }
-
- entries = dst_entries_get_slow(&ipv4_dst_ops);
- /* Calculate number of entries, which we want to expire now. */
- goal = entries - (ip_rt_gc_elasticity << rt_hash_log);
- if (goal <= 0) {
- if (equilibrium < ipv4_dst_ops.gc_thresh)
- equilibrium = ipv4_dst_ops.gc_thresh;
- goal = entries - equilibrium;
- if (goal > 0) {
- equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- goal = entries - equilibrium;
- }
- } else {
- /* We are in dangerous area. Try to reduce cache really
- * aggressively.
- */
- goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1);
- equilibrium = entries - goal;
- }
-
- if (now - last_gc >= ip_rt_gc_min_interval)
- last_gc = now;
-
- if (goal <= 0) {
- equilibrium += goal;
- goto work_done;
- }
-
- do {
- int i, k;
-
- for (i = rt_hash_mask, k = rover; i >= 0; i--) {
- unsigned long tmo = expire;
-
- k = (k + 1) & rt_hash_mask;
- rthp = &rt_hash_table[k].chain;
- spin_lock_bh(rt_hash_lock_addr(k));
- while ((rth = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(k)))) != NULL) {
- if (!rt_is_expired(rth) &&
- !rt_may_expire(rth, tmo, expire)) {
- tmo >>= 1;
- rthp = &rth->dst.rt_next;
- continue;
- }
- *rthp = rth->dst.rt_next;
- rt_free(rth);
- goal--;
- }
- spin_unlock_bh(rt_hash_lock_addr(k));
- if (goal <= 0)
- break;
- }
- rover = k;
-
- if (goal <= 0)
- goto work_done;
-
- /* Goal is not achieved. We stop process if:
-
- - if expire reduced to zero. Otherwise, expire is halfed.
- - if table is not full.
- - if we are called from interrupt.
- - jiffies check is just fallback/debug loop breaker.
- We will not spin here for long time in any case.
- */
-
- RT_CACHE_STAT_INC(gc_goal_miss);
-
- if (expire == 0)
- break;
-
- expire >>= 1;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, i);
-#endif
-
- if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- } while (!in_softirq() && time_before_eq(jiffies, now));
-
- if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size)
- goto out;
- if (net_ratelimit())
- printk(KERN_WARNING "dst cache overflow\n");
- RT_CACHE_STAT_INC(gc_dst_overflow);
- return 1;
-
-work_done:
- expire += ip_rt_gc_min_interval;
- if (expire > ip_rt_gc_timeout ||
- dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh ||
- dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh)
- expire = ip_rt_gc_timeout;
-#if RT_CACHE_DEBUG >= 2
- printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire,
- dst_entries_get_fast(&ipv4_dst_ops), goal, rover);
-#endif
-out: return 0;
}
-/*
- * Returns number of entries in a hash chain that have different hash_inputs
- */
-static int slow_chain_length(const struct rtable *head)
+static struct rtable *rt_finalize(struct rtable *rt, struct sk_buff *skb)
{
- int length = 0;
- const struct rtable *rth = head;
-
- while (rth) {
- length += has_noalias(head, rth);
- rth = rcu_dereference_protected(rth->dst.rt_next, 1);
- }
- return length >> FRACT_BITS;
-}
-
-static struct rtable *rt_intern_hash(unsigned hash, struct rtable *rt,
- struct sk_buff *skb, int ifindex)
-{
- struct rtable *rth, *cand;
- struct rtable __rcu **rthp, **candp;
- unsigned long now;
- u32 min_score;
- int chain_length;
- int attempts = !in_softirq();
-
-restart:
- chain_length = 0;
- min_score = ~(u32)0;
- cand = NULL;
- candp = NULL;
- now = jiffies;
-
- if (!rt_caching(dev_net(rt->dst.dev))) {
- /*
- * If we're not caching, just tell the caller we
- * were successful and don't touch the route. The
- * caller hold the sole reference to the cache entry, and
- * it will be released when the caller is done with it.
- * If we drop it here, the callers have no way to resolve routes
- * when we're not caching. Instead, just point *rp at rt, so
- * the caller gets a single use out of the route
- * Note that we do rt_free on this new route entry, so that
- * once its refcount hits zero, we are still able to reap it
- * (Thanks Alexey)
- * Note: To avoid expensive rcu stuff for this uncached dst,
- * we set DST_NOCACHE so that dst_release() can free dst without
- * waiting a grace period.
- */
-
- rt->dst.flags |= DST_NOCACHE;
- if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
- int err = arp_bind_neighbour(&rt->dst);
- if (err) {
- if (net_ratelimit())
- printk(KERN_WARNING
- "Neighbour table failure & not caching routes.\n");
- ip_rt_put(rt);
- return ERR_PTR(err);
- }
- }
-
- goto skip_hashing;
- }
-
- rthp = &rt_hash_table[hash].chain;
-
- spin_lock_bh(rt_hash_lock_addr(hash));
- while ((rth = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(hash)))) != NULL) {
- if (rt_is_expired(rth)) {
- *rthp = rth->dst.rt_next;
- rt_free(rth);
- continue;
- }
- if (compare_keys(rth, rt) && compare_netns(rth, rt)) {
- /* Put it first */
- *rthp = rth->dst.rt_next;
- /*
- * Since lookup is lockfree, the deletion
- * must be visible to another weakly ordered CPU before
- * the insertion at the start of the hash chain.
- */
- rcu_assign_pointer(rth->dst.rt_next,
- rt_hash_table[hash].chain);
- /*
- * Since lookup is lockfree, the update writes
- * must be ordered for consistency on SMP.
- */
- rcu_assign_pointer(rt_hash_table[hash].chain, rth);
-
- dst_use(&rth->dst, now);
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- rt_drop(rt);
- if (skb)
- skb_dst_set(skb, &rth->dst);
- return rth;
- }
-
- if (!atomic_read(&rth->dst.__refcnt)) {
- u32 score = rt_score(rth);
-
- if (score <= min_score) {
- cand = rth;
- candp = rthp;
- min_score = score;
- }
- }
-
- chain_length++;
-
- rthp = &rth->dst.rt_next;
- }
-
- if (cand) {
- /* ip_rt_gc_elasticity used to be average length of chain
- * length, when exceeded gc becomes really aggressive.
- *
- * The second limit is less certain. At the moment it allows
- * only 2 entries per bucket. We will see.
- */
- if (chain_length > ip_rt_gc_elasticity) {
- *candp = cand->dst.rt_next;
- rt_free(cand);
- }
- } else {
- if (chain_length > rt_chain_length_max &&
- slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
- struct net *net = dev_net(rt->dst.dev);
- int num = ++net->ipv4.current_rt_cache_rebuild_count;
- if (!rt_caching(net)) {
- printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
- rt->dst.dev->name, num);
- }
- rt_emergency_hash_rebuild(net);
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- hash = rt_hash(rt->rt_key_dst, rt->rt_key_src,
- ifindex, rt_genid(net));
- goto restart;
- }
- }
-
- /* Try to bind route to arp only if it is output
- route or unicast forwarding path.
- */
if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
int err = arp_bind_neighbour(&rt->dst);
if (err) {
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
- if (err != -ENOBUFS) {
- rt_drop(rt);
- return ERR_PTR(err);
- }
-
- /* Neighbour tables are full and nothing
- can be released. Try to shrink route cache,
- it is most likely it holds some neighbour records.
- */
- if (attempts-- > 0) {
- int saved_elasticity = ip_rt_gc_elasticity;
- int saved_int = ip_rt_gc_min_interval;
- ip_rt_gc_elasticity = 1;
- ip_rt_gc_min_interval = 0;
- rt_garbage_collect(&ipv4_dst_ops);
- ip_rt_gc_min_interval = saved_int;
- ip_rt_gc_elasticity = saved_elasticity;
- goto restart;
- }
-
if (net_ratelimit())
- printk(KERN_WARNING "ipv4: Neighbour table overflow.\n");
- rt_drop(rt);
- return ERR_PTR(-ENOBUFS);
+ printk(KERN_WARNING
+ "Neighbour table failure & not caching routes.\n");
+ ip_rt_put(rt);
+ return ERR_PTR(err);
}
}
-
- rt->dst.rt_next = rt_hash_table[hash].chain;
-
-#if RT_CACHE_DEBUG >= 2
- if (rt->dst.rt_next) {
- struct rtable *trt;
- printk(KERN_DEBUG "rt_cache @%02x: %pI4",
- hash, &rt->rt_dst);
- for (trt = rt->dst.rt_next; trt; trt = trt->dst.rt_next)
- printk(" . %pI4", &trt->rt_dst);
- printk("\n");
- }
-#endif
- /*
- * Since lookup is lockfree, we must make sure
- * previous writes to rt are committed to memory
- * before making rt visible to other CPUS.
- */
- rcu_assign_pointer(rt_hash_table[hash].chain, rt);
-
- spin_unlock_bh(rt_hash_lock_addr(hash));
-
-skip_hashing:
if (skb)
skb_dst_set(skb, &rt->dst);
return rt;
@@ -1266,26 +569,6 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more)
}
EXPORT_SYMBOL(__ip_select_ident);
-static void rt_del(unsigned hash, struct rtable *rt)
-{
- struct rtable __rcu **rthp;
- struct rtable *aux;
-
- rthp = &rt_hash_table[hash].chain;
- spin_lock_bh(rt_hash_lock_addr(hash));
- ip_rt_put(rt);
- while ((aux = rcu_dereference_protected(*rthp,
- lockdep_is_held(rt_hash_lock_addr(hash)))) != NULL) {
- if (aux == rt || rt_is_expired(aux)) {
- *rthp = aux->dst.rt_next;
- rt_free(aux);
- continue;
- }
- rthp = &aux->dst.rt_next;
- }
- spin_unlock_bh(rt_hash_lock_addr(hash));
-}
-
/* called in rcu_read_lock() section */
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
__be32 saddr, struct net_device *dev)
@@ -1344,14 +627,11 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
ip_rt_put(rt);
ret = NULL;
} else if (rt->rt_flags & RTCF_REDIRECTED) {
- unsigned hash = rt_hash(rt->rt_key_dst, rt->rt_key_src,
- rt->rt_oif,
- rt_genid(dev_net(dst->dev)));
#if RT_CACHE_DEBUG >= 1
printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n",
- &rt->rt_dst, rt->rt_key_tos);
+ &rt->rt_dst, rt->rt_key_tos);
#endif
- rt_del(hash, rt);
+ ip_rt_put(rt);
ret = NULL;
} else if (rt->peer &&
rt->peer->pmtu_expires &&
@@ -1836,7 +1116,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev,
bool nopolicy, bool noxfrm)
{
return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
- DST_HOST |
+ DST_HOST | DST_NOCACHE |
(nopolicy ? DST_NOPOLICY : 0) |
(noxfrm ? DST_NOXFRM : 0));
}
@@ -1845,7 +1125,6 @@ static struct rtable *rt_dst_alloc(struct net_device *dev,
static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, int our)
{
- unsigned int hash;
struct rtable *rth;
__be32 spec_dst;
struct in_device *in_dev = __in_dev_get_rcu(dev);
@@ -1909,8 +1188,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
#endif
RT_CACHE_STAT_INC(in_slow_mc);
- hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
- rth = rt_intern_hash(hash, rth, skb, dev->ifindex);
+ rth = rt_finalize(rth, skb);
err = 0;
if (IS_ERR(rth))
err = PTR_ERR(rth);
@@ -2055,7 +1333,6 @@ static int ip_mkroute_input(struct sk_buff *skb,
{
struct rtable* rth = NULL;
int err;
- unsigned hash;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
@@ -2067,10 +1344,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
if (err)
return err;
- /* put it into the cache */
- hash = rt_hash(daddr, saddr, fl4->flowi4_iif,
- rt_genid(dev_net(rth->dst.dev)));
- rth = rt_intern_hash(hash, rth, skb, fl4->flowi4_iif);
+ rth = rt_finalize(rth, skb);
if (IS_ERR(rth))
return PTR_ERR(rth);
return 0;
@@ -2096,7 +1370,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
unsigned flags = 0;
u32 itag = 0;
struct rtable * rth;
- unsigned hash;
__be32 spec_dst;
int err = -EINVAL;
struct net * net = dev_net(dev);
@@ -2223,8 +1496,7 @@ local_input:
rth->dst.error= -err;
rth->rt_flags &= ~RTCF_LOCAL;
}
- hash = rt_hash(daddr, saddr, fl4.flowi4_iif, rt_genid(net));
- rth = rt_intern_hash(hash, rth, skb, fl4.flowi4_iif);
+ rth = rt_finalize(rth, skb);
err = 0;
if (IS_ERR(rth))
err = PTR_ERR(rth);
@@ -2271,47 +1543,10 @@ martian_source_keep_err:
int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev, bool noref)
{
- struct rtable * rth;
- unsigned hash;
- int iif = dev->ifindex;
- struct net *net;
int res;
- net = dev_net(dev);
-
rcu_read_lock();
- if (!rt_caching(net))
- goto skip_cache;
-
- tos &= IPTOS_RT_MASK;
- hash = rt_hash(daddr, saddr, iif, rt_genid(net));
-
- for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
- rth = rcu_dereference(rth->dst.rt_next)) {
- if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) |
- ((__force u32)rth->rt_key_src ^ (__force u32)saddr) |
- (rth->rt_iif ^ iif) |
- rth->rt_oif |
- (rth->rt_key_tos ^ tos)) == 0 &&
- rth->rt_mark == skb->mark &&
- net_eq(dev_net(rth->dst.dev), net) &&
- !rt_is_expired(rth)) {
- if (noref) {
- dst_use_noref(&rth->dst, jiffies);
- skb_dst_set_noref(skb, &rth->dst);
- } else {
- dst_use(&rth->dst, jiffies);
- skb_dst_set(skb, &rth->dst);
- }
- RT_CACHE_STAT_INC(in_hit);
- rcu_read_unlock();
- return 0;
- }
- RT_CACHE_STAT_INC(in_hlist_search);
- }
-
-skip_cache:
/* Multicast recognition logic is moved from route cache to here.
The problem was that too many Ethernet cards have broken/missing
hardware multicast filters :-( As result the host on multicasting
@@ -2454,10 +1689,9 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
/*
* Major route resolver routine.
- * called with rcu_read_lock();
*/
-static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
+struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
{
struct net_device *dev_out = NULL;
u32 tos = RT_FL_TOS(fl4);
@@ -2637,57 +1871,13 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4)
make_route:
rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif,
dev_out, flags);
- if (!IS_ERR(rth)) {
- unsigned int hash;
-
- hash = rt_hash(orig_daddr, orig_saddr, orig_oif,
- rt_genid(dev_net(dev_out)));
- rth = rt_intern_hash(hash, rth, NULL, orig_oif);
- }
+ if (!IS_ERR(rth))
+ rth = rt_finalize(rth, NULL);
out:
rcu_read_unlock();
return rth;
}
-
-struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4)
-{
- struct rtable *rth;
- unsigned int hash;
-
- if (!rt_caching(net))
- goto slow_output;
-
- hash = rt_hash(flp4->daddr, flp4->saddr, flp4->flowi4_oif, rt_genid(net));
-
- rcu_read_lock_bh();
- for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth;
- rth = rcu_dereference_bh(rth->dst.rt_next)) {
- if (rth->rt_key_dst == flp4->daddr &&
- rth->rt_key_src == flp4->saddr &&
- rt_is_output_route(rth) &&
- rth->rt_oif == flp4->flowi4_oif &&
- rth->rt_mark == flp4->flowi4_mark &&
- !((rth->rt_key_tos ^ flp4->flowi4_tos) &
- (IPTOS_RT_MASK | RTO_ONLINK)) &&
- net_eq(dev_net(rth->dst.dev), net) &&
- !rt_is_expired(rth)) {
- dst_use(&rth->dst, jiffies);
- RT_CACHE_STAT_INC(out_hit);
- rcu_read_unlock_bh();
- if (!flp4->saddr)
- flp4->saddr = rth->rt_src;
- if (!flp4->daddr)
- flp4->daddr = rth->rt_dst;
- return rth;
- }
- RT_CACHE_STAT_INC(out_hlist_search);
- }
- rcu_read_unlock_bh();
-
-slow_output:
- return ip_route_output_slow(net, flp4);
-}
EXPORT_SYMBOL_GPL(__ip_route_output_key);
static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie)
@@ -2984,43 +2174,6 @@ errout_free:
int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
- struct rtable *rt;
- int h, s_h;
- int idx, s_idx;
- struct net *net;
-
- net = sock_net(skb->sk);
-
- s_h = cb->args[0];
- if (s_h < 0)
- s_h = 0;
- s_idx = idx = cb->args[1];
- for (h = s_h; h <= rt_hash_mask; h++, s_idx = 0) {
- if (!rt_hash_table[h].chain)
- continue;
- rcu_read_lock_bh();
- for (rt = rcu_dereference_bh(rt_hash_table[h].chain), idx = 0; rt;
- rt = rcu_dereference_bh(rt->dst.rt_next), idx++) {
- if (!net_eq(dev_net(rt->dst.dev), net) || idx < s_idx)
- continue;
- if (rt_is_expired(rt))
- continue;
- skb_dst_set_noref(skb, &rt->dst);
- if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, RTM_NEWROUTE,
- 1, NLM_F_MULTI) <= 0) {
- skb_dst_drop(skb);
- rcu_read_unlock_bh();
- goto done;
- }
- skb_dst_drop(skb);
- }
- rcu_read_unlock_bh();
- }
-
-done:
- cb->args[0] = h;
- cb->args[1] = idx;
return skb->len;
}
@@ -3255,16 +2408,6 @@ static __net_initdata struct pernet_operations rt_genid_ops = {
struct ip_rt_acct __percpu *ip_rt_acct __read_mostly;
#endif /* CONFIG_IP_ROUTE_CLASSID */
-static __initdata unsigned long rhash_entries;
-static int __init set_rhash_entries(char *str)
-{
- if (!str)
- return 0;
- rhash_entries = simple_strtoul(str, &str, 0);
- return 1;
-}
-__setup("rhash_entries=", set_rhash_entries);
-
int __init ip_rt_init(void)
{
int rc = 0;
@@ -3287,21 +2430,8 @@ int __init ip_rt_init(void)
if (dst_entries_init(&ipv4_dst_blackhole_ops) < 0)
panic("IP: failed to allocate ipv4_dst_blackhole_ops counter\n");
- rt_hash_table = (struct rt_hash_bucket *)
- alloc_large_system_hash("IP route cache",
- sizeof(struct rt_hash_bucket),
- rhash_entries,
- (totalram_pages >= 128 * 1024) ?
- 15 : 17,
- 0,
- &rt_hash_log,
- &rt_hash_mask,
- rhash_entries ? 0 : 512 * 1024);
- memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket));
- rt_hash_lock_init();
-
- ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
- ip_rt_max_size = (rt_hash_mask + 1) * 16;
+ ipv4_dst_ops.gc_thresh = ~0;
+ ip_rt_max_size = INT_MAX;
devinet_init();
ip_fib_init();
--
1.7.5.1
^ permalink raw reply related
* [PATCH v6 0/3] rtcache removal respin
From: David Miller @ 2011-05-05 23:35 UTC (permalink / raw)
To: netdev; +Cc: tgraf, jpirko, herbert, eric.dumazet
As before, this is just a respin of the routing cache removal patches
for people who want to play with this stuff.
The patch set has shrunk significantly, because several changes in the
previous series have been integrated to net-next-2.6
One new change is that now rt->rt_key_tos is removed alongside
rt->rt_key_{dst,src}
And finally, I've included an extra bonus patch showing an
experimental scheme I'm working on which will make output route
resolution in a routing-cache-less environment extremely fast.
Enjoy.
^ permalink raw reply
* Re: [PATCHv4 2/2] tg3: Allow ethtool to enable/disable loopback.
From: Mahesh Bandewar @ 2011-05-05 23:16 UTC (permalink / raw)
To: Michał Mirosław
Cc: Matt Carlson, David Miller, netdev, Michael Chan, Tom Herbert
In-Reply-To: <BANLkTikJ67YLGzR-3rjazkUgmffMxp1nJQ@mail.gmail.com>
On Thu, May 5, 2011 at 11:35 AM, Michał Mirosław <mirqus@gmail.com> wrote:
> W dniu 5 maja 2011 19:47 użytkownik Mahesh Bandewar
> <maheshb@google.com> napisał:
>> On Wed, May 4, 2011 at 11:59 PM, Michał Mirosław <mirqus@gmail.com> wrote:
>>> 2011/5/5 Mahesh Bandewar <maheshb@google.com>:
>>>> This patch adds tg3_set_features() to handle loopback mode. Currently the
>>>> capability is added for the devices which support internal MAC loopback mode.
>>>> So when enabled, it enables internal-MAC loopback.
> [...]
>>>> @@ -9485,6 +9533,15 @@ static int tg3_open(struct net_device *dev)
>>>>
>>>> netif_tx_start_all_queues(dev);
>>>>
>>>> + /*
>>>> + * Reset loopback feature if it was turned on while the device was down
>>>> + * to avoid and any discrepancy in features reporting.
>>>> + */
>>>> + if (dev->features & NETIF_F_LOOPBACK) {
>>>> + dev->features &= ~NETIF_F_LOOPBACK;
>>>> + dev->wanted_features &= ~NETIF_F_LOOPBACK;
>>>> + }
>>>> +
>>>
>>> if (dev->features & NETIF_F_LOOPBACK)
>>> tg3_set_loopback(dev, dev->features);
>>>
>> Unfortunately at this stage device will not be able to set-loopback so
>> I resorted to clearing the bit(s).
>
> ndo_fix_features+ndo_set_features might be caled before ndo_open - the
> first might be just from register_netdev() so even before ndo_open
> callback.
>
ndo_open is the triggering event, so anything before that point does
not really help.
>>> Whatever you do, don't modify wanted_features in drivers.
>> Since just clearing the 'features' would leave wanted_features in
>> discrepant state, I thought this will bring it to a sane state. So
>> what is a preferred way?
>
> If you really can't do other way, driver should keep additional state
> that is checked in ndo_fix_features callback.
>
ndo_fix_features callback is called just before calling
ndo_set_features callback. Also this is called during update_features,
so having the state maintained is not really going to help in this
scenario since that is not happening when device reaches ready state
(to remove this discrepancy in the feature-set).
There must be a reason (that you did not explain!) why driver code
should not alter wanted_feature set. So in this scenario, just leaving
the wanted_features as it is and clearing the features bit is correct
/ enough?
>>> BTW, similar problems (also like in previous versions) are in
>>> forcedeth implementation.
>> Yes, whatever we decide about the state of the wanted_features, I'll
>> implement similarly for forcedeth. Which previous problem you are
>> referring to? Is it the return value? There is a different kind of
>> failure (error while writing the register). Since update_features()
>> cant handle return value, I'm ignoring the return value. As far as the
>> correct return code is concerned, I wasn't sure what is appropriate
>> return code here (may be PHY_ERROR would be appropriate there) but
>> again I could ignore it just the way rest of the code is ignoring.
>
> Let's wait for this threads points to be resolved. You will probably
> change the forcedeth's implementation then anyway. :-)
>
agreed.
Thanks,
--mahesh..
> Best Regards,
> Michał Mirosław
>
^ permalink raw reply
* Re: [Bugme-new] [Bug 34322] New: No ECN marking in IPv6
From: Andrew Morton @ 2011-05-05 21:41 UTC (permalink / raw)
To: netdev; +Cc: bugzilla-daemon, bugme-daemon, sgunderson
In-Reply-To: <bug-34322-10286@https.bugzilla.kernel.org/>
(switched to email. Please respond via emailed reply-to-all, not via the
bugzilla web interface).
On Tue, 3 May 2011 20:05:00 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=34322
>
> Summary: No ECN marking in IPv6
> Product: Networking
> Version: 2.5
> Kernel Version: 2.6.38.4
> Platform: All
> OS/Version: Linux
> Tree: Mainline
> Status: NEW
> Severity: normal
> Priority: P1
> Component: IPV6
> AssignedTo: yoshfuji@linux-ipv6.org
> ReportedBy: sgunderson@bigfoot.com
> Regression: No
>
>
> Hi,
>
> I'm completely unable to get ECN to work for IPv6. /proc/sys/net/ipv4/tcp_ecn
> is set to 1 on both sides, and ECN works just fine for IPv4 TCP connections,
> but when I connect over IPv6 tclass just stays at 0x0, and as far as I'd
> understood, there should be two bits here set to 10 (like in the diffserv field
> of IPv4), right?
>
> I do get ECN-echo bits in the TCP header, though (for the initial SYN and
> SYN/ACK packets).
>
and
> I looked at the code, and although I don't understand all of it, it
> looks like e9df2e8fd8fbc95c57dbd1d33dada66c4627b44c (which also brought
> ECN for IPv6 SCTP) might be the culprit. It seems like TCP_ECN_send()
> calls INET_ECN_xmit(), which only sets the ECN bit in the IPv4 ToS
> field (inet_sk(sk)->tos), but after the patch, what's checked is
> inet6_sk(sk)->tclass, which is a completely different field.
>
> Is the analysis correct? Should the tclass be set as well?
and
> OK, as a quick hack, I did this:
>
> --- a/linux-2.6.38.5/include/net/inet_ecn.h 2011-04-14 22:03:56.000000000+0200
> +++ b/linux-2.6.38.5/include/net/inet_ecn.h 2011-05-04 00:36:52.803377902+0200
> @@ -38,7 +38,7 @@
> return outer;
> }
>
> -#define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0)
> +#define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; if (inet6_sk(sk) != NULL) inet6_sk(sk)->tclass |= INET_ECN_ECT_0; } while (0)
> #define INET_ECN_dontxmit(sk) \
> do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0)
>
> and now my packets are properly marked with tclass 0x02 (ie.,
> signalling ECN-capable transport, no congestion experienced yet).
>
> I guess this isn't the right way of doing it, but at least it confirms
> that the lack of setting tclass is part of the problem.
^ permalink raw reply
* Re: [PATCH 0/2] wireless: Make and use const struct ieee80211_channel
From: Joe Perches @ 2011-05-05 22:21 UTC (permalink / raw)
To: John W. Linville
Cc: libertas-dev, linux-wireless, orinoco-users, orinoco-devel,
netdev, LKML
In-Reply-To: <20110505184934.GB3005@tuxdriver.com>
On Thu, 2011-05-05 at 14:49 -0400, John W. Linville wrote:
> These patches generated a lot of warnings in net/mac80211. Did you
> actually build them?
Yes.
Did you apply patch 1/2 first?
It's a dependent patch.
^ permalink raw reply
* Re: [PATCH V2 2/3] MIPS: lantiq: add ethernet driver
From: John Crispin @ 2011-05-05 22:16 UTC (permalink / raw)
To: David Miller; +Cc: ralf, ralph.hempel, linux-mips, netdev
In-Reply-To: <20110505.151049.35056363.davem@davemloft.net>
On 06/05/11 00:10, David Miller wrote:
> From: John Crispin <blogic@openwrt.org>
> Date: Fri, 6 May 2011 00:10:01 +0200
>
>
>> This patch adds the driver for the ETOP Packet Processing Engine (PPE32) found
>> inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit ethernet
>> work. Support for all 8 dma channels, gbit and the embedded switch found on
>> the ar9/vr9 still needs to be implemented.
>>
>> Signed-off-by: John Crispin <blogic@openwrt.org>
>> Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
>>
> No objections from me and this can go via the MIPS tree:
>
> Acked-by: David S. Miller <davem@davemloft.net>
>
>
Thank you !
^ permalink raw reply
* Re: [PATCH V2 2/3] MIPS: lantiq: add ethernet driver
From: David Miller @ 2011-05-05 22:10 UTC (permalink / raw)
To: blogic; +Cc: ralf, ralph.hempel, linux-mips, netdev
In-Reply-To: <1304633402-24161-3-git-send-email-blogic@openwrt.org>
From: John Crispin <blogic@openwrt.org>
Date: Fri, 6 May 2011 00:10:01 +0200
> This patch adds the driver for the ETOP Packet Processing Engine (PPE32) found
> inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit ethernet
> work. Support for all 8 dma channels, gbit and the embedded switch found on
> the ar9/vr9 still needs to be implemented.
>
> Signed-off-by: John Crispin <blogic@openwrt.org>
> Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
No objections from me and this can go via the MIPS tree:
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* [PATCH V2 2/3] MIPS: lantiq: add ethernet driver
From: John Crispin @ 2011-05-05 22:10 UTC (permalink / raw)
To: Ralf Baechle; +Cc: John Crispin, Ralph Hempel, linux-mips, netdev
In-Reply-To: <1304633402-24161-1-git-send-email-blogic@openwrt.org>
This patch adds the driver for the ETOP Packet Processing Engine (PPE32) found
inside the XWAY family of Lantiq MIPS SoCs. This driver makes 100MBit ethernet
work. Support for all 8 dma channels, gbit and the embedded switch found on
the ar9/vr9 still needs to be implemented.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Ralph Hempel <ralph.hempel@lantiq.com>
Cc: linux-mips@linux-mips.org
Cc: netdev@vger.kernel.org
---
Changes in V2:
* use spinlocks
* use NAPI
* remove duplicate stats counter
.../mips/include/asm/mach-lantiq/lantiq_platform.h | 7 +
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 4 +-
drivers/net/Kconfig | 7 +
drivers/net/Makefile | 1 +
drivers/net/lantiq_etop.c | 794 ++++++++++++++++++++
5 files changed, 811 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/lantiq_etop.c
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
index 1f1dba6..a305f1d 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
@@ -10,6 +10,7 @@
#define _LANTIQ_PLATFORM_H__
#include <linux/mtd/partitions.h>
+#include <linux/socket.h>
/* struct used to pass info to the pci core */
enum {
@@ -43,4 +44,10 @@ struct ltq_pci_data {
int irq[16];
};
+/* struct used to pass info to network drivers */
+struct ltq_eth_data {
+ struct sockaddr mac;
+ int mii_mode;
+};
+
#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index 95f1882..0213601 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -81,8 +81,8 @@
#define PMU_SWITCH 0x10000000
/* ETOP - ethernet */
-#define LTQ_PPE32_BASE_ADDR 0xBE180000
-#define LTQ_PPE32_SIZE 0x40000
+#define LTQ_ETOP_BASE_ADDR 0x1E180000
+#define LTQ_ETOP_SIZE 0x40000
/* DMA */
#define LTQ_DMA_BASE_ADDR 0x1E104100
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b30c688..4878587 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2017,6 +2017,13 @@ config FTMAC100
from Faraday. It is used on Faraday A320, Andes AG101 and some
other ARM/NDS32 SoC's.
+config LANTIQ_ETOP
+ tristate "Lantiq SoC ETOP driver"
+ depends on SOC_TYPE_XWAY
+ help
+ Support for the MII0 inside the Lantiq SoC
+
+
source "drivers/net/fs_enet/Kconfig"
source "drivers/net/octeon/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fbfca11..df71da7 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -261,6 +261,7 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/
obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_ETHOC) += ethoc.o
obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
diff --git a/drivers/net/lantiq_etop.c b/drivers/net/lantiq_etop.c
new file mode 100644
index 0000000..3c9d34f
--- /dev/null
+++ b/drivers/net/lantiq_etop.c
@@ -0,0 +1,794 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/phy.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/checksum.h>
+
+#include <lantiq_soc.h>
+#include <xway_dma.h>
+#include <lantiq_platform.h>
+
+#define LTQ_ETOP_MDIO 0x11804
+#define MDIO_REQUEST 0x80000000
+#define MDIO_READ 0x40000000
+#define MDIO_ADDR_MASK 0x1f
+#define MDIO_ADDR_OFFSET 0x15
+#define MDIO_REG_MASK 0x1f
+#define MDIO_REG_OFFSET 0x10
+#define MDIO_VAL_MASK 0xffff
+
+#define PPE32_CGEN 0x800
+#define LQ_PPE32_ENET_MAC_CFG 0x1840
+
+#define LTQ_ETOP_ENETS0 0x11850
+#define LTQ_ETOP_MAC_DA0 0x1186C
+#define LTQ_ETOP_MAC_DA1 0x11870
+#define LTQ_ETOP_CFG 0x16020
+#define LTQ_ETOP_IGPLEN 0x16080
+
+#define MAX_DMA_CHAN 0x8
+#define MAX_DMA_CRC_LEN 0x4
+#define MAX_DMA_DATA_LEN 0x600
+
+#define ETOP_FTCU BIT(28)
+#define ETOP_MII_MASK 0xf
+#define ETOP_MII_NORMAL 0xd
+#define ETOP_MII_REVERSE 0xe
+#define ETOP_PLEN_UNDER 0x40
+#define ETOP_CGEN 0x800
+
+/* use 2 static channels for TX/RX */
+#define LTQ_ETOP_TX_CHANNEL 1
+#define LTQ_ETOP_RX_CHANNEL 6
+#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
+#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
+
+#define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
+#define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
+#define ltq_etop_w32_mask(x, y, z) \
+ ltq_w32_mask(x, y, ltq_etop_membase + (z))
+
+#define DRV_VERSION "1.0"
+
+static void __iomem *ltq_etop_membase;
+
+struct ltq_etop_chan {
+ int idx;
+ int tx_free;
+ struct net_device *netdev;
+ struct napi_struct napi;
+ struct ltq_dma_channel dma;
+ struct sk_buff *skb[LTQ_DESC_NUM];
+};
+
+struct ltq_etop_priv {
+ struct net_device *netdev;
+ struct ltq_eth_data *pldata;
+ struct resource *res;
+
+ struct mii_bus *mii_bus;
+ struct phy_device *phydev;
+
+ struct ltq_etop_chan ch[MAX_DMA_CHAN];
+ int tx_free[MAX_DMA_CHAN >> 1];
+
+ spinlock_t lock;
+};
+
+static int
+ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
+{
+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
+ if (!ch->skb[ch->dma.desc])
+ return -ENOMEM;
+ ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
+ ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN, DMA_FROM_DEVICE);
+ ch->dma.desc_base[ch->dma.desc].addr =
+ CPHYSADDR(ch->skb[ch->dma.desc]->data);
+ ch->dma.desc_base[ch->dma.desc].ctl =
+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | MAX_DMA_DATA_LEN;
+ skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN);
+ return 0;
+}
+
+static void
+ltq_etop_hw_receive(struct ltq_etop_chan *ch)
+{
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+ struct sk_buff *skb = ch->skb[ch->dma.desc];
+ int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (ltq_etop_alloc_skb(ch)) {
+ netdev_err(ch->netdev,
+ "failed to allocate new rx buffer, stopping DMA\n");
+ ltq_dma_close(&ch->dma);
+ }
+ ch->dma.desc++;
+ ch->dma.desc %= LTQ_DESC_NUM;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ skb_put(skb, len);
+ skb->dev = ch->netdev;
+ skb->protocol = eth_type_trans(skb, ch->netdev);
+ netif_receive_skb(skb);
+}
+
+static int
+ltq_etop_poll_rx(struct napi_struct *napi, int budget)
+{
+ struct ltq_etop_chan *ch = container_of(napi, struct ltq_etop_chan, napi);
+ int rx = 0;
+ int complete = 0;
+
+ while ((rx < budget) && !complete) {
+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+ ltq_etop_hw_receive(ch);
+ rx++;
+ } else {
+ complete = 1;
+ }
+ }
+ if (complete || !rx) {
+ napi_complete(&ch->napi);
+ ltq_dma_ack_irq(&ch->dma);
+ }
+ return rx;
+}
+
+static int
+ltq_etop_poll_tx(struct napi_struct *napi, int budget)
+{
+ struct ltq_etop_chan *ch =
+ container_of(napi, struct ltq_etop_chan, napi);
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+ struct netdev_queue *txq =
+ netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ while ((ch->dma.desc_base[ch->tx_free].ctl &
+ (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+ dev_kfree_skb_any(ch->skb[ch->tx_free]);
+ ch->skb[ch->tx_free] = NULL;
+ memset(&ch->dma.desc_base[ch->tx_free], 0,
+ sizeof(struct ltq_dma_desc));
+ ch->tx_free++;
+ ch->tx_free %= LTQ_DESC_NUM;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (netif_tx_queue_stopped(txq))
+ netif_tx_start_queue(txq);
+ napi_complete(&ch->napi);
+ ltq_dma_ack_irq(&ch->dma);
+ return 1;
+}
+
+static irqreturn_t
+ltq_etop_dma_irq(int irq, void *_priv)
+{
+ struct ltq_etop_priv *priv = _priv;
+ int ch = irq - LTQ_DMA_CH0_INT;
+
+ napi_schedule(&priv->ch[ch].napi);
+ return IRQ_HANDLED;
+}
+
+static void
+ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ ltq_dma_free(&ch->dma);
+ if (ch->dma.irq)
+ free_irq(ch->dma.irq, priv);
+ if (IS_RX(ch->idx)) {
+ int desc;
+ for (desc = 0; desc < LTQ_DESC_NUM; desc++)
+ dev_kfree_skb_any(ch->skb[ch->dma.desc]);
+ }
+}
+
+static void
+ltq_etop_hw_exit(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int i;
+
+ ltq_pmu_disable(PMU_PPE);
+ for (i = 0; i < MAX_DMA_CHAN; i++)
+ if (IS_TX(i) || IS_RX(i))
+ ltq_etop_free_channel(dev, &priv->ch[i]);
+}
+
+static int
+ltq_etop_hw_init(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int i;
+
+ ltq_pmu_enable(PMU_PPE);
+
+ switch (priv->pldata->mii_mode) {
+ case PHY_INTERFACE_MODE_RMII:
+ ltq_etop_w32_mask(ETOP_MII_MASK,
+ ETOP_MII_REVERSE, LTQ_ETOP_CFG);
+ break;
+
+ case PHY_INTERFACE_MODE_MII:
+ ltq_etop_w32_mask(ETOP_MII_MASK,
+ ETOP_MII_NORMAL, LTQ_ETOP_CFG);
+ break;
+
+ default:
+ netdev_err(dev, "unknown mii mode %d\n",
+ priv->pldata->mii_mode);
+ return -ENOTSUPP;
+ }
+
+ /* enable crc generation */
+ ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
+
+ ltq_dma_init_port(DMA_PORT_ETOP);
+
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
+ int irq = LTQ_DMA_CH0_INT + i;
+ struct ltq_etop_chan *ch = &priv->ch[i];
+
+ ch->idx = ch->dma.nr = i;
+
+ if (IS_TX(i)) {
+ ltq_dma_alloc_tx(&ch->dma);
+ request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ "etop_tx", priv);
+ } else if (IS_RX(i)) {
+ ltq_dma_alloc_rx(&ch->dma);
+ for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
+ ch->dma.desc++)
+ if (ltq_etop_alloc_skb(ch))
+ return -ENOMEM;
+ ch->dma.desc = 0;
+ request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+ "etop_rx", priv);
+ }
+ ch->dma.irq = irq;
+ }
+ return 0;
+}
+
+static void
+ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, "Lantiq ETOP");
+ strcpy(info->bus_info, "internal");
+ strcpy(info->version, DRV_VERSION);
+}
+
+static int
+ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_nway_reset(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ return phy_start_aneg(priv->phydev);
+}
+
+static const struct ethtool_ops ltq_etop_ethtool_ops = {
+ .get_drvinfo = ltq_etop_get_drvinfo,
+ .get_settings = ltq_etop_get_settings,
+ .set_settings = ltq_etop_set_settings,
+ .nway_reset = ltq_etop_nway_reset,
+};
+
+static int
+ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_REQUEST |
+ ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+ ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
+ phy_data;
+
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+ ;
+ ltq_etop_w32(val, LTQ_ETOP_MDIO);
+ return 0;
+}
+
+static int
+ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+ u32 val = MDIO_REQUEST | MDIO_READ |
+ ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+ ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
+
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+ ;
+ ltq_etop_w32(val, LTQ_ETOP_MDIO);
+ while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+ ;
+ val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
+ return val;
+}
+
+static void
+ltq_etop_mdio_link(struct net_device *dev)
+{
+ /* nothing to do */
+}
+
+static int
+ltq_etop_mdio_probe(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ int phy_addr;
+
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ if (priv->mii_bus->phy_map[phy_addr]) {
+ phydev = priv->mii_bus->phy_map[phy_addr];
+ break;
+ }
+ }
+
+ if (!phydev) {
+ netdev_err(dev, "no PHY found\n");
+ return -ENODEV;
+ }
+
+ phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link,
+ 0, priv->pldata->mii_mode);
+
+ if (IS_ERR(phydev)) {
+ netdev_err(dev, "Could not attach to PHY\n");
+ return PTR_ERR(phydev);
+ }
+
+ phydev->supported &= (SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half
+ | SUPPORTED_100baseT_Full
+ | SUPPORTED_Autoneg
+ | SUPPORTED_MII
+ | SUPPORTED_TP);
+
+ phydev->advertising = phydev->supported;
+ priv->phydev = phydev;
+ pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
+ dev->name, phydev->drv->name,
+ dev_name(&phydev->dev), phydev->irq);
+
+ return 0;
+}
+
+static int
+ltq_etop_mdio_init(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int i;
+ int err;
+
+ priv->mii_bus = mdiobus_alloc();
+ if (!priv->mii_bus) {
+ netdev_err(dev, "failed to allocate mii bus\n");
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ priv->mii_bus->priv = dev;
+ priv->mii_bus->read = ltq_etop_mdio_rd;
+ priv->mii_bus->write = ltq_etop_mdio_wr;
+ priv->mii_bus->name = "ltq_mii";
+ snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
+ priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!priv->mii_bus->irq) {
+ err = -ENOMEM;
+ goto err_out_free_mdiobus;
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
+ priv->mii_bus->irq[i] = PHY_POLL;
+
+ if (mdiobus_register(priv->mii_bus)) {
+ err = -ENXIO;
+ goto err_out_free_mdio_irq;
+ }
+
+ if (ltq_etop_mdio_probe(dev)) {
+ err = -ENXIO;
+ goto err_out_unregister_bus;
+ }
+ return 0;
+
+err_out_unregister_bus:
+ mdiobus_unregister(priv->mii_bus);
+err_out_free_mdio_irq:
+ kfree(priv->mii_bus->irq);
+err_out_free_mdiobus:
+ mdiobus_free(priv->mii_bus);
+err_out:
+ return err;
+}
+
+static void
+ltq_etop_mdio_cleanup(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ phy_disconnect(priv->phydev);
+ mdiobus_unregister(priv->mii_bus);
+ kfree(priv->mii_bus->irq);
+ mdiobus_free(priv->mii_bus);
+}
+
+static int
+ltq_etop_open(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int i;
+
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
+ struct ltq_etop_chan *ch = &priv->ch[i];
+
+ if (!IS_TX(i) && (!IS_RX(i)))
+ continue;
+ ltq_dma_open(&ch->dma);
+ napi_enable(&ch->napi);
+ }
+ phy_start(priv->phydev);
+ netif_tx_start_all_queues(dev);
+ return 0;
+}
+
+static int
+ltq_etop_stop(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int i;
+
+ netif_tx_stop_all_queues(dev);
+ phy_stop(priv->phydev);
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
+ struct ltq_etop_chan *ch = &priv->ch[i];
+
+ if (!IS_RX(i) && !IS_TX(i))
+ continue;
+ napi_disable(&ch->napi);
+ ltq_dma_close(&ch->dma);
+ }
+ return 0;
+}
+
+static int
+ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ int queue = skb_get_queue_mapping(skb);
+ struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+ int len;
+ unsigned long flags;
+ u32 byte_offset;
+
+ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+ dev_kfree_skb_any(skb);
+ netdev_err(dev, "tx ring full\n");
+ netif_tx_stop_queue(txq);
+ return NETDEV_TX_BUSY;
+ }
+
+ /* dma needs to start on a 16 byte aligned address */
+ byte_offset = CPHYSADDR(skb->data) % 16;
+ ch->skb[ch->dma.desc] = skb;
+
+ dev->trans_start = jiffies;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
+ DMA_TO_DEVICE)) - byte_offset;
+ wmb();
+ desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
+ LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
+ ch->dma.desc++;
+ ch->dma.desc %= LTQ_DESC_NUM;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
+ netif_tx_stop_queue(txq);
+
+ return NETDEV_TX_OK;
+}
+
+static int
+ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
+{
+ int ret = eth_change_mtu(dev, new_mtu);
+
+ if (!ret) {
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
+ LTQ_ETOP_IGPLEN);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ return ret;
+}
+
+static int
+ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+
+ /* TODO: mii-toll reports "No MII transceiver present!." ?!*/
+ return phy_mii_ioctl(priv->phydev, rq, cmd);
+}
+
+static int
+ltq_etop_set_mac_address(struct net_device *dev, void *p)
+{
+ int ret = eth_mac_addr(dev, p);
+
+ if (!ret) {
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ /* store the mac for the unicast filter */
+ spin_lock_irqsave(&priv->lock, flags);
+ ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0);
+ ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16,
+ LTQ_ETOP_MAC_DA1);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ return ret;
+}
+
+static void
+ltq_etop_set_multicast_list(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ /* ensure that the unicast filter is not enabled in promiscious mode */
+ spin_lock_irqsave(&priv->lock, flags);
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
+ ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0);
+ else
+ ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static u16
+ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ /* we are currently only using the first queue */
+ return 0;
+}
+
+static int
+ltq_etop_init(struct net_device *dev)
+{
+ struct ltq_etop_priv *priv = netdev_priv(dev);
+ int err;
+
+ ether_setup(dev);
+ dev->watchdog_timeo = 10 * HZ;
+ err = ltq_etop_hw_init(dev);
+ if (err)
+ goto err_hw;
+ ltq_etop_change_mtu(dev, 1500);
+ err = ltq_etop_set_mac_address(dev, &priv->pldata->mac);
+ if (err)
+ goto err_netdev;
+ ltq_etop_set_multicast_list(dev);
+ err = ltq_etop_mdio_init(dev);
+ if (err)
+ goto err_netdev;
+ return 0;
+
+err_netdev:
+ unregister_netdev(dev);
+ free_netdev(dev);
+err_hw:
+ ltq_etop_hw_exit(dev);
+ return err;
+}
+
+static void
+ltq_etop_tx_timeout(struct net_device *dev)
+{
+ int err;
+
+ ltq_etop_hw_exit(dev);
+ err = ltq_etop_hw_init(dev);
+ if (err)
+ goto err_hw;
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+ return;
+
+err_hw:
+ ltq_etop_hw_exit(dev);
+ netdev_err(dev, "failed to restart etop after TX timeout\n");
+}
+
+static const struct net_device_ops ltq_eth_netdev_ops = {
+ .ndo_open = ltq_etop_open,
+ .ndo_stop = ltq_etop_stop,
+ .ndo_start_xmit = ltq_etop_tx,
+ .ndo_change_mtu = ltq_etop_change_mtu,
+ .ndo_do_ioctl = ltq_etop_ioctl,
+ .ndo_set_mac_address = ltq_etop_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = ltq_etop_set_multicast_list,
+ .ndo_select_queue = ltq_etop_select_queue,
+ .ndo_init = ltq_etop_init,
+ .ndo_tx_timeout = ltq_etop_tx_timeout,
+};
+
+static int __init
+ltq_etop_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct ltq_etop_priv *priv;
+ struct resource *res;
+ int err;
+ int i;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get etop resource\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+
+ res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), dev_name(&pdev->dev));
+ if (!res) {
+ dev_err(&pdev->dev, "failed to request etop resource\n");
+ err = -EBUSY;
+ goto err_out;
+ }
+
+ ltq_etop_membase = devm_ioremap_nocache(&pdev->dev,
+ res->start, resource_size(res));
+ if (!ltq_etop_membase) {
+ dev_err(&pdev->dev, "failed to remap etop engine %d\n",
+ pdev->id);
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
+ strcpy(dev->name, "eth%d");
+ dev->netdev_ops = <q_eth_netdev_ops;
+ dev->ethtool_ops = <q_etop_ethtool_ops;
+ priv = netdev_priv(dev);
+ priv->res = res;
+ priv->pldata = dev_get_platdata(&pdev->dev);
+ priv->netdev = dev;
+ spin_lock_init(&priv->lock);
+
+ for (i = 0; i < MAX_DMA_CHAN; i++) {
+ if (IS_TX(i))
+ netif_napi_add(dev, &priv->ch[i].napi,
+ ltq_etop_poll_tx, 8);
+ else if (IS_RX(i))
+ netif_napi_add(dev, &priv->ch[i].napi,
+ ltq_etop_poll_rx, 32);
+ priv->ch[i].netdev = dev;
+ }
+
+ err = register_netdev(dev);
+ if (err)
+ goto err_free;
+
+ platform_set_drvdata(pdev, dev);
+ return 0;
+
+err_free:
+ kfree(dev);
+err_out:
+ return err;
+}
+
+static int __devexit
+ltq_etop_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ if (dev) {
+ netif_tx_stop_all_queues(dev);
+ ltq_etop_hw_exit(dev);
+ ltq_etop_mdio_cleanup(dev);
+ unregister_netdev(dev);
+ }
+ return 0;
+}
+
+static struct platform_driver ltq_mii_driver = {
+ .remove = __devexit_p(ltq_etop_remove),
+ .driver = {
+ .name = "ltq_etop",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __init
+init_ltq_etop(void)
+{
+ int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe);
+
+ if (ret)
+ pr_err("ltq_etop: Error registering platfom driver!");
+ return ret;
+}
+
+static void __exit
+exit_ltq_etop(void)
+{
+ platform_driver_unregister(<q_mii_driver);
+}
+
+module_init(init_ltq_etop);
+module_exit(exit_ltq_etop);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq SoC ETOP");
+MODULE_LICENSE("GPL");
--
1.7.2.3
^ permalink raw reply related
* Re: [RFC v3 02/10] Revert "lsm: Remove the socket_post_accept() hook"
From: Tetsuo Handa @ 2011-05-05 21:43 UTC (permalink / raw)
To: paul.moore, sam
Cc: linux-security-module, linux-kernel, netdev, netfilter-devel,
hadi, kaber, zbr, root
In-Reply-To: <201105051011.32845.paul.moore@hp.com>
Paul Moore wrote:
> On Tuesday, May 03, 2011 10:28:24 PM Tetsuo Handa wrote:
> > Paul Moore wrote:
> > > On Tuesday, May 03, 2011 10:24:15 AM Samir Bellabes wrote:
> > > > snet needs to reintroduce this hook, as it was designed to be: a hook
> > > > for updating security informations on objects.
> > >
> > > Looking at this and 5/10 again, it seems that you should be able to do
> > > what you need with the sock_graft() hook. Am I missing something?
> > >
> > > My apologies if we've already discussed this approach previously ...
> >
> > Second problem is that genlmsg_unicast() might return -EAGAIN because we
> > can't sleep inside write_lock_bh()/write_unlock_bh().
>
> Ah yes, the real problem. I forgot that snet relied on a user space tool. I
> tend to agree with others who have suggested this is not the right approach,
> but I understand why you want the post_accept() hook; thanks for reminding me.
>
However, it sounds that Samir says genlmsg_unicast() failure is not fatal.
Samir Bellabes wrote:
> using snet_do_send_event() means that system is sending data to
> userspace. the system is not waiting for a verdict from userspace.
>
> If error occurs, we actually loose the information data.
> I may be able to write a solution which try to send the data again, but
> we need a exit solution for this loop (a number of try ?).
If genlmsg_unicast() failure is not fatal, snet doesn't need the
socket_post_accept hook. Samir, is genlmsg_unicast() failure fatal for snet?
(Although, I'd like to ask for revival of the hook for TOMOYO anyway.)
^ permalink raw reply
* Re: pull request: wireless-next-2.6 2011-05-05
From: David Miller @ 2011-05-05 21:12 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20110505191219.GC3005@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Thu, 5 May 2011 15:12:20 -0400
> Another big Cinco de Mayo batch of stuff intended for 2.6.40...
Aye caramba! :-)
> Highlights include a number of mwifiex bug fixes, a batch of wl12xx
> updates (including some new hardware support), a big batch of rtlwifi
> fixups in preparation for some new hardware drivers, some mwl8k and
> rt2x00 updates, the usual variety of iwlwifi and ath9k updates, a set
> of updates to the iwlegacy drivers from Stanislaw, some ssb udpates
> form Rafał, a bunch of Bluetooth updates from Gustavo and friends,
> and a handful of enhancements to other drivers and to mac80211.
>
> Please let me know if there are problems!
Pulled, thanks a lot John!
^ permalink raw reply
* Re: [PATCH V4 2/8] netdevice.h: Add a new zerocopy device flag
From: Shirley Ma @ 2011-05-05 21:02 UTC (permalink / raw)
To: Sridhar Samudrala
Cc: David Miller, mst, Eric Dumazet, Avi Kivity, Arnd Bergmann,
netdev, kvm, linux-kernel
In-Reply-To: <4DC1DD9D.6070708@us.ibm.com>
On Wed, 2011-05-04 at 16:13 -0700, Sridhar Samudrala wrote:
> On Wed, 2011-05-04 at 00:55 -0700, Shirley Ma wrote:
> > Signed-off-by: Shirley Ma <xma@us.ibm.com>
> > ---
> >
> > include/linux/netdevice.h | 10 ++++++++++
> > 1 files changed, 10 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> > index 0249fe7..0808f1e 100644
> > --- a/include/linux/netdevice.h
> > +++ b/include/linux/netdevice.h
> > @@ -1067,6 +1067,16 @@ struct net_device {
> > #define NETIF_F_RXHASH (1 << 28) /* Receive hashing offload */
> > #define NETIF_F_RXCSUM (1 << 29) /* Receive checksumming offload */
> >
> > +/*
> > + * Bit 31 is for device to map userspace buffers -- zerocopy
> > + * Device can set this flag when it supports HIGHDMA.
> > + * Device can't recycle this kind of skb buffers.
> > + * There are 256 bytes copied, the rest of buffers are mapped.
> > + * The userspace callback should only be called when last reference to this skb
> > + * is gone.
> > + */
> > +#define NETIF_F_ZEROCOPY (1 << 31)
> > +
> Should we make this TX_ZEROCOPY as we may need a seperate flag for
> RX_ZEROCOPY in future?
>
> Same with socket flag.
We might be able to use the same flag for both TX and RX. If RX
zero-copy requires only HIGHDMA feature only. If not, then we might need
different feature bit. Same for sock flag.
> Thanks
> Sridhar
>
>
^ permalink raw reply
* Re: [PATCH V4 5/8]macvtap: macvtap TX zero-copy support
From: Shirley Ma @ 2011-05-05 20:59 UTC (permalink / raw)
To: Sridhar Samudrala
Cc: David Miller, mst, Eric Dumazet, Avi Kivity, Arnd Bergmann,
netdev, kvm, linux-kernel
In-Reply-To: <4DC1DD83.2020801@us.ibm.com>
On Wed, 2011-05-04 at 16:13 -0700, Sridhar Samudrala wrote:
> On Wed, 2011-05-04 at 01:14 -0700, Shirley Ma wrote:
> > Only when buffer size is greater than GOODCOPY_LEN (256), macvtap
> > enables zero-copy.
> >
> > Signed-off-by: Shirley Ma <xma@us.ibm.com>
> > ---
> >
> > drivers/net/macvtap.c | 126 ++++++++++++++++++++++++++++++++++++++++++++----
> > 1 files changed, 115 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> > index 6696e56..e8bc5ff 100644
> > --- a/drivers/net/macvtap.c
> > +++ b/drivers/net/macvtap.c
> > @@ -60,6 +60,7 @@ static struct proto macvtap_proto = {
> > */
> > static dev_t macvtap_major;
> > #define MACVTAP_NUM_DEVS 65536
> > +#define GOODCOPY_LEN 256
> > static struct class *macvtap_class;
> > static struct cdev macvtap_cdev;
> >
> > @@ -340,6 +341,7 @@ static int macvtap_open(struct inode *inode, struct file *file)
> > {
> > struct net *net = current->nsproxy->net_ns;
> > struct net_device *dev = dev_get_by_index(net, iminor(inode));
> > + struct macvlan_dev *vlan = netdev_priv(dev);
> > struct macvtap_queue *q;
> > int err;
> >
> > @@ -369,6 +371,16 @@ static int macvtap_open(struct inode *inode, struct file *file)
> > q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
> > q->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
> >
> > + /*
> > + * so far only VM uses macvtap, enable zero copy between guest
> > + * kernel and host kernel when lower device supports high memory
> > + * DMA
> > + */
> Instead of VM uses macvtap, it makes it more clear to say 'KVM virtio
> uses macvtap for guest networking'.
> Also you are checking if lower device allows zerocopy, not high dma.
Sure.
>
> > + if (vlan) {
> > + if (vlan->lowerdev->features & NETIF_F_ZEROCOPY)
> > + sock_set_flag(&q->sk, SOCK_ZEROCOPY);
> > + }
> > +
>
> Do we need to check for vlan? If required, both if conditions can be
> combined.
Yes, I will run more test before enabling it.
> > err = macvtap_set_queue(dev, file, q);
> > if (err)
> > sock_put(&q->sk);
> > @@ -433,6 +445,80 @@ static inline struct sk_buff *macvtap_alloc_skb(struct sock *sk, size_t prepad,
> > return skb;
> > }
> >
> > +/* set skb frags from iovec, this can move to core network code for reuse */
> > +static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from,
> > + int offset, size_t count)
> > +{
> > + int len = iov_length(from, count) - offset;
> > + int copy = skb_headlen(skb);
> > + int size, offset1 = 0;
> > + int i = 0;
> > + skb_frag_t *f;
> > +
> > + /* Skip over from offset */
> > + while (offset >= from->iov_len) {
> > + offset -= from->iov_len;
> > + ++from;
> > + --count;
> > + }
> > +
> > + /* copy up to skb headlen */
> > + while (copy > 0) {
> > + size = min_t(unsigned int, copy, from->iov_len - offset);
> > + if (copy_from_user(skb->data + offset1, from->iov_base + offset,
> > + size))
> > + return -EFAULT;
> > + if (copy > size) {
> > + ++from;
> > + --count;
> > + }
> > + copy -= size;
> > + offset1 += size;
> > + offset = 0;
> > + }
>
> I think you need to check for count reaching zero in the above 2 while
> loops.
Doesn't hurt to check count here, in this case, caller has
copylen/len/offset less than count/len already.
> > +
> > + if (len == offset1)
> > + return 0;
> > +
> > + while (count--) {
> > + struct page *page[MAX_SKB_FRAGS];
> > + int num_pages;
> > + unsigned long base;
> > +
> > + len = from->iov_len - offset1;
> > + if (!len) {
> > + offset1 = 0;
> > + ++from;
> > + continue;
> > + }
> > + base = (unsigned long)from->iov_base + offset1;
> > + size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
> > + num_pages = get_user_pages_fast(base, size, 0, &page[i]);
> > + if ((num_pages != size) ||
> > + (num_pages > MAX_SKB_FRAGS - skb_shinfo(skb)->nr_frags))
> > + /* put_page is in skb free */
> > + return -EFAULT;
> > + skb->data_len += len;
> > + skb->len += len;
> > + skb->truesize += len;
> > + while (len) {
> > + f = &skb_shinfo(skb)->frags[i];
> > + f->page = page[i];
> > + f->page_offset = base & ~PAGE_MASK;
> > + f->size = min_t(int, len, PAGE_SIZE - f->page_offset);
> > + skb_shinfo(skb)->nr_frags++;
> > + /* increase sk_wmem_alloc */
> > + atomic_add(f->size, &skb->sk->sk_wmem_alloc);
> > + base += f->size;
> > + len -= f->size;
> > + i++;
> > + }
> > + offset1 = 0;
> > + ++from;
> > + }
> > + return 0;
> > +}
> > +
> > /*
> > * macvtap_skb_from_vnet_hdr and macvtap_skb_to_vnet_hdr should
> > * be shared with the tun/tap driver.
> > @@ -515,17 +601,19 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
> >
> >
> > /* Get packet from user space buffer */
> > -static ssize_t macvtap_get_user(struct macvtap_queue *q,
> > - const struct iovec *iv, size_t count,
> > - int noblock)
> > +static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> > + const struct iovec *iv, unsigned long total_len,
> > + size_t count, int noblock)
> > {
> > struct sk_buff *skb;
> > struct macvlan_dev *vlan;
> > - size_t len = count;
> > + unsigned long len = total_len;
> > int err;
> > struct virtio_net_hdr vnet_hdr = { 0 };
> > int vnet_hdr_len = 0;
> > + int copylen, zerocopy;
> zerocopy can be boolean
Yes, I have changed it in V5.
> > + zerocopy = sock_flag(&q->sk, SOCK_ZEROCOPY) && (len > GOODCOPY_LEN);
> > if (q->flags & IFF_VNET_HDR) {
> > vnet_hdr_len = q->vnet_hdr_sz;
> >
> > @@ -552,12 +640,28 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
> > if (unlikely(len < ETH_HLEN))
> > goto err;
> >
> > - skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len,
> > - noblock, &err);
> > + if (zerocopy)
> > + /* There are 256 bytes to be copied in skb, so there is enough
> > + * room for skb expand head in case it is used.
> > + * The rest buffer is mapped from userspace.
> > + */
> > + copylen = GOODCOPY_LEN;
> > + else
> > + copylen = len;
> > +
> > + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen,
> > + vnet_hdr.hdr_len, noblock, &err);
> > if (!skb)
> > goto err;
> >
> > - err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, len);
> > + if (zerocopy)
> > + err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
> > + else
> > + err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
> > + len);
> > + if (sock_flag(&q->sk, SOCK_ZEROCOPY))
> > + memcpy(&skb_shinfo(skb)->ubuf, m->msg_control,
> > + sizeof(struct skb_ubuf_info));
> Why are you doing a separate check for this memcpy? Is this required
> if the len < 256?
Yes. But I have changed it V5 based on MST's suggestion to leave copied
buffer maintain in vhost.
> > if (err)
> > goto err_kfree;
> >
> > @@ -579,7 +683,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
> > kfree_skb(skb);
> > rcu_read_unlock_bh();
> >
> > - return count;
> > + return total_len;
> >
> > err_kfree:
> > kfree_skb(skb);
> > @@ -601,8 +705,8 @@ static ssize_t macvtap_aio_write(struct kiocb *iocb, const struct iovec *iv,
> > ssize_t result = -ENOLINK;
> > struct macvtap_queue *q = file->private_data;
> >
> > - result = macvtap_get_user(q, iv, iov_length(iv, count),
> > - file->f_flags & O_NONBLOCK);
> > + result = macvtap_get_user(q, NULL, iv, iov_length(iv, count), count,
> > + file->f_flags & O_NONBLOCK);
> > return result;
> > }
> >
> > @@ -815,7 +919,7 @@ static int macvtap_sendmsg(struct kiocb *iocb, struct socket *sock,
> > struct msghdr *m, size_t total_len)
> > {
> > struct macvtap_queue *q = container_of(sock, struct macvtap_queue, sock);
> > - return macvtap_get_user(q, m->msg_iov, total_len,
> > + return macvtap_get_user(q, m, m->msg_iov, total_len, m->msg_iovlen,
> > m->msg_flags & MSG_DONTWAIT);
> > }
> >
> >
> >
>
^ permalink raw reply
* Re: ARM, AF_PACKET: caching problems on Marvell Kirkwood
From: Andrew Lunn @ 2011-05-05 19:46 UTC (permalink / raw)
To: linux-arm-kernel, netdev, ne, Johann Baudy, Lennert Buytenhek,
Nicolas Pitre
In-Reply-To: <20110505141107.GC30443@orbit.nwl.cc>
On Thu, May 05, 2011 at 04:11:07PM +0200, Phil Sutter wrote:
> Hi,
>
> Hasn't anyone experienced this bug but me? Can anyone reproduce the
> described behaviour on his Kirkwood-based (or even generic ARM) machine?
> I am still not sure if this is a problem of just my CPU or common
> amongst Kirkwood/VIPT/ARM machines.
Hi Phil
I can reproduce it on a Kirkwood:
[ 0.000000] CPU: Feroceon 88FR131 [56251311] revision 1 (ARMv5TE), cr=00053977
Andrew
^ permalink raw reply
* pull request: wireless-next-2.6 2011-05-05
From: John W. Linville @ 2011-05-05 19:12 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
Dave,
Another big Cinco de Mayo batch of stuff intended for 2.6.40...
Highlights include a number of mwifiex bug fixes, a batch of wl12xx
updates (including some new hardware support), a big batch of rtlwifi
fixups in preparation for some new hardware drivers, some mwl8k and
rt2x00 updates, the usual variety of iwlwifi and ath9k updates, a set
of updates to the iwlegacy drivers from Stanislaw, some ssb udpates
form Rafał, a bunch of Bluetooth updates from Gustavo and friends,
and a handful of enhancements to other drivers and to mac80211.
Please let me know if there are problems!
John
---
The following changes since commit 5a412ad7f4c95bb5b756aa12b52646e857e7c75d:
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6 (2011-05-04 13:54:50 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git for-davem
Adrian Chadd (1):
ath9k: fix AR9160 xpaBiasLvlFreq endianness handling
Amitkumar Karwar (4):
cfg80211: module_param to disable HT40 in 2.4GHz band
mwifiex: check firmware capabilities while initialising 5GHz band parameters
mwifiex: HT capability information handling
mwifiex: fix bug in mwifiex_save_curr_bcn()
Arik Nemtsov (5):
wl12xx: 1281/1283 support - Use different FW file for AP mode wl127x/wl128x chips
wl12xx: Clamp byte mode transfers for 128x chips
wl12xx: configure channel/band while FW is off
mac80211: allow low level drivers to report packet loss
wl12xx: support FW TX inactivity triggers
Bing Zhao (1):
mwifiex: fix missing tsf_val TLV
Chaoming_Li (17):
rtlwifi: Change efuse routines addition of RTL8192SE and RTL8192DE
rtlwifi: Change wifi.h for rtl8192se and rtl8192de
rtlwifi: Change base routines for addition of rtl8192se and rtl8192de
rtlwifi: Change cam routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert core routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert pci routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert ps routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert rc routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert regulatory domain routines for addition of rtl8192se and rtl8192de
rtlwifi: Convert usb routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192c-common: Convert common dynamic management routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192c-common: Change common firmware routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192c-common: Change common PHY routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192ce: Change hw routine for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192ce: Change sw and LED routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192ce: Change phy and rc routines for addition of rtl8192se and rtl8192de
rtlwifi: rtl8192ce: Change rtl8192ce routines phy and trx and modify rtl8192cu for addition of rtl8192se and rtl8192de
Christian Lamparter (4):
p54: implement multicast filter
carl9170: improve unicast PS buffering
mac80211: fix too early reorder release timer
mac80211: consolidate MIC failure report handling
Don Fry (2):
iwlagn: mod param cleanup
iwlagn: semaphore and calib cleanup
Eliad Peller (2):
wl12xx: set the actual tid instead of the ac
wl12xx: rearrange some ELP wake_up/sleep calls
Gertjan van Wingerde (2):
rt2x00: Streamline rt2800 eeprom initialisations.
rt2x00: Introduce capability flag for Bluetooth co-existence.
Gustavo F. Padovan (11):
Merge master.kernel.org:/.../padovan/bluetooth-2.6
Bluetooth: Refactor L2CAP channel allocation
Bluetooth: Move conf_state to struct l2cap_chan
Bluetooth: Rename l2cap_do_connect() to l2cap_chan_connect()
Bluetooth: Move some more elements to struct l2cap_chan
Bluetooth: Move more vars to struct l2cap_chan
Bluetooth: Move more channel info to struct l2cap_chan
Bluetooth: Move more vars to struct l2cap_chan
Bluetooth: Move conn to struct l2cap_chan
Bluetooth: Fix memory leak with L2CAP channels
Bluetooth: Don't export l2cap_sock_ops
Ido Yariv (5):
wl12xx: Clean up and fix the 128x boot sequence
wl12xx: Clean up the block size alignment code
wl12xx: Clean up the dummy packet mechanism
wl12xx: Simplify TX blocks accounting
wl12xx: Handle platforms without level trigger interrupts
Ivo van Doorn (4):
rt2x00: Reduce tx status reading timeout
rt2x00: Optimize TX_STA_FIFO register reading
rt2x00: Fix optimize register access for rt2800pci
rt2x00: Add autowake support for USB hardware
Johan Hedberg (14):
Bluetooth: Add basic discovery commands to the management interface
Bluetooth: Add discovering event to the Management interface
Bluetooth: Add automated SSP user confirmation responses
Bluetooth: Add variable SSP auto-accept delay support
Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests
Bluetooth: Add confirm_hint parameter to user confirmation requests
Bluetooth: Fix reason code for pairing rejection
Bluetooth: Fix logic in hci_pin_code_request_evt
Bluetooth: Fix link key persistent storage criteria
Bluetooth: Fix old_key_type logic for non-persistent keys
Bluetooth: Fix connection key type updating for buggy controllers
Bluetooth: Remove old_key_type from mgmt_ev_new_key
Bluetooth: Add store_hint parameter to mgmt_new_key
Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
Johannes Berg (18):
iwlagn: simplify error table reading
iwlagn: clean up some exit code
iwlagn: refactor down path
iwlagn: refactor up path
iwlagn: extend notification wait function
iwlagn: make iwlagn_wait_notification return error code
iwlagn: leave notification waits on firmware errors
iwlagn: implement synchronous firmware load
iwlagn: combine firmware code/data
iwlagn: remove hw_ready variable
mac80211: tear down BA sessions properly on suspend
iwlagn: avoid hangs when restarting device
iwlagn: introduce silent grabbing of NIC access
iwlagn: refactor restart
iwlagn: use proper good CRC threshold behaviour
iwlagn: remove spectrum measurement header
iwlagn: improve RXON checking
iwlagn: prefer BSS context
John W. Linville (10):
Merge branch 'for-linville' of git://git.kernel.org/.../luca/wl12xx
Merge branch 'wireless-next-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
mwl8k: replace rateinfo bitfields with mask and shift macros
ath5k: fix uninitialized var warning for txf2txs
b43: avoid uninitialized variable warnings in phy_n
mwifiex: fix copy-n-paste 'thinko' for tsf_val
p54: avoid uninitialized variable warning for freq
Merge branch 'master' of git://git.kernel.org/.../padovan/bluetooth-next-2.6
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6 into for-davem
Juuso Oikarinen (3):
wl12xx: Fix potential incorrect band in rx-status
wl12xx: Add mutex protection for interface list
wl12xx: Handle duplicate calling of remove interface
Larry Finger (2):
rtlwifi: rtl8192ce: rtl8192cu: Fix most sparse warnings
rtlwifi: Fix typo in pci.c
Luciano Coelho (11):
wl12xx: add new board_tcxo_clock element to the platform data
wl12xx: 1281/1283 support - add block size handling for sdio and spi
wl12xx: use 1 spare TX block instead of two
wl12xx: set the skbuff priority for dummy packets
wl12xx: fix SG BT load value to reflect its new meaning
wl12xx: fix a couple of sparse warnings about undeclared functions
wl12xx: use a bitmask instead of list of booleans in scanned_ch
wl12xx: use kstrtoul functions
wl12xx: move hardcoded hci_io_ds value into the conf struct
wl12xx: remove unused conf_radio_params structure
wl12xx: fix sparse warning about undeclared wl12xx_alloc_dummy_packet
Luis R. Rodriguez (1):
cfg80211: fix regresion on reg user timeout
Mohammed Shafi Shajakhan (3):
ath9k: remove the unlikely check for autosleep
ath9k: Add TSFOOR interrupt stats in debug info
mac80211: Fix a warning due to skipping tailroom reservation for IV
Nishant Sarmukadam (2):
mwl8k: Reserve buffers for tx management frames
mwl8k: Enable life time expiry for tx packets in the hardware
Ohad Ben-Cohen (3):
wl12xx: update bet_max_consecutive
wl12xx: fix roaming
wl12xx: fix "JOIN while associated" commentary
Pradeep Nemavat (2):
mwl8k: Do not stop tx queues
mwl8k: Add timestamp information for tx packets
Rafał Miłecki (10):
ssb: pci: trivial: correct amount of maximum retries
ssb: cc: use correct min_msk for 0x4312
ssb: cc: add & fix defines
ssb: cc: clear GPIOPULL registers on init
ssb: mark bus as powered up earlier
ssb: update reject bit for Target State Low
ssb: pci: separate workarounds
ssb: pci: update PCIe workarounds
ssb: pci: early fix for SPROM core index
ssb: cc: prepare clockmode support for cores rev 10+
Rajkumar Manoharan (3):
ath9k_hw: Fix Tx IQ Calibration hang issue in AR9003 chips
ath9k: set beacon related ps flags on bss_info change
mac80211: Fix warnings due to -Wunused-but-set-variable
Randy Dunlap (1):
libertas: use kernel-doc notation, fix comment style
Senthil Balasubramanian (5):
ath9k: Fix LED gpio for AR93xx chipsets.
ath9k_hw: Fix incorrect baseband PLL phase shift for AR9485
ath9k: optimize the usage of power save wrappers.
ath9k: cleanup hw pll work handler
ath9k: Add power save wrappers and modularize hw_pll handler
Shahar Levi (11):
wl12xx: 1281/1283 support - move IRQ polarity
wl12xx: 1281/1283 support - Add Definitions
wl12xx: 1281/1283 support - Add acx commands
wl12xx: 1281/1283 support - New radio structs and functions
wl12xx: 1281/1283 support - Loading FW & NVS
wl12xx: 1281/1283 support - New boot sequence
wl12xx: 1281/1283 support - use dynamic memory for the RX/TX pools
wl12xx: 1281/1283 support - Improve Tx & Rx path
wl12xx: 1281/1283 support - Add dummy packet support
wl12xx: 1281/1283 support - enable chip support
wl12xx: Add support for 11n Rx STBC one spatial stream
Stanislaw Gruszka (12):
iwlwifi: fix possible data overwrite in hcmd callback
iwlagn: fix tx power initialization
iwlegacy: remove duplicate initialization in iwl4956_down()
iwlegacy: enable only rfkill interrupt when device is down
iwlegacy: simplify init geos
iwlegacy: remove unneeded disable_hw_scan check
iwlegacy: remove unneeded __packed
iwlegacy: remove scan_tx_antennas
iwlegacy: comment typo fix diable -> disable
iwlegacy: fix enqueue hcmd race conditions
iwlegacy: more priv->mutex serialization
iwlegacy: remove sync_cmd_mutex
Sujith Manoharan (13):
ath9k: Fix warnings from -Wunused-but-set-variable
ath9k_htc: Fix AMPDU subframe handling
ath9k_htc: Fix max A-MPDU size handling
ath9k_htc: Use power save wrappers when accessing HW
ath9k_htc: Remove unused macros and structures
mac80211: Add new API for rate selection
ath9k_htc: Increase credit size for AR7010 devices
ath9k_htc: Remove unused WMI_AGGR_LIMIT_CMD
ath9k_htc: Add a new WMI command to set a rate mask
ath9k_htc: Add set_bitrate_mask() callback
ath9k_htc: Dump base eeprom header for UB91/94/95
ath9k_htc: Dump modal eeprom header for UB91/94/95
ath9k_htc: Revamp LED management
Vasanthakumar Thiagarajan (24):
ath9k_hw: Define devid and mac version for AR9340
ath9k_hw: Take care of few host interface register changes for AR9340
ath9k_hw: Get AHB clock information from ath9k_platform_data
ath9k_hw: Configure pll control register accordingly for AR9340
ath9k_hw: Add initvals.h for ar9340
ath9k_hw: Initialize mode registers from initvals.h for AR9340
ath9k_hw: Don't do ani initialization for AR9340
ath9k_hw: Initialize tx and rx gain table from initvals.h for ar9340
ath9k_hw: Read spur frequency information from eeprom for AR9340
ath9k_hw: Configure RF channel freqency for AR9340
ath9k_hw: Clean up rx/tx chain configuration before AGC/IQ cal
ath9k_hw: Fix register offset AR_PHY_65NM_CH0_THERM for AR9340
ath9k_hw: Don't configure AR_CH0_THERM for AR9340
ath9k_hw: Skip internal regulator configuration for AR9340
ath9k_hw: Configure tuning capacitance value for AR9340 as well
ath9k_hw: Enable byte Tx/Rx data swap for AR9340
ath9k_hw: Configure chain switch table and attenuation control only for active chains
ath9k_hw: Read iq calibration data only for active chains
ath9k: Add AR9340 platform id to id table
ath9k_hw: Assign macversion based on devid for built-in wmac
ath9k_hw: Disable INTR_HOST1_FATAL to avoid interrupt strom with ar9430
ath9k_hw: Enable AR9340 support
ath9k: Fix bug in configuring hw timer
ath9k: Fix warning: symbol 'ath9k_platform_id_table' was not declared. Should it be static?
Vivek Natarajan (4):
ath9k_hw: Move bt_stomp to hw from common.
ath9k_hw: Add support for btcoexistence in AR9300.
ath9k_hw: Enable generic timer interrupt.
ath9k: Use ps wrappers for btcoex logic.
Waldemar Rymarkiewicz (6):
Bluetooth: Add definitions for link key types
Bluetooth: Don't modify sec_level if auth failed
Bluetooth: Map sec_level to link key requirements
Bluetooth: Ignore key unauthenticated for high security
Bluetooth: Respect local MITM req in io_cap reply
Bluetooth: Add secure flag for mgmt_pin_code_req
Wey-Yi Guy (5):
iwlagn: make rxon_assoc static function
iwlagn: remove 5000 from rxon_assoc structure
iwlagn: connect and disconnect sequence for RXON
iwlagn: new 105 series device
iwlagn: remove un-necessary debugfs callback
Yogesh Ashok Powar (2):
mac80211: Skip tailroom reservation for full HW-crypto devices
mwl8k: Reducing extra_tx_headroom for tx optimization in AP mode
drivers/net/wireless/ath/ath5k/reset.c | 5 +
drivers/net/wireless/ath/ath9k/ahb.c | 6 +-
drivers/net/wireless/ath/ath9k/ani.c | 6 -
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 387 ++---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 61 +-
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 101 ++-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 36 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.h | 25 +-
drivers/net/wireless/ath/ath9k/ar9340_initvals.h | 1525 ++++++++++++++++++++
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +
drivers/net/wireless/ath/ath9k/beacon.c | 6 -
drivers/net/wireless/ath/ath9k/btcoex.c | 100 ++-
drivers/net/wireless/ath/ath9k/btcoex.h | 20 +-
drivers/net/wireless/ath/ath9k/common.c | 31 -
drivers/net/wireless/ath/ath9k/common.h | 8 -
drivers/net/wireless/ath/ath9k/debug.c | 5 +
drivers/net/wireless/ath/ath9k/debug.h | 4 +
drivers/net/wireless/ath/ath9k/eeprom_9287.c | 3 +-
drivers/net/wireless/ath/ath9k/eeprom_def.c | 4 +
drivers/net/wireless/ath/ath9k/gpio.c | 19 +-
drivers/net/wireless/ath/ath9k/hif_usb.h | 3 +
drivers/net/wireless/ath/ath9k/htc.h | 89 +-
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 6 +-
drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 477 ++++++-
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 204 +---
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 41 +-
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 95 ++-
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 -
drivers/net/wireless/ath/ath9k/htc_hst.h | 11 -
drivers/net/wireless/ath/ath9k/hw.c | 125 ++-
drivers/net/wireless/ath/ath9k/hw.h | 13 +-
drivers/net/wireless/ath/ath9k/init.c | 2 +
drivers/net/wireless/ath/ath9k/mac.c | 13 +-
drivers/net/wireless/ath/ath9k/main.c | 49 +-
drivers/net/wireless/ath/ath9k/phy.h | 3 +
drivers/net/wireless/ath/ath9k/rc.c | 12 +-
drivers/net/wireless/ath/ath9k/recv.c | 5 +-
drivers/net/wireless/ath/ath9k/reg.h | 99 +-
drivers/net/wireless/ath/ath9k/wmi.c | 4 +-
drivers/net/wireless/ath/ath9k/wmi.h | 2 +-
drivers/net/wireless/ath/ath9k/xmit.c | 23 -
drivers/net/wireless/ath/carl9170/carl9170.h | 2 +
drivers/net/wireless/ath/carl9170/main.c | 92 +--
drivers/net/wireless/ath/carl9170/tx.c | 157 ++-
drivers/net/wireless/b43/phy_n.c | 7 +-
drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 3 -
drivers/net/wireless/iwlegacy/iwl-core.c | 20 +-
drivers/net/wireless/iwlegacy/iwl-core.h | 1 -
drivers/net/wireless/iwlegacy/iwl-dev.h | 4 +-
drivers/net/wireless/iwlegacy/iwl-hcmd.c | 4 +-
drivers/net/wireless/iwlegacy/iwl-helpers.h | 6 +
drivers/net/wireless/iwlegacy/iwl-tx.c | 52 +-
drivers/net/wireless/iwlegacy/iwl3945-base.c | 22 +-
drivers/net/wireless/iwlegacy/iwl4965-base.c | 45 +-
drivers/net/wireless/iwlwifi/Makefile | 1 -
drivers/net/wireless/iwlwifi/iwl-1000.c | 19 +-
drivers/net/wireless/iwlwifi/iwl-2000.c | 79 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 36 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 37 +-
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 1025 -------------
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h | 70 -
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 41 +-
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 50 -
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 124 ++-
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 259 +++--
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 245 +++-
drivers/net/wireless/iwlwifi/iwl-agn.c | 545 +++-----
drivers/net/wireless/iwlwifi/iwl-agn.h | 45 +-
drivers/net/wireless/iwlwifi/iwl-commands.h | 105 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 87 +-
drivers/net/wireless/iwlwifi/iwl-core.h | 23 +-
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 1012 +++++++++++++-
drivers/net/wireless/iwlwifi/iwl-dev.h | 35 +-
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 50 +-
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 3 -
drivers/net/wireless/iwlwifi/iwl-helpers.h | 24 -
drivers/net/wireless/iwlwifi/iwl-io.c | 36 +-
drivers/net/wireless/iwlwifi/iwl-io.h | 11 +
drivers/net/wireless/iwlwifi/iwl-rx.c | 57 +-
drivers/net/wireless/iwlwifi/iwl-spectrum.h | 92 --
drivers/net/wireless/iwlwifi/iwl-tx.c | 15 +-
drivers/net/wireless/libertas/cfg.c | 45 +-
drivers/net/wireless/libertas/cmd.c | 245 ++--
drivers/net/wireless/libertas/cmdresp.c | 19 +-
drivers/net/wireless/libertas/debugfs.c | 36 +-
drivers/net/wireless/libertas/decl.h | 8 +-
drivers/net/wireless/libertas/defs.h | 113 +-
drivers/net/wireless/libertas/dev.h | 20 +-
drivers/net/wireless/libertas/ethtool.c | 3 +-
drivers/net/wireless/libertas/host.h | 33 +-
drivers/net/wireless/libertas/if_cs.c | 35 +-
drivers/net/wireless/libertas/if_spi.c | 134 ++-
drivers/net/wireless/libertas/if_spi.h | 68 +-
drivers/net/wireless/libertas/if_usb.c | 113 +-
drivers/net/wireless/libertas/if_usb.h | 14 +-
drivers/net/wireless/libertas/main.c | 99 +-
drivers/net/wireless/libertas/mesh.c | 210 ++-
drivers/net/wireless/libertas/mesh.h | 6 +-
drivers/net/wireless/libertas/rx.c | 34 +-
drivers/net/wireless/libertas/tx.c | 34 +-
drivers/net/wireless/libertas/types.h | 18 +-
drivers/net/wireless/mwifiex/11n.c | 102 +-
drivers/net/wireless/mwifiex/11n.h | 2 +-
drivers/net/wireless/mwifiex/cfg80211.c | 61 +-
drivers/net/wireless/mwifiex/join.c | 4 +-
drivers/net/wireless/mwifiex/main.h | 2 +-
drivers/net/wireless/mwifiex/scan.c | 32 +-
drivers/net/wireless/mwl8k.c | 111 +-
drivers/net/wireless/p54/eeprom.c | 2 +-
drivers/net/wireless/p54/fwio.c | 31 +
drivers/net/wireless/p54/lmac.h | 1 +
drivers/net/wireless/p54/main.c | 31 +
drivers/net/wireless/p54/p54.h | 2 +
drivers/net/wireless/rt2x00/rt2500usb.c | 1 +
drivers/net/wireless/rt2x00/rt2800lib.c | 31 +-
drivers/net/wireless/rt2x00/rt2800pci.c | 4 +-
drivers/net/wireless/rt2x00/rt2800usb.c | 14 +-
drivers/net/wireless/rt2x00/rt2x00.h | 18 +
drivers/net/wireless/rt2x00/rt2x00config.c | 31 +
drivers/net/wireless/rt2x00/rt2x00dev.c | 88 ++
drivers/net/wireless/rt2x00/rt2x00usb.c | 11 +-
drivers/net/wireless/rt2x00/rt2x00usb.h | 4 +-
drivers/net/wireless/rt2x00/rt73usb.c | 1 +
drivers/net/wireless/rtlwifi/base.c | 720 ++++++++--
drivers/net/wireless/rtlwifi/base.h | 60 +-
drivers/net/wireless/rtlwifi/cam.c | 106 ++-
drivers/net/wireless/rtlwifi/cam.h | 5 +-
drivers/net/wireless/rtlwifi/core.c | 408 ++++--
drivers/net/wireless/rtlwifi/core.h | 1 +
drivers/net/wireless/rtlwifi/efuse.c | 97 +-
drivers/net/wireless/rtlwifi/efuse.h | 5 +-
drivers/net/wireless/rtlwifi/pci.c | 626 ++++++---
drivers/net/wireless/rtlwifi/pci.h | 15 +-
drivers/net/wireless/rtlwifi/ps.c | 258 +++-
drivers/net/wireless/rtlwifi/ps.h | 9 +
drivers/net/wireless/rtlwifi/rc.c | 212 ++--
drivers/net/wireless/rtlwifi/rc.h | 9 +-
drivers/net/wireless/rtlwifi/regd.c | 97 +-
drivers/net/wireless/rtlwifi/regd.h | 2 +-
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 523 ++++++-
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 2 +
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 81 +-
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 4 +-
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 128 +-
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 76 +-
drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 27 -
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 2 +
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 1 +
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 509 +++++---
drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | 34 +-
drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 5 +-
drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 2 -
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 223 +--
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 55 +-
drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 58 +-
drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 24 +-
drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | 17 +-
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 122 ++-
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 14 +-
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 180 +--
drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 7 +-
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 11 +-
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 5 +-
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 14 +-
drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | 14 +
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 4 +-
drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | 4 +
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 2 +-
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 48 +-
drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | 5 +-
drivers/net/wireless/rtlwifi/usb.c | 19 +-
drivers/net/wireless/rtlwifi/usb.h | 2 +
drivers/net/wireless/rtlwifi/wifi.h | 155 ++-
drivers/net/wireless/wl12xx/Kconfig | 2 +-
drivers/net/wireless/wl12xx/acx.c | 93 +-
drivers/net/wireless/wl12xx/acx.h | 23 +-
drivers/net/wireless/wl12xx/boot.c | 285 +++-
drivers/net/wireless/wl12xx/boot.h | 52 +
drivers/net/wireless/wl12xx/cmd.c | 99 ++-
drivers/net/wireless/wl12xx/cmd.h | 34 +
drivers/net/wireless/wl12xx/conf.h | 29 +-
drivers/net/wireless/wl12xx/debugfs.c | 2 +-
drivers/net/wireless/wl12xx/event.c | 64 +-
drivers/net/wireless/wl12xx/event.h | 17 +-
drivers/net/wireless/wl12xx/ini.h | 98 ++-
drivers/net/wireless/wl12xx/init.c | 51 +-
drivers/net/wireless/wl12xx/init.h | 1 +
drivers/net/wireless/wl12xx/io.c | 11 +
drivers/net/wireless/wl12xx/io.h | 3 +
drivers/net/wireless/wl12xx/main.c | 353 ++++-
drivers/net/wireless/wl12xx/ps.c | 3 -
drivers/net/wireless/wl12xx/reg.h | 15 +-
drivers/net/wireless/wl12xx/rx.c | 44 +-
drivers/net/wireless/wl12xx/scan.c | 17 +-
drivers/net/wireless/wl12xx/sdio.c | 27 +-
drivers/net/wireless/wl12xx/sdio_test.c | 20 +-
drivers/net/wireless/wl12xx/spi.c | 17 +-
drivers/net/wireless/wl12xx/testmode.c | 6 +-
drivers/net/wireless/wl12xx/tx.c | 234 +++-
drivers/net/wireless/wl12xx/tx.h | 60 +-
drivers/net/wireless/wl12xx/wl12xx.h | 66 +-
drivers/ssb/driver_chipcommon.c | 68 +-
drivers/ssb/driver_chipcommon_pmu.c | 2 +
drivers/ssb/driver_pcicore.c | 131 ++-
drivers/ssb/main.c | 23 +-
include/linux/ath9k_platform.h | 2 +
include/linux/ssb/ssb_driver_chipcommon.h | 11 +-
include/linux/ssb/ssb_regs.h | 2 +-
include/linux/wl12xx.h | 29 +-
include/net/bluetooth/hci.h | 9 +
include/net/bluetooth/hci_core.h | 16 +-
include/net/bluetooth/l2cap.h | 69 +-
include/net/bluetooth/mgmt.h | 10 +-
include/net/mac80211.h | 17 +
net/bluetooth/cmtp/core.c | 3 +-
net/bluetooth/hci_conn.c | 78 +-
net/bluetooth/hci_core.c | 75 +-
net/bluetooth/hci_event.c | 163 ++-
net/bluetooth/hci_sysfs.c | 31 +
net/bluetooth/hidp/core.c | 6 +-
net/bluetooth/l2cap_core.c | 588 ++++----
net/bluetooth/l2cap_sock.c | 242 ++--
net/bluetooth/mgmt.c | 95 ++-
net/bluetooth/rfcomm/core.c | 21 +-
net/bluetooth/rfcomm/sock.c | 5 +-
net/mac80211/aes_ccm.c | 6 +-
net/mac80211/cfg.c | 15 +-
net/mac80211/driver-ops.h | 18 +
net/mac80211/driver-trace.h | 27 +
net/mac80211/ibss.c | 7 +-
net/mac80211/ieee80211_i.h | 3 +
net/mac80211/key.c | 21 +-
net/mac80211/main.c | 18 -
net/mac80211/mesh.c | 3 -
net/mac80211/mesh_hwmp.c | 4 -
net/mac80211/pm.c | 16 +-
net/mac80211/rx.c | 49 +-
net/mac80211/sta_info.c | 2 -
net/mac80211/status.c | 8 +
net/mac80211/tx.c | 15 +-
net/mac80211/work.c | 6 +-
net/mac80211/wpa.c | 62 +-
net/wireless/core.c | 17 +
net/wireless/reg.c | 3 +-
244 files changed, 12283 insertions(+), 6490 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/ar9340_initvals.h
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
delete mode 100644 drivers/net/wireless/iwlwifi/iwl-spectrum.h
Omnibus patch available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2011-05-05.patch.bz2
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Christoph Lameter @ 2011-05-05 19:05 UTC (permalink / raw)
To: Eric Dumazet
Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <1304621296.3032.98.camel@edumazet-laptop>
On Thu, 5 May 2011, Eric Dumazet wrote:
> > Combining this one with the patch I sent to remove the #ifdeffery would
> > make this much simpler.
>
> I must missed it, could you please resend it ?
Subject: slub: Remove CONFIG_CMPXCHG_LOCAL ifdeffery
Remove the #ifdefs. This means that the irqsafe_cpu_cmpxchg_double() is used
everywhere.
There may be performance implications since:
A. We now have to manage a transaction ID for all arches
B. The interrupt holdoff for arches not supporting CONFIG_CMPXCHG_LOCAL is reduced
to a very short irqoff section.
There are no multiple irqoff/irqon sequences as a result of this change. Even in the fallback
case we only have to do one disable and enable like before.
Signed-off-by: Christoph Lameter <cl@linux.com>
---
include/linux/slub_def.h | 2 -
mm/slub.c | 56 -----------------------------------------------
2 files changed, 58 deletions(-)
Index: linux-2.6/include/linux/slub_def.h
===================================================================
--- linux-2.6.orig/include/linux/slub_def.h 2011-05-04 09:33:08.000000000 -0500
+++ linux-2.6/include/linux/slub_def.h 2011-05-04 09:42:05.000000000 -0500
@@ -37,9 +37,7 @@ enum stat_item {
struct kmem_cache_cpu {
void **freelist; /* Pointer to next available object */
-#ifdef CONFIG_CMPXCHG_LOCAL
unsigned long tid; /* Globally unique transaction id */
-#endif
struct page *page; /* The slab from which we are allocating */
int node; /* The node of the page (or -1 for debug) */
#ifdef CONFIG_SLUB_STATS
Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c 2011-05-04 09:41:59.000000000 -0500
+++ linux-2.6/mm/slub.c 2011-05-04 09:48:11.000000000 -0500
@@ -1540,7 +1540,6 @@ static void unfreeze_slab(struct kmem_ca
}
}
-#ifdef CONFIG_CMPXCHG_LOCAL
#ifdef CONFIG_PREEMPT
/*
* Calculate the next globally unique transaction for disambiguiation
@@ -1600,17 +1599,12 @@ static inline void note_cmpxchg_failure(
stat(s, CMPXCHG_DOUBLE_CPU_FAIL);
}
-#endif
-
void init_kmem_cache_cpus(struct kmem_cache *s)
{
-#ifdef CONFIG_CMPXCHG_LOCAL
int cpu;
for_each_possible_cpu(cpu)
per_cpu_ptr(s->cpu_slab, cpu)->tid = init_tid(cpu);
-#endif
-
}
/*
* Remove the cpu slab
@@ -1643,9 +1637,7 @@ static void deactivate_slab(struct kmem_
page->inuse--;
}
c->page = NULL;
-#ifdef CONFIG_CMPXCHG_LOCAL
c->tid = next_tid(c->tid);
-#endif
unfreeze_slab(s, page, tail);
}
@@ -1780,7 +1772,6 @@ static void *__slab_alloc(struct kmem_ca
{
void **object;
struct page *new;
-#ifdef CONFIG_CMPXCHG_LOCAL
unsigned long flags;
local_irq_save(flags);
@@ -1792,7 +1783,6 @@ static void *__slab_alloc(struct kmem_ca
*/
c = this_cpu_ptr(s->cpu_slab);
#endif
-#endif
/* We handle __GFP_ZERO in the caller */
gfpflags &= ~__GFP_ZERO;
@@ -1819,10 +1809,8 @@ load_freelist:
c->node = page_to_nid(c->page);
unlock_out:
slab_unlock(c->page);
-#ifdef CONFIG_CMPXCHG_LOCAL
c->tid = next_tid(c->tid);
local_irq_restore(flags);
-#endif
stat(s, ALLOC_SLOWPATH);
return object;
@@ -1858,9 +1846,7 @@ new_slab:
}
if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
slab_out_of_memory(s, gfpflags, node);
-#ifdef CONFIG_CMPXCHG_LOCAL
local_irq_restore(flags);
-#endif
return NULL;
debug:
if (!alloc_debug_processing(s, c->page, object, addr))
@@ -1887,20 +1873,12 @@ static __always_inline void *slab_alloc(
{
void **object;
struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
unsigned long tid;
-#else
- unsigned long flags;
-#endif
if (slab_pre_alloc_hook(s, gfpflags))
return NULL;
-#ifndef CONFIG_CMPXCHG_LOCAL
- local_irq_save(flags);
-#else
redo:
-#endif
/*
* Must read kmem_cache cpu data via this cpu ptr. Preemption is
@@ -1910,7 +1888,6 @@ redo:
*/
c = __this_cpu_ptr(s->cpu_slab);
-#ifdef CONFIG_CMPXCHG_LOCAL
/*
* The transaction ids are globally unique per cpu and per operation on
* a per cpu queue. Thus they can be guarantee that the cmpxchg_double
@@ -1919,7 +1896,6 @@ redo:
*/
tid = c->tid;
barrier();
-#endif
object = c->freelist;
if (unlikely(!object || !node_match(c, node)))
@@ -1927,7 +1903,6 @@ redo:
object = __slab_alloc(s, gfpflags, node, addr, c);
else {
-#ifdef CONFIG_CMPXCHG_LOCAL
/*
* The cmpxchg will only match if there was no additional
* operation and if we are on the right processor.
@@ -1948,16 +1923,9 @@ redo:
note_cmpxchg_failure("slab_alloc", s, tid);
goto redo;
}
-#else
- c->freelist = get_freepointer(s, object);
-#endif
stat(s, ALLOC_FASTPATH);
}
-#ifndef CONFIG_CMPXCHG_LOCAL
- local_irq_restore(flags);
-#endif
-
if (unlikely(gfpflags & __GFP_ZERO) && object)
memset(object, 0, s->objsize);
@@ -2034,11 +2002,9 @@ static void __slab_free(struct kmem_cach
{
void *prior;
void **object = (void *)x;
-#ifdef CONFIG_CMPXCHG_LOCAL
unsigned long flags;
local_irq_save(flags);
-#endif
slab_lock(page);
stat(s, FREE_SLOWPATH);
@@ -2070,9 +2036,7 @@ checks_ok:
out_unlock:
slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
local_irq_restore(flags);
-#endif
return;
slab_empty:
@@ -2084,9 +2048,7 @@ slab_empty:
stat(s, FREE_REMOVE_PARTIAL);
}
slab_unlock(page);
-#ifdef CONFIG_CMPXCHG_LOCAL
local_irq_restore(flags);
-#endif
stat(s, FREE_SLAB);
discard_slab(s, page);
return;
@@ -2113,20 +2075,11 @@ static __always_inline void slab_free(st
{
void **object = (void *)x;
struct kmem_cache_cpu *c;
-#ifdef CONFIG_CMPXCHG_LOCAL
unsigned long tid;
-#else
- unsigned long flags;
-#endif
slab_free_hook(s, x);
-#ifndef CONFIG_CMPXCHG_LOCAL
- local_irq_save(flags);
-
-#else
redo:
-#endif
/*
* Determine the currently cpus per cpu slab.
@@ -2136,15 +2089,12 @@ redo:
*/
c = __this_cpu_ptr(s->cpu_slab);
-#ifdef CONFIG_CMPXCHG_LOCAL
tid = c->tid;
barrier();
-#endif
if (likely(page == c->page && c->node != NUMA_NO_NODE)) {
set_freepointer(s, object, c->freelist);
-#ifdef CONFIG_CMPXCHG_LOCAL
if (unlikely(!irqsafe_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
c->freelist, tid,
@@ -2153,16 +2103,10 @@ redo:
note_cmpxchg_failure("slab_free", s, tid);
goto redo;
}
-#else
- c->freelist = object;
-#endif
stat(s, FREE_FASTPATH);
} else
__slab_free(s, page, x, addr);
-#ifndef CONFIG_CMPXCHG_LOCAL
- local_irq_restore(flags);
-#endif
}
void kmem_cache_free(struct kmem_cache *s, void *x)
^ permalink raw reply
* Re: [PATCH 0/2] wireless: Make and use const struct ieee80211_channel
From: John W. Linville @ 2011-05-05 18:49 UTC (permalink / raw)
To: Joe Perches
Cc: linux-wireless, libertas-dev, orinoco-users, orinoco-devel,
netdev, linux-kernel
In-Reply-To: <cover.1304054543.git.joe@perches.com>
These patches generated a lot of warnings in net/mac80211. Did you
actually build them?
On Thu, Apr 28, 2011 at 10:25:06PM -0700, Joe Perches wrote:
> Joe Perches (2):
> wireless: Make struct ieee80211_channel const where possible
> wireless: Use const struct ieee80211_channel where possible
>
> drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 2 +-
> drivers/net/wireless/iwlegacy/iwl3945-base.c | 2 +-
> drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +-
> drivers/net/wireless/iwmc3200wifi/cfg80211.c | 4 +-
> drivers/net/wireless/libertas/cfg.c | 2 +-
> drivers/net/wireless/mwifiex/cfg80211.c | 9 ++++---
> drivers/net/wireless/orinoco/cfg.c | 2 +-
> drivers/net/wireless/rndis_wlan.c | 9 ++++---
> drivers/net/wireless/wl1251/cmd.c | 2 +-
> drivers/net/wireless/wl1251/cmd.h | 2 +-
> include/net/cfg80211.h | 34 +++++++++++++-------------
> net/wireless/chan.c | 10 ++++----
> net/wireless/core.h | 14 ++++++----
> net/wireless/debugfs.c | 2 +-
> net/wireless/ibss.c | 6 ++--
> net/wireless/mlme.c | 15 ++++++-----
> net/wireless/nl80211.c | 31 ++++++++++++-----------
> net/wireless/nl80211.h | 9 ++++---
> net/wireless/reg.c | 11 ++++----
> net/wireless/reg.h | 4 +-
> net/wireless/scan.c | 6 ++--
> net/wireless/wext-sme.c | 2 +-
> 22 files changed, 94 insertions(+), 86 deletions(-)
>
> --
> 1.7.5.rc3.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Eric Dumazet @ 2011-05-05 18:48 UTC (permalink / raw)
To: Christoph Lameter
Cc: Pekka Enberg, casteyde.christian, Andrew Morton, netdev,
bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <alpine.DEB.2.00.1105051339310.6821@router.home>
Le jeudi 05 mai 2011 à 13:40 -0500, Christoph Lameter a écrit :
> On Thu, 5 May 2011, Pekka Enberg wrote:
>
> > > > -#ifdef CONFIG_CMPXCHG_LOCAL
> > > > +#ifdef SLUB_USE_CMPXCHG_DOUBLE
> > > > /*
> > > > * Must align to double word boundary for the double cmpxchg
> > > > instructions
> > > > * to work.
> > > >
> > >
> > >
> > > Is anybody taking the patch and sending it upstream ?
> >
> > Oh, sorry, it got lost in my inbox. I can take care of it.
>
> Combining this one with the patch I sent to remove the #ifdeffery would
> make this much simpler.
I must missed it, could you please resend it ?
Thanks
^ permalink raw reply
* Re: [Bugme-new] [Bug 33502] New: Caught 64-bit read from uninitialized memory in __alloc_skb
From: Christoph Lameter @ 2011-05-05 18:40 UTC (permalink / raw)
To: Pekka Enberg
Cc: Eric Dumazet, casteyde.christian, Andrew Morton, netdev,
bugzilla-daemon, bugme-daemon, Vegard Nossum
In-Reply-To: <4DC24239.7050806@cs.helsinki.fi>
On Thu, 5 May 2011, Pekka Enberg wrote:
> > > -#ifdef CONFIG_CMPXCHG_LOCAL
> > > +#ifdef SLUB_USE_CMPXCHG_DOUBLE
> > > /*
> > > * Must align to double word boundary for the double cmpxchg
> > > instructions
> > > * to work.
> > >
> >
> >
> > Is anybody taking the patch and sending it upstream ?
>
> Oh, sorry, it got lost in my inbox. I can take care of it.
Combining this one with the patch I sent to remove the #ifdeffery would
make this much simpler.
^ permalink raw reply
* Re: [PATCHv4 2/2] tg3: Allow ethtool to enable/disable loopback.
From: Michał Mirosław @ 2011-05-05 18:35 UTC (permalink / raw)
To: Mahesh Bandewar
Cc: Matt Carlson, David Miller, netdev, Michael Chan, Tom Herbert
In-Reply-To: <BANLkTin88L+YBrpdaHR57CSx3dg2dMF7Yg@mail.gmail.com>
W dniu 5 maja 2011 19:47 użytkownik Mahesh Bandewar
<maheshb@google.com> napisał:
> On Wed, May 4, 2011 at 11:59 PM, Michał Mirosław <mirqus@gmail.com> wrote:
>> 2011/5/5 Mahesh Bandewar <maheshb@google.com>:
>>> This patch adds tg3_set_features() to handle loopback mode. Currently the
>>> capability is added for the devices which support internal MAC loopback mode.
>>> So when enabled, it enables internal-MAC loopback.
[...]
>>> @@ -9485,6 +9533,15 @@ static int tg3_open(struct net_device *dev)
>>>
>>> netif_tx_start_all_queues(dev);
>>>
>>> + /*
>>> + * Reset loopback feature if it was turned on while the device was down
>>> + * to avoid and any discrepancy in features reporting.
>>> + */
>>> + if (dev->features & NETIF_F_LOOPBACK) {
>>> + dev->features &= ~NETIF_F_LOOPBACK;
>>> + dev->wanted_features &= ~NETIF_F_LOOPBACK;
>>> + }
>>> +
>>
>> if (dev->features & NETIF_F_LOOPBACK)
>> tg3_set_loopback(dev, dev->features);
>>
> Unfortunately at this stage device will not be able to set-loopback so
> I resorted to clearing the bit(s).
ndo_fix_features+ndo_set_features might be caled before ndo_open - the
first might be just from register_netdev() so even before ndo_open
callback.
>> Whatever you do, don't modify wanted_features in drivers.
> Since just clearing the 'features' would leave wanted_features in
> discrepant state, I thought this will bring it to a sane state. So
> what is a preferred way?
If you really can't do other way, driver should keep additional state
that is checked in ndo_fix_features callback.
>> BTW, similar problems (also like in previous versions) are in
>> forcedeth implementation.
> Yes, whatever we decide about the state of the wanted_features, I'll
> implement similarly for forcedeth. Which previous problem you are
> referring to? Is it the return value? There is a different kind of
> failure (error while writing the register). Since update_features()
> cant handle return value, I'm ignoring the return value. As far as the
> correct return code is concerned, I wasn't sure what is appropriate
> return code here (may be PHY_ERROR would be appropriate there) but
> again I could ignore it just the way rest of the code is ignoring.
Let's wait for this threads points to be resolved. You will probably
change the forcedeth's implementation then anyway. :-)
Best Regards,
Michał Mirosław
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox