Re: [PLEASE-TESTME] Zerocopy networking patch, 2.4.0-1

yodaiken@fsmlabs.com
Sat, 13 Jan 2001 08:43:17 -0700


FWIW: POSIX mq_send does not promise that the buffer is safe, it only
promises that the message is queued. Interesting interface.

On Wed, Jan 10, 2001 at 09:41:24AM +0100, Manfred Spraul wrote:
> > > In user space, how do you know when its safe to reuse the buffer that
> > > was handed to sendmsg() with the MSG_NOCOPY flag? Or does sendmsg()
> > > with that flag block until the buffer isn't needed by the kernel any
> > > more? If it does block, doesn't that defeat the use of non-blocking
> > > I/O?
> >
> > sendmsg() marks those pages COW and copies the original page into a new
> > one for further usage. (the old page is used until the packet is
> > released.) So for maximum performance user-space should not reuse such
> > buffers immediately.
> >
> That means sendmsg() changes the page tables? I measures
> smp_call_function on my Dual Pentium 350, and it took around 1950 cpu
> ticks.
> I'm sure that for an 8 way server the total lost time on all cpus (multi
> threaded server) is larger than the time required to copy the complete
> page.
> (I've attached my patch, just run "insmod dummy p_shift=0")
>
>
> --
> Manfred
> --- 2.4/drivers/net/dummy.c Mon Dec 4 02:45:22 2000
> +++ build-2.4/drivers/net/dummy.c Wed Jan 10 09:15:20 2001
> @@ -95,9 +95,168 @@
>
> static struct net_device dev_dummy;
>
> +/* ************************************* */
> +int p_shift = -1;
> +MODULE_PARM (p_shift, "1i");
> +MODULE_PARM_DESC(p_shift, "Shift for the profile buffer");
> +
> +int p_size = 0;
> +MODULE_PARM (p_size, "1i");
> +MODULE_PARM_DESC(p_size, "size");
> +
> +
> +#define STAT_TABLELEN 16384
> +static unsigned long totals[STAT_TABLELEN];
> +static unsigned int overflows;
> +
> +static unsigned long long stime;
> +static void start_measure(void)
> +{
> + __asm__ __volatile__ (
> + ".align 64\n\t"
> + "pushal\n\t"
> + "cpuid\n\t"
> + "popal\n\t"
> + "rdtsc\n\t"
> + "movl %%eax,(%0)\n\t"
> + "movl %%edx,4(%0)\n\t"
> + : /* no output */
> + : "c"(&stime)
> + : "eax", "edx", "memory" );
> +}
> +
> +static void end_measure(void)
> +{
> +static unsigned long long etime;
> + __asm__ __volatile__ (
> + "pushal\n\t"
> + "cpuid\n\t"
> + "popal\n\t"
> + "rdtsc\n\t"
> + "movl %%eax,(%0)\n\t"
> + "movl %%edx,4(%0)\n\t"
> + : /* no output */
> + : "c"(&etime)
> + : "eax", "edx", "memory" );
> + {
> + unsigned long time = (unsigned long)(etime-stime);
> + time >>= p_shift;
> + if(time < STAT_TABLELEN) {
> + totals[time]++;
> + } else {
> + overflows++;
> + }
> + }
> +}
> +
> +static void clean_buf(void)
> +{
> + memset(totals,0,sizeof(totals));
> + overflows = 0;
> +}
> +
> +static void print_line(unsigned long* array)
> +{
> + int i;
> + for(i=0;i<32;i++) {
> + if((i%32)==16)
> + printk(":");
> + printk("%lx ",array[i]);
> + }
> +}
> +
> +static void print_buf(char* caption)
> +{
> + int i, other = 0;
> + printk("Results - %s - shift %d",
> + caption, p_shift);
> +
> + for(i=0;i<STAT_TABLELEN;i+=32) {
> + int j;
> + int local = 0;
> + for(j=0;j<32;j++)
> + local += totals[i+j];
> +
> + if(local) {
> + printk("\n%3x: ",i);
> + print_line(&totals[i]);
> + other += local;
> + }
> + }
> + printk("\nOverflows: %d.\n",
> + overflows);
> + printk("Sum: %ld\n",other+overflows);
> +}
> +
> +static void return_immediately(void* dummy)
> +{
> + return;
> +}
> +
> +static void just_one_page(void* dummy)
> +{
> + __flush_tlb_one(0x12345678);
> + return;
> +}
> +
> +
> static int __init dummy_init_module(void)
> {
> int err;
> +
> + if(p_shift != -1) {
> + int i;
> + void* p;
> + kmem_cache_t* cachep;
> + /* empty test measurement: */
> + printk("******** kernel cpu benchmark started **********\n");
> + clean_buf();
> + set_current_state(TASK_UNINTERRUPTIBLE);
> + schedule_timeout(200);
> + for(i=0;i<100;i++) {
> + start_measure();
> + return_immediately(NULL);
> + return_immediately(NULL);
> + return_immediately(NULL);
> + return_immediately(NULL);
> + end_measure();
> + }
> + print_buf("zero");
> + clean_buf();
> +
> + set_current_state(TASK_UNINTERRUPTIBLE);
> + schedule_timeout(200);
> + for(i=0;i<100;i++) {
> + start_measure();
> + return_immediately(NULL);
> + return_immediately(NULL);
> + smp_call_function(return_immediately,NULL,
> + 1, 1);
> + return_immediately(NULL);
> + return_immediately(NULL);
> + end_measure();
> + }
> + print_buf("empty smp_call_function()");
> + clean_buf();
> +
> + set_current_state(TASK_UNINTERRUPTIBLE);
> + schedule_timeout(200);
> + for(i=0;i<100;i++) {
> + start_measure();
> + return_immediately(NULL);
> + return_immediately(NULL);
> + smp_call_function(just_one_page,NULL,
> + 1, 1);
> + just_one_page(NULL);
> + return_immediately(NULL);
> + return_immediately(NULL);
> + end_measure();
> + }
> + print_buf("flush_one_page()");
> + clean_buf();
> +
> + return -EINVAL;
> + }
>
> dev_dummy.init = dummy_init;
> SET_MODULE_OWNER(&dev_dummy);
>

-- 
---------------------------------------------------------
Victor Yodaiken 
Finite State Machine Labs: The RTLinux Company.
 www.fsmlabs.com  www.rtlinux.com

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/