From: Ralf Baechle <ralf@linux-mips.org>
To: "David S. Miller" <davem@davemloft.net>, netdev@vger.kernel.org
Subject: [AX.25 2/2] Fix reference counting by socket timers
Date: Fri, 21 Jul 2006 11:36:40 -0400 [thread overview]
Message-ID: <20060721153640.GA16379@linux-mips.org> (raw)
In-Reply-To: <20060721152946.GA16317@linux-mips.org>
With struct sock and ax25_cb in a unified data structure it now is
possible to fix the reference counting by using the sk_reset_timer
and sk_stop_timer helper function - the previous implementation was
based simply on "principle hope".
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
include/net/ax25.h | 5 +++
include/net/rose.h | 1
net/ax25/af_ax25.c | 55 ++++++++++++++++++---------------
net/ax25/ax25_timer.c | 82 ++++++++++++++++++++------------------------------
net/netrom/nr_timer.c | 29 +++++++++--------
net/rose/af_rose.c | 6 +--
net/rose/rose_timer.c | 79 +++++++++++++++++++-----------------------------
7 files changed, 120 insertions(+), 137 deletions(-)
Index: linux-net/net/ax25/af_ax25.c
===================================================================
--- linux-net.orig/net/ax25/af_ax25.c 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/net/ax25/af_ax25.c 2006-07-14 01:36:04.000000000 +0100
@@ -49,8 +49,6 @@
#include <net/ip.h>
#include <net/arp.h>
-
-
HLIST_HEAD(ax25_list);
DEFINE_SPINLOCK(ax25_list_lock);
@@ -261,13 +259,10 @@ void ax25_destroy_socket(struct ax25_soc
*/
static void ax25_destroy_timer(unsigned long data)
{
- struct ax25_sock *ax25 = (struct ax25_sock *)data;
- struct sock *sk;
-
- sk=ax25->sk;
-
+ struct ax25_sock *ax25 = (struct ax25_sock *) data;
+ struct sock *sk = ax25->sk;
+
bh_lock_sock(sk);
- sock_hold(sk);
ax25_destroy_socket(ax25);
bh_unlock_sock(sk);
sock_put(sk);
@@ -281,6 +276,7 @@ static void ax25_destroy_timer(unsigned
*/
void ax25_destroy_socket(struct ax25_sock *ax25)
{
+ struct sock *sk = ax25->sk;
struct sk_buff *skb;
ax25_cb_del(ax25);
@@ -293,9 +289,9 @@ void ax25_destroy_socket(struct ax25_soc
ax25_clear_queues(ax25); /* Flush the queues */
- if (ax25->sk != NULL) {
+ if (sk) {
while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
- if (skb->sk != ax25->sk) {
+ if (skb->sk != sk) {
/* A pending connection */
struct ax25_sock *sax25 = ax25_sk(skb->sk);
@@ -308,23 +304,14 @@ void ax25_destroy_socket(struct ax25_soc
kfree_skb(skb);
}
- skb_queue_purge(&ax25->sk->sk_write_queue);
- }
+ skb_queue_purge(&sk->sk_write_queue);
- if (ax25->sk != NULL) {
- if (atomic_read(&ax25->sk->sk_wmem_alloc) ||
- atomic_read(&ax25->sk->sk_rmem_alloc)) {
+ if (atomic_read(&sk->sk_wmem_alloc) ||
+ atomic_read(&sk->sk_rmem_alloc)) {
/* Defer: outstanding buffers */
- init_timer(&ax25->dtimer);
- ax25->dtimer.expires = jiffies + 2 * HZ;
- ax25->dtimer.function = ax25_destroy_timer;
- ax25->dtimer.data = (unsigned long)ax25;
- add_timer(&ax25->dtimer);
- } else {
- struct sock *sk=ax25->sk;
- ax25->sk=NULL;
+ sk_reset_timer(sk, &ax25->dtimer, jiffies + 2 * HZ);
+ } else
sock_put(sk);
- }
} else {
sock_put(&ax25->sock);
}
@@ -497,11 +484,29 @@ struct ax25_sock *ax25_alloc_sock(struct
skb_queue_head_init(&ax25->ack_queue);
skb_queue_head_init(&ax25->reseq_queue);
- init_timer(&ax25->timer);
init_timer(&ax25->t1timer);
+ ax25->t1timer.function = &ax25_t1timer_expiry;
+ ax25->t1timer.data = (unsigned long) ax25;
+
init_timer(&ax25->t2timer);
+ ax25->t2timer.function = &ax25_t2timer_expiry;
+ ax25->t2timer.data = (unsigned long) ax25;
+
init_timer(&ax25->t3timer);
+ ax25->t3timer.function = &ax25_t3timer_expiry;
+ ax25->t3timer.data = (unsigned long) ax25;
+
init_timer(&ax25->idletimer);
+ ax25->idletimer.function= &ax25_idletimer_expiry;
+ ax25->idletimer.data = (unsigned long) ax25;
+
+ init_timer(&ax25->timer);
+ ax25->timer.function = &ax25_heartbeat_expiry;
+ ax25->timer.data = (unsigned long) ax25;
+
+ init_timer(&ax25->dtimer);
+ ax25->dtimer.function = ax25_destroy_timer;
+ ax25->dtimer.data = (unsigned long)ax25;
ax25_fillin_cb(ax25, NULL);
Index: linux-net/net/ax25/ax25_timer.c
===================================================================
--- linux-net.orig/net/ax25/ax25_timer.c 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/net/ax25/ax25_timer.c 2006-07-14 01:36:04.000000000 +0100
@@ -34,94 +34,70 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
-static void ax25_heartbeat_expiry(unsigned long);
-static void ax25_t1timer_expiry(unsigned long);
-static void ax25_t2timer_expiry(unsigned long);
-static void ax25_t3timer_expiry(unsigned long);
-static void ax25_idletimer_expiry(unsigned long);
-
void ax25_start_heartbeat(struct ax25_sock *ax25)
{
- del_timer(&ax25->timer);
-
- ax25->timer.data = (unsigned long)ax25;
- ax25->timer.function = &ax25_heartbeat_expiry;
- ax25->timer.expires = jiffies + 5 * HZ;
+ struct sock *sk = &ax25->sock;
- add_timer(&ax25->timer);
+ sk_reset_timer(sk, &ax25->timer, jiffies + 5 * HZ);
}
void ax25_start_t1timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t1timer);
-
- ax25->t1timer.data = (unsigned long)ax25;
- ax25->t1timer.function = &ax25_t1timer_expiry;
- ax25->t1timer.expires = jiffies + ax25->t1;
+ struct sock *sk = &ax25->sock;
- add_timer(&ax25->t1timer);
+ sk_reset_timer(sk, &ax25->t1timer, jiffies + ax25->t1);
}
void ax25_start_t2timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t2timer);
+ struct sock *sk = &ax25->sock;
- ax25->t2timer.data = (unsigned long)ax25;
- ax25->t2timer.function = &ax25_t2timer_expiry;
- ax25->t2timer.expires = jiffies + ax25->t2;
-
- add_timer(&ax25->t2timer);
+ sk_reset_timer(sk, &ax25->t2timer, jiffies + ax25->t2);
}
void ax25_start_t3timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t3timer);
+ struct sock *sk = &ax25->sock;
- if (ax25->t3 > 0) {
- ax25->t3timer.data = (unsigned long)ax25;
- ax25->t3timer.function = &ax25_t3timer_expiry;
- ax25->t3timer.expires = jiffies + ax25->t3;
+ sk_stop_timer(sk, &ax25->t3timer);
- add_timer(&ax25->t3timer);
- }
+ if (ax25->t3 > 0)
+ sk_reset_timer(sk, &ax25->t3timer, jiffies + ax25->t3);
}
void ax25_start_idletimer(struct ax25_sock *ax25)
{
- del_timer(&ax25->idletimer);
+ struct sock *sk = &ax25->sock;
- if (ax25->idle > 0) {
- ax25->idletimer.data = (unsigned long)ax25;
- ax25->idletimer.function = &ax25_idletimer_expiry;
- ax25->idletimer.expires = jiffies + ax25->idle;
+ sk_stop_timer(sk, &ax25->idletimer);
- add_timer(&ax25->idletimer);
- }
+ if (ax25->idle > 0)
+ sk_reset_timer(sk, &ax25->idletimer, jiffies + ax25->idle);
}
void ax25_stop_heartbeat(struct ax25_sock *ax25)
{
- del_timer(&ax25->timer);
+ sk_stop_timer(&ax25->sock, &ax25->timer);
}
void ax25_stop_t1timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t1timer);
+ sk_stop_timer(&ax25->sock, &ax25->t1timer);
}
void ax25_stop_t2timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t2timer);
+ sk_stop_timer(&ax25->sock, &ax25->t2timer);
}
void ax25_stop_t3timer(struct ax25_sock *ax25)
{
- del_timer(&ax25->t3timer);
+ sk_stop_timer(&ax25->sock, &ax25->t3timer);
}
void ax25_stop_idletimer(struct ax25_sock *ax25)
{
- del_timer(&ax25->idletimer);
+ sk_stop_timer(&ax25->sock, &ax25->idletimer);
}
int ax25_t1timer_running(struct ax25_sock *ax25)
@@ -139,7 +115,7 @@ unsigned long ax25_display_timer(struct
EXPORT_SYMBOL(ax25_display_timer);
-static void ax25_heartbeat_expiry(unsigned long param)
+void ax25_heartbeat_expiry(unsigned long param)
{
int proto = AX25_PROTO_STD_SIMPLEX;
struct ax25_sock *ax25 = (struct ax25_sock *)param;
@@ -162,9 +138,11 @@ static void ax25_heartbeat_expiry(unsign
break;
#endif
}
+
+ sock_put(&ax25->sock);
}
-static void ax25_t1timer_expiry(unsigned long param)
+void ax25_t1timer_expiry(unsigned long param)
{
struct ax25_sock *ax25 = (struct ax25_sock *)param;
@@ -181,9 +159,11 @@ static void ax25_t1timer_expiry(unsigned
break;
#endif
}
+
+ sock_put(&ax25->sock);
}
-static void ax25_t2timer_expiry(unsigned long param)
+void ax25_t2timer_expiry(unsigned long param)
{
struct ax25_sock *ax25 = (struct ax25_sock *)param;
@@ -200,9 +180,11 @@ static void ax25_t2timer_expiry(unsigned
break;
#endif
}
+
+ sock_put(&ax25->sock);
}
-static void ax25_t3timer_expiry(unsigned long param)
+void ax25_t3timer_expiry(unsigned long param)
{
struct ax25_sock *ax25 = (struct ax25_sock *)param;
@@ -221,9 +203,11 @@ static void ax25_t3timer_expiry(unsigned
break;
#endif
}
+
+ sock_put(&ax25->sock);
}
-static void ax25_idletimer_expiry(unsigned long param)
+void ax25_idletimer_expiry(unsigned long param)
{
struct ax25_sock *ax25 = (struct ax25_sock *)param;
@@ -242,4 +226,6 @@ static void ax25_idletimer_expiry(unsign
break;
#endif
}
+
+ sock_put(&ax25->sock);
}
Index: linux-net/include/net/ax25.h
===================================================================
--- linux-net.orig/include/net/ax25.h 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/include/net/ax25.h 2006-07-14 01:36:04.000000000 +0100
@@ -395,6 +395,11 @@ extern void ax25_stop_t1timer(struct ax2
extern void ax25_stop_t2timer(struct ax25_sock *);
extern void ax25_stop_t3timer(struct ax25_sock *);
extern void ax25_stop_idletimer(struct ax25_sock *);
+extern void ax25_heartbeat_expiry(unsigned long);
+extern void ax25_t1timer_expiry(unsigned long);
+extern void ax25_t2timer_expiry(unsigned long);
+extern void ax25_t3timer_expiry(unsigned long);
+extern void ax25_idletimer_expiry(unsigned long);
extern int ax25_t1timer_running(struct ax25_sock *);
extern unsigned long ax25_display_timer(struct timer_list *);
Index: linux-net/net/netrom/nr_timer.c
===================================================================
--- linux-net.orig/net/netrom/nr_timer.c 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/net/netrom/nr_timer.c 2006-07-14 01:37:19.000000000 +0100
@@ -65,21 +65,21 @@ void nr_start_t1timer(struct sock *sk)
{
struct nr_sock *nr = nr_sk(sk);
- mod_timer(&nr->t1timer, jiffies + nr->t1);
+ sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1);
}
void nr_start_t2timer(struct sock *sk)
{
struct nr_sock *nr = nr_sk(sk);
- mod_timer(&nr->t2timer, jiffies + nr->t2);
+ sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2);
}
void nr_start_t4timer(struct sock *sk)
{
struct nr_sock *nr = nr_sk(sk);
- mod_timer(&nr->t4timer, jiffies + nr->t4);
+ sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4);
}
void nr_start_idletimer(struct sock *sk)
@@ -87,37 +87,37 @@ void nr_start_idletimer(struct sock *sk)
struct nr_sock *nr = nr_sk(sk);
if (nr->idle > 0)
- mod_timer(&nr->idletimer, jiffies + nr->idle);
+ sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle);
}
void nr_start_heartbeat(struct sock *sk)
{
- mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ);
}
void nr_stop_t1timer(struct sock *sk)
{
- del_timer(&nr_sk(sk)->t1timer);
+ sk_stop_timer(sk, &nr_sk(sk)->t1timer);
}
void nr_stop_t2timer(struct sock *sk)
{
- del_timer(&nr_sk(sk)->t2timer);
+ sk_stop_timer(sk, &nr_sk(sk)->t2timer);
}
void nr_stop_t4timer(struct sock *sk)
{
- del_timer(&nr_sk(sk)->t4timer);
+ sk_stop_timer(sk, &nr_sk(sk)->t4timer);
}
void nr_stop_idletimer(struct sock *sk)
{
- del_timer(&nr_sk(sk)->idletimer);
+ sk_stop_timer(sk, &nr_sk(sk)->idletimer);
}
void nr_stop_heartbeat(struct sock *sk)
{
- del_timer(&sk->sk_timer);
+ sk_stop_timer(sk, &sk->sk_timer);
}
int nr_t1timer_running(struct sock *sk)
@@ -137,10 +137,7 @@ static void nr_heartbeat_expiry(unsigned
is accepted() it isn't 'dead' so doesn't get removed. */
if (sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
- sock_hold(sk);
- bh_unlock_sock(sk);
nr_destroy_socket(sk);
- sock_put(sk);
return;
}
break;
@@ -161,7 +158,9 @@ static void nr_heartbeat_expiry(unsigned
}
nr_start_heartbeat(sk);
+
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void nr_t2timer_expiry(unsigned long param)
@@ -175,6 +174,7 @@ static void nr_t2timer_expiry(unsigned l
nr_enquiry_response(sk);
}
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void nr_t4timer_expiry(unsigned long param)
@@ -184,6 +184,7 @@ static void nr_t4timer_expiry(unsigned l
bh_lock_sock(sk);
nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY;
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void nr_idletimer_expiry(unsigned long param)
@@ -212,6 +213,7 @@ static void nr_idletimer_expiry(unsigned
sock_set_flag(sk, SOCK_DEAD);
}
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void nr_t1timer_expiry(unsigned long param)
@@ -257,4 +259,5 @@ static void nr_t1timer_expiry(unsigned l
nr_start_t1timer(sk);
bh_unlock_sock(sk);
+ sock_put(sk);
}
Index: linux-net/include/net/rose.h
===================================================================
--- linux-net.orig/include/net/rose.h 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/include/net/rose.h 2006-07-14 01:36:04.000000000 +0100
@@ -218,6 +218,7 @@ extern int rose_parse_facilities(unsign
extern void rose_disconnect(struct sock *, int, int, int);
/* rose_timer.c */
+extern void rose_init_timers(struct sock *sk);
extern void rose_start_heartbeat(struct sock *);
extern void rose_start_t1timer(struct sock *);
extern void rose_start_t2timer(struct sock *);
Index: linux-net/net/rose/af_rose.c
===================================================================
--- linux-net.orig/net/rose/af_rose.c 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/net/rose/af_rose.c 2006-07-14 01:36:04.000000000 +0100
@@ -522,8 +522,7 @@ static int rose_create(struct socket *so
sock->ops = &rose_proto_ops;
sk->sk_protocol = protocol;
- init_timer(&rose->timer);
- init_timer(&rose->idletimer);
+ rose_init_timers(sk);
rose->t1 = msecs_to_jiffies(sysctl_rose_call_request_timeout);
rose->t2 = msecs_to_jiffies(sysctl_rose_reset_request_timeout);
@@ -567,8 +566,7 @@ static struct sock *rose_make_new(struct
sk->sk_sleep = osk->sk_sleep;
sock_copy_flags(sk, osk);
- init_timer(&rose->timer);
- init_timer(&rose->idletimer);
+ rose_init_timers(sk);
orose = rose_sk(osk);
rose->t1 = orose->t1;
Index: linux-net/net/rose/rose_timer.c
===================================================================
--- linux-net.orig/net/rose/rose_timer.c 2006-07-14 01:34:39.000000000 +0100
+++ linux-net/net/rose/rose_timer.c 2006-07-14 01:36:04.000000000 +0100
@@ -5,7 +5,7 @@
* (at your option) any later version.
*
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
- * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
+ * Copyright (C) 2002, 06 Ralf Baechle DL5RB (ralf@gnu.org)
*/
#include <linux/errno.h>
#include <linux/types.h>
@@ -33,97 +33,78 @@ static void rose_heartbeat_expiry(unsign
static void rose_timer_expiry(unsigned long);
static void rose_idletimer_expiry(unsigned long);
-void rose_start_heartbeat(struct sock *sk)
+void rose_init_timers(struct sock *sk)
{
- del_timer(&sk->sk_timer);
+ struct rose_sock *rose = rose_sk(sk);
- sk->sk_timer.data = (unsigned long)sk;
+ sk->sk_timer.data = (unsigned long) sk;
sk->sk_timer.function = &rose_heartbeat_expiry;
- sk->sk_timer.expires = jiffies + 5 * HZ;
- add_timer(&sk->sk_timer);
+ init_timer(&rose->timer);
+ rose->timer.data = (unsigned long) sk;
+ rose->timer.function = &rose_timer_expiry;
+
+ init_timer(&rose->idletimer);
+ rose->idletimer.data = (unsigned long) sk;
+ rose->idletimer.function = &rose_idletimer_expiry;
+}
+
+void rose_start_heartbeat(struct sock *sk)
+{
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ);
}
void rose_start_t1timer(struct sock *sk)
{
struct rose_sock *rose = rose_sk(sk);
- del_timer(&rose->timer);
-
- rose->timer.data = (unsigned long)sk;
- rose->timer.function = &rose_timer_expiry;
- rose->timer.expires = jiffies + rose->t1;
-
- add_timer(&rose->timer);
+ sk_reset_timer(sk, &rose->timer, jiffies + rose->t1);
}
void rose_start_t2timer(struct sock *sk)
{
struct rose_sock *rose = rose_sk(sk);
- del_timer(&rose->timer);
-
- rose->timer.data = (unsigned long)sk;
- rose->timer.function = &rose_timer_expiry;
- rose->timer.expires = jiffies + rose->t2;
-
- add_timer(&rose->timer);
+ sk_reset_timer(sk, &rose->timer, jiffies + rose->t2);
}
void rose_start_t3timer(struct sock *sk)
{
struct rose_sock *rose = rose_sk(sk);
- del_timer(&rose->timer);
-
- rose->timer.data = (unsigned long)sk;
- rose->timer.function = &rose_timer_expiry;
- rose->timer.expires = jiffies + rose->t3;
-
- add_timer(&rose->timer);
+ sk_reset_timer(sk, &rose->timer, jiffies + rose->t3);
}
void rose_start_hbtimer(struct sock *sk)
{
struct rose_sock *rose = rose_sk(sk);
- del_timer(&rose->timer);
-
- rose->timer.data = (unsigned long)sk;
- rose->timer.function = &rose_timer_expiry;
- rose->timer.expires = jiffies + rose->hb;
-
- add_timer(&rose->timer);
+ sk_reset_timer(sk, &rose->timer, jiffies + rose->hb);
}
void rose_start_idletimer(struct sock *sk)
{
struct rose_sock *rose = rose_sk(sk);
- del_timer(&rose->idletimer);
-
- if (rose->idle > 0) {
- rose->idletimer.data = (unsigned long)sk;
- rose->idletimer.function = &rose_idletimer_expiry;
- rose->idletimer.expires = jiffies + rose->idle;
+ sk_stop_timer(sk, &rose->idletimer);
- add_timer(&rose->idletimer);
- }
+ if (rose->idle > 0)
+ sk_reset_timer(sk, &rose->idletimer, jiffies + rose->idle);
}
void rose_stop_heartbeat(struct sock *sk)
{
- del_timer(&sk->sk_timer);
+ sk_stop_timer(sk, &sk->sk_timer);
}
void rose_stop_timer(struct sock *sk)
{
- del_timer(&rose_sk(sk)->timer);
+ sk_stop_timer(sk, &rose_sk(sk)->timer);
}
void rose_stop_idletimer(struct sock *sk)
{
- del_timer(&rose_sk(sk)->idletimer);
+ sk_stop_timer(sk, &rose_sk(sk)->idletimer);
}
static void rose_heartbeat_expiry(unsigned long param)
@@ -138,9 +119,8 @@ static void rose_heartbeat_expiry(unsign
is accepted() it isn't 'dead' so doesn't get removed. */
if (sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
- bh_unlock_sock(sk);
rose_destroy_socket(sk);
- return;
+ goto out_unlock;
}
break;
@@ -161,7 +141,10 @@ static void rose_heartbeat_expiry(unsign
}
rose_start_heartbeat(sk);
+
+out_unlock:
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void rose_timer_expiry(unsigned long param)
@@ -191,6 +174,7 @@ static void rose_timer_expiry(unsigned l
break;
}
bh_unlock_sock(sk);
+ sock_put(sk);
}
static void rose_idletimer_expiry(unsigned long param)
@@ -214,4 +198,5 @@ static void rose_idletimer_expiry(unsign
sock_set_flag(sk, SOCK_DEAD);
}
bh_unlock_sock(sk);
+ sock_put(sk);
}
next prev parent reply other threads:[~2006-07-21 15:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-21 15:29 [AX.25 1/2] Introduce struct ax25_sock Ralf Baechle
2006-07-21 15:36 ` Ralf Baechle [this message]
2006-07-21 17:26 ` Arnaldo Carvalho de Melo
2006-07-22 8:36 ` David Miller
2006-07-22 12:13 ` Ralf Baechle
2006-07-23 0:05 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060721153640.GA16379@linux-mips.org \
--to=ralf@linux-mips.org \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).