* [PATCH] Netchannel: default, find, add to socket
@ 2006-07-11 5:39 Kelly Daly
2006-07-11 5:57 ` Evgeniy Polyakov
0 siblings, 1 reply; 6+ messages in thread
From: Kelly Daly @ 2006-07-11 5:39 UTC (permalink / raw)
To: David Miller; +Cc: netdev, rusty
Implement finding of correct netchannel for buffer, default netchannel and
attach a netchannel to a socket
Signed-off-by: Kelly Daly <kelly@au.ibm.com>
---
diff -urp davem/include/linux/netchannel.h
kelly_new/include/linux/netchannel.h
--- davem/include/linux/netchannel.h 2006-06-16 15:14:15.000000000 +1000
+++ kelly_new/include/linux/netchannel.h 2006-07-10 14:04:54.000000000 +1000
@@ -19,6 +19,7 @@ struct netchannel {
void (*netchan_callb)(struct netchannel *);
void *netchan_callb_data;
unsigned long netchan_head;
+ wait_queue_head_t wq;
};
extern void netchannel_init(struct netchannel *,
@@ -56,6 +57,11 @@ static inline unsigned char *netchan_buf
return netchan_buf_base(bp) + bp->netchan_buf_offset;
}
+static inline int netchan_data_len(const struct netchannel_buftrailer *bp)
+{
+ return bp->netchan_buf_len - bp->netchan_buf_offset;
+}
+
extern int netchannel_enqueue(struct netchannel *, struct
netchannel_buftrailer *);
extern struct netchannel_buftrailer *__netchannel_dequeue(struct netchannel
*);
static inline struct netchannel_buftrailer *netchannel_dequeue(struct
netchannel *np)
@@ -65,6 +71,10 @@ static inline struct netchannel_buftrail
return __netchannel_dequeue(np);
}
+extern struct netchannel *find_netchannel(const struct netchannel_buftrailer
*bp);
+extern int sock_add_netchannel(struct sock *sk);
extern struct sk_buff *skb_netchan_graft(struct netchannel_buftrailer *,
gfp_t);
#endif /* _LINUX_NETCHANNEL_H */
diff -urp davem/include/net/inet_hashtables.h
kelly_new/include/net/inet_hashtables.h
--- davem/include/net/inet_hashtables.h 2006-06-16 14:34:20.000000000 +1000
+++ kelly_new/include/net/inet_hashtables.h 2006-06-19 10:42:45.000000000
+1000
@@ -418,4 +418,7 @@ static inline struct sock *inet_lookup(s
extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
+extern void inet_hash_register(u8 proto, struct inet_hashinfo *hashinfo);
+extern struct sock *inet_lookup_proto(u8 protocol, u32 saddr, u16 sport, u32
daddr, u16 dport, int ifindex);
+
#endif /* _INET_HASHTABLES_H */
diff -urp davem/include/net/sock.h kelly_new/include/net/sock.h
--- davem/include/net/sock.h 2006-06-16 15:14:16.000000000 +1000
+++ kelly_new/include/net/sock.h 2006-06-19 10:42:45.000000000 +1000
@@ -196,6 +196,7 @@ struct sock {
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
+ struct netchannel *sk_channel;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
struct xfrm_policy *sk_policy[2];
diff -urp davem/net/core/dev.c kelly_new/net/core/dev.c
--- davem/net/core/dev.c 2006-06-16 15:14:16.000000000 +1000
+++ kelly_new/net/core/dev.c 2006-07-10 14:11:22.000000000 +1000
@@ -113,9 +113,12 @@
#include <linux/delay.h>
#include <linux/wireless.h>
#include <linux/netchannel.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
#include <net/iw_handler.h>
#include <asm/current.h>
#include <linux/audit.h>
+#include <net/inet_hashtables.h>
/*
* The list of packet types we will receive (as opposed to discard)
@@ -190,6 +193,8 @@ static inline struct hlist_head *dev_ind
return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
}
+static struct netchannel default_netchannel;
+
/*
* Our notifier list
*/
@@ -1854,11 +1859,18 @@ softnet_break:
goto out;
}
+void netchannel_wake(struct netchannel *np)
+{
+ wake_up(&np->wq);
+}
+
void netchannel_init(struct netchannel *np,
void (*callb)(struct netchannel *), void *callb_data)
{
memset(np, 0, sizeof(*np));
+ init_waitqueue_head(&np->wq);
+
np->netchan_callb = callb;
np->netchan_callb_data = callb_data;
}
@@ -1912,6 +1924,122 @@ struct netchannel_buftrailer *__netchann
}
EXPORT_SYMBOL_GPL(__netchannel_dequeue);
+/* Find the channel for a packet, or return default channel. */
+struct netchannel *find_netchannel(const struct netchannel_buftrailer *bp)
+{
+ struct sock *sk = NULL;
+ int datalen = netchan_data_len(bp);
+
+ switch (bp->netchan_buf_proto) {
+ case __constant_htons(ETH_P_IP): {
+ struct iphdr *ip = (void *)bp - datalen;
+ int iphl = ip->ihl * 4;
+
+ /* FIXME: Do sanity checks, parse packet. */
+
+ if (datalen >+ (iphl + 4) && iphl == sizeof(struct iphdr)) {
+ u16 *ports = (u16 *)ip + 1;
+ sk = inet_lookup_proto(ip->protocol,
+ ip->saddr, ports[0],
+ ip->daddr, ports[1],
+ bp->netchan_buf_dev->ifindex);
+ }
+ break;
+ }
+ }
+
+ if (sk && sk->sk_channel)
+ return sk->sk_channel;
+ return &default_netchannel;
+}
+EXPORT_SYMBOL_GPL(find_netchannel);
+
+/* add the netchannel to the socket */
+int sock_add_netchannel(struct sock *sk)
+{
+ struct netchannel *np;
+
+ np = kmalloc(sizeof(struct netchannel), GFP_KERNEL);
+ if (!np)
+ return -ENOMEM;
+ netchannel_init(np, netchannel_wake, (void *)np);
+ sk->sk_channel = np;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sock_add_netchannel);
+
+/* deal with packets coming to default thread */
+static int netchannel_default_thread(void *unused)
+{
+ struct netchannel *np = &default_netchannel;
+ struct netchannel_buftrailer *nbp;
+ struct sk_buff *skbp;
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&np->wq, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+
+ while (!kthread_should_stop()) {
+ while (np->netchan_tail != np->netchan_head) {
+ nbp = netchannel_dequeue(np);
+ skbp = skb_netchan_graft(nbp, GFP_KERNEL);
+ netif_receive_skb(skbp);
+ }
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
+ remove_wait_queue(&np->wq, &wait);
+ __set_current_state(TASK_RUNNING);
+
+ return 0;
+}
+
static gifconf_func_t * gifconf_list [NPROTO];
/**
@@ -3426,6 +3554,10 @@ static int __init net_dev_init(void)
hotcpu_notifier(dev_cpu_callback, 0);
dst_init();
dev_mcast_init();
+
+ netchannel_init(&default_netchannel, netchannel_wake, (void
*)&default_netchannel);
+ kthread_run(netchannel_default_thread, NULL, "nc_def");
+
rc = 0;
out:
return rc;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Netchannel: default, find, add to socket
2006-07-11 5:39 [PATCH] Netchannel: default, find, add to socket Kelly Daly
@ 2006-07-11 5:57 ` Evgeniy Polyakov
2006-07-11 6:14 ` Kelly Daly
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Evgeniy Polyakov @ 2006-07-11 5:57 UTC (permalink / raw)
To: Kelly Daly; +Cc: David Miller, netdev, rusty
On Tue, Jul 11, 2006 at 03:39:25PM +1000, Kelly Daly (kelly@au1.ibm.com) wrote:
> Implement finding of correct netchannel for buffer, default netchannel and
> attach a netchannel to a socket
>
> Signed-off-by: Kelly Daly <kelly@au.ibm.com>
Hi Kelly.
You have a typo in the code commented below.
I have a question regarsing your netchannel design - as far as I can
see, you steal data in interrupts and then convert it into skb and run
through usual netif_receive_skb(). Thus you dedicate one thread (one
CPU) to do the whole processing for all sockets which do not have
netchannels bound to them. Did you benchmarked such approach both with
and without netchannel bound to the socket?
> +/* Find the channel for a packet, or return default channel. */
> +struct netchannel *find_netchannel(const struct netchannel_buftrailer *bp)
> +{
> + struct sock *sk = NULL;
> + int datalen = netchan_data_len(bp);
> +
> + switch (bp->netchan_buf_proto) {
> + case __constant_htons(ETH_P_IP): {
> + struct iphdr *ip = (void *)bp - datalen;
> + int iphl = ip->ihl * 4;
> +
> + /* FIXME: Do sanity checks, parse packet. */
> +
> + if (datalen >+ (iphl + 4) && iphl == sizeof(struct iphdr)) {
A typo ">+" instead of ">=".
--
Evgeniy Polyakov
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Netchannel: default, find, add to socket
2006-07-11 5:57 ` Evgeniy Polyakov
@ 2006-07-11 6:14 ` Kelly Daly
2006-07-11 6:17 ` Kelly Daly
2006-07-11 7:37 ` David Miller
2 siblings, 0 replies; 6+ messages in thread
From: Kelly Daly @ 2006-07-11 6:14 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: Kelly Daly, David Miller, netdev, rusty
On Tuesday, 11 July 2006 03:57 pm, Evgeniy Polyakov wrote:
> You have a typo in the code commented below.
D'oh!!! That one completely slipped by me - thanks!
I'll resend this patch =)
> I have a question regarsing your netchannel design - as far as I can
> see, you steal data in interrupts and then convert it into skb and run
> through usual netif_receive_skb(). Thus you dedicate one thread (one
> CPU) to do the whole processing for all sockets which do not have
> netchannels bound to them. Did you benchmarked such approach both with
> and without netchannel bound to the socket?
No benchmarking as of yet... Have been a bit busy of late with something
else, but getting back into this V shortly and will hopefully have a whole
lot more info for you soon.
Cheers,
K
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Netchannel: default, find, add to socket
2006-07-11 5:57 ` Evgeniy Polyakov
2006-07-11 6:14 ` Kelly Daly
@ 2006-07-11 6:17 ` Kelly Daly
2006-07-26 0:21 ` David Miller
2006-07-11 7:37 ` David Miller
2 siblings, 1 reply; 6+ messages in thread
From: Kelly Daly @ 2006-07-11 6:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev, rusty, Evgeniy Polyakov
Implement finding of correct netchannel for buffer, default netchannel and
attach a netchannel to a socket
Signed-off-by: Kelly Daly <kelly@au.ibm.com>
---
diff -urp davem/include/linux/netchannel.h
kelly_new/include/linux/netchannel.h
--- davem/include/linux/netchannel.h 2006-06-16 15:14:15.000000000 +1000
+++ kelly_new/include/linux/netchannel.h 2006-07-10 14:04:54.000000000
+1000
@@ -19,6 +19,7 @@ struct netchannel {
void (*netchan_callb)(struct netchannel *);
void *netchan_callb_data;
unsigned long netchan_head;
+ wait_queue_head_t wq;
};
extern void netchannel_init(struct netchannel *,
@@ -56,6 +57,11 @@ static inline unsigned char *netchan_buf
return netchan_buf_base(bp) + bp->netchan_buf_offset;
}
+static inline int netchan_data_len(const struct netchannel_buftrailer *bp)
+{
+ return bp->netchan_buf_len - bp->netchan_buf_offset;
+}
+
extern int netchannel_enqueue(struct netchannel *, struct
netchannel_buftrailer *);
extern struct netchannel_buftrailer *__netchannel_dequeue(struct netchannel
*);
static inline struct netchannel_buftrailer *netchannel_dequeue(struct
netchannel *np)
@@ -65,6 +71,10 @@ static inline struct netchannel_buftrail
return __netchannel_dequeue(np);
}
+extern struct netchannel *find_netchannel(const struct netchannel_buftrailer
*bp);
+extern int sock_add_netchannel(struct sock *sk);
extern struct sk_buff *skb_netchan_graft(struct netchannel_buftrailer *,
gfp_t);
#endif /* _LINUX_NETCHANNEL_H */
diff -urp davem/include/net/inet_hashtables.h
kelly_new/include/net/inet_hashtables.h
--- davem/include/net/inet_hashtables.h 2006-06-16 14:34:20.000000000 +1000
+++ kelly_new/include/net/inet_hashtables.h 2006-06-19 10:42:45.000000000
+1000
@@ -418,4 +418,7 @@ static inline struct sock *inet_lookup(s
extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
+extern void inet_hash_register(u8 proto, struct inet_hashinfo *hashinfo);
+extern struct sock *inet_lookup_proto(u8 protocol, u32 saddr, u16 sport, u32
daddr, u16 dport, int ifindex);
+
#endif /* _INET_HASHTABLES_H */
diff -urp davem/include/net/sock.h kelly_new/include/net/sock.h
--- davem/include/net/sock.h 2006-06-16 15:14:16.000000000 +1000
+++ kelly_new/include/net/sock.h 2006-06-19 10:42:45.000000000 +1000
@@ -196,6 +196,7 @@ struct sock {
unsigned short sk_type;
int sk_rcvbuf;
socket_lock_t sk_lock;
+ struct netchannel *sk_channel;
wait_queue_head_t *sk_sleep;
struct dst_entry *sk_dst_cache;
struct xfrm_policy *sk_policy[2];
diff -urp davem/net/core/dev.c kelly_new/net/core/dev.c
--- davem/net/core/dev.c 2006-06-16 15:14:16.000000000 +1000
+++ kelly_new/net/core/dev.c 2006-07-10 14:11:22.000000000 +1000
@@ -113,9 +113,12 @@
#include <linux/delay.h>
#include <linux/wireless.h>
#include <linux/netchannel.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
#include <net/iw_handler.h>
#include <asm/current.h>
#include <linux/audit.h>
+#include <net/inet_hashtables.h>
/*
* The list of packet types we will receive (as opposed to discard)
@@ -190,6 +193,8 @@ static inline struct hlist_head *dev_ind
return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
}
+static struct netchannel default_netchannel;
+
/*
* Our notifier list
*/
@@ -1854,11 +1859,18 @@ softnet_break:
goto out;
}
+void netchannel_wake(struct netchannel *np)
+{
+ wake_up(&np->wq);
+}
+
void netchannel_init(struct netchannel *np,
void (*callb)(struct netchannel *), void *callb_data)
{
memset(np, 0, sizeof(*np));
+ init_waitqueue_head(&np->wq);
+
np->netchan_callb = callb;
np->netchan_callb_data = callb_data;
}
@@ -1912,6 +1924,122 @@ struct netchannel_buftrailer *__netchann
}
EXPORT_SYMBOL_GPL(__netchannel_dequeue);
+/* Find the channel for a packet, or return default channel. */
+struct netchannel *find_netchannel(const struct netchannel_buftrailer *bp)
+{
+ struct sock *sk = NULL;
+ int datalen = netchan_data_len(bp);
+
+ switch (bp->netchan_buf_proto) {
+ case __constant_htons(ETH_P_IP): {
+ struct iphdr *ip = (void *)bp - datalen;
+ int iphl = ip->ihl * 4;
+
+ /* FIXME: Do sanity checks, parse packet. */
+
+ if (datalen >= (iphl + 4) && iphl == sizeof(struct iphdr)) {
+ u16 *ports = (u16 *)ip + 1;
+ sk = inet_lookup_proto(ip->protocol,
+ ip->saddr, ports[0],
+ ip->daddr, ports[1],
+ bp->netchan_buf_dev->ifindex);
+ }
+ break;
+ }
+ }
+
+ if (sk && sk->sk_channel)
+ return sk->sk_channel;
+ return &default_netchannel;
+}
+EXPORT_SYMBOL_GPL(find_netchannel);
+
+/* add the netchannel to the socket */
+int sock_add_netchannel(struct sock *sk)
+{
+ struct netchannel *np;
+
+ np = kmalloc(sizeof(struct netchannel), GFP_KERNEL);
+ if (!np)
+ return -ENOMEM;
+ netchannel_init(np, netchannel_wake, (void *)np);
+ sk->sk_channel = np;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sock_add_netchannel);
+
+/* deal with packets coming to default thread */
+static int netchannel_default_thread(void *unused)
+{
+ struct netchannel *np = &default_netchannel;
+ struct netchannel_buftrailer *nbp;
+ struct sk_buff *skbp;
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&np->wq, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+
+ while (!kthread_should_stop()) {
+ while (np->netchan_tail != np->netchan_head) {
+ nbp = netchannel_dequeue(np);
+ skbp = skb_netchan_graft(nbp, GFP_KERNEL);
+ netif_receive_skb(skbp);
+ }
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+
+ remove_wait_queue(&np->wq, &wait);
+ __set_current_state(TASK_RUNNING);
+
+ return 0;
+}
+
static gifconf_func_t * gifconf_list [NPROTO];
/**
@@ -3426,6 +3554,10 @@ static int __init net_dev_init(void)
hotcpu_notifier(dev_cpu_callback, 0);
dst_init();
dev_mcast_init();
+
+ netchannel_init(&default_netchannel, netchannel_wake, (void
*)&default_netchannel);
+ kthread_run(netchannel_default_thread, NULL, "nc_def");
+
rc = 0;
out:
return rc;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Netchannel: default, find, add to socket
2006-07-11 5:57 ` Evgeniy Polyakov
2006-07-11 6:14 ` Kelly Daly
2006-07-11 6:17 ` Kelly Daly
@ 2006-07-11 7:37 ` David Miller
2 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2006-07-11 7:37 UTC (permalink / raw)
To: johnpol; +Cc: kelly, netdev, rusty
From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Date: Tue, 11 Jul 2006 09:57:08 +0400
> Did you benchmarked such approach both with
> and without netchannel bound to the socket?
It is not meant to be used in "real life" :-)
So benchmark is quite useless.
We are starting simple, and eventually all types of packets will hit
some kind of channel, thus making the default channel a kind of
anomaly slow path.
That code will not come immediately, therefore it would be nice
if the performance were not too bad, and it can be made into a
software interrupt or tasklet with some care.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Netchannel: default, find, add to socket
2006-07-11 6:17 ` Kelly Daly
@ 2006-07-26 0:21 ` David Miller
0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2006-07-26 0:21 UTC (permalink / raw)
To: kelly; +Cc: netdev, rusty, johnpol
From: Kelly Daly <kelly@au1.ibm.com>
Date: Tue, 11 Jul 2006 16:17:56 +1000
> Implement finding of correct netchannel for buffer, default netchannel and
> attach a netchannel to a socket
>
> Signed-off-by: Kelly Daly <kelly@au.ibm.com>
Kelly, I want to apply this, but your email client has busted up the
patch by placing new lines all over. It also has turned tabs into
spaces, which also corrupts the patch.
Can you configure KMail not to corrupt the patch like this and
resubmit?
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-07-26 0:20 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-11 5:39 [PATCH] Netchannel: default, find, add to socket Kelly Daly
2006-07-11 5:57 ` Evgeniy Polyakov
2006-07-11 6:14 ` Kelly Daly
2006-07-11 6:17 ` Kelly Daly
2006-07-26 0:21 ` David Miller
2006-07-11 7:37 ` David Miller
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).