* Re: [PATCH] rtnl: Add #ifdef CONFIG_RPS around num_rx_queues reference
From: David Miller @ 2012-07-22 19:28 UTC (permalink / raw)
To: mgreer; +Cc: netdev, jiri
In-Reply-To: <1342827313-2827-1-git-send-email-mgreer@animalcreek.com>
From: "Mark A. Greer" <mgreer@animalcreek.com>
Date: Fri, 20 Jul 2012 16:35:13 -0700
> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> Commit 76ff5cc91935c51fcf1a6a99ffa28b97a6e7a884
> (rtnl: allow to specify number of rx and tx queues
> on device creation) added a reference to the net_device
> structure's 'num_rx_queues' member in
>
> net/core/rtnetlink.c:rtnl_fill_ifinfo()
>
> However, the definition for 'num_rx_queues' is surrounded
> by an '#ifdef CONFIG_RPS' while the new reference to it is
> not. This causes a compile error when CONFIG_RPS is not
> defined.
>
> Fix the compile error by surrounding the new reference to
> 'num_rx_queues' by an '#ifdef CONFIG_RPS'.
>
> CC: Jiri Pirko <jiri@resnulli.us>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Applied, thanks Mark.
^ permalink raw reply
* Re: [patch net-next] rtnl: do not include num_rx_queues into msg when CONFIG_RPS is not set
From: David Miller @ 2012-07-22 19:27 UTC (permalink / raw)
To: jiri; +Cc: netdev, sfr
In-Reply-To: <1342942002-26731-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Sun, 22 Jul 2012 09:26:42 +0200
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Jiri, I've been patiently waiting for you to ACK Mark A. Greear's
patch fixing this bug, did you not see it at all?
http://patchwork.ozlabs.org/patch/172393/
I'm just going to apply it since you're not watching for fixes
for code you've changed.
^ permalink raw reply
* Re: [net-next 00/13][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2012-07-22 19:24 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, gospo, sassmann
In-Reply-To: <1342912142-11130-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Sat, 21 Jul 2012 16:08:49 -0700
> This series contains updates to ixgbe and ixgbevf.
>
> The following are changes since commit 186e868786f97c8026f0a81400b451ace306b3a4:
> forcedeth: spin_unlock_irq in interrupt handler fix
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master
Pulled, thanks Jeff.
^ permalink raw reply
* Re: [PULL] vhost-net changes for net/3.6
From: David Miller @ 2012-07-22 19:19 UTC (permalink / raw)
To: mst
Cc: netdev, linux-kernel, asias, nab, nab, pbonzini, stefanha,
stefanha, wuzhy
In-Reply-To: <20120721225436.GA23519@redhat.com>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Sun, 22 Jul 2012 01:54:36 +0300
> The following changes since commit 186e868786f97c8026f0a81400b451ace306b3a4:
>
> forcedeth: spin_unlock_irq in interrupt handler fix (2012-07-20 16:18:36 -0700)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net-next
>
> for you to fetch changes up to 163049aefdc04323a2d17ec9f2862027b43b0502:
>
> vhost: make vhost work queue visible (2012-07-22 01:22:23 +0300)
Pulled, thanks.
^ permalink raw reply
* Re: [PATCH] wimax: fix printk format warnings
From: David Miller @ 2012-07-22 19:18 UTC (permalink / raw)
To: rdunlap; +Cc: netdev, geert, inaky.perez-gonzalez, linux-wimax, wimax, akpm
In-Reply-To: <500B170B.4000000@xenotime.net>
From: Randy Dunlap <rdunlap@xenotime.net>
Date: Sat, 21 Jul 2012 13:54:35 -0700
> From: Randy Dunlap <rdunlap@xenotime.net>
>
> Fix printk format warnings in drivers/net/wimax/i2400m:
>
> drivers/net/wimax/i2400m/control.c: warning: format '%zu' expects argument of type 'size_t', but argument 4 has type 'ssize_t' [-Wformat]
> drivers/net/wimax/i2400m/control.c: warning: format '%zu' expects argument of type 'size_t', but argument 5 has type 'ssize_t' [-Wformat]
> drivers/net/wimax/i2400m/usb-fw.c: warning: format '%zu' expects argument of type 'size_t', but argument 4 has type 'ssize_t' [-Wformat]
>
> I don't see these warnings on x86. The warnings that are quoted above
> are from Geert's kernel build reports.
>
> Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Applied, thanks Randy.
^ permalink raw reply
* Re: [PATCH v6] sctp: Implement quick failover draft from tsvwg
From: Neil Horman <nhorman@tuxdriver.com> @ 2012-07-22 19:18 UTC (permalink / raw)
To: David Miller, vyasevich; +Cc: netdev, sri, linux-sctp, joe
In-Reply-To: <20120722.121409.377271257112948379.davem@davemloft.net>
Thanks all!
David Miller <davem@davemloft.net> wrote:
>From: Vlad Yasevich <vyasevich@gmail.com>
>Date: Sun, 22 Jul 2012 14:18:12 -0400
>
>> Neil Horman <nhorman@tuxdriver.com> wrote:
>>
>>>I've seen several attempts recently made to do quick failover of sctp
>>>transports
>>>by reducing various retransmit timers and counters. While its
>possible
>>>to
>>>implement a faster failover on multihomed sctp associations, its not
>>>particularly robust, in that it can lead to unneeded retransmits, as
>>>well as
>>>false connection failures due to intermittent latency on a network.
>>>
>>>Instead, lets implement the new ietf quick failover draft found here:
>>>http://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05
>>>
>>>This will let the sctp stack identify transports that have had a
>small
>>>number of
>>>errors, and avoid using them quickly until their reliability can be
>>>re-established. I've tested this out on two virt guests connected
>via
>>>multiple
>>>isolated virt networks and believe its in compliance with the above
>>>draft and
>>>works well.
>>>
>>>Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> ...
>> Acked-by: Vlad Yasevich <vyasevich@gmail.com>
>
>Applied, thanks everyone.
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
^ permalink raw reply
* Re: [PATCH v6] sctp: Implement quick failover draft from tsvwg
From: David Miller @ 2012-07-22 19:14 UTC (permalink / raw)
To: vyasevich; +Cc: nhorman, netdev, sri, linux-sctp, joe
In-Reply-To: <2e6ee3f1-ea4f-4c13-b27b-1f2291fdb0c0@email.android.com>
From: Vlad Yasevich <vyasevich@gmail.com>
Date: Sun, 22 Jul 2012 14:18:12 -0400
> Neil Horman <nhorman@tuxdriver.com> wrote:
>
>>I've seen several attempts recently made to do quick failover of sctp
>>transports
>>by reducing various retransmit timers and counters. While its possible
>>to
>>implement a faster failover on multihomed sctp associations, its not
>>particularly robust, in that it can lead to unneeded retransmits, as
>>well as
>>false connection failures due to intermittent latency on a network.
>>
>>Instead, lets implement the new ietf quick failover draft found here:
>>http://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05
>>
>>This will let the sctp stack identify transports that have had a small
>>number of
>>errors, and avoid using them quickly until their reliability can be
>>re-established. I've tested this out on two virt guests connected via
>>multiple
>>isolated virt networks and believe its in compliance with the above
>>draft and
>>works well.
>>
>>Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
...
> Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH] net: fix race condition in several drivers when reading stats
From: David Miller @ 2012-07-22 19:12 UTC (permalink / raw)
To: kgroeneveld; +Cc: netdev
In-Reply-To: <1342888250-28352-1-git-send-email-kgroeneveld@gmail.com>
From: Kevin Groeneveld <kgroeneveld@gmail.com>
Date: Sat, 21 Jul 2012 12:30:50 -0400
> Fix race condition in several network drivers when reading stats on 32bit
> UP architectures. These drivers update their stats in a BH context and
> therefore should use u64_stats_fetch_begin_bh/u64_stats_fetch_retry_bh
> instead of u64_stats_fetch_begin/u64_stats_fetch_retry when reading the
> stats.
>
> Signed-off-by: Kevin Groeneveld <kgroeneveld@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next v2] ipv4: tcp: remove per net tcp_sock
From: David Miller @ 2012-07-22 19:08 UTC (permalink / raw)
To: eric.dumazet; +Cc: shimoda.hiroaki, netdev, therbert, wsommerfeld
In-Reply-To: <1342859331.2626.8385.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 21 Jul 2012 10:28:51 +0200
> [PATCH net-next] ipv4: tcp: set unicast_sock uc_ttl to -1
>
> Set unicast_sock uc_ttl to -1 so that we select the right ttl,
> instead of sending packets with a 0 ttl.
>
> Bug added in commit be9f4a44e7d4 (ipv4: tcp: remove per net tcp_sock)
>
> Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
APplied, thanks everyone.
^ permalink raw reply
* Re: [PATCH net-next 1/4] bnx2x: advertise transmit time stamping
From: Eilon Greenstein @ 2012-07-22 18:29 UTC (permalink / raw)
To: Richard Cochran; +Cc: netdev, David Miller, Willem de Bruijn, Merav Sircon
In-Reply-To: <379f084af5dcbcccda309ecb0d0032196fb496f3.1342976654.git.richardcochran@gmail.com>
On Sun, 2012-07-22 at 19:15 +0200, Richard Cochran wrote:
> This driver now offers software transmit time stamping, so it should
> advertise that fact via ethtool. Compile tested only.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
> Cc: Eilon Greenstein <eilong@broadcom.com>
> Cc: Willem de Bruijn <willemb@google.com>
Thanks Richard. I was sure it was sent upstream weeks ago, but I see it
is somehow still pending to be sent. Thanks for catching it.
Acked-by: Eilon Greenstein <eilong@broadcom.com>
^ permalink raw reply
* Re: [PATCH v6] sctp: Implement quick failover draft from tsvwg
From: Vlad Yasevich @ 2012-07-22 18:18 UTC (permalink / raw)
To: Neil Horman, netdev; +Cc: Sridhar Samudrala, David S. Miller, linux-sctp, joe
In-Reply-To: <1342893367-981-1-git-send-email-nhorman@tuxdriver.com>
Neil Horman <nhorman@tuxdriver.com> wrote:
>I've seen several attempts recently made to do quick failover of sctp
>transports
>by reducing various retransmit timers and counters. While its possible
>to
>implement a faster failover on multihomed sctp associations, its not
>particularly robust, in that it can lead to unneeded retransmits, as
>well as
>false connection failures due to intermittent latency on a network.
>
>Instead, lets implement the new ietf quick failover draft found here:
>http://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05
>
>This will let the sctp stack identify transports that have had a small
>number of
>errors, and avoid using them quickly until their reliability can be
>re-established. I've tested this out on two virt guests connected via
>multiple
>isolated virt networks and believe its in compliance with the above
>draft and
>works well.
>
>Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>CC: Vlad Yasevich <vyasevich@gmail.com>
>CC: Sridhar Samudrala <sri@us.ibm.com>
>CC: "David S. Miller" <davem@davemloft.net>
>CC: linux-sctp@vger.kernel.org
>CC: joe@perches.com
>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
-vlad
>---
>Change notes:
>
>V2)
>- Added socket option API from section 6.1 of the specification, as per
>request from Vlad. Adding this socket option allows us to alter both
>the path
>maximum retransmit value and the path partial failure threshold for
>each
>transport and the association as a whole.
>
>- Added a per transport pf_retrans value, and initialized it from the
>association value. This makes each transport independently
>configurable as per
>the socket option above, and prevents changes in the sysctl from
>bleeding into
>an already created association.
>
>V3)
>- Cleaned up some line spacing (Joe Perches)
>- Fixed some socket option user data sanitization (Vlad Yasevich)
>
>V4)
>- Added additional documentation (Flavio Leitner)
>
>V5)
>- Modified setsockopt option to ignore 0 pathmaxrxt rather than return
> error (Vlad Yasevich)
>- Modified getsocopt to return option length written (Vlad Y.)
>
>V6)
>- Fixed stupid mistake about returning optval incorrectly (Vlad Y)
>---
> Documentation/networking/ip-sysctl.txt | 14 +++++
> include/net/sctp/constants.h | 1 +
> include/net/sctp/structs.h | 20 ++++++-
> include/net/sctp/user.h | 11 ++++
> net/sctp/associola.c | 37 +++++++++--
> net/sctp/outqueue.c | 6 +-
> net/sctp/sm_sideeffect.c | 33 +++++++++-
>net/sctp/socket.c | 101
>++++++++++++++++++++++++++++++++
> net/sctp/sysctl.c | 9 +++
> net/sctp/transport.c | 4 +-
> 10 files changed, 221 insertions(+), 15 deletions(-)
>
>diff --git a/Documentation/networking/ip-sysctl.txt
>b/Documentation/networking/ip-sysctl.txt
>index 47b6c79..c636f9c 100644
>--- a/Documentation/networking/ip-sysctl.txt
>+++ b/Documentation/networking/ip-sysctl.txt
>@@ -1408,6 +1408,20 @@ path_max_retrans - INTEGER
>
> Default: 5
>
>+pf_retrans - INTEGER
>+ The number of retransmissions that will be attempted on a given path
>+ before traffic is redirected to an alternate transport (should one
>+ exist). Note this is distinct from path_max_retrans, as a path that
>+ passes the pf_retrans threshold can still be used. Its only
>+ deprioritized when a transmission path is selected by the stack.
>This
>+ setting is primarily used to enable fast failover mechanisms without
>+ having to reduce path_max_retrans to a very low value. See:
>+ http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt
>+ for details. Note also that a value of pf_retrans > path_max_retrans
>+ disables this feature
>+
>+ Default: 0
>+
> rto_initial - INTEGER
> The initial round trip timeout value in milliseconds that will be used
> in calculating round trip times. This is the initial time interval
>diff --git a/include/net/sctp/constants.h
>b/include/net/sctp/constants.h
>index 942b864..d053d2e 100644
>--- a/include/net/sctp/constants.h
>+++ b/include/net/sctp/constants.h
>@@ -334,6 +334,7 @@ typedef enum {
> typedef enum {
> SCTP_TRANSPORT_UP,
> SCTP_TRANSPORT_DOWN,
>+ SCTP_TRANSPORT_PF,
> } sctp_transport_cmd_t;
>
> /* These are the address scopes defined mainly for IPv4 addresses
>diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
>index e4652fe..cee0678 100644
>--- a/include/net/sctp/structs.h
>+++ b/include/net/sctp/structs.h
>@@ -161,6 +161,12 @@ extern struct sctp_globals {
> int max_retrans_path;
> int max_retrans_init;
>
>+ /* Potentially-Failed.Max.Retrans sysctl value
>+ * taken from:
>+ * http://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05
>+ */
>+ int pf_retrans;
>+
> /*
> * Policy for preforming sctp/socket accounting
> * 0 - do socket level accounting, all assocs share sk_sndbuf
>@@ -258,6 +264,7 @@ extern struct sctp_globals {
> #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy)
> #define sctp_rcvbuf_policy (sctp_globals.rcvbuf_policy)
> #define sctp_max_retrans_path (sctp_globals.max_retrans_path)
>+#define sctp_pf_retrans (sctp_globals.pf_retrans)
> #define sctp_max_retrans_init (sctp_globals.max_retrans_init)
> #define sctp_sack_timeout (sctp_globals.sack_timeout)
> #define sctp_hb_interval (sctp_globals.hb_interval)
>@@ -987,10 +994,15 @@ struct sctp_transport {
>
> /* This is the max_retrans value for the transport and will
> * be initialized from the assocs value. This can be changed
>- * using SCTP_SET_PEER_ADDR_PARAMS socket option.
>+ * using the SCTP_SET_PEER_ADDR_PARAMS socket option.
> */
> __u16 pathmaxrxt;
>
>+ /* This is the partially failed retrans value for the transport
>+ * and will be initialized from the assocs value. This can be
>changed
>+ * using the SCTP_PEER_ADDR_THLDS socket option
>+ */
>+ int pf_retrans;
> /* PMTU : The current known path MTU. */
> __u32 pathmtu;
>
>@@ -1660,6 +1672,12 @@ struct sctp_association {
> */
> int max_retrans;
>
>+ /* This is the partially failed retrans value for the transport
>+ * and will be initialized from the assocs value. This can be
>+ * changed using the SCTP_PEER_ADDR_THLDS socket option
>+ */
>+ int pf_retrans;
>+
> /* Maximum number of times the endpoint will retransmit INIT */
> __u16 max_init_attempts;
>
>diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
>index 0842ef0..1b02d7a 100644
>--- a/include/net/sctp/user.h
>+++ b/include/net/sctp/user.h
>@@ -93,6 +93,7 @@ typedef __s32 sctp_assoc_t;
> #define SCTP_GET_ASSOC_NUMBER 28 /* Read only */
> #define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
> #define SCTP_AUTO_ASCONF 30
>+#define SCTP_PEER_ADDR_THLDS 31
>
> /* Internal Socket Options. Some of the sctp library functions are
> * implemented using these socket options.
>@@ -649,6 +650,7 @@ struct sctp_paddrinfo {
> */
> enum sctp_spinfo_state {
> SCTP_INACTIVE,
>+ SCTP_PF,
> SCTP_ACTIVE,
> SCTP_UNCONFIRMED,
> SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */
>@@ -741,4 +743,13 @@ typedef struct {
> int sd;
> } sctp_peeloff_arg_t;
>
>+/*
>+ * Peer Address Thresholds socket option
>+ */
>+struct sctp_paddrthlds {
>+ sctp_assoc_t spt_assoc_id;
>+ struct sockaddr_storage spt_address;
>+ __u16 spt_pathmaxrxt;
>+ __u16 spt_pathpfthld;
>+};
> #endif /* __net_sctp_user_h__ */
>diff --git a/net/sctp/associola.c b/net/sctp/associola.c
>index 5bc9ab1..90fe36b 100644
>--- a/net/sctp/associola.c
>+++ b/net/sctp/associola.c
>@@ -124,6 +124,8 @@ static struct sctp_association
>*sctp_association_init(struct sctp_association *a
> * socket values.
> */
> asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
>+ asoc->pf_retrans = sctp_pf_retrans;
>+
> asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
> asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
> asoc->rto_min = msecs_to_jiffies(sp->rtoinfo.srto_min);
>@@ -685,6 +687,9 @@ struct sctp_transport *sctp_assoc_add_peer(struct
>sctp_association *asoc,
> /* Set the path max_retrans. */
> peer->pathmaxrxt = asoc->pathmaxrxt;
>
>+ /* And the partial failure retrnas threshold */
>+ peer->pf_retrans = asoc->pf_retrans;
>+
> /* Initialize the peer's SACK delay timeout based on the
> * association configured value.
> */
>@@ -840,6 +845,7 @@ void sctp_assoc_control_transport(struct
>sctp_association *asoc,
> struct sctp_ulpevent *event;
> struct sockaddr_storage addr;
> int spc_state = 0;
>+ bool ulp_notify = true;
>
> /* Record the transition on the transport. */
> switch (command) {
>@@ -853,6 +859,14 @@ void sctp_assoc_control_transport(struct
>sctp_association *asoc,
> spc_state = SCTP_ADDR_CONFIRMED;
> else
> spc_state = SCTP_ADDR_AVAILABLE;
>+ /* Don't inform ULP about transition from PF to
>+ * active state and set cwnd to 1, see SCTP
>+ * Quick failover draft section 5.1, point 5
>+ */
>+ if (transport->state == SCTP_PF) {
>+ ulp_notify = false;
>+ transport->cwnd = 1;
>+ }
> transport->state = SCTP_ACTIVE;
> break;
>
>@@ -871,6 +885,11 @@ void sctp_assoc_control_transport(struct
>sctp_association *asoc,
> spc_state = SCTP_ADDR_UNREACHABLE;
> break;
>
>+ case SCTP_TRANSPORT_PF:
>+ transport->state = SCTP_PF;
>+ ulp_notify = false;
>+ break;
>+
> default:
> return;
> }
>@@ -878,12 +897,15 @@ void sctp_assoc_control_transport(struct
>sctp_association *asoc,
> /* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the
> * user.
> */
>- memset(&addr, 0, sizeof(struct sockaddr_storage));
>- memcpy(&addr, &transport->ipaddr,
>transport->af_specific->sockaddr_len);
>- event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
>- 0, spc_state, error, GFP_ATOMIC);
>- if (event)
>- sctp_ulpq_tail_event(&asoc->ulpq, event);
>+ if (ulp_notify) {
>+ memset(&addr, 0, sizeof(struct sockaddr_storage));
>+ memcpy(&addr, &transport->ipaddr,
>+ transport->af_specific->sockaddr_len);
>+ event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
>+ 0, spc_state, error, GFP_ATOMIC);
>+ if (event)
>+ sctp_ulpq_tail_event(&asoc->ulpq, event);
>+ }
>
> /* Select new active and retran paths. */
>
>@@ -899,7 +921,8 @@ void sctp_assoc_control_transport(struct
>sctp_association *asoc,
> transports) {
>
> if ((t->state == SCTP_INACTIVE) ||
>- (t->state == SCTP_UNCONFIRMED))
>+ (t->state == SCTP_UNCONFIRMED) ||
>+ (t->state == SCTP_PF))
> continue;
> if (!first || t->last_time_heard > first->last_time_heard) {
> second = first;
>diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
>index a0fa19f..e7aa177c 100644
>--- a/net/sctp/outqueue.c
>+++ b/net/sctp/outqueue.c
>@@ -792,7 +792,8 @@ static int sctp_outq_flush(struct sctp_outq *q, int
>rtx_timeout)
> if (!new_transport)
> new_transport = asoc->peer.active_path;
> } else if ((new_transport->state == SCTP_INACTIVE) ||
>- (new_transport->state == SCTP_UNCONFIRMED)) {
>+ (new_transport->state == SCTP_UNCONFIRMED) ||
>+ (new_transport->state == SCTP_PF)) {
> /* If the chunk is Heartbeat or Heartbeat Ack,
> * send it to chunk->transport, even if it's
> * inactive.
>@@ -987,7 +988,8 @@ static int sctp_outq_flush(struct sctp_outq *q, int
>rtx_timeout)
> new_transport = chunk->transport;
> if (!new_transport ||
> ((new_transport->state == SCTP_INACTIVE) ||
>- (new_transport->state == SCTP_UNCONFIRMED)))
>+ (new_transport->state == SCTP_UNCONFIRMED) ||
>+ (new_transport->state == SCTP_PF)))
> new_transport = asoc->peer.active_path;
> if (new_transport->state == SCTP_UNCONFIRMED)
> continue;
>diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
>index c96d1a8..285e26a 100644
>--- a/net/sctp/sm_sideeffect.c
>+++ b/net/sctp/sm_sideeffect.c
>@@ -76,6 +76,8 @@ static int sctp_side_effects(sctp_event_t event_type,
>sctp_subtype_t subtype,
> sctp_cmd_seq_t *commands,
> gfp_t gfp);
>
>+static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
>+ struct sctp_transport *t);
> /********************************************************************
> * Helper functions
> ********************************************************************/
>@@ -470,7 +472,8 @@ sctp_timer_event_t
>*sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
> * notification SHOULD be sent to the upper layer.
> *
> */
>-static void sctp_do_8_2_transport_strike(struct sctp_association
>*asoc,
>+static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands,
>+ struct sctp_association *asoc,
> struct sctp_transport *transport,
> int is_hb)
> {
>@@ -495,6 +498,23 @@ static void sctp_do_8_2_transport_strike(struct
>sctp_association *asoc,
> transport->error_count++;
> }
>
>+ /* If the transport error count is greater than the pf_retrans
>+ * threshold, and less than pathmaxrtx, then mark this transport
>+ * as Partially Failed, ee SCTP Quick Failover Draft, secon 5.1,
>+ * point 1
>+ */
>+ if ((transport->state != SCTP_PF) &&
>+ (asoc->pf_retrans < transport->pathmaxrxt) &&
>+ (transport->error_count > asoc->pf_retrans)) {
>+
>+ sctp_assoc_control_transport(asoc, transport,
>+ SCTP_TRANSPORT_PF,
>+ 0);
>+
>+ /* Update the hb timer to resend a heartbeat every rto */
>+ sctp_cmd_hb_timer_update(commands, transport);
>+ }
>+
> if (transport->state != SCTP_INACTIVE &&
> (transport->error_count > transport->pathmaxrxt)) {
> SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
>@@ -699,6 +719,10 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t
>*cmds,
> SCTP_HEARTBEAT_SUCCESS);
> }
>
>+ if (t->state == SCTP_PF)
>+ sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
>+ SCTP_HEARTBEAT_SUCCESS);
>+
> /* The receiver of the HEARTBEAT ACK should also perform an
> * RTT measurement for that destination transport address
> * using the time value carried in the HEARTBEAT ACK chunk.
>@@ -1565,8 +1589,8 @@ static int sctp_cmd_interpreter(sctp_event_t
>event_type,
>
> case SCTP_CMD_STRIKE:
> /* Mark one strike against a transport. */
>- sctp_do_8_2_transport_strike(asoc, cmd->obj.transport,
>- 0);
>+ sctp_do_8_2_transport_strike(commands, asoc,
>+ cmd->obj.transport, 0);
> break;
>
> case SCTP_CMD_TRANSPORT_IDLE:
>@@ -1576,7 +1600,8 @@ static int sctp_cmd_interpreter(sctp_event_t
>event_type,
>
> case SCTP_CMD_TRANSPORT_HB_SENT:
> t = cmd->obj.transport;
>- sctp_do_8_2_transport_strike(asoc, t, 1);
>+ sctp_do_8_2_transport_strike(commands, asoc,
>+ t, 1);
> t->hb_sent = 1;
> break;
>
>diff --git a/net/sctp/socket.c b/net/sctp/socket.c
>index b3b8a8d..8665b81 100644
>--- a/net/sctp/socket.c
>+++ b/net/sctp/socket.c
>@@ -3470,6 +3470,56 @@ static int sctp_setsockopt_auto_asconf(struct
>sock *sk, char __user *optval,
> }
>
>
>+/*
>+ * SCTP_PEER_ADDR_THLDS
>+ *
>+ * This option allows us to alter the partially failed threshold for
>one or all
>+ * transports in an association. See Section 6.1 of:
>+ * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt
>+ */
>+static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
>+ char __user *optval,
>+ unsigned int optlen)
>+{
>+ struct sctp_paddrthlds val;
>+ struct sctp_transport *trans;
>+ struct sctp_association *asoc;
>+
>+ if (optlen < sizeof(struct sctp_paddrthlds))
>+ return -EINVAL;
>+ if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval,
>+ sizeof(struct sctp_paddrthlds)))
>+ return -EFAULT;
>+
>+
>+ if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
>+ asoc = sctp_id2assoc(sk, val.spt_assoc_id);
>+ if (!asoc)
>+ return -ENOENT;
>+ list_for_each_entry(trans, &asoc->peer.transport_addr_list,
>+ transports) {
>+ if (val.spt_pathmaxrxt)
>+ trans->pathmaxrxt = val.spt_pathmaxrxt;
>+ trans->pf_retrans = val.spt_pathpfthld;
>+ }
>+
>+ if (val.spt_pathmaxrxt)
>+ asoc->pathmaxrxt = val.spt_pathmaxrxt;
>+ asoc->pf_retrans = val.spt_pathpfthld;
>+ } else {
>+ trans = sctp_addr_id2transport(sk, &val.spt_address,
>+ val.spt_assoc_id);
>+ if (!trans)
>+ return -ENOENT;
>+
>+ if (val.spt_pathmaxrxt)
>+ trans->pathmaxrxt = val.spt_pathmaxrxt;
>+ trans->pf_retrans = val.spt_pathpfthld;
>+ }
>+
>+ return 0;
>+}
>+
> /* API 6.2 setsockopt(), getsockopt()
> *
> * Applications use setsockopt() and getsockopt() to set or retrieve
>@@ -3619,6 +3669,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk,
>int level, int optname,
> case SCTP_AUTO_ASCONF:
> retval = sctp_setsockopt_auto_asconf(sk, optval, optlen);
> break;
>+ case SCTP_PEER_ADDR_THLDS:
>+ retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen);
>+ break;
> default:
> retval = -ENOPROTOOPT;
> break;
>@@ -5490,6 +5543,51 @@ static int sctp_getsockopt_assoc_ids(struct sock
>*sk, int len,
> return 0;
> }
>
>+/*
>+ * SCTP_PEER_ADDR_THLDS
>+ *
>+ * This option allows us to fetch the partially failed threshold for
>one or all
>+ * transports in an association. See Section 6.1 of:
>+ * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt
>+ */
>+static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
>+ char __user *optval,
>+ int len,
>+ int __user *optlen)
>+{
>+ struct sctp_paddrthlds val;
>+ struct sctp_transport *trans;
>+ struct sctp_association *asoc;
>+
>+ if (len < sizeof(struct sctp_paddrthlds))
>+ return -EINVAL;
>+ len = sizeof(struct sctp_paddrthlds);
>+ if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval,
>len))
>+ return -EFAULT;
>+
>+ if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
>+ asoc = sctp_id2assoc(sk, val.spt_assoc_id);
>+ if (!asoc)
>+ return -ENOENT;
>+
>+ val.spt_pathpfthld = asoc->pf_retrans;
>+ val.spt_pathmaxrxt = asoc->pathmaxrxt;
>+ } else {
>+ trans = sctp_addr_id2transport(sk, &val.spt_address,
>+ val.spt_assoc_id);
>+ if (!trans)
>+ return -ENOENT;
>+
>+ val.spt_pathmaxrxt = trans->pathmaxrxt;
>+ val.spt_pathpfthld = trans->pf_retrans;
>+ }
>+
>+ if (put_user(len, optlen) || copy_to_user(optval, &val, len))
>+ return -EFAULT;
>+
>+ return 0;
>+}
>+
>SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int
>optname,
> char __user *optval, int __user *optlen)
> {
>@@ -5628,6 +5726,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk,
>int level, int optname,
> case SCTP_AUTO_ASCONF:
> retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen);
> break;
>+ case SCTP_PEER_ADDR_THLDS:
>+ retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen);
>+ break;
> default:
> retval = -ENOPROTOOPT;
> break;
>diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
>index e5fe639..2b2bfe9 100644
>--- a/net/sctp/sysctl.c
>+++ b/net/sctp/sysctl.c
>@@ -141,6 +141,15 @@ static ctl_table sctp_table[] = {
> .extra2 = &int_max
> },
> {
>+ .procname = "pf_retrans",
>+ .data = &sctp_pf_retrans,
>+ .maxlen = sizeof(int),
>+ .mode = 0644,
>+ .proc_handler = proc_dointvec_minmax,
>+ .extra1 = &zero,
>+ .extra2 = &int_max
>+ },
>+ {
> .procname = "max_init_retransmits",
> .data = &sctp_max_retrans_init,
> .maxlen = sizeof(int),
>diff --git a/net/sctp/transport.c b/net/sctp/transport.c
>index b026ba0..194d0f3 100644
>--- a/net/sctp/transport.c
>+++ b/net/sctp/transport.c
>@@ -85,6 +85,7 @@ static struct sctp_transport
>*sctp_transport_init(struct sctp_transport *peer,
>
> /* Initialize the default path max_retrans. */
> peer->pathmaxrxt = sctp_max_retrans_path;
>+ peer->pf_retrans = sctp_pf_retrans;
>
> INIT_LIST_HEAD(&peer->transmitted);
> INIT_LIST_HEAD(&peer->send_ready);
>@@ -585,7 +586,8 @@ unsigned long sctp_transport_timeout(struct
>sctp_transport *t)
> {
> unsigned long timeout;
> timeout = t->rto + sctp_jitter(t->rto);
>- if (t->state != SCTP_UNCONFIRMED)
>+ if ((t->state != SCTP_UNCONFIRMED) &&
>+ (t->state != SCTP_PF))
> timeout += t->hbinterval;
> timeout += jiffies;
> return timeout;
>--
>1.7.7.6
--
Sent from my Android phone with SkitMail. Please excuse my brevity.
^ permalink raw reply
* [PATCH] USB: plusb: Add support for PL-2501
From: kyak @ 2012-07-22 17:42 UTC (permalink / raw)
To: linux-kernel; +Cc: Greg Kroah-Hartman, linux-usb, netdev
From: Mikhail Peselnik <peselnik@gmail.com>
This patch adds support for PL-2501 by adding the appropriate USB
ID's. This chip is used in several USB 'Easy Trasfer' Cables.
Signed-off-by: Mikhail Peselnik <peselnik@gmail.com>
Tested-by: Mikhail Peselnik <peselnik@gmail.com>
---
Now with proper sign-offs and right people in cc.
plusb driver (drivers/net/usb/plusb.c) doesn't recognize PL2501 chip.
Since PL2501 uses the same code as PL2301/PL2302 (PL2501 works in
compatibility mode with PL2301/PL2302), the fix is trivial and
attached as a patch.
Just to note: the patch is not mine, it can be found here and there on
Internet.
I've tested the patch and it works great.
Thank you.
--- linux-3.5/drivers/net/usb/plusb.c.orig 2012-07-22
21:06:41.905802795 +0400
+++ linux-3.5/drivers/net/usb/plusb.c 2012-07-22 21:07:00.345552404 +0400
@@ -107,7 +107,7 @@ static int pl_reset(struct usbnet *dev)
}
static const struct driver_info prolific_info = {
- .description = "Prolific PL-2301/PL-2302/PL-25A1",
+ .description = "Prolific PL-2301/PL-2302/PL-25A1/PL-2501",
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
/* some PL-2302 versions seem to fail usb_set_interface() */
.reset = pl_reset,
@@ -139,6 +139,9 @@ static const struct usb_device_id produc
}, {
USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */
.driver_info = (unsigned long) &prolific_info,
+}, {
+ USB_DEVICE(0x067b, 0x2501), /* PL-2501 */
+ .driver_info = (unsigned long) &prolific_info,
},
{ }, // END
@@ -158,5 +161,5 @@ static struct usb_driver plusb_driver =
module_usb_driver(plusb_driver);
MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver");
+MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1/2501 USB Host to Host
Link Driver");
MODULE_LICENSE("GPL");
^ permalink raw reply
* [PATCH net-next 4/4] forcedeth: advertise transmit time stamping
From: Richard Cochran @ 2012-07-22 17:15 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Willem de Bruijn
In-Reply-To: <cover.1342976654.git.richardcochran@gmail.com>
This driver now offers software transmit time stamping, so it should
advertise that fact via ethtool. Compile tested only.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Cc: Willem de Bruijn <willemb@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 67edc2e..f45def0 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -5182,6 +5182,7 @@ static const struct ethtool_ops ops = {
.get_ethtool_stats = nv_get_ethtool_stats,
.get_sset_count = nv_get_sset_count,
.self_test = nv_self_test,
+ .get_ts_info = ethtool_op_get_ts_info,
};
/* The mgmt unit and driver use a semaphore to access the phy during init */
--
1.7.2.5
^ permalink raw reply related
* [PATCH net-next 3/4] e1000e: advertise transmit time stamping
From: Richard Cochran @ 2012-07-22 17:15 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Willem de Bruijn, Jeff Kirsher, e1000-devel
In-Reply-To: <cover.1342976654.git.richardcochran@gmail.com>
This driver now offers software transmit time stamping, so it should
advertise that fact via ethtool. Compile tested only.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: e1000-devel@lists.sourceforge.net
---
drivers/net/ethernet/intel/e1000e/ethtool.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 105d554..0349e24 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -2061,6 +2061,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_coalesce = e1000_get_coalesce,
.set_coalesce = e1000_set_coalesce,
.get_rxnfc = e1000_get_rxnfc,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void e1000e_set_ethtool_ops(struct net_device *netdev)
--
1.7.2.5
^ permalink raw reply related
* [PATCH net-next 2/4] e1000: advertise transmit time stamping
From: Richard Cochran @ 2012-07-22 17:15 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Willem de Bruijn, Jeff Kirsher, e1000-devel
In-Reply-To: <cover.1342976654.git.richardcochran@gmail.com>
This driver now offers software transmit time stamping, so it should
advertise that fact via ethtool. Compile tested only.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: e1000-devel@lists.sourceforge.net
---
drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index 3103f0b..736a7d9 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -1851,6 +1851,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_sset_count = e1000_get_sset_count,
.get_coalesce = e1000_get_coalesce,
.set_coalesce = e1000_set_coalesce,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void e1000_set_ethtool_ops(struct net_device *netdev)
--
1.7.2.5
^ permalink raw reply related
* [PATCH net-next 1/4] bnx2x: advertise transmit time stamping
From: Richard Cochran @ 2012-07-22 17:15 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Eilon Greenstein, Willem de Bruijn
In-Reply-To: <cover.1342976654.git.richardcochran@gmail.com>
This driver now offers software transmit time stamping, so it should
advertise that fact via ethtool. Compile tested only.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Cc: Eilon Greenstein <eilong@broadcom.com>
Cc: Willem de Bruijn <willemb@google.com>
---
.../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index bff3129..fc4e0e3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -2978,6 +2978,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.get_module_eeprom = bnx2x_get_module_eeprom,
.get_eee = bnx2x_get_eee,
.set_eee = bnx2x_set_eee,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void bnx2x_set_ethtool_ops(struct net_device *netdev)
--
1.7.2.5
^ permalink raw reply related
* [PATCH net-next 0/4] Tx time stamp advertising for four drivers
From: Richard Cochran @ 2012-07-22 17:15 UTC (permalink / raw)
To: netdev; +Cc: David Miller
This series updates the ethtool code for four drivers that recently
add the skb_tx_timestamp hook. Since these drivers now support
software transmit time stamps, let us also advertise this via ethtool.
Thanks,
Richard
Richard Cochran (4):
bnx2x: advertise transmit time stamping
e1000: advertise transmit time stamping
e1000e: advertise transmit time stamping
forcedeth: advertise transmit time stamping
.../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 1 +
drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 1 +
drivers/net/ethernet/intel/e1000e/ethtool.c | 1 +
drivers/net/ethernet/nvidia/forcedeth.c | 1 +
4 files changed, 4 insertions(+), 0 deletions(-)
--
1.7.2.5
^ permalink raw reply
* net-next compilation failure since 76ff5cc9
From: Richard Cochran @ 2012-07-22 16:21 UTC (permalink / raw)
To: netdev; +Cc: Jiri Pirko, David S. Miller
Without CONFIG_RPS, net-next fails to compile with
CC net/core/rtnetlink.o
/linux/net/core/rtnetlink.c: In function ‘rtnl_fill_ifinfo’:
/linux/net/core/rtnetlink.c:895: error: ‘struct net_device’ has no member named ‘num_rx_queues’
make[3]: *** [net/core/rtnetlink.o] Error 1
Looks like this was caused by
76ff5cc9 rtnl: allow to specify number of rx and tx queues on device creation
Not sure how to fix.
Thanks,
Richard
^ permalink raw reply
* RE: [PATCH 00/13] drivers: hv: kvp
From: KY Srinivasan @ 2012-07-22 15:08 UTC (permalink / raw)
To: Ben Hutchings
Cc: Olaf Hering, Greg KH, apw@canonical.com,
devel@linuxdriverproject.org, virtualization@lists.osdl.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <1342925458.11373.210.camel@deadeye.wl.decadent.org.uk>
> -----Original Message-----
> From: Ben Hutchings [mailto:ben@decadent.org.uk]
> Sent: Saturday, July 21, 2012 10:51 PM
> To: KY Srinivasan
> Cc: Olaf Hering; Greg KH; apw@canonical.com; devel@linuxdriverproject.org;
> virtualization@lists.osdl.org; linux-kernel@vger.kernel.org;
> netdev@vger.kernel.org
> Subject: Re: [PATCH 00/13] drivers: hv: kvp
>
> On Tue, 2012-07-03 at 15:24 +0000, KY Srinivasan wrote:
> >
> > > -----Original Message-----
> > > From: Ben Hutchings [mailto:ben@decadent.org.uk]
> > > Sent: Monday, July 02, 2012 3:57 PM
> > > To: KY Srinivasan
> > > Cc: Olaf Hering; Greg KH; apw@canonical.com; devel@linuxdriverproject.org;
> > > virtualization@lists.osdl.org; linux-kernel@vger.kernel.org;
> > > netdev@vger.kernel.org
> > > Subject: Re: [PATCH 00/13] drivers: hv: kvp
> > >
> > > On Mon, Jul 02, 2012 at 03:22:25PM +0000, KY Srinivasan wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Olaf Hering [mailto:olaf@aepfle.de]
> > > > > Sent: Thursday, June 28, 2012 10:24 AM
> > > > > To: KY Srinivasan
> > > > > Cc: Greg KH; apw@canonical.com; devel@linuxdriverproject.org;
> > > > > virtualization@lists.osdl.org; linux-kernel@vger.kernel.org
> > > > > Subject: Re: [PATCH 00/13] drivers: hv: kvp
> > > > >
> > > > > On Tue, Jun 26, KY Srinivasan wrote:
> > > > >
> > > > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > > > The fact that it was Red Hat specific was the main part, this should be
> > > > > > > done in a standard way, with standard tools, right?
> > > > > >
> > > > > > The reason I asked this question was to make sure I address these
> > > > > > issues in addition to whatever I am debugging now. I use the standard
> > > > > > tools and calls to retrieve all the IP configuration. As I look at
> > > > > > each distribution the files they keep persistent IP configuration
> > > > > > Information is different and that is the reason I chose to start with
> > > > > > RedHat. If there is a standard way to store the configuration, I will
> > > > > > do that.
> > > > >
> > > > >
> > > > > KY,
> > > > >
> > > > > instead of using system() in kvp_get_ipconfig_info and kvp_set_ip_info,
> > > > > wouldnt it be easier to call an external helper script which does all
> > > > > the distribution specific work? Just define some API to pass values to
> > > > > the script, and something to read values collected by the script back
> > > > > into the daemon.
> > > >
> > > > On the "Get" side I mostly use standard commands/APIs to get all the
> > > information:
> > > >
> > > > 1) IP address information and subnet mask: getifaddrs()
> > > > 2) DNS information: Parsing /etc/resolv.conf
> > > > 3) /sbin/ip command for all the routing information
> > >
> > > If you're interested in the *current* configuration then (1) and (3)
> > > are OK but you should really use the rtnetlink API.
> > >
> > > However, I suspect that Hyper-V assumes that current and persistent
> > > configuration are the same thing, which is obviously not true in
> > > general on Linux. But if NetworkManager is running then you can
> > > assume they are.
> >
> > I am only interested in the currently active information. Why do you
> > recommend the use of rtnetlink API over the "ip" command. If I am not
> > mistaken, the ip command uses netlink to get the information.
> [...]
>
> 'Screen-scraping' the output of administrative tools is not good
> practice. It may be the best you can do when writing a shell script,
> but for a C program it's generaly less reliable and often more difficult
> than using the underlying C API.
Ben,
Based on the input I have gotten, the consensus appears to be to have external
scripts to both GET and SET IP related configuration information. So, the KVP
daemon will need to parse information returned from these external distro specific
scripts (on the GET side). While I agree with you that it is good to use C APIs, I currently
have the implementation using the "ip" command and it appears to be quite simple.
Furthermore, given that the information I need to pass back to the host needs to be
appropriately formatted (based on host specified format), I suspect using the "ip" command
may actually simplify the code.
Regards,
K. Y
^ permalink raw reply
* Re: [PATCH] Fix divide zero crash when xmit with no enabled port
From: Jiri Pirko @ 2012-07-22 13:59 UTC (permalink / raw)
To: ISHIKAWA Mutsumi; +Cc: netdev
In-Reply-To: <20120721203035.71B4DFFC4A@master.hanzubon.jp>
Sat, Jul 21, 2012 at 10:30:35PM CEST, ishikawa@hanzubon.jp wrote:
>
>hash calculation in lb_transmit() cause divide zero crash when
>xmit on teaming loadbalance mode with no team member port is enabled
>(this situation means team->en_port_count = 0). Add check
>team->en_port_count is not 0.
What kernel are you see the issue one?
I believe this is fixed in net-next already:
commit 122bb046bcfb8f3d2d94d9f7f6b74da187a740f2
Author: Jiri Pirko <jpirko@redhat.com>
Date: Tue Jun 26 06:52:45 2012 +0000
team: fix team_adjust_ops with regard to enabled ports
team_adjust_ops should check for enabled ports, not all ports.
This may lead to division by zero. This patch fixes this.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
>
>---
> drivers/net/team/team_mode_loadbalance.c | 2 ++
> 1 file changed, 2 insertions(+)
>
>diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
>index 86e8183..7b878d5 100644
>--- a/drivers/net/team/team_mode_loadbalance.c
>+++ b/drivers/net/team/team_mode_loadbalance.c
>@@ -38,6 +38,8 @@ static bool lb_transmit(struct team *team, struct sk_buff *skb)
> if (unlikely(!fp))
> goto drop;
> hash = SK_RUN_FILTER(fp, skb);
>+ if (team->en_port_count < 1)
>+ goto drop;
> port_index = hash % team->en_port_count;
> port = team_get_port_by_index_rcu(team, port_index);
> if (unlikely(!port))
>--
>1.7.10.4
>
^ permalink raw reply
* Claim requirements
From: Nokia Promotion @ 2012-07-22 12:03 UTC (permalink / raw)
You are receiving this message because you are a Winner of 300,000 Pounds from
Nokia Online Lottery game 2012.
Claim requirements are as follows:
(1) Your full names
(2) Contact Address
(3) Age
(4) Occupation
(5) Telephone
(6) Sex
(7) Nationality
Contact Mr. Thomas Hillary on (nokiadp76@yahoo.cn)
Copyright ©2012 Nokia. All rights reserved.
^ permalink raw reply
* Re: [PATCH] mlx4: Add support for EEH error recovery
From: Or Gerlitz @ 2012-07-22 10:29 UTC (permalink / raw)
To: Kleber Sacilotto de Souza
Cc: David S. Miller, netdev, Jack Morgenstein, Yevgeny Petrilin,
cascardo, brking, Shlomo Pongratz
In-Reply-To: <1342814143-5744-1-git-send-email-klebers@linux.vnet.ibm.com>
On 7/20/2012 10:55 PM, Kleber Sacilotto de Souza wrote:
> Currently the mlx4 drivers don't have the necessary callbacks to
> implement EEH errors detection and recovery [...]
Hi,
Shlomo Pongratz from Mellanox took a look on the patch, and we'd like
to clarify with you something - OTOH you mention EEH (Extended Error
Handling) error recovery which is a PPC related term mentioned in
Documentation/powerpc/eeh-pci-error-recovery.txt, but OTHO you've
implemented callbacks mentioned in the AER (Advanced Error Reporting)
doc of Documentation/PCI/pcieaer-howto.txt, is there anything in the
code you added which maybe implicitly assumes PPC arch?
Or.
^ permalink raw reply
* [PATCH RFC] tcp: use seqlock for all cached tcp_metrics
From: Julian Anastasov @ 2012-07-22 9:44 UTC (permalink / raw)
To: netdev
The ability to reclaim existing cache entries
requires metrics to be accessed with additional seqlock.
fastopen_cache tried to provide such locking for its values
but there is always the risk to access reclaimed entry.
So, we add global metrics_seqlock and two macros to
access metrics for read/write purposes. The macros are not
checkpatch friendly but with capital letters and no gotos in
the code we avoid additional level of indentation.
We provide access structure, initialized according to
the socket type with information about the hash bucket, dst, etc.
We also fix some problems:
- tcpm_stamp was not updated in tcpm_check_stamp when tcpm_suck_dst
was called, move the update into tcpm_suck_dst, so that we do not
call it infinitely on every next cache hit
- in tcp_tw_remember_stamp we incorrectly checked tw instead of tm,
it can lead to oops if the cached entry is not found
Signed-off-by: Julian Anastasov <ja@ssi.bg>
---
Open questions:
- is it safe to upgrade a seqlock reader to writer? May be
it is a good idea to provide such method seqlock_is_upgraded
in include/linux/seqlock.h. In our case it can safe 1 of the 3
lookups that we do in write mode.
net/ipv4/tcp_metrics.c | 471 +++++++++++++++++++++++++++++-------------------
1 files changed, 287 insertions(+), 184 deletions(-)
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 992f1bf..6c623cc 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -49,6 +49,11 @@ struct tcp_metrics_block {
struct tcp_fastopen_metrics tcpm_fastopen;
};
+#define TCP_METRICS_TIMEOUT (60 * 60 * HZ)
+#define TCP_METRICS_RECLAIM_DEPTH 5
+
+static DEFINE_SEQLOCK(metrics_seqlock);
+
static bool tcp_metric_locked(struct tcp_metrics_block *tm,
enum tcp_metric_index idx)
{
@@ -101,12 +106,19 @@ struct tcpm_hash_bucket {
struct tcp_metrics_block __rcu *chain;
};
-static DEFINE_SPINLOCK(tcp_metrics_lock);
+static inline struct tcpm_hash_bucket *tcpm_hash_bucket_get(struct net *net,
+ unsigned int hash)
+{
+ hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
+ return net->ipv4.tcp_metrics_hash + hash;
+}
static void tcpm_suck_dst(struct tcp_metrics_block *tm, struct dst_entry *dst)
{
u32 val;
+ tm->tcpm_stamp = jiffies;
+
val = 0;
if (dst_metric_locked(dst, RTAX_RTT))
val |= 1 << TCP_METRIC_RTT;
@@ -132,20 +144,111 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, struct dst_entry *dst)
tm->tcpm_fastopen.cookie.len = 0;
}
-static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
- struct inetpeer_addr *addr,
- unsigned int hash,
- bool reclaim)
+/* Read if present */
+#define TCP_METRIC_MODE_READ 0x00
+
+/* Can refresh metrics from dst if expired */
+#define TCP_METRIC_MODE_REFRESH 0x01
+
+/* Write access is required/acquired */
+#define TCP_METRIC_MODE_WRITE 0x02
+
+/* Can create new or reclaim existing entry */
+#define TCP_METRIC_MODE_CREATE 0x04
+
+/* Writer needs exclusive access */
+#define TCP_METRIC_MODE_SET (TCP_METRIC_MODE_REFRESH | \
+ TCP_METRIC_MODE_WRITE | \
+ TCP_METRIC_MODE_CREATE)
+
+/* Writer needs exclusive access only if entry is already cached */
+#define TCP_METRIC_MODE_UPDATE (TCP_METRIC_MODE_REFRESH | \
+ TCP_METRIC_MODE_WRITE)
+
+/* Reader needs up to date metrics only if already cached,
+ * can become writer on refresh
+ */
+#define TCP_METRIC_MODE_GET_CACHED TCP_METRIC_MODE_REFRESH
+
+/* Reader needs up to date metrics, can become writer on refresh or
+ * reclaim/create
+ */
+#define TCP_METRIC_MODE_GET (TCP_METRIC_MODE_REFRESH | \
+ TCP_METRIC_MODE_CREATE)
+
+struct tcp_metrics_access {
+ struct inetpeer_addr addr;
+ struct tcpm_hash_bucket *hb;
+ struct dst_entry *dst;
+ int mode;
+ unsigned int seq;
+};
+
+/* Start access for metrics:
+ * - on return tm can be dereferenced only before TCP_METRIC_ACCESS_STOP
+ * - Writers will update before TCP_METRIC_ACCESS_STOP
+ * - Readers should copy values before TCP_METRIC_ACCESS_STOP and
+ * will return values after TCP_METRIC_ACCESS_STOP
+ */
+#define TCP_METRIC_ACCESS_START(a, tm, m) \
+ do { \
+ a.mode = (m); \
+ tm = tcpm_start(&a)
+
+/* Stop accessing the metrics, readers will retry on clash with writer */
+#define TCP_METRIC_ACCESS_STOP(a) } while (unlikely(tcpm_stop(&a)))
+
+/* Start access for metrics under RCU protection
+ * dst: used for refresh, optional, required for TCP_METRIC_MODE_CREATE
+ * Return with locked seqlock in R/W mode depending on TCP_METRIC_MODE_WRITE
+ * Caller should call tcpm_stop in all cases
+ */
+static struct tcp_metrics_block *tcpm_start(struct tcp_metrics_access *a)
{
+ struct dst_entry *dst = a->dst;
+ struct tcpm_hash_bucket *hb = a->hb;
+ struct inetpeer_addr *addr = &a->addr;
+ int mode = a->mode;
struct tcp_metrics_block *tm;
- struct net *net;
+ int depth;
- spin_lock_bh(&tcp_metrics_lock);
- net = dev_net(dst->dev);
- if (unlikely(reclaim)) {
+ if (likely(!(mode & TCP_METRIC_MODE_WRITE)))
+ a->seq = read_seqbegin(&metrics_seqlock);
+ else
+ write_seqlock_bh(&metrics_seqlock);
+
+restart:
+ depth = 0;
+ for (tm = rcu_dereference(hb->chain); tm;
+ tm = rcu_dereference(tm->tcpm_next)) {
+ if (addr_same(&tm->tcpm_addr, addr))
+ break;
+ depth++;
+ }
+
+ if (tm) {
+ if (mode & TCP_METRIC_MODE_REFRESH &&
+ unlikely(time_after(jiffies, tm->tcpm_stamp +
+ TCP_METRICS_TIMEOUT)) && dst)
+ goto refresh;
+ return tm;
+ }
+
+ if (!(mode & TCP_METRIC_MODE_CREATE))
+ return NULL;
+ if (!(mode & TCP_METRIC_MODE_WRITE)) {
+ mode |= TCP_METRIC_MODE_WRITE;
+ a->mode = mode;
+ write_seqlock_bh(&metrics_seqlock);
+ /* !seqlock_is_upgraded(&metrics_seqlock, a->seq) ? */
+ if (read_seqretry(&metrics_seqlock, a->seq + 1))
+ goto restart;
+ }
+
+ if (depth > TCP_METRICS_RECLAIM_DEPTH) {
struct tcp_metrics_block *oldest;
- oldest = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain);
+ oldest = rcu_dereference(hb->chain);
for (tm = rcu_dereference(oldest->tcpm_next); tm;
tm = rcu_dereference(tm->tcpm_next)) {
if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp))
@@ -155,165 +258,115 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
} else {
tm = kmalloc(sizeof(*tm), GFP_ATOMIC);
if (!tm)
- goto out_unlock;
+ return NULL;
+ tm->tcpm_next = hb->chain;
+ rcu_assign_pointer(hb->chain, tm);
}
tm->tcpm_addr = *addr;
- tm->tcpm_stamp = jiffies;
+reset:
tcpm_suck_dst(tm, dst);
-
- if (likely(!reclaim)) {
- tm->tcpm_next = net->ipv4.tcp_metrics_hash[hash].chain;
- rcu_assign_pointer(net->ipv4.tcp_metrics_hash[hash].chain, tm);
- }
-
-out_unlock:
- spin_unlock_bh(&tcp_metrics_lock);
return tm;
-}
-#define TCP_METRICS_TIMEOUT (60 * 60 * HZ)
-
-static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst)
-{
- if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT)))
- tcpm_suck_dst(tm, dst);
-}
-
-#define TCP_METRICS_RECLAIM_DEPTH 5
-#define TCP_METRICS_RECLAIM_PTR (struct tcp_metrics_block *) 0x1UL
-
-static struct tcp_metrics_block *tcp_get_encode(struct tcp_metrics_block *tm, int depth)
-{
- if (tm)
- return tm;
- if (depth > TCP_METRICS_RECLAIM_DEPTH)
- return TCP_METRICS_RECLAIM_PTR;
- return NULL;
+refresh:
+ if (mode & TCP_METRIC_MODE_WRITE)
+ goto reset;
+ mode |= TCP_METRIC_MODE_WRITE;
+ a->mode = mode;
+ write_seqlock_bh(&metrics_seqlock);
+ /* seqlock_is_upgraded(&metrics_seqlock, a->seq) ? */
+ if (!read_seqretry(&metrics_seqlock, a->seq + 1))
+ goto reset;
+ if (addr_same(&tm->tcpm_addr, addr))
+ goto reset;
+ goto restart;
}
-static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *addr,
- struct net *net, unsigned int hash)
+/* Stop Read/Write (0) or retry Read (1) */
+static inline int tcpm_stop(struct tcp_metrics_access *a)
{
- struct tcp_metrics_block *tm;
- int depth = 0;
-
- for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
- tm = rcu_dereference(tm->tcpm_next)) {
- if (addr_same(&tm->tcpm_addr, addr))
- break;
- depth++;
- }
- return tcp_get_encode(tm, depth);
+ if (likely(!(a->mode & TCP_METRIC_MODE_WRITE)))
+ return read_seqretry(&metrics_seqlock, a->seq);
+ write_sequnlock_bh(&metrics_seqlock);
+ return 0;
}
-static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
- struct dst_entry *dst)
+/* Fill access structure from socket req */
+static bool tcpm_access_from_sock_req(struct tcp_metrics_access *a,
+ struct request_sock *req,
+ struct dst_entry *dst)
{
- struct tcp_metrics_block *tm;
- struct inetpeer_addr addr;
unsigned int hash;
- struct net *net;
- addr.family = req->rsk_ops->family;
- switch (addr.family) {
+ a->addr.family = req->rsk_ops->family;
+ switch (a->addr.family) {
case AF_INET:
- addr.addr.a4 = inet_rsk(req)->rmt_addr;
- hash = (__force unsigned int) addr.addr.a4;
+ a->addr.addr.a4 = inet_rsk(req)->rmt_addr;
+ hash = (__force unsigned int) a->addr.addr.a4;
break;
case AF_INET6:
- *(struct in6_addr *)addr.addr.a6 = inet6_rsk(req)->rmt_addr;
+ *(struct in6_addr *)a->addr.addr.a6 = inet6_rsk(req)->rmt_addr;
hash = ipv6_addr_hash(&inet6_rsk(req)->rmt_addr);
break;
default:
- return NULL;
+ return false;
}
- net = dev_net(dst->dev);
- hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
-
- for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
- tm = rcu_dereference(tm->tcpm_next)) {
- if (addr_same(&tm->tcpm_addr, &addr))
- break;
- }
- tcpm_check_stamp(tm, dst);
- return tm;
+ a->hb = tcpm_hash_bucket_get(dev_net(dst->dev), hash);
+ a->dst = dst;
+ return true;
}
-static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock *tw)
+/* Fill access structure from tw socket */
+static bool tcpm_access_from_tw_sock(struct tcp_metrics_access *a,
+ struct inet_timewait_sock *tw)
{
struct inet6_timewait_sock *tw6;
- struct tcp_metrics_block *tm;
- struct inetpeer_addr addr;
unsigned int hash;
- struct net *net;
- addr.family = tw->tw_family;
- switch (addr.family) {
+ a->addr.family = tw->tw_family;
+ switch (a->addr.family) {
case AF_INET:
- addr.addr.a4 = tw->tw_daddr;
- hash = (__force unsigned int) addr.addr.a4;
+ a->addr.addr.a4 = tw->tw_daddr;
+ hash = (__force unsigned int) a->addr.addr.a4;
break;
case AF_INET6:
tw6 = inet6_twsk((struct sock *)tw);
- *(struct in6_addr *)addr.addr.a6 = tw6->tw_v6_daddr;
+ *(struct in6_addr *) a->addr.addr.a6 = tw6->tw_v6_daddr;
hash = ipv6_addr_hash(&tw6->tw_v6_daddr);
break;
default:
- return NULL;
+ return false;
}
- net = twsk_net(tw);
- hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
-
- for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
- tm = rcu_dereference(tm->tcpm_next)) {
- if (addr_same(&tm->tcpm_addr, &addr))
- break;
- }
- return tm;
+ a->hb = tcpm_hash_bucket_get(twsk_net(tw), hash);
+ a->dst = NULL;
+ return true;
}
-static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk,
- struct dst_entry *dst,
- bool create)
+/* Fill access structure from normal socket */
+static bool tcpm_access_from_sock(struct tcp_metrics_access *a,
+ struct sock *sk, struct dst_entry *dst)
{
- struct tcp_metrics_block *tm;
- struct inetpeer_addr addr;
unsigned int hash;
- struct net *net;
- bool reclaim;
- addr.family = sk->sk_family;
- switch (addr.family) {
+ a->addr.family = sk->sk_family;
+ switch (a->addr.family) {
case AF_INET:
- addr.addr.a4 = inet_sk(sk)->inet_daddr;
- hash = (__force unsigned int) addr.addr.a4;
+ a->addr.addr.a4 = inet_sk(sk)->inet_daddr;
+ hash = (__force unsigned int) a->addr.addr.a4;
break;
case AF_INET6:
- *(struct in6_addr *)addr.addr.a6 = inet6_sk(sk)->daddr;
+ *(struct in6_addr *) a->addr.addr.a6 = inet6_sk(sk)->daddr;
hash = ipv6_addr_hash(&inet6_sk(sk)->daddr);
break;
default:
- return NULL;
- }
-
- net = dev_net(dst->dev);
- hash = hash_32(hash, net->ipv4.tcp_metrics_hash_log);
-
- tm = __tcp_get_metrics(&addr, net, hash);
- reclaim = false;
- if (tm == TCP_METRICS_RECLAIM_PTR) {
- reclaim = true;
- tm = NULL;
+ return false;
}
- if (!tm && create)
- tm = tcpm_new(dst, &addr, hash, reclaim);
- else
- tcpm_check_stamp(tm, dst);
- return tm;
+ a->hb = tcpm_hash_bucket_get(dev_net(dst->dev), hash);
+ a->dst = dst;
+ return true;
}
/* Save metrics learned by this TCP session. This function is called
@@ -325,10 +378,11 @@ void tcp_update_metrics(struct sock *sk)
const struct inet_connection_sock *icsk = inet_csk(sk);
struct dst_entry *dst = __sk_dst_get(sk);
struct tcp_sock *tp = tcp_sk(sk);
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
unsigned long rtt;
u32 val;
- int m;
+ int m, reset_rtt, mode;
if (sysctl_tcp_nometrics_save || !dst)
return;
@@ -336,21 +390,29 @@ void tcp_update_metrics(struct sock *sk)
if (dst->flags & DST_HOST)
dst_confirm(dst);
+ if (!tcpm_access_from_sock(&a, sk, dst))
+ return;
+
+ reset_rtt = 0;
rcu_read_lock();
if (icsk->icsk_backoff || !tp->srtt) {
/* This session failed to estimate rtt. Why?
* Probably, no packets returned in time. Reset our
* results.
*/
- tm = tcp_get_metrics(sk, dst, false);
- if (tm && !tcp_metric_locked(tm, TCP_METRIC_RTT))
- tcp_metric_set(tm, TCP_METRIC_RTT, 0);
- goto out_unlock;
- } else
- tm = tcp_get_metrics(sk, dst, true);
+ reset_rtt = 1;
+ }
+ mode = reset_rtt ? TCP_METRIC_MODE_UPDATE : TCP_METRIC_MODE_SET;
+ TCP_METRIC_ACCESS_START(a, tm, mode);
if (!tm)
- goto out_unlock;
+ goto out_stop;
+
+ if (reset_rtt) {
+ if (!tcp_metric_locked(tm, TCP_METRIC_RTT))
+ tcp_metric_set(tm, TCP_METRIC_RTT, 0);
+ goto out_stop;
+ }
rtt = tcp_metric_get_jiffies(tm, TCP_METRIC_RTT);
m = rtt - tp->srtt;
@@ -435,7 +497,9 @@ void tcp_update_metrics(struct sock *sk)
}
}
tm->tcpm_stamp = jiffies;
-out_unlock:
+
+out_stop:;
+ TCP_METRIC_ACCESS_STOP(a);
rcu_read_unlock();
}
@@ -445,6 +509,8 @@ void tcp_init_metrics(struct sock *sk)
{
struct dst_entry *dst = __sk_dst_get(sk);
struct tcp_sock *tp = tcp_sk(sk);
+ struct tcp_metrics_access a;
+ struct tcp_metrics_block copy;
struct tcp_metrics_block *tm;
u32 val;
@@ -453,12 +519,21 @@ void tcp_init_metrics(struct sock *sk)
dst_confirm(dst);
- rcu_read_lock();
- tm = tcp_get_metrics(sk, dst, true);
- if (!tm) {
- rcu_read_unlock();
+ if (!tcpm_access_from_sock(&a, sk, dst))
goto reset;
+
+ rcu_read_lock();
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_GET);
+ if (tm) {
+ /* We need only metric values */
+ copy.tcpm_lock = tm->tcpm_lock;
+ memcpy(copy.tcpm_vals, tm->tcpm_vals, sizeof(tm->tcpm_vals));
}
+ TCP_METRIC_ACCESS_STOP(a);
+ rcu_read_unlock();
+ if (!tm)
+ goto reset;
+ tm = ©
if (tcp_metric_locked(tm, TCP_METRIC_CWND))
tp->snd_cwnd_clamp = tcp_metric_get(tm, TCP_METRIC_CWND);
@@ -482,10 +557,8 @@ void tcp_init_metrics(struct sock *sk)
}
val = tcp_metric_get(tm, TCP_METRIC_RTT);
- if (val == 0 || tp->srtt == 0) {
- rcu_read_unlock();
+ if (val == 0 || tp->srtt == 0)
goto reset;
- }
/* Initial rtt is determined from SYN,SYN-ACK.
* The segment is small and rtt may appear much
* less than real one. Use per-dst memory
@@ -510,7 +583,6 @@ void tcp_init_metrics(struct sock *sk)
tp->mdev = val;
tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk));
}
- rcu_read_unlock();
tcp_set_rto(sk);
reset:
@@ -536,30 +608,41 @@ reset:
tp->snd_cwnd_stamp = tcp_time_stamp;
}
-bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check)
+bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst,
+ bool paws_check)
{
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
- bool ret;
+ u32 tcpm_ts_stamp = 0;
+ u32 tcpm_ts = 0;
+ u32 rtt = 0;
+ bool ret = false;
- if (!dst)
- return false;
+ if (!dst || !tcpm_access_from_sock_req(&a, req, dst))
+ return ret;
rcu_read_lock();
- tm = __tcp_get_metrics_req(req, dst);
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_GET_CACHED);
+ if (tm) {
+ tcpm_ts_stamp = tm->tcpm_ts_stamp;
+ tcpm_ts = tm->tcpm_ts;
+ rtt = tcp_metric_get(tm, TCP_METRIC_RTT);
+ }
+ TCP_METRIC_ACCESS_STOP(a);
+ rcu_read_unlock();
if (paws_check) {
if (tm &&
- (u32)get_seconds() - tm->tcpm_ts_stamp < TCP_PAWS_MSL &&
- (s32)(tm->tcpm_ts - req->ts_recent) > TCP_PAWS_WINDOW)
+ (u32) get_seconds() - tcpm_ts_stamp < TCP_PAWS_MSL &&
+ (s32) (tcpm_ts - req->ts_recent) > TCP_PAWS_WINDOW)
ret = false;
else
ret = true;
} else {
- if (tm && tcp_metric_get(tm, TCP_METRIC_RTT) && tm->tcpm_ts_stamp)
+ if (tm && rtt && tcpm_ts_stamp)
ret = true;
else
ret = false;
}
- rcu_read_unlock();
return ret;
}
@@ -567,19 +650,29 @@ EXPORT_SYMBOL_GPL(tcp_peer_is_proven);
void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst)
{
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
+ u32 tcpm_ts_stamp = 0;
+ u32 tcpm_ts = 0;
+ if (!tcpm_access_from_sock(&a, sk, dst))
+ return;
rcu_read_lock();
- tm = tcp_get_metrics(sk, dst, true);
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_GET);
+ if (tm) {
+ tcpm_ts_stamp = tm->tcpm_ts_stamp;
+ tcpm_ts = tm->tcpm_ts;
+ }
+ TCP_METRIC_ACCESS_STOP(a);
+ rcu_read_unlock();
if (tm) {
struct tcp_sock *tp = tcp_sk(sk);
- if ((u32)get_seconds() - tm->tcpm_ts_stamp <= TCP_PAWS_MSL) {
- tp->rx_opt.ts_recent_stamp = tm->tcpm_ts_stamp;
- tp->rx_opt.ts_recent = tm->tcpm_ts;
+ if ((u32)get_seconds() - tcpm_ts_stamp <= TCP_PAWS_MSL) {
+ tp->rx_opt.ts_recent_stamp = tcpm_ts_stamp;
+ tp->rx_opt.ts_recent = tcpm_ts;
}
}
- rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(tcp_fetch_timewait_stamp);
@@ -591,37 +684,42 @@ EXPORT_SYMBOL_GPL(tcp_fetch_timewait_stamp);
bool tcp_remember_stamp(struct sock *sk)
{
struct dst_entry *dst = __sk_dst_get(sk);
+ struct tcp_metrics_access a;
+ struct tcp_metrics_block *tm;
bool ret = false;
- if (dst) {
- struct tcp_metrics_block *tm;
+ if (!dst || !tcpm_access_from_sock(&a, sk, dst))
+ return ret;
- rcu_read_lock();
- tm = tcp_get_metrics(sk, dst, true);
- if (tm) {
- struct tcp_sock *tp = tcp_sk(sk);
+ rcu_read_lock();
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_SET);
+ if (tm) {
+ struct tcp_sock *tp = tcp_sk(sk);
- if ((s32)(tm->tcpm_ts - tp->rx_opt.ts_recent) <= 0 ||
- ((u32)get_seconds() - tm->tcpm_ts_stamp > TCP_PAWS_MSL &&
- tm->tcpm_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) {
- tm->tcpm_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp;
- tm->tcpm_ts = tp->rx_opt.ts_recent;
- }
- ret = true;
+ if ((s32)(tm->tcpm_ts - tp->rx_opt.ts_recent) <= 0 ||
+ ((u32)get_seconds() - tm->tcpm_ts_stamp > TCP_PAWS_MSL &&
+ tm->tcpm_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) {
+ tm->tcpm_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp;
+ tm->tcpm_ts = tp->rx_opt.ts_recent;
}
- rcu_read_unlock();
+ ret = true;
}
+ TCP_METRIC_ACCESS_STOP(a);
+ rcu_read_unlock();
return ret;
}
bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw)
{
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
bool ret = false;
+ if (!tcpm_access_from_tw_sock(&a, tw))
+ return ret;
rcu_read_lock();
- tm = __tcp_get_metrics_tw(tw);
- if (tw) {
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_WRITE);
+ if (tm) {
const struct tcp_timewait_sock *tcptw;
struct sock *sk = (struct sock *) tw;
@@ -634,48 +732,53 @@ bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw)
}
ret = true;
}
+ TCP_METRIC_ACCESS_STOP(a);
rcu_read_unlock();
return ret;
}
-static DEFINE_SEQLOCK(fastopen_seqlock);
-
void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
struct tcp_fastopen_cookie *cookie,
int *syn_loss, unsigned long *last_syn_loss)
{
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
+ struct tcp_fastopen_metrics tfom_copy[1], *tfom;
+
+ if (!tcpm_access_from_sock(&a, sk, __sk_dst_get(sk)))
+ return;
rcu_read_lock();
- tm = tcp_get_metrics(sk, __sk_dst_get(sk), false);
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_GET_CACHED);
+ if (tm)
+ tfom_copy[0] = tm->tcpm_fastopen;
+ TCP_METRIC_ACCESS_STOP(a);
+ rcu_read_unlock();
if (tm) {
- struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen;
- unsigned int seq;
-
- do {
- seq = read_seqbegin(&fastopen_seqlock);
- if (tfom->mss)
- *mss = tfom->mss;
- *cookie = tfom->cookie;
- *syn_loss = tfom->syn_loss;
- *last_syn_loss = *syn_loss ? tfom->last_syn_loss : 0;
- } while (read_seqretry(&fastopen_seqlock, seq));
+ tfom = tfom_copy;
+ if (tfom->mss)
+ *mss = tfom->mss;
+ *cookie = tfom->cookie;
+ *syn_loss = tfom->syn_loss;
+ *last_syn_loss = *syn_loss ? tfom->last_syn_loss : 0;
}
- rcu_read_unlock();
}
void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
struct tcp_fastopen_cookie *cookie, bool syn_lost)
{
+ struct tcp_metrics_access a;
struct tcp_metrics_block *tm;
+ if (!tcpm_access_from_sock(&a, sk, __sk_dst_get(sk)))
+ return;
+
rcu_read_lock();
- tm = tcp_get_metrics(sk, __sk_dst_get(sk), true);
+ TCP_METRIC_ACCESS_START(a, tm, TCP_METRIC_MODE_SET);
if (tm) {
struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen;
- write_seqlock_bh(&fastopen_seqlock);
tfom->mss = mss;
if (cookie->len > 0)
tfom->cookie = *cookie;
@@ -684,8 +787,8 @@ void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
tfom->last_syn_loss = jiffies;
} else
tfom->syn_loss = 0;
- write_sequnlock_bh(&fastopen_seqlock);
}
+ TCP_METRIC_ACCESS_STOP(a);
rcu_read_unlock();
}
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH 00/16] Remove the ipv4 routing cache
From: Vijay Subramanian @ 2012-07-22 7:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120720.142502.1144557295933737451.davem@davemloft.net>
On 20 July 2012 14:25, David Miller <davem@davemloft.net> wrote:
> On a SPARC-T3 output route lookups are ~876 cycles. Input route
> lookups are ~1169 cycles with rpfilter disabled, and about ~1468
> cycles with rpfilter enabled.
>
> These measurements were taken with the kbench_mod test module in the
> net_test_tools GIT tree:
...
> In fact anyone suitable motivated can just fire up perf on the loading
> of the test net_test_tools benchmark kernel module. I spend much of
> my time going:
>
> bash# perf record insmod ./kbench_mod.ko dst=172.30.42.22 src=74.128.0.1 iif=2
> bash# perf report
>
Dave,
I have been running your routing removal patches for the past 3 days
(upgraded yesterday to latest set including the 17th patch you sent in
response to Eric's comment) and have not seen any issues (crashes
etc).
I used the kbench_mod module in net_test_tools for testing. Averaging
after 16 runs (with 4 samples in each run), I get the following for
output route lookups
(ip_route_output_key):
with route-removal patches: average of 544 cycles with min and max
of 511 and 721
without patches: (commit fa0afcd10 ) : average of 211 cycles with
min and max of 196 and 266
Apart from time spent in fib_table_lookup(), it seems time is also
spent in check_leaf(). I assume this is expected behavior.
Here are 2 sample perf outputs (I have appended the kbench outputs to
each file)
With patches applied:
# ========
# captured on: Sat Jul 21 23:49:43 2012
# hostname : vijaynsu
# os release : 3.5.0-rc7vns+
# perf version : 3.4.13690.gfda9f
# arch : x86_64
# nrcpus online : 8
# nrcpus avail : 8
# cpudesc : Intel(R) Xeon(R) CPU E5320 @ 1.86GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 16407032 kB
# cmdline : /usr/src/net-next/tools/perf/perf record insmod
./kbench_mod.ko dst=172.27.231.128 src=172.27.231.28
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0,
config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 1, 2, 3, 4, 5, 6,
7, 8 }
# HEADER_CPU_TOPOLOGY info available, use -I to display
# ========
#
# Samples: 458 of event 'cycles'
# Event count (approx.): 209175177
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .............................
#
40.62% insmod [kernel.kallsyms] [k] fib_table_lookup
24.38% insmod [kernel.kallsyms] [k] __ip_route_output_key
12.33% insmod [kernel.kallsyms] [k] check_leaf
9.29% insmod [kernel.kallsyms] [k] dst_release
6.43% insmod [kernel.kallsyms] [k] __ip_dev_find
2.67% insmod [edac_core] [k] 0x000000000000c1d7
1.33% insmod [kernel.kallsyms] [k] ip_route_output_flow
0.70% insmod [kernel.kallsyms] [k] copy_user_generic_string
0.46% insmod [kernel.kallsyms] [k] path_openat
0.41% insmod [kernel.kallsyms] [k] clear_page_c
0.38% insmod libc-2.11.1.so [.] _dl_addr
0.23% insmod [kernel.kallsyms] [k] native_write_msr_safe
0.22% insmod [kernel.kallsyms] [k] rcu_irq_enter
0.22% insmod [kernel.kallsyms] [k] mem_cgroup_count_vm_event
0.19% insmod [kernel.kallsyms] [k] do_mpage_readpage
0.12% insmod [kernel.kallsyms] [k] math_state_restore
0.02% insmod [kernel.kallsyms] [k] stop_one_cpu
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
Jul 21 23:49:43 vijaynsu kernel: [ 146.382382] kbench:
Jul 21 23:49:43 vijaynsu kernel: [ 146.382382] flow
[IIF(0),OIF(0),MARK(0x00000000),D(172.27.231.128),S(172.27.231.28),TOS(0x00)]
Jul 21 23:49:43 vijaynsu kernel: [ 146.382388] kbench: sizeof(struct
rtable)==176
Jul 21 23:49:43 vijaynsu kernel: [ 146.409943] kbench:
ip_route_output_key tdiff: 546
Jul 21 23:49:43 vijaynsu kernel: [ 146.437490] kbench:
ip_route_output_key tdiff: 546
Jul 21 23:49:43 vijaynsu kernel: [ 146.465064] kbench:
ip_route_output_key tdiff: 511
Jul 21 23:49:43 vijaynsu kernel: [ 146.492615] kbench:
ip_route_output_key tdiff: 672
--------------
Without patches applied : (omitting hardware info)
# Overhead Command Shared Object Symbol
# ........ ....... ................. ............................
#
46.47% insmod [kernel.kallsyms] [k] __ip_route_output_key
17.71% insmod [kernel.kallsyms] [k] dst_release
15.51% insmod [kernel.kallsyms] [k] local_bh_enable
5.92% insmod [kvm] [k] 0x00000000000771ea
4.92% insmod [kernel.kallsyms] [k] local_bh_disable
2.37% insmod [kernel.kallsyms] [k] ip_route_output_flow
1.80% insmod [kernel.kallsyms] [k] clear_page_c
1.32% insmod [kernel.kallsyms] [k] find_get_page
1.31% insmod [kernel.kallsyms] [k] page_remove_rmap
1.15% insmod [kernel.kallsyms] [k] copy_user_generic_string
0.59% insmod [kernel.kallsyms] [k] trace_module_notify
0.59% insmod [kernel.kallsyms] [k] free_pcppages_bulk
0.25% insmod [kernel.kallsyms] [k] __do_fault
0.05% insmod [kernel.kallsyms] [k] wait_for_common
0.02% insmod [kernel.kallsyms] [k] finish_task_switch
0.00% insmod [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
Jul 21 23:33:09 vijaynsu kernel: [13465.736545] kbench:
Jul 21 23:33:09 vijaynsu kernel: [13465.736545] flow
[IIF(0),OIF(0),MARK(0x00000000),D(172.27.231.128),S(172.27.231.28),TOS(0x00)]
Jul 21 23:33:09 vijaynsu kernel: [13465.736551] kbench: sizeof(struct
rtable)==216
Jul 21 23:33:09 vijaynsu kernel: [13465.746394] kbench:
ip_route_output_key tdiff: 231
Jul 21 23:33:09 vijaynsu kernel: [13465.756229] kbench:
ip_route_output_key tdiff: 210
Jul 21 23:33:09 vijaynsu kernel: [13465.766062] kbench:
ip_route_output_key tdiff: 196
Jul 21 23:33:09 vijaynsu kernel: [13465.775894] kbench:
ip_route_output_key tdiff: 196
Thanks,
Vijay
^ permalink raw reply
* [patch net-next] rtnl: do not include num_rx_queues into msg when CONFIG_RPS is not set
From: Jiri Pirko @ 2012-07-22 7:26 UTC (permalink / raw)
To: netdev; +Cc: davem, sfr
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
net/core/rtnetlink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 5bb1ebc..334b930 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -892,7 +892,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put_u32(skb, IFLA_GROUP, dev->group) ||
nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) ||
+#ifdef CONFIG_RPS
nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) ||
+#endif
(dev->ifindex != dev->iflink &&
nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
(dev->master &&
--
1.7.10.4
^ permalink raw reply related
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