Netdev List
 help / color / mirror / Atom feed
* [RFC 0/4] pktgen patches
From: Stephen Hemminger @ 2009-08-26  6:15 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner, Ingo Molnar

These are some experimental (not ready yet), patches to try and
improve the pktgen timer code. Need some review by the hrtimer folks
as well.


-- 


^ permalink raw reply

* [RFC 1/4] pktgen: convert to use ktime_t
From: Stephen Hemminger @ 2009-08-26  6:15 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner, Ingo Molnar
In-Reply-To: <20090826061513.755294685@vyatta.com>

[-- Attachment #1: pktgen-ktime.patch --]
[-- Type: text/plain, Size: 11538 bytes --]

The kernel ktime_t is a nice generic infrastructure for mananging
high resolution times, as is done in pktgen. It also switchs from
using gettimeofday() to a monotonic clock which avoids any
NTP disturbance. In the process base resolution is increased
to nanoseconds.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/net/core/pktgen.c	2009-08-25 21:36:52.469711951 -0700
+++ b/net/core/pktgen.c	2009-08-25 22:35:59.321461854 -0700
@@ -246,16 +246,14 @@ struct pktgen_dev {
 	int max_pkt_size;	/* = ETH_ZLEN; */
 	int pkt_overhead;	/* overhead for MPLS, VLANs, IPSEC etc */
 	int nfrags;
-	__u32 delay_us;		/* Default delay */
-	__u32 delay_ns;
+	u64 delay;		/* nano-seconds */
+
 	__u64 count;		/* Default No packets to send */
 	__u64 sofar;		/* How many pkts we've sent so far */
 	__u64 tx_bytes;		/* How many bytes we've transmitted */
 	__u64 errors;		/* Errors when trying to transmit, pkts will be re-sent */
 
 	/* runtime counters relating to clone_skb */
-	__u64 next_tx_us;	/* timestamp of when to tx next */
-	__u32 next_tx_ns;
 
 	__u64 allocated_skbs;
 	__u32 clone_count;
@@ -263,9 +261,11 @@ struct pktgen_dev {
 				 * Or a failed transmit of some sort?  This will keep
 				 * sequence numbers in order, for example.
 				 */
-	__u64 started_at;	/* micro-seconds */
-	__u64 stopped_at;	/* micro-seconds */
-	__u64 idle_acc;		/* micro-seconds */
+	ktime_t next_tx;
+	ktime_t started_at;
+	ktime_t stopped_at;
+	u64	idle_acc;	/* nano-seconds */
+
 	__u32 seq_num;
 
 	int clone_skb;		/* Use multiple SKBs during packet gen.  If this number
@@ -397,23 +397,20 @@ struct pktgen_thread {
 #define REMOVE 1
 #define FIND   0
 
-/** Convert to micro-seconds */
-static inline __u64 tv_to_us(const struct timeval *tv)
+static inline ktime_t ktime_now(void)
 {
-	__u64 us = tv->tv_usec;
-	us += (__u64) tv->tv_sec * (__u64) 1000000;
-	return us;
+	struct timespec ts;
+	ktime_get_ts(&ts);
+
+	return timespec_to_ktime(ts);
 }
 
-static __u64 getCurUs(void)
+/* This works even if 32 bit because of careful byte order choice */
+static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
 {
-	struct timeval tv;
-	do_gettimeofday(&tv);
-	return tv_to_us(&tv);
+	return cmp1.tv64 < cmp2.tv64;
 }
 
-/* old include end */
-
 static char version[] __initdata = VERSION;
 
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
@@ -510,9 +507,8 @@ static const struct file_operations pktg
 static int pktgen_if_show(struct seq_file *seq, void *v)
 {
 	struct pktgen_dev *pkt_dev = seq->private;
-	__u64 sa;
-	__u64 stopped;
-	__u64 now = getCurUs();
+	ktime_t stopped;
+	struct timeval trun, idle;
 
 	seq_printf(seq,
 		   "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
@@ -520,9 +516,8 @@ static int pktgen_if_show(struct seq_fil
 		   pkt_dev->max_pkt_size);
 
 	seq_printf(seq,
-		   "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
-		   pkt_dev->nfrags,
-		   1000 * pkt_dev->delay_us + pkt_dev->delay_ns,
+		   "     frags: %d  delay: %llu  clone_skb: %d  ifname: %s\n",
+		   pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
 		   pkt_dev->clone_skb, pkt_dev->odev->name);
 
 	seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
@@ -654,17 +649,19 @@ static int pktgen_if_show(struct seq_fil
 
 	seq_puts(seq, "\n");
 
-	sa = pkt_dev->started_at;
-	stopped = pkt_dev->stopped_at;
-	if (pkt_dev->running)
-		stopped = now;	/* not really stopped, more like last-running-at */
+	/* not really stopped, more like last-running-at */
+	stopped = pkt_dev->running ? ktime_now() : pkt_dev->stopped_at;
+	trun = ktime_to_timeval(ktime_sub(stopped, pkt_dev->started_at));
+	idle = ns_to_timeval(pkt_dev->idle_acc);
 
 	seq_printf(seq,
-		   "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+		   "Current:\n     pkts-sofar: %llu  errors: %llu\n",
 		   (unsigned long long)pkt_dev->sofar,
-		   (unsigned long long)pkt_dev->errors, (unsigned long long)sa,
-		   (unsigned long long)stopped,
-		   (unsigned long long)pkt_dev->idle_acc);
+		   (unsigned long long)pkt_dev->errors);
+
+	seq_printf(seq, "     running: %d.%06ds idle: %d.%06ds\n",
+		   (int)trun.tv_sec, (int)trun.tv_usec,
+		   (int)idle.tv_sec, (int)idle.tv_usec);
 
 	seq_printf(seq,
 		   "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
@@ -950,15 +947,13 @@ static ssize_t pktgen_if_write(struct fi
 			return len;
 		}
 		i += len;
-		if (value == 0x7FFFFFFF) {
-			pkt_dev->delay_us = 0x7FFFFFFF;
-			pkt_dev->delay_ns = 0;
-		} else {
-			pkt_dev->delay_us = value / 1000;
-			pkt_dev->delay_ns = value % 1000;
-		}
-		sprintf(pg_result, "OK: delay=%u",
-			1000 * pkt_dev->delay_us + pkt_dev->delay_ns);
+		if (value == 0x7FFFFFFF)
+			pkt_dev->delay = ULLONG_MAX;
+		else
+			pkt_dev->delay = (u64)value * NSEC_PER_USEC;
+
+		sprintf(pg_result, "OK: delay=%llu",
+			(unsigned long long) pkt_dev->delay);
 		return count;
 	}
 	if (!strcmp(name, "udp_src_min")) {
@@ -2089,27 +2084,33 @@ static void pktgen_setup_inject(struct p
 	pkt_dev->nflows = 0;
 }
 
-static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
+static inline s64 delta_ns(ktime_t a, ktime_t b)
 {
-	__u64 start;
-	__u64 now;
+	return ktime_to_ns(ktime_sub(a, b));
+}
 
-	start = now = getCurUs();
-	while (now < spin_until_us) {
+static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
+{
+	ktime_t start, now;
+	s64 dt;
+
+	start = now = ktime_now();
+
+	while ((dt = delta_ns(spin_until, now)) > 0) {
 		/* TODO: optimize sleeping behavior */
-		if (spin_until_us - now > jiffies_to_usecs(1) + 1)
+		if (dt > TICK_NSEC)
 			schedule_timeout_interruptible(1);
-		else if (spin_until_us - now > 100) {
+		else if (dt > 100*NSEC_PER_USEC) {
 			if (!pkt_dev->running)
 				return;
 			if (need_resched())
 				schedule();
 		}
 
-		now = getCurUs();
+		now = ktime_now();
 	}
 
-	pkt_dev->idle_acc += now - start;
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3072,9 +3073,9 @@ static void pktgen_run(struct pktgen_thr
 			pktgen_clear_counters(pkt_dev);
 			pkt_dev->running = 1;	/* Cranke yeself! */
 			pkt_dev->skb = NULL;
-			pkt_dev->started_at = getCurUs();
-			pkt_dev->next_tx_us = getCurUs();	/* Transmit immediately */
-			pkt_dev->next_tx_ns = 0;
+			pkt_dev->started_at =
+				pkt_dev->next_tx = ktime_now();
+
 			set_pkt_overhead(pkt_dev);
 
 			strcpy(pkt_dev->result, "Starting");
@@ -3193,28 +3194,21 @@ static void pktgen_reset_all_threads(voi
 
 static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
 {
-	__u64 total_us, bps, mbps, pps, idle;
+	__u64 bps, mbps, pps;
 	char *p = pkt_dev->result;
-
-	total_us = pkt_dev->stopped_at - pkt_dev->started_at;
-
-	idle = pkt_dev->idle_acc;
-
-	p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
-		     (unsigned long long)total_us,
-		     (unsigned long long)(total_us - idle),
-		     (unsigned long long)idle,
+	ktime_t elapsed = ktime_sub(pkt_dev->stopped_at,
+				    pkt_dev->started_at);
+	ktime_t idle = ns_to_ktime(pkt_dev->idle_acc);
+
+	p += sprintf(p, "OK: %llu(c%llu+d%llu) nsec, %llu (%dbyte,%dfrags)\n",
+		     (unsigned long long)ktime_to_us(elapsed),
+		     (unsigned long long)ktime_to_us(ktime_sub(elapsed, idle)),
+		     (unsigned long long)ktime_to_us(idle),
 		     (unsigned long long)pkt_dev->sofar,
 		     pkt_dev->cur_pkt_size, nr_frags);
 
-	pps = pkt_dev->sofar * USEC_PER_SEC;
-
-	while ((total_us >> 32) != 0) {
-		pps >>= 1;
-		total_us >>= 1;
-	}
-
-	do_div(pps, total_us);
+	pps = div64_u64(pkt_dev->sofar * NSEC_PER_SEC,
+			ktime_to_ns(elapsed));
 
 	bps = pps * 8 * pkt_dev->cur_pkt_size;
 
@@ -3239,7 +3233,7 @@ static int pktgen_stop_device(struct pkt
 		return -EINVAL;
 	}
 
-	pkt_dev->stopped_at = getCurUs();
+	pkt_dev->stopped_at = ktime_now();
 	pkt_dev->running = 0;
 
 	show_results(pkt_dev, nr_frags);
@@ -3258,7 +3252,7 @@ static struct pktgen_dev *next_to_run(st
 			continue;
 		if (best == NULL)
 			best = pkt_dev;
-		else if (pkt_dev->next_tx_us < best->next_tx_us)
+		else if (ktime_lt(pkt_dev->next_tx, best->next_tx))
 			best = pkt_dev;
 	}
 	if_unlock(t);
@@ -3354,23 +3348,19 @@ static __inline__ void pktgen_xmit(struc
 	int (*xmit)(struct sk_buff *, struct net_device *)
 		= odev->netdev_ops->ndo_start_xmit;
 	struct netdev_queue *txq;
-	__u64 idle_start = 0;
 	u16 queue_map;
 	int ret;
 
-	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
-		u64 now;
-
-		now = getCurUs();
-		if (now < pkt_dev->next_tx_us)
-			spin(pkt_dev, pkt_dev->next_tx_us);
+	if (pkt_dev->delay) {
+		if (ktime_lt(ktime_now(), pkt_dev->next_tx))
+			spin(pkt_dev, pkt_dev->next_tx);
 
 		/* This is max DELAY, this has special meaning of
 		 * "never transmit"
 		 */
-		if (pkt_dev->delay_us == 0x7FFFFFFF) {
-			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
-			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
+		if (pkt_dev->delay == ULLONG_MAX) {
+			pkt_dev->next_tx = ktime_add_ns(pkt_dev->next_tx,
+							LONG_MAX);
 			goto out;
 		}
 	}
@@ -3386,7 +3376,7 @@ static __inline__ void pktgen_xmit(struc
 	if (netif_tx_queue_stopped(txq) ||
 	    netif_tx_queue_frozen(txq) ||
 	    need_resched()) {
-		idle_start = getCurUs();
+		ktime_t idle_start = ktime_now();
 
 		if (!netif_running(odev)) {
 			pktgen_stop_device(pkt_dev);
@@ -3397,12 +3387,12 @@ static __inline__ void pktgen_xmit(struc
 		if (need_resched())
 			schedule();
 
-		pkt_dev->idle_acc += getCurUs() - idle_start;
+		pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
+							   idle_start));
 
 		if (netif_tx_queue_stopped(txq) ||
 		    netif_tx_queue_frozen(txq)) {
-			pkt_dev->next_tx_us = getCurUs();	/* TODO */
-			pkt_dev->next_tx_ns = 0;
+			pkt_dev->next_tx = ktime_now();
 			goto out;	/* Try the next interface */
 		}
 	}
@@ -3459,22 +3449,10 @@ static __inline__ void pktgen_xmit(struc
 			pkt_dev->last_ok = 0;
 		}
 
-		pkt_dev->next_tx_us = getCurUs();
-		pkt_dev->next_tx_ns = 0;
-
-		pkt_dev->next_tx_us += pkt_dev->delay_us;
-		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
-
-		if (pkt_dev->next_tx_ns > 1000) {
-			pkt_dev->next_tx_us++;
-			pkt_dev->next_tx_ns -= 1000;
-		}
-	}
-
-	else {			/* Retry it next time */
+		pkt_dev->next_tx = ktime_add_ns(ktime_now(), pkt_dev->delay);
+	} else {			/* Retry it next time */
 		pkt_dev->last_ok = 0;
-		pkt_dev->next_tx_us = getCurUs();	/* TODO */
-		pkt_dev->next_tx_ns = 0;
+		pkt_dev->next_tx = ktime_now();
 	}
 
 	__netif_tx_unlock_bh(txq);
@@ -3482,14 +3460,17 @@ static __inline__ void pktgen_xmit(struc
 	/* If pkt_dev->count is zero, then run forever */
 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
 		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-			idle_start = getCurUs();
+			ktime_t idle_start = ktime_now();
+
 			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
 				if (signal_pending(current)) {
 					break;
 				}
 				schedule();
 			}
-			pkt_dev->idle_acc += getCurUs() - idle_start;
+			pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
+								   idle_start));
+
 		}
 
 		/* Done with this */
@@ -3651,8 +3632,7 @@ static int pktgen_add_device(struct pktg
 	pkt_dev->max_pkt_size = ETH_ZLEN;
 	pkt_dev->nfrags = 0;
 	pkt_dev->clone_skb = pg_clone_skb_d;
-	pkt_dev->delay_us = pg_delay_d / 1000;
-	pkt_dev->delay_ns = pg_delay_d % 1000;
+	pkt_dev->delay = pg_delay_d;
 	pkt_dev->count = pg_count_d;
 	pkt_dev->sofar = 0;
 	pkt_dev->udp_src_min = 9;	/* sink port */

-- 


^ permalink raw reply

* [RFC 2/4] pktgen: spin using hrtimer
From: Stephen Hemminger @ 2009-08-26  6:15 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner, Ingo Molnar
In-Reply-To: <20090826061513.755294685@vyatta.com>

[-- Attachment #1: pktgen-hrtimer-spin.patch --]
[-- Type: text/plain, Size: 3108 bytes --]

This changes how the pktgen thread spins/waits between
packets if delay is configured.  The new code is basically
an revised version of what the nanosleep system call does.

It requires exporting hrtimer_init_sleeper from standard hrtimer
code, since pktgen can be a module.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 kernel/hrtimer.c  |    1 +
 net/core/pktgen.c |   43 ++++++++++++++++++++++++++-----------------
 2 files changed, 27 insertions(+), 17 deletions(-)

--- a/net/core/pktgen.c	2009-08-25 22:49:33.979402479 -0700
+++ b/net/core/pktgen.c	2009-08-25 22:49:55.966424251 -0700
@@ -131,6 +131,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/capability.h>
+#include <linux/hrtimer.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
@@ -2084,33 +2085,32 @@ static void pktgen_setup_inject(struct p
 	pkt_dev->nflows = 0;
 }
 
-static inline s64 delta_ns(ktime_t a, ktime_t b)
-{
-	return ktime_to_ns(ktime_sub(a, b));
-}
-
 static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 {
-	ktime_t start, now;
-	s64 dt;
+	struct hrtimer_sleeper t;
+	enum hrtimer_mode mode = HRTIMER_MODE_REL;
+	unsigned long slack = rt_task(current) ? 0 : current->timer_slack_ns;
+
+	hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
+	hrtimer_set_expires_range_ns(&t.timer, spin_until, slack);
+	hrtimer_init_sleeper(&t, current);
 
-	start = now = ktime_now();
+	/* based on do_nanosleep() */
+	do {
+		set_current_state(TASK_INTERRUPTIBLE);
+		hrtimer_start_expires(&t.timer, mode);
+		if (!hrtimer_active(&t.timer))
+			t.task = NULL;
 
-	while ((dt = delta_ns(spin_until, now)) > 0) {
-		/* TODO: optimize sleeping behavior */
-		if (dt > TICK_NSEC)
-			schedule_timeout_interruptible(1);
-		else if (dt > 100*NSEC_PER_USEC) {
-			if (!pkt_dev->running)
-				return;
-			if (need_resched())
-				schedule();
-		}
+		if (likely(t.task))
+			schedule();
 
-		now = ktime_now();
-	}
+		hrtimer_cancel(&t.timer);
+		mode = HRTIMER_MODE_ABS;
+	} while (t.task && pkt_dev->running && !signal_pending(current));
 
-	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
+	__set_current_state(TASK_RUNNING);
+	destroy_hrtimer_on_stack(&t.timer);
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3352,8 +3352,12 @@ static __inline__ void pktgen_xmit(struc
 	int ret;
 
 	if (pkt_dev->delay) {
-		if (ktime_lt(ktime_now(), pkt_dev->next_tx))
+		ktime_t start = ktime_now();
+		if (ktime_lt(start, pkt_dev->next_tx)) {
 			spin(pkt_dev, pkt_dev->next_tx);
+			pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
+								   start));
+		}
 
 		/* This is max DELAY, this has special meaning of
 		 * "never transmit"
--- a/kernel/hrtimer.c	2009-08-25 22:49:29.768405220 -0700
+++ b/kernel/hrtimer.c	2009-08-25 22:49:48.777711560 -0700
@@ -1477,6 +1477,7 @@ void hrtimer_init_sleeper(struct hrtimer
 	sl->timer.function = hrtimer_wakeup;
 	sl->task = task;
 }
+EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
 
 static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
 {

-- 


^ permalink raw reply

* [RFC 3/4] pktgen: clock optimizations
From: Stephen Hemminger @ 2009-08-26  6:15 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner, Ingo Molnar
In-Reply-To: <20090826061513.755294685@vyatta.com>

[-- Attachment #1: pktgen-avoid-clock.patch --]
[-- Type: text/plain, Size: 1399 bytes --]

This optimizes pktgen to avoid calling ktime_get_ts unless
it is needed. 
  * if delay is 0, then no need to update next_tx
  * if queue is stopped, then keep old value will already force
    tx on next cycle.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 net/core/pktgen.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/net/core/pktgen.c	2009-08-25 22:49:55.966424251 -0700
+++ b/net/core/pktgen.c	2009-08-25 22:51:21.162461840 -0700
@@ -3425,11 +3425,12 @@ static __inline__ void pktgen_xmit(struc
 	txq = netdev_get_tx_queue(odev, queue_map);
 
 	__netif_tx_lock_bh(txq);
-	if (!netif_tx_queue_stopped(txq) &&
-	    !netif_tx_queue_frozen(txq)) {
+	if (netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq))
+		pkt_dev->last_ok = 0; 			/* Retry it next time */
+	else {
 
 		atomic_inc(&(pkt_dev->skb->users));
-	      retry_now:
+retry_now:
 		ret = (*xmit)(pkt_dev->skb, odev);
 		if (likely(ret == NETDEV_TX_OK)) {
 			txq_trans_update(txq);
@@ -3453,10 +3454,9 @@ static __inline__ void pktgen_xmit(struc
 			pkt_dev->last_ok = 0;
 		}
 
-		pkt_dev->next_tx = ktime_add_ns(ktime_now(), pkt_dev->delay);
-	} else {			/* Retry it next time */
-		pkt_dev->last_ok = 0;
-		pkt_dev->next_tx = ktime_now();
+		if (pkt_dev->delay)
+			pkt_dev->next_tx = ktime_add_ns(ktime_now(),
+							pkt_dev->delay);
 	}
 
 	__netif_tx_unlock_bh(txq);

-- 


^ permalink raw reply

* Re: skb header allocation
From: Frank Blaschka @ 2009-08-26  6:01 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Chris Ross, netdev
In-Reply-To: <20090825201514.0dd143ad@nehalam>

Is it save to change dev->hard_header_len to a value other than ETH_HLEN for
an ethernet device?

I rememeber we run in trouble with some kernel components (netfilter?, I'm
not sure can't remember the details ...) when we did this is the past.

Is this not an issue any more?

Thanks

Stephen Hemminger schrieb:
> On Tue, 25 Aug 2009 22:04:10 -0500
> Chris Ross <chris@compilednetworks.com> wrote:
> 
>> I have a network driver that acts as a Ethernet device and builds up a
>> series of outer headers on skb(s) it receives from upper layers. I am
>> currently using the technique that is in ipip.c to ensure I have
>> enough room to add my header ...
>>
>> if (skb_headroom(skb) < some_value || skb_shared(skb) ||
>>          ((skb_cloned(skb) && !skb_clone_writable(skb, 0))))
>>    {
>>       if ((skb2 = skb_realloc_headroom(skb, some_value)) == NULL)
>>          return -1;
>>
>>       dev_kfree_skb(skb);
>>       skb = skb2;
>>    }
>>
>> Is this the best practice for a high bandwidth scenario?
> 
> Define a value of dev->hard_header_len that adds space for what you need.
> Use skb_cow_head(skb, headroom) before touching skb header.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



^ permalink raw reply

* Re: [PATCH 01/26] et1310: kill pAdapter in favour of a sane name
From: Greg KH @ 2009-08-26  5:49 UTC (permalink / raw)
  To: Alan Cox; +Cc: netdev
In-Reply-To: <20090825145732.16176.83630.stgit@localhost.localdomain>

On Tue, Aug 25, 2009 at 03:57:36PM +0100, Alan Cox wrote:
> Signed-off-by: Alan Cox <alan@linux.intel.com>

Odd, every single hunk of this patch fails to apply to my tree :(

What did you diff it against? I have 4 et131x patches in my tree, but
they are all from you already.

confused,

greg k-h

^ permalink raw reply

* Re: [PATCH 1/2] trace_events: fix napi's tracepoint
From: Xiao Guangrong @ 2009-08-26  5:40 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Steven Rostedt, Frederic Weisbecker, Neil Horman, Wei Yongjun,
	David Miller, Netdev, LKML
In-Reply-To: <4A94C612.60200@cn.fujitsu.com>



Xiao Guangrong wrote:
> 
> Xiao Guangrong wrote:
>> Currently, the napi's tracepoint works will is depend on
>> "DECLARE_TRACE" definiens in include/trace/define_trace.h,
>> like below:
>>
>> #include <trace/events/skb.h>    // include define_trace.h
>> #include <trace/events/napi.h>
>>
>> there have error, if we remove "#include <trace/events/skb.h>"
>> or include napi.h in the front of include skb.h, It should
>> depend on the definiens in include/linux/tracepoint.h and we
>> can remove the "DECLARE_TRACE" definiens in
>> include/trace/define_trace.h, because "TRACE_EVENT" not use it
>>
>> Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
> 
> Hi Steven,
> 
> I'm sorry, please pull this patch too, because 
> "[PATCH 7/8] tracing/events: fix the include file dependencies" 
> is based on this patch, else will occur building error.
> 

Sorry again, I say the wrong words, it not has building error, just
not complete fix the bug which I mention it in the changelog of
"[PATCH 7/8] tracing/events: fix the include file dependencies", that
is we can't include more TRACE_EVENT head file in .c file all the same,
like below:

Both define TRACE_EVENT in trace_a.h and trace_b.h, if we include
those in .c file, like this:

#define CREATE_TRACE_POINTS
include <trace/events/trace_a.h>  // re-define DECLARE_TRACE

include <trace/events/trace_b.h>  // use the DECLARE_TRACE definition
				  // that re-define by trace_a.h

Thanks,
Xiao



^ permalink raw reply

* Re: [PATCH 1/2] trace_events: fix napi's tracepoint
From: Xiao Guangrong @ 2009-08-26  5:20 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Steven Rostedt, Frederic Weisbecker, Neil Horman, Wei Yongjun,
	David Miller, Netdev, LKML
In-Reply-To: <4A93895F.4010708@cn.fujitsu.com>



Xiao Guangrong wrote:
> Currently, the napi's tracepoint works will is depend on
> "DECLARE_TRACE" definiens in include/trace/define_trace.h,
> like below:
> 
> #include <trace/events/skb.h>    // include define_trace.h
> #include <trace/events/napi.h>
> 
> there have error, if we remove "#include <trace/events/skb.h>"
> or include napi.h in the front of include skb.h, It should
> depend on the definiens in include/linux/tracepoint.h and we
> can remove the "DECLARE_TRACE" definiens in
> include/trace/define_trace.h, because "TRACE_EVENT" not use it
> 
> Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>

Hi Steven,

I'm sorry, please pull this patch too, because 
"[PATCH 7/8] tracing/events: fix the include file dependencies" 
is based on this patch, else will occur building error.

Thanks,
Xiao

^ permalink raw reply

* Re: Page allocation failures in guest
From: Pierre Ossman @ 2009-08-26  4:55 UTC (permalink / raw)
  To: Rusty Russell
  Cc: Avi Kivity, Minchan Kim, kvm, LKML, linux-mm, Wu Fengguang,
	KOSAKI Motohiro, Rik van Riel, netdev
In-Reply-To: <200908261147.17838.rusty@rustcorp.com.au>

[-- Attachment #1: Type: text/plain, Size: 892 bytes --]

On Wed, 26 Aug 2009 11:47:17 +0930
Rusty Russell <rusty@rustcorp.com.au> wrote:

> On Fri, 14 Aug 2009 05:55:48 am Pierre Ossman wrote:
> > On Wed, 12 Aug 2009 15:01:52 +0930
> > Rusty Russell <rusty@rustcorp.com.au> wrote:
> > > Subject: virtio: net refill on out-of-memory
> ... 
> > Patch applied. Now we wait. :)
> 
> Any results?
> 

It's been up for 12 days, so I'd say it works. But there is nothing in
dmesg, which suggests I haven't triggered the condition yet.

I wonder if there might be something broken with Fedora's kernel. :/
(I am running the same upstream version, and their conf, for this test,
but not all of their patches)

Rgds
-- 
     -- Pierre Ossman

  WARNING: This correspondence is being monitored by the
  Swedish government. Make sure your server uses encryption
  for SMTP traffic and consider using PGP for end-to-end
  encryption.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* [GIT]: Networking
From: David Miller @ 2009-08-26  3:50 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) Fix for warning introduced unintentionally last round, spotted by
   Stephen Rothwell.

2) Fix for two incorrect netdev_ops conversions in IRDA, from
   Alex Beregalov.

Please pull, thanks a lot!

The following changes since commit 7c0a57d5c47bcfc492b3139e77400f888a935c44:
  Linus Torvalds (1):
        Merge branch 'fixes' of git://git.marvell.com/orion

are available in the git repository at:

  master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git master

Alexander Beregalov (2):
      irda/au1k_ir: fix broken netdev_ops conversion
      irda/sa1100_ir: fix broken netdev_ops conversion

David S. Miller (1):
      pkt_sched: Fix bogon in tasklet_hrtimer changes.

 drivers/net/irda/au1k_ir.c   |    4 ----
 drivers/net/irda/sa1100_ir.c |    4 ----
 net/sched/sch_api.c          |    2 +-
 net/sched/sch_cbq.c          |    2 +-
 4 files changed, 2 insertions(+), 10 deletions(-)

^ permalink raw reply

* Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts
From: Eric W. Biederman @ 2009-08-26  3:47 UTC (permalink / raw)
  To: Francois Romieu
  Cc: David Dillow, Michael Riepe, Michael Buesch, Rui Santos,
	Michael B??ker, linux-kernel, netdev
In-Reply-To: <20090825221903.GA13630@electric-eye.fr.zoreil.com>

Francois Romieu <romieu@fr.zoreil.com> writes:

> Eric W. Biederman <ebiederm@xmission.com> :
> [...]
>> I am a bit curious about TxDescUnavail.  Perhaps we had a temporary
>> memory shortage and that is what was screaming?  I don't think we do
>> anything at all with that state.
>
> You are not alone, the driver completely ignores this bit.
>
> As far as I remember, the TxDescUnavail event mostly pops up when the
> driver makes an excessive use of TxPoll requests.
>
>> Perhaps the flaw here is simply not masking TxDescUnavail while we are
>> in NAPI mode ?
>
> Yes, it is worth trying.

At first blush things seem better, but it isn't sufficient.
I still have a problem with RxFIFOOver set.
r8169 screaming irq status 00000040 mask 0000ffe2 event 0000803f napi 0000001d

The patch I ran is below.

Eric

---
 drivers/net/r8169.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 3b19e0c..e144bc1 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3552,6 +3552,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 	void __iomem *ioaddr = tp->mmio_addr;
 	int handled = 0;
 	int status;
+	int count = 0;
 
 	/* loop handling interrupts until we have no new ones or
 	 * we hit a invalid/hotplug case.
@@ -3560,6 +3561,14 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 	while (status && status != 0xffff) {
 		handled = 1;
 
+		if (count++ > 100) {                                                                                               
+			printk_once("r8169 screaming irq status %08x "
+				"mask %08x event %08x napi %08x\n",
+				status, tp->intr_mask, tp->intr_event,
+				tp->napi_event);
+			break;
+		}
+
 		/* Handle all of the error cases first. These will reset
 		 * the chip, so just exit the loop.
 		 */
@@ -3609,6 +3618,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 		RTL_W16(IntrStatus,
 			(status & RxFIFOOver) ? (status | RxOverflow) : status);
 		status = RTL_R16(IntrStatus);
+		if (status == 0xffff)
+			break;
+		status &= tp->intr_mask;
 	}
 
 	return IRQ_RETVAL(handled);
-- 
1.6.2.5


^ permalink raw reply related

* Re: [PATCH 2/2] irda/sa1100_ir: fix broken netdev_ops conversion
From: David Miller @ 2009-08-26  3:39 UTC (permalink / raw)
  To: a.beregalov; +Cc: netdev, linux-arm-kernel, linux-arm-kernel
In-Reply-To: <1251125760-6547-1-git-send-email-a.beregalov@gmail.com>

From: Alexander Beregalov <a.beregalov@gmail.com>
Date: Mon, 24 Aug 2009 18:56:00 +0400

> This patch is based on commit d2f3ad4 (pxaficp-ir: remove incorrect
> net_device_ops). Do the same for sa1100_ir.
> Untested.
> 
> Signed-off-by: Alexander Beregalov <a.beregalov@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH 1/2] irda/au1k_ir: fix broken netdev_ops conversion
From: David Miller @ 2009-08-26  3:39 UTC (permalink / raw)
  To: a.beregalov; +Cc: netdev, linux-mips
In-Reply-To: <1251125667-6509-1-git-send-email-a.beregalov@gmail.com>

From: Alexander Beregalov <a.beregalov@gmail.com>
Date: Mon, 24 Aug 2009 18:54:27 +0400

> This patch is based on commit d2f3ad4 (pxaficp-ir: remove incorrect
> net_device_ops). Do the same for au1k_ir.
> Untested.
> 
> Signed-off-by: Alexander Beregalov <a.beregalov@gmail.com>

Applied.

^ permalink raw reply

* Re: skb header allocation
From: Stephen Hemminger @ 2009-08-26  3:15 UTC (permalink / raw)
  To: Chris Ross; +Cc: netdev
In-Reply-To: <17cd85320908252004r31874732n9e06921d6eae4ad7@mail.gmail.com>

On Tue, 25 Aug 2009 22:04:10 -0500
Chris Ross <chris@compilednetworks.com> wrote:

> I have a network driver that acts as a Ethernet device and builds up a
> series of outer headers on skb(s) it receives from upper layers. I am
> currently using the technique that is in ipip.c to ensure I have
> enough room to add my header ...
> 
> if (skb_headroom(skb) < some_value || skb_shared(skb) ||
>          ((skb_cloned(skb) && !skb_clone_writable(skb, 0))))
>    {
>       if ((skb2 = skb_realloc_headroom(skb, some_value)) == NULL)
>          return -1;
> 
>       dev_kfree_skb(skb);
>       skb = skb2;
>    }
> 
> Is this the best practice for a high bandwidth scenario?

Define a value of dev->hard_header_len that adds space for what you need.
Use skb_cow_head(skb, headroom) before touching skb header.

^ permalink raw reply

* skb header allocation
From: Chris Ross @ 2009-08-26  3:04 UTC (permalink / raw)
  To: netdev

I have a network driver that acts as a Ethernet device and builds up a
series of outer headers on skb(s) it receives from upper layers. I am
currently using the technique that is in ipip.c to ensure I have
enough room to add my header ...

if (skb_headroom(skb) < some_value || skb_shared(skb) ||
         ((skb_cloned(skb) && !skb_clone_writable(skb, 0))))
   {
      if ((skb2 = skb_realloc_headroom(skb, some_value)) == NULL)
         return -1;

      dev_kfree_skb(skb);
      skb = skb2;
   }

Is this the best practice for a high bandwidth scenario?

thanks

-chris

^ permalink raw reply

* [IPv6] kernel refuses to install blackhole routes without dev lo
From: Henrique de Moraes Holschuh @ 2009-08-26  2:35 UTC (permalink / raw)
  To: netdev

(Please keep me in the CC, I am not subscribed to netdev)

To make a long history short, and to get right to the point:

# ip -6 route add blackhole ::/0
RTNETLINK answers: No such device

while

# ip -6 route add blackhole ::/0 dev lo

and

# ip route add unreachable ::/0     

works just fine.  Looks like a bug, and it annoys the heck out of people
trying to use the standard way of null-routing on Quagga :-)

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

^ permalink raw reply

* Re: Page allocation failures in guest
From: Rusty Russell @ 2009-08-26  2:17 UTC (permalink / raw)
  To: Pierre Ossman
  Cc: Avi Kivity, Minchan Kim, kvm, LKML, linux-mm, Wu Fengguang,
	KOSAKI Motohiro, Rik van Riel, netdev
In-Reply-To: <20090813222548.5e0743dd@mjolnir.ossman.eu>

On Fri, 14 Aug 2009 05:55:48 am Pierre Ossman wrote:
> On Wed, 12 Aug 2009 15:01:52 +0930
> Rusty Russell <rusty@rustcorp.com.au> wrote:
> > Subject: virtio: net refill on out-of-memory
... 
> Patch applied. Now we wait. :)

Any results?

Thanks,
Rusty.

^ permalink raw reply

* AlacrityVM benchmark numbers updated
From: Gregory Haskins @ 2009-08-26  1:01 UTC (permalink / raw)
  To: alacrityvm-devel
  Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	Michael S. Tsirkin, netdev

[-- Attachment #1: Type: text/plain, Size: 862 bytes --]

We are pleased to announce the availability of the latest networking
benchmark numbers for AlacrityVM.  We've made several tweaks to the
original v0.1 release to improve performance.  The most notable is a
switch from get_user_pages to switch_mm+copy_[to/from]_user thanks to a
review suggestion from Michael Tsirkin (as well as his patch to
implement it).

This change alone accounted for freeing up an additional 1.2Gbps, which
is over 25% improvement from v0.1.  The previous numbers were 4560Gbps
before the change, and 5708Gbps after (for 1500mtu over 10GE).  This
moves us ever closer to the goal of native performance under virtualization.

These changes will be incorporated into the upcoming v0.2 release.  For
more details, please visit our project wiki:

http://developer.novell.com/wiki/index.php/AlacrityVM

Kind Regards,
-Greg


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 267 bytes --]

^ permalink raw reply

* Re: [PATCH 1/2] trace_events: fix napi's tracepoint
From: Xiao Guangrong @ 2009-08-26  0:49 UTC (permalink / raw)
  To: Neil Horman
  Cc: Ingo Molnar, Steven Rostedt, Frederic Weisbecker, Wei Yongjun,
	David Miller, Netdev, LKML
In-Reply-To: <20090825105707.GA24710@hmsreliant.think-freely.org>



Neil Horman wrote:
> On Tue, Aug 25, 2009 at 09:58:16AM +0200, Ingo Molnar wrote:
>> * Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> wrote:
>>
>> This will collide with tracing bits in the networking tree. The 
>> skb-tracing plugin there should be turned into proper TRACE_EVENT() 
>> tracepoints.
>>
>> Neil was away for some time but i think soon we should see some 
>> movement here.
>>
>> 	Ingo
>>
> 
> Thank you Ingo, yes, I'm back from the beach now and will look at this shortly.
> I concur, we should just convert the napi_poll tracepoint to be defined via the
> TRACE_EVENT macro, same as the kfree_skb tracepoint.  Xaio would you like to
> take care of that, or shall I?
>

Hi Neil,

I'm glad to do it.

Actually, we should fix the include file dependencies first
(the second patch in this patchset), else we can't include two
TRACE_EVENT head files in net-traces.c

Steve will pull this patchset, so, I'll convert it after this
patchset merged.

^ permalink raw reply

* Re: why is IP_MAX_MTU limited to 65520 bytes
From: David Miller @ 2009-08-25 23:30 UTC (permalink / raw)
  To: sri; +Cc: netdev
In-Reply-To: <1251242740.3169.69.camel@w-sridhar.beaverton.ibm.com>

From: Sridhar Samudrala <sri@us.ibm.com>
Date: Tue, 25 Aug 2009 16:25:40 -0700

> Any reason why the maximum IP payload is limited to IP_MAX_MTU(0xFFF0) bytes
> instead of the maximum possible value of 0xFFFF

0xffff is an odd value, IP fragments must be a multiple of
8 bytes, etc. etc.

^ permalink raw reply

* why is IP_MAX_MTU limited to 65520 bytes
From: Sridhar Samudrala @ 2009-08-25 23:25 UTC (permalink / raw)
  To: netdev

Any reason why the maximum IP payload is limited to IP_MAX_MTU(0xFFF0) bytes
instead of the maximum possible value of 0xFFFF

Thanks
Sridhar


^ permalink raw reply

* Re: 2.6.31-rc6-git5: Reported regressions from 2.6.30
From: Larry Finger @ 2009-08-25 23:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Adrian Bunk, DRI, Linux SCSI List, Network Development,
	Linux Wireless List, Linux Kernel Mailing List,
	Natalie Protasevich, Linux ACPI, Andrew Morton,
	Kernel Testers List, Linus Torvalds, Linux PM List
In-Reply-To: <200908220002.03707.rjw@sisk.pl>

Rafael J. Wysocki wrote:
> On Friday 21 August 2009, Larry Finger wrote:
>> Rafael J. Wysocki wrote:
>>
>>> Bug-Entry	: http://bugzilla.kernel.org/show_bug.cgi?id=13960
>>> Subject		: rtl8187 not connect to wifi
>>> Submitter	: okias <d.okias@gmail.com>
>>> Date		: 2009-08-10 19:16 (10 days old)
>> The patch for this one was sent from Linville to DaveM earlier today,
>> and should be sent to mainline in the near future.
>>
>> AFAIK, the OP has not yet tested the patch, but I think I was able to
>> reproduce the problem, and the patch did fit it for me.
> 
> Thanks for the update.
> 
> Can you please close the bug when the patch is merged?

The patch hit mainline as commit
1a9937b7f07ab6e35515e32a7625f0ba50ab7670. The bug has been closed.

Larry

^ permalink raw reply

* Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts
From: Francois Romieu @ 2009-08-25 23:11 UTC (permalink / raw)
  To: David Dillow
  Cc: Eric W. Biederman, Michael Riepe, Michael Buesch, Rui Santos,
	Michael B?ker, linux-kernel, netdev
In-Reply-To: <1251237296.9607.42.camel@lap75545.ornl.gov>

David Dillow <dave@thedillows.org> :
[...]
> I wouldn't object if you did it, but I don't have time for it right now.
> And it may make Francois's life harder when he does his periodic sweep
> of the vendor driver, looking for differences.

This part of Realtek's driver(s) is not too tricky (I wonder if some code is
there by design or accident but it is a different story).

I do not feel safe with the TxDescUnavail bit : the driver does not
explicitely do anything to handle it but the behavior of the driver
can change depending on it. :o/

-- 
Ueimor

^ permalink raw reply

* Re: UDP multicast packet loss not reported if TX ring overrun?
From: Sridhar Samudrala @ 2009-08-25 22:35 UTC (permalink / raw)
  To: Christoph Lameter
  Cc: David Stevens, David S. Miller, Eric Dumazet, netdev,
	netdev-owner, niv, sri
In-Reply-To: <alpine.DEB.1.10.0908251514190.17963@gentwo.org>

On Tue, 2009-08-25 at 15:15 -0400, Christoph Lameter wrote:
> On Tue, 25 Aug 2009, David Stevens wrote:
> 
> > Christoph Lameter <cl@linux-foundation.org> wrote on 08/25/2009 06:48:24
> > AM:
> >
> > > On Mon, 24 Aug 2009, Sridhar Samudrala wrote:
> >
> > > > If we count these drops as qdisc drops, should we also count them as
> > IP OUTDISCARDS?
> > >
> > > Yes.
> >
> > Actually, no. (!)
> >
> > IP_OUTDISCARDS should count the packets IP dropped, not
> > anything dropped at a lower layer (which, in general, it
> > is not aware of). If you count these in multiple layers,
> > then you don't really know who dropped it.
> 
> You are right. I skipped that IP OUTDICARDS reference. They need to be
> accounted at the qdisc level though.

Yes. Now that we agree that drops at dev_queue_xmit level should be counted
under qdisc stats, the following patch should address 1 of the 3 places where
NET_XMIT_DROP is returned, but qdisc drop stats is not incremented.
The other 2 places are in ipsec output functions esp_output and esp6_output.
I am not sure where these drops should be accounted.

Could you check if the UDP packet losses you are seeing are accounted for in
qdisc drops with this patch. But i am not completely positive on this as this
case happens only if qdisc is deactivated.

diff --git a/net/core/dev.c b/net/core/dev.c
index 6a94475..8b6a075 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1864,8 +1864,7 @@ gso:
 		spin_lock(root_lock);
 
 		if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
-			kfree_skb(skb);
-			rc = NET_XMIT_DROP;
+			rc = qdisc_drop(skb, q);
 		} else {
 			rc = qdisc_enqueue_root(skb, q);
 			qdisc_run(q);

Thanks
Sridhar


^ permalink raw reply related

* Re: [PATCH 2.6.30-rc4] r8169: avoid losing MSI interrupts
From: Francois Romieu @ 2009-08-25 22:19 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: David Dillow, Michael Riepe, Michael Buesch, Rui Santos,
	Michael B??ker, linux-kernel, netdev
In-Reply-To: <m1k50r8u4p.fsf@fess.ebiederm.org>

Eric W. Biederman <ebiederm@xmission.com> :
[...]
> I am a bit curious about TxDescUnavail.  Perhaps we had a temporary
> memory shortage and that is what was screaming?  I don't think we do
> anything at all with that state.

You are not alone, the driver completely ignores this bit.

As far as I remember, the TxDescUnavail event mostly pops up when the
driver makes an excessive use of TxPoll requests.

> Perhaps the flaw here is simply not masking TxDescUnavail while we are
> in NAPI mode ?

Yes, it is worth trying.

-- 
Ueimor

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox