patch-2.4.21 linux-2.4.21/net/ipv4/icmp.c
Next file: linux-2.4.21/net/ipv4/igmp.c
Previous file: linux-2.4.21/net/ipv4/fib_semantics.c
Back to the patch index
Back to the overall index
- Lines: 151
- Date:
2003-06-13 07:51:39.000000000 -0700
- Orig file:
linux-2.4.20/net/ipv4/icmp.c
- Orig date:
2002-08-02 17:39:46.000000000 -0700
diff -urN linux-2.4.20/net/ipv4/icmp.c linux-2.4.21/net/ipv4/icmp.c
@@ -178,55 +178,27 @@
static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
/*
- * The ICMP socket. This is the most convenient way to flow control
+ * The ICMP socket(s). This is the most convenient way to flow control
* our ICMP output as well as maintain a clean interface throughout
* all layers. All Socketless IP sends will soon be gone.
*/
-struct inode icmp_inode;
-struct socket *icmp_socket = &icmp_inode.u.socket_i;
+static struct inode __icmp_inode[NR_CPUS];
+#define icmp_socket (&__icmp_inode[smp_processor_id()].u.socket_i)
+#define icmp_socket_cpu(X) (&__icmp_inode[(X)].u.socket_i)
-/* ICMPv4 socket is only a bit non-reenterable (unlike ICMPv6,
- which is strongly non-reenterable). A bit later it will be made
- reenterable and the lock may be removed then.
- */
-
-static int icmp_xmit_holder = -1;
-
-static int icmp_xmit_lock_bh(void)
-{
- if (!spin_trylock(&icmp_socket->sk->lock.slock)) {
- if (icmp_xmit_holder == smp_processor_id())
- return -EAGAIN;
- spin_lock(&icmp_socket->sk->lock.slock);
- }
- icmp_xmit_holder = smp_processor_id();
- return 0;
-}
-
-static __inline__ int icmp_xmit_lock(void)
+static void icmp_xmit_lock(void)
{
- int ret;
local_bh_disable();
- ret = icmp_xmit_lock_bh();
- if (ret)
- local_bh_enable();
- return ret;
-}
-
-static void icmp_xmit_unlock_bh(void)
-{
- icmp_xmit_holder = -1;
- spin_unlock(&icmp_socket->sk->lock.slock);
+ if (unlikely(!spin_trylock(&icmp_socket->sk->lock.slock)))
+ BUG();
}
-static __inline__ void icmp_xmit_unlock(void)
+static void icmp_xmit_unlock(void)
{
- icmp_xmit_unlock_bh();
- local_bh_enable();
+ spin_unlock_bh(&icmp_socket->sk->lock.slock);
}
-
/*
* Send an ICMP frame.
*/
@@ -348,8 +320,7 @@
if (ip_options_echo(&icmp_param->replyopts, skb))
return;
- if (icmp_xmit_lock_bh())
- return;
+ icmp_xmit_lock();
icmp_param->data.icmph.checksum=0;
icmp_param->csum=0;
@@ -374,7 +345,7 @@
}
ip_rt_put(rt);
out:
- icmp_xmit_unlock_bh();
+ icmp_xmit_unlock();
}
@@ -456,8 +427,7 @@
}
}
- if (icmp_xmit_lock())
- return;
+ icmp_xmit_lock();
/*
* Construct source address and options.
@@ -985,29 +955,32 @@
void __init icmp_init(struct net_proto_family *ops)
{
- int err;
+ int err, i;
- icmp_inode.i_mode = S_IFSOCK;
- icmp_inode.i_sock = 1;
- icmp_inode.i_uid = 0;
- icmp_inode.i_gid = 0;
- init_waitqueue_head(&icmp_inode.i_wait);
- init_waitqueue_head(&icmp_inode.u.socket_i.wait);
-
- icmp_socket->inode = &icmp_inode;
- icmp_socket->state = SS_UNCONNECTED;
- icmp_socket->type=SOCK_RAW;
-
- if ((err=ops->create(icmp_socket, IPPROTO_ICMP))<0)
- panic("Failed to create the ICMP control socket.\n");
- icmp_socket->sk->allocation=GFP_ATOMIC;
- icmp_socket->sk->sndbuf = SK_WMEM_MAX*2;
- icmp_socket->sk->protinfo.af_inet.ttl = MAXTTL;
- icmp_socket->sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
-
- /* Unhash it so that IP input processing does not even
- * see it, we do not wish this socket to see incoming
- * packets.
- */
- icmp_socket->sk->prot->unhash(icmp_socket->sk);
+ for (i = 0; i < NR_CPUS; i++) {
+ __icmp_inode[i].i_mode = S_IFSOCK;
+ __icmp_inode[i].i_sock = 1;
+ __icmp_inode[i].i_uid = 0;
+ __icmp_inode[i].i_gid = 0;
+ init_waitqueue_head(&__icmp_inode[i].i_wait);
+ init_waitqueue_head(&__icmp_inode[i].u.socket_i.wait);
+
+ icmp_socket_cpu(i)->inode = &__icmp_inode[i];
+ icmp_socket_cpu(i)->state = SS_UNCONNECTED;
+ icmp_socket_cpu(i)->type = SOCK_RAW;
+
+ if ((err=ops->create(icmp_socket_cpu(i), IPPROTO_ICMP)) < 0)
+ panic("Failed to create the ICMP control socket.\n");
+
+ icmp_socket_cpu(i)->sk->allocation=GFP_ATOMIC;
+ icmp_socket_cpu(i)->sk->sndbuf = SK_WMEM_MAX*2;
+ icmp_socket_cpu(i)->sk->protinfo.af_inet.ttl = MAXTTL;
+ icmp_socket_cpu(i)->sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
+
+ /* Unhash it so that IP input processing does not even
+ * see it, we do not wish this socket to see incoming
+ * packets.
+ */
+ icmp_socket_cpu(i)->sk->prot->unhash(icmp_socket_cpu(i)->sk);
+ }
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)