* Re: [PATCH 13/14] x86/ticketlock: add slowpath logic
From: Srivatsa Vaddagiri @ 2011-01-17 15:22 UTC (permalink / raw)
To: Jeremy Fitzhardinge
Cc: Xen-devel, Mathieu Desnoyers, Nick Piggin, Peter Zijlstra,
Linux Kernel Mailing List, Jan Beulich, Eric Dumazet,
Jeremy Fitzhardinge, suzuki, Avi Kivity, H. Peter Anvin,
Américo Wang, Linux Virtualization
In-Reply-To: <97ed99ae9160bdb6477284b333bd6708fb7a19cb.1289940821.git.jeremy.fitzhardinge@citrix.com>
On Tue, Nov 16, 2010 at 01:08:44PM -0800, Jeremy Fitzhardinge wrote:
> From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
>
> Maintain a flag in both LSBs of the ticket lock which indicates whether
> anyone is in the lock slowpath and may need kicking when the current
> holder unlocks. The flags are set when the first locker enters
> the slowpath, and cleared when unlocking to an empty queue.
>
> In the specific implementation of lock_spinning(), make sure to set
> the slowpath flags on the lock just before blocking. We must do
> this before the last-chance pickup test to prevent a deadlock
> with the unlocker:
>
> Unlocker Locker
> test for lock pickup
> -> fail
> test slowpath + unlock
> -> false
> set slowpath flags
> block
>
> Whereas this works in any ordering:
>
> Unlocker Locker
> set slowpath flags
> test for lock pickup
> -> fail
> block
> test slowpath + unlock
> -> true, kick
I think this is still racy ..
Unlocker Locker
test slowpath
-> false
set slowpath flag
test for lock pickup
-> fail
block
unlock
unlock needs to happen first before testing slowpath? I have made that change
for my KVM guest and it seems to be working well with that change .. Will
cleanup and post my patches shortly
- vatsa
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Jesper Nilsson @ 2011-01-17 13:58 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Russell King - ARM Linux, Richard Henderson, Ivan Kokshaysky,
Matt Turner, Mike Frysinger, Mikael Starvik, Tony Luck,
Fenghua Yu, Hirokazu Takata, Ralf Baechle, David Howells,
Koichi Yasutake, Kyle McMartin, Helge Deller,
James E.J. Bottomley, Benjamin Herrenschmidt, Paul Mackerras,
Martin Schwidefsky, Heiko Carstens
In-Reply-To: <1295264509.30950.59.camel@laptop>
On Mon, Jan 17, 2011 at 12:41:49PM +0100, Peter Zijlstra wrote:
> Index: linux-2.6/arch/cris/arch-v32/kernel/smp.c
> ===================================================================
> --- linux-2.6.orig/arch/cris/arch-v32/kernel/smp.c
> +++ linux-2.6/arch/cris/arch-v32/kernel/smp.c
> @@ -340,15 +340,18 @@ irqreturn_t crisv32_ipi_interrupt(int ir
>
> ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi);
>
> + if (ipi.vector & IPI_SCHEDULE) {
> + scheduler_ipi();
> + }
> if (ipi.vector & IPI_CALL) {
> - func(info);
> + func(info);
> }
> if (ipi.vector & IPI_FLUSH_TLB) {
> - if (flush_mm == FLUSH_ALL)
> - __flush_tlb_all();
> - else if (flush_vma == FLUSH_ALL)
> + if (flush_mm == FLUSH_ALL)
> + __flush_tlb_all();
> + else if (flush_vma == FLUSH_ALL)
> __flush_tlb_mm(flush_mm);
> - else
> + else
> __flush_tlb_page(flush_vma, flush_addr);
> }
>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
/^JN - Jesper Nilsson
--
Jesper Nilsson -- jesper.nilsson@axis.com
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Chris Metcalf @ 2011-01-17 13:52 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Russell King - ARM Linux, Richard Henderson, Ivan Kokshaysky,
Matt Turner, Mike Frysinger, Mikael Starvik, Jesper Nilsson,
Tony Luck, Fenghua Yu, Hirokazu Takata, Ralf Baechle,
David Howells, Koichi Yasutake, Kyle McMartin, Helge Deller,
James E.J. Bottomley, Benjamin Herrenschmidt, Paul Mackerras,
Martin Schwidefsky
In-Reply-To: <1295264509.30950.59.camel@laptop>
On 1/17/2011 6:41 AM, Peter Zijlstra wrote:
> Index: linux-2.6/arch/tile/kernel/smp.c
> ===================================================================
> --- linux-2.6.orig/arch/tile/kernel/smp.c
> +++ linux-2.6/arch/tile/kernel/smp.c
> @@ -184,12 +184,8 @@ void flush_icache_range(unsigned long st
> /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
> static irqreturn_t handle_reschedule_ipi(int irq, void *token)
> {
> - /*
> - * Nothing to do here; when we return from interrupt, the
> - * rescheduling will occur there. But do bump the interrupt
> - * profiler count in the meantime.
> - */
> __get_cpu_var(irq_stat).irq_resched_count++;
> + scheduler_ipi();
>
> return IRQ_HANDLED;
> }
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
--
Chris Metcalf, Tilera Corp.
http://www.tilera.com
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Martin Schwidefsky @ 2011-01-17 12:18 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner, Russell King,
Mike Frysinger, Mikael Starvik, Jesper Nilsson, Tony Luck,
Fenghua Yu, Hirokazu Takata, Ralf Baechle, David Howells,
Koichi Yasutake, Kyle McMartin, Helge Deller,
James E.J. Bottomley, Benjamin Herrenschmidt, Paul Mackerras,
Heiko Carstens, linux390@
In-Reply-To: <1295262433.30950.53.camel@laptop>
On Mon, 17 Jan 2011 12:07:13 +0100
Peter Zijlstra <peterz@infradead.org> wrote:
> I visited existing smp_send_reschedule() implementations and tried to
> add a call to scheduler_ipi() in their handler part, but esp. for MIPS
> I'm not quite sure I actually got all of them.
>
> diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
> index 94cf510..61789e8 100644
> --- a/arch/s390/kernel/smp.c
> +++ b/arch/s390/kernel/smp.c
> @@ -163,12 +163,12 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
>
> /*
> * handle bit signal external calls
> - *
> - * For the ec_schedule signal we have to do nothing. All the work
> - * is done automatically when we return from the interrupt.
> */
> bits = xchg(&S390_lowcore.ext_call_fast, 0);
>
> + if (test_bit(ec_schedule, &bits))
> + scheduler_ipi();
> +
> if (test_bit(ec_call_function, &bits))
> generic_smp_call_function_interrupt();
>
s390 bits are fine.
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Russell King - ARM Linux @ 2011-01-17 11:57 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner, Mike Frysinger,
Mikael Starvik, Jesper Nilsson, Tony Luck, Fenghua Yu,
Hirokazu Takata, Ralf Baechle, David Howells, Koichi Yasutake,
Kyle McMartin, Helge Deller, James E.J. Bottomley,
Benjamin Herrenschmidt, Paul Mackerras, Martin Schwidefsky,
Heiko Carstens
In-Reply-To: <1295264509.30950.59.camel@laptop>
On Mon, Jan 17, 2011 at 12:41:49PM +0100, Peter Zijlstra wrote:
> ===================================================================
> --- linux-2.6.orig/arch/arm/kernel/smp.c
> +++ linux-2.6/arch/arm/kernel/smp.c
> @@ -575,10 +575,7 @@ asmlinkage void __exception do_IPI(struc
> break;
>
> case IPI_RESCHEDULE:
> - /*
> - * nothing more to do - eveything is
> - * done on the interrupt return path
> - */
> + scheduler_ipi();
> break;
>
> case IPI_CALL_FUNC:
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Peter Zijlstra @ 2011-01-17 11:41 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-ia64-u79uwXL29TY76Z2rM5mHXA,
linux-sh-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
Heiko Carstens, James E.J. Bottomley, David Howells,
Paul Mackerras, H. Peter Anvin, sparclinux-u79uwXL29TY76Z2rM5mHXA,
Ralf-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b, Linux-Arch,
Jesper-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b,
Mike-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b, Jeremy Fitzhardinge,
Hirokazu Takata, x86-DgEjT+Ai2ygdnm+yROfE0A,
Koichi-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b,
virtualization-qjLDD68F18O7TbgM5vRIOg, Ingo Molnar, Matt Turner,
Yu, Frysinger, user-mo
In-Reply-To: <1295263884.30950.54.camel@laptop>
On Mon, 2011-01-17 at 12:31 +0100, Peter Zijlstra wrote:
> On Mon, 2011-01-17 at 11:26 +0000, Russell King - ARM Linux wrote:
> > Maybe remove the comment "everything is done on the interrupt return path"
> > as with this function call, that is no longer the case.
(Removed am33, m32r-ka, m32r, arm-kernel lists because they kept sending
bounces)
---
Subject: sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Peter Zijlstra <peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
Date: Mon, 17 Jan 2011 12:07:13 +0100
For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Signed-off-by: Peter Zijlstra <a.p.zijlstra-/NLkJaSkS4VmR6Xm/wNWPw@public.gmane.org>
LKML-Reference: <new-submission>
---
arch/alpha/kernel/smp.c | 3 +--
arch/arm/kernel/smp.c | 5 +----
arch/blackfin/mach-common/smp.c | 5 ++---
arch/cris/arch-v32/kernel/smp.c | 13 ++++++++-----
arch/ia64/kernel/irq_ia64.c | 2 ++
arch/ia64/xen/irq_xen.c | 10 +++++++++-
arch/m32r/kernel/smp.c | 4 +---
arch/mips/kernel/smtc.c | 2 +-
arch/mips/sibyte/bcm1480/smp.c | 7 +++----
arch/mips/sibyte/sb1250/smp.c | 7 +++----
arch/mn10300/kernel/smp.c | 5 +----
arch/parisc/kernel/smp.c | 5 +----
arch/powerpc/kernel/smp.c | 2 +-
arch/s390/kernel/smp.c | 6 +++---
arch/sh/kernel/smp.c | 2 ++
arch/sparc/kernel/smp_32.c | 2 +-
arch/sparc/kernel/smp_64.c | 1 +
arch/tile/kernel/smp.c | 6 +-----
arch/um/kernel/smp.c | 2 +-
arch/x86/kernel/smp.c | 5 ++---
arch/x86/xen/smp.c | 5 ++---
include/linux/sched.h | 1 +
22 files changed, 48 insertions(+), 52 deletions(-)
Index: linux-2.6/arch/alpha/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/smp.c
+++ linux-2.6/arch/alpha/kernel/smp.c
@@ -585,8 +585,7 @@ handle_ipi(struct pt_regs *regs)
switch (which) {
case IPI_RESCHEDULE:
- /* Reschedule callback. Everything to be done
- is done by the interrupt return path. */
+ scheduler_ipi();
break;
case IPI_CALL_FUNC:
Index: linux-2.6/arch/arm/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/smp.c
+++ linux-2.6/arch/arm/kernel/smp.c
@@ -575,10 +575,7 @@ asmlinkage void __exception do_IPI(struc
break;
case IPI_RESCHEDULE:
- /*
- * nothing more to do - eveything is
- * done on the interrupt return path
- */
+ scheduler_ipi();
break;
case IPI_CALL_FUNC:
Index: linux-2.6/arch/blackfin/mach-common/smp.c
===================================================================
--- linux-2.6.orig/arch/blackfin/mach-common/smp.c
+++ linux-2.6/arch/blackfin/mach-common/smp.c
@@ -154,8 +154,7 @@ static irqreturn_t ipi_handler(int irq,
list_del(&msg->list);
switch (msg->type) {
case BFIN_IPI_RESCHEDULE:
- /* That's the easiest one; leave it to
- * return_from_int. */
+ scheduler_ipi();
kfree(msg);
break;
case BFIN_IPI_CALL_FUNC:
@@ -301,7 +300,7 @@ void smp_send_reschedule(int cpu)
msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
if (!msg)
- return;
+ return; /* XXX unreliable needs fixing ! */
INIT_LIST_HEAD(&msg->list);
msg->type = BFIN_IPI_RESCHEDULE;
Index: linux-2.6/arch/cris/arch-v32/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/cris/arch-v32/kernel/smp.c
+++ linux-2.6/arch/cris/arch-v32/kernel/smp.c
@@ -340,15 +340,18 @@ irqreturn_t crisv32_ipi_interrupt(int ir
ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi);
+ if (ipi.vector & IPI_SCHEDULE) {
+ scheduler_ipi();
+ }
if (ipi.vector & IPI_CALL) {
- func(info);
+ func(info);
}
if (ipi.vector & IPI_FLUSH_TLB) {
- if (flush_mm == FLUSH_ALL)
- __flush_tlb_all();
- else if (flush_vma == FLUSH_ALL)
+ if (flush_mm == FLUSH_ALL)
+ __flush_tlb_all();
+ else if (flush_vma == FLUSH_ALL)
__flush_tlb_mm(flush_mm);
- else
+ else
__flush_tlb_page(flush_vma, flush_addr);
}
Index: linux-2.6/arch/ia64/kernel/irq_ia64.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/irq_ia64.c
+++ linux-2.6/arch/ia64/kernel/irq_ia64.c
@@ -31,6 +31,7 @@
#include <linux/irq.h>
#include <linux/ratelimit.h>
#include <linux/acpi.h>
+#include <linux/sched.h>
#include <asm/delay.h>
#include <asm/intrinsics.h>
@@ -496,6 +497,7 @@ ia64_handle_irq (ia64_vector vector, str
smp_local_flush_tlb();
kstat_incr_irqs_this_cpu(irq, desc);
} else if (unlikely(IS_RESCHEDULE(vector))) {
+ scheduler_ipi();
kstat_incr_irqs_this_cpu(irq, desc);
} else {
ia64_setreg(_IA64_REG_CR_TPR, vector);
Index: linux-2.6/arch/ia64/xen/irq_xen.c
===================================================================
--- linux-2.6.orig/arch/ia64/xen/irq_xen.c
+++ linux-2.6/arch/ia64/xen/irq_xen.c
@@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt;
static int xen_slab_ready;
#ifdef CONFIG_SMP
+#include <linux/sched.h>
+
/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
* it ends up to issue several memory accesses upon percpu data and
* thus adds unnecessary traffic to other paths.
@@ -99,7 +101,13 @@ static int xen_slab_ready;
static irqreturn_t
xen_dummy_handler(int irq, void *dev_id)
{
+ return IRQ_HANDLED;
+}
+static irqreturn_t
+xen_resched_handler(int irq, void *dev_id)
+{
+ scheduler_ipi();
return IRQ_HANDLED;
}
@@ -110,7 +118,7 @@ static struct irqaction xen_ipi_irqactio
};
static struct irqaction xen_resched_irqaction = {
- .handler = xen_dummy_handler,
+ .handler = xen_resched_handler,
.flags = IRQF_DISABLED,
.name = "resched"
};
Index: linux-2.6/arch/m32r/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/smp.c
+++ linux-2.6/arch/m32r/kernel/smp.c
@@ -122,8 +122,6 @@ void smp_send_reschedule(int cpu_id)
*
* Description: This routine executes on CPU which received
* 'RESCHEDULE_IPI'.
- * Rescheduling is processed at the exit of interrupt
- * operation.
*
* Born on Date: 2002.02.05
*
@@ -138,7 +136,7 @@ void smp_send_reschedule(int cpu_id)
*==========================================================================*/
void smp_reschedule_interrupt(void)
{
- /* nothing to do */
+ scheduler_ipi();
}
/*==========================================================================*
Index: linux-2.6/arch/mips/kernel/smtc.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/smtc.c
+++ linux-2.6/arch/mips/kernel/smtc.c
@@ -930,7 +930,7 @@ static void post_direct_ipi(int cpu, str
static void ipi_resched_interrupt(void)
{
- /* Return from interrupt should be enough to cause scheduler check */
+ scheduler_ipi();
}
static void ipi_call_interrupt(void)
Index: linux-2.6/arch/mips/sibyte/bcm1480/smp.c
===================================================================
--- linux-2.6.orig/arch/mips/sibyte/bcm1480/smp.c
+++ linux-2.6/arch/mips/sibyte/bcm1480/smp.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
+#include <linux/sched.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
@@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void)
/* Clear the mailbox to clear the interrupt */
__raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (actione & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
Index: linux-2.6/arch/mips/sibyte/sb1250/smp.c
===================================================================
--- linux-2.6.orig/arch/mips/sibyte/sb1250/smp.c
+++ linux-2.6/arch/mips/sibyte/sb1250/smp.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
+#include <linux/sched.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
@@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void)
/* Clear the mailbox to clear the interrupt */
____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
Index: linux-2.6/arch/mn10300/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/mn10300/kernel/smp.c
+++ linux-2.6/arch/mn10300/kernel/smp.c
@@ -464,14 +464,11 @@ void smp_send_stop(void)
* @irq: The interrupt number.
* @dev_id: The device ID.
*
- * We need do nothing here, since the scheduling will be effected on our way
- * back through entry.S.
- *
* Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
*/
static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
{
- /* do nothing */
+ scheduler_ipi();
return IRQ_HANDLED;
}
Index: linux-2.6/arch/parisc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/smp.c
+++ linux-2.6/arch/parisc/kernel/smp.c
@@ -155,10 +155,7 @@ ipi_interrupt(int irq, void *dev_id)
case IPI_RESCHEDULE:
smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
- /*
- * Reschedule callback. Everything to be
- * done is done by the interrupt return path.
- */
+ scheduler_ipi();
break;
case IPI_CALL_FUNC:
Index: linux-2.6/arch/powerpc/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/smp.c
+++ linux-2.6/arch/powerpc/kernel/smp.c
@@ -127,7 +127,7 @@ static irqreturn_t call_function_action(
static irqreturn_t reschedule_action(int irq, void *data)
{
- /* we just need the return path side effect of checking need_resched */
+ scheduler_ipi();
return IRQ_HANDLED;
}
Index: linux-2.6/arch/s390/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/smp.c
+++ linux-2.6/arch/s390/kernel/smp.c
@@ -163,12 +163,12 @@ static void do_ext_call_interrupt(unsign
/*
* handle bit signal external calls
- *
- * For the ec_schedule signal we have to do nothing. All the work
- * is done automatically when we return from the interrupt.
*/
bits = xchg(&S390_lowcore.ext_call_fast, 0);
+ if (test_bit(ec_schedule, &bits))
+ scheduler_ipi();
+
if (test_bit(ec_call_function, &bits))
generic_smp_call_function_interrupt();
Index: linux-2.6/arch/sh/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/smp.c
+++ linux-2.6/arch/sh/kernel/smp.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -323,6 +324,7 @@ void smp_message_recv(unsigned int msg)
generic_smp_call_function_interrupt();
break;
case SMP_MSG_RESCHEDULE:
+ scheduler_ipi();
break;
case SMP_MSG_FUNCTION_SINGLE:
generic_smp_call_function_single_interrupt();
Index: linux-2.6/arch/sparc/kernel/smp_32.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_32.c
+++ linux-2.6/arch/sparc/kernel/smp_32.c
@@ -125,7 +125,7 @@ struct linux_prom_registers smp_penguin_
void smp_send_reschedule(int cpu)
{
- /* See sparc64 */
+ scheduler_ipi();
}
void smp_send_stop(void)
Index: linux-2.6/arch/sparc/kernel/smp_64.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/smp_64.c
+++ linux-2.6/arch/sparc/kernel/smp_64.c
@@ -1369,6 +1369,7 @@ void smp_send_reschedule(int cpu)
void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
+ scheduler_ipi();
}
/* This is a nop because we capture all other cpus
Index: linux-2.6/arch/tile/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/tile/kernel/smp.c
+++ linux-2.6/arch/tile/kernel/smp.c
@@ -184,12 +184,8 @@ void flush_icache_range(unsigned long st
/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
static irqreturn_t handle_reschedule_ipi(int irq, void *token)
{
- /*
- * Nothing to do here; when we return from interrupt, the
- * rescheduling will occur there. But do bump the interrupt
- * profiler count in the meantime.
- */
__get_cpu_var(irq_stat).irq_resched_count++;
+ scheduler_ipi();
return IRQ_HANDLED;
}
Index: linux-2.6/arch/um/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/um/kernel/smp.c
+++ linux-2.6/arch/um/kernel/smp.c
@@ -173,7 +173,7 @@ void IPI_handler(int cpu)
break;
case 'R':
- set_tsk_need_resched(current);
+ scheduler_ipi();
break;
case 'S':
Index: linux-2.6/arch/x86/kernel/smp.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/smp.c
+++ linux-2.6/arch/x86/kernel/smp.c
@@ -194,14 +194,13 @@ static void native_stop_other_cpus(int w
}
/*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
+ * Reschedule call back.
*/
void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ scheduler_ipi();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
Index: linux-2.6/arch/x86/xen/smp.c
===================================================================
--- linux-2.6.orig/arch/x86/xen/smp.c
+++ linux-2.6/arch/x86/xen/smp.c
@@ -46,13 +46,12 @@ static irqreturn_t xen_call_function_int
static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
/*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
+ * Reschedule call back.
*/
static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
{
inc_irq_stat(irq_resched_count);
+ scheduler_ipi();
return IRQ_HANDLED;
}
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -2183,6 +2183,7 @@ extern void set_task_comm(struct task_st
extern char *get_task_comm(char *to, struct task_struct *tsk);
#ifdef CONFIG_SMP
+static inline void scheduler_ipi(void) { }
extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
#else
static inline unsigned long wait_task_inactive(struct task_struct *p,
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Peter Zijlstra @ 2011-01-17 11:31 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner, Mike Frysinger,
Mikael Starvik, Jesper Nilsson, Tony Luck, Fenghua Yu,
Hirokazu Takata, Ralf Baechle, David Howells, Koichi Yasutake,
Kyle McMartin, Helge Deller, James E.J. Bottomley,
Benjamin Herrenschmidt, Paul Mackerras, Martin Schwidefsky,
Heiko Carstens
In-Reply-To: <20110117112637.GA18599@n2100.arm.linux.org.uk>
On Mon, 2011-01-17 at 11:26 +0000, Russell King - ARM Linux wrote:
> On Mon, Jan 17, 2011 at 12:07:13PM +0100, Peter Zijlstra wrote:
> > diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
> > index 42aa078..c4a570b 100644
> > --- a/arch/alpha/kernel/smp.c
> > +++ b/arch/alpha/kernel/smp.c
> > @@ -587,6 +587,7 @@ handle_ipi(struct pt_regs *regs)
> > case IPI_RESCHEDULE:
> > /* Reschedule callback. Everything to be done
> > is done by the interrupt return path. */
> > + scheduler_ipi();
> > break;
> >
> > case IPI_CALL_FUNC:
> > diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> > index 9066473..ffde790 100644
> > --- a/arch/arm/kernel/smp.c
> > +++ b/arch/arm/kernel/smp.c
> > @@ -579,6 +579,7 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs)
> > * nothing more to do - eveything is
> > * done on the interrupt return path
> > */
> > + scheduler_ipi();
>
> Maybe remove the comment "everything is done on the interrupt return path"
> as with this function call, that is no longer the case.
>
> Looks like the same is true for Alpha as well?
Right, will do, thanks! It looks like I've somewhat inconsistent with
that.
^ permalink raw reply
* Re: [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Russell King - ARM Linux @ 2011-01-17 11:26 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner, Mike Frysinger,
Mikael Starvik, Jesper Nilsson, Tony Luck, Fenghua Yu,
Hirokazu Takata, Ralf Baechle, David Howells, Koichi Yasutake,
Kyle McMartin, Helge Deller, James E.J. Bottomley,
Benjamin Herrenschmidt, Paul Mackerras, Martin Schwidefsky,
Heiko Carstens
In-Reply-To: <1295262433.30950.53.camel@laptop>
On Mon, Jan 17, 2011 at 12:07:13PM +0100, Peter Zijlstra wrote:
> diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
> index 42aa078..c4a570b 100644
> --- a/arch/alpha/kernel/smp.c
> +++ b/arch/alpha/kernel/smp.c
> @@ -587,6 +587,7 @@ handle_ipi(struct pt_regs *regs)
> case IPI_RESCHEDULE:
> /* Reschedule callback. Everything to be done
> is done by the interrupt return path. */
> + scheduler_ipi();
> break;
>
> case IPI_CALL_FUNC:
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 9066473..ffde790 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -579,6 +579,7 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs)
> * nothing more to do - eveything is
> * done on the interrupt return path
> */
> + scheduler_ipi();
Maybe remove the comment "everything is done on the interrupt return path"
as with this function call, that is no longer the case.
Looks like the same is true for Alpha as well?
^ permalink raw reply
* [PATCH] sched: provide scheduler_ipi() callback in response to smp_send_reschedule()
From: Peter Zijlstra @ 2011-01-17 11:07 UTC (permalink / raw)
To: Richard Henderson, Ivan Kokshaysky, Matt Turner, Russell King
For future rework of try_to_wake_up() we'd like to push part of that
onto the CPU the task is actually going to run on, in order to do so we
need a generic callback from the existing scheduler IPI.
This patch introduces such a generic callback: scheduler_ipi() and
implements it as a NOP.
I visited existing smp_send_reschedule() implementations and tried to
add a call to scheduler_ipi() in their handler part, but esp. for MIPS
I'm not quite sure I actually got all of them.
Also, while reading through all this, I noticed the blackfin SMP code
looks to be broken, it simply discards any IPI when low on memory.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
arch/alpha/kernel/smp.c | 1 +
arch/arm/kernel/smp.c | 1 +
arch/blackfin/mach-common/smp.c | 3 ++-
arch/cris/arch-v32/kernel/smp.c | 13 ++++++++-----
arch/ia64/kernel/irq_ia64.c | 2 ++
arch/ia64/xen/irq_xen.c | 10 +++++++++-
arch/m32r/kernel/smp.c | 2 +-
arch/mips/kernel/smtc.c | 1 +
arch/mips/sibyte/bcm1480/smp.c | 7 +++----
arch/mips/sibyte/sb1250/smp.c | 7 +++----
arch/mn10300/kernel/smp.c | 2 +-
arch/parisc/kernel/smp.c | 1 +
arch/powerpc/kernel/smp.c | 1 +
arch/s390/kernel/smp.c | 6 +++---
arch/sh/kernel/smp.c | 2 ++
arch/sparc/kernel/smp_32.c | 2 +-
arch/sparc/kernel/smp_64.c | 1 +
arch/tile/kernel/smp.c | 1 +
arch/um/kernel/smp.c | 2 +-
arch/x86/kernel/smp.c | 1 +
arch/x86/xen/smp.c | 1 +
include/linux/sched.h | 1 +
22 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 42aa078..c4a570b 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -587,6 +587,7 @@ handle_ipi(struct pt_regs *regs)
case IPI_RESCHEDULE:
/* Reschedule callback. Everything to be done
is done by the interrupt return path. */
+ scheduler_ipi();
break;
case IPI_CALL_FUNC:
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 9066473..ffde790 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -579,6 +579,7 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs)
* nothing more to do - eveything is
* done on the interrupt return path
*/
+ scheduler_ipi();
break;
case IPI_CALL_FUNC:
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index a17107a..e210f8a 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -156,6 +156,7 @@ static irqreturn_t ipi_handler(int irq, void *dev_instance)
case BFIN_IPI_RESCHEDULE:
/* That's the easiest one; leave it to
* return_from_int. */
+ scheduler_ipi();
kfree(msg);
break;
case BFIN_IPI_CALL_FUNC:
@@ -301,7 +302,7 @@ void smp_send_reschedule(int cpu)
msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
if (!msg)
- return;
+ return; /* XXX unreliable needs fixing ! */
INIT_LIST_HEAD(&msg->list);
msg->type = BFIN_IPI_RESCHEDULE;
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 84fed3b..86e3c76 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -340,15 +340,18 @@ irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id)
ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi);
+ if (ipi.vector & IPI_SCHEDULE) {
+ scheduler_ipi();
+ }
if (ipi.vector & IPI_CALL) {
- func(info);
+ func(info);
}
if (ipi.vector & IPI_FLUSH_TLB) {
- if (flush_mm == FLUSH_ALL)
- __flush_tlb_all();
- else if (flush_vma == FLUSH_ALL)
+ if (flush_mm == FLUSH_ALL)
+ __flush_tlb_all();
+ else if (flush_vma == FLUSH_ALL)
__flush_tlb_mm(flush_mm);
- else
+ else
__flush_tlb_page(flush_vma, flush_addr);
}
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 9a26015..a580230 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -31,6 +31,7 @@
#include <linux/irq.h>
#include <linux/ratelimit.h>
#include <linux/acpi.h>
+#include <linux/sched.h>
#include <asm/delay.h>
#include <asm/intrinsics.h>
@@ -496,6 +497,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
smp_local_flush_tlb();
kstat_incr_irqs_this_cpu(irq, desc);
} else if (unlikely(IS_RESCHEDULE(vector))) {
+ scheduler_ipi();
kstat_incr_irqs_this_cpu(irq, desc);
} else {
ia64_setreg(_IA64_REG_CR_TPR, vector);
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c
index a3fb7cf..2f235a3 100644
--- a/arch/ia64/xen/irq_xen.c
+++ b/arch/ia64/xen/irq_xen.c
@@ -92,6 +92,8 @@ static unsigned short saved_irq_cnt;
static int xen_slab_ready;
#ifdef CONFIG_SMP
+#include <linux/sched.h>
+
/* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
* it ends up to issue several memory accesses upon percpu data and
* thus adds unnecessary traffic to other paths.
@@ -99,7 +101,13 @@ static int xen_slab_ready;
static irqreturn_t
xen_dummy_handler(int irq, void *dev_id)
{
+ return IRQ_HANDLED;
+}
+static irqreturn_t
+xen_resched_handler(int irq, void *dev_id)
+{
+ scheduler_ipi();
return IRQ_HANDLED;
}
@@ -110,7 +118,7 @@ static struct irqaction xen_ipi_irqaction = {
};
static struct irqaction xen_resched_irqaction = {
- .handler = xen_dummy_handler,
+ .handler = xen_resched_handler,
.flags = IRQF_DISABLED,
.name = "resched"
};
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 31cef20..f0ecc3f 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -138,7 +138,7 @@ void smp_send_reschedule(int cpu_id)
*==========================================================================*/
void smp_reschedule_interrupt(void)
{
- /* nothing to do */
+ scheduler_ipi();
}
/*==========================================================================*
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 39c0825..0443e91 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -931,6 +931,7 @@ static void post_direct_ipi(int cpu, struct smtc_ipi *pipi)
static void ipi_resched_interrupt(void)
{
/* Return from interrupt should be enough to cause scheduler check */
+ scheduler_ipi();
}
static void ipi_call_interrupt(void)
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 47b347c..513a301 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
+#include <linux/sched.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
@@ -189,10 +190,8 @@ void bcm1480_mailbox_interrupt(void)
/* Clear the mailbox to clear the interrupt */
__raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (actione & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index c00a5cb..38e7f6b 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
+#include <linux/sched.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
@@ -177,10 +178,8 @@ void sb1250_mailbox_interrupt(void)
/* Clear the mailbox to clear the interrupt */
____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
- /*
- * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
- * interrupt will do the reschedule for us
- */
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 0dcd1c6..17f16ca 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -471,7 +471,7 @@ void smp_send_stop(void)
*/
static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
{
- /* do nothing */
+ scheduler_ipi();
return IRQ_HANDLED;
}
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 69d63d3..f8f7970 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -155,6 +155,7 @@ ipi_interrupt(int irq, void *dev_id)
case IPI_RESCHEDULE:
smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
+ scheduler_ipi();
/*
* Reschedule callback. Everything to be
* done is done by the interrupt return path.
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 68034bb..7ee0fc3 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -128,6 +128,7 @@ static irqreturn_t call_function_action(int irq, void *data)
static irqreturn_t reschedule_action(int irq, void *data)
{
/* we just need the return path side effect of checking need_resched */
+ scheduler_ipi();
return IRQ_HANDLED;
}
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 94cf510..61789e8 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -163,12 +163,12 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
/*
* handle bit signal external calls
- *
- * For the ec_schedule signal we have to do nothing. All the work
- * is done automatically when we return from the interrupt.
*/
bits = xchg(&S390_lowcore.ext_call_fast, 0);
+ if (test_bit(ec_schedule, &bits))
+ scheduler_ipi();
+
if (test_bit(ec_call_function, &bits))
generic_smp_call_function_interrupt();
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 509b36b..6207561 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -323,6 +324,7 @@ void smp_message_recv(unsigned int msg)
generic_smp_call_function_interrupt();
break;
case SMP_MSG_RESCHEDULE:
+ scheduler_ipi();
break;
case SMP_MSG_FUNCTION_SINGLE:
generic_smp_call_function_single_interrupt();
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 91c10fb..042d8c9 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -125,7 +125,7 @@ struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 };
void smp_send_reschedule(int cpu)
{
- /* See sparc64 */
+ scheduler_ipi();
}
void smp_send_stop(void)
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index b6a2b8f..68e26e2 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1369,6 +1369,7 @@ void smp_send_reschedule(int cpu)
void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
{
clear_softint(1 << irq);
+ scheduler_ipi();
}
/* This is a nop because we capture all other cpus
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index 9575b37..91a1ddf 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -190,6 +190,7 @@ static irqreturn_t handle_reschedule_ipi(int irq, void *token)
* profiler count in the meantime.
*/
__get_cpu_var(irq_stat).irq_resched_count++;
+ scheduler_ipi();
return IRQ_HANDLED;
}
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 106bf27..eefb107 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -173,7 +173,7 @@ void IPI_handler(int cpu)
break;
case 'R':
- set_tsk_need_resched(current);
+ scheduler_ipi();
break;
case 'S':
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 513deac..e38c2d8 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -202,6 +202,7 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
inc_irq_stat(irq_resched_count);
+ scheduler_ipi();
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 72a4c79..6196fb1 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -53,6 +53,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
{
inc_irq_stat(irq_resched_count);
+ scheduler_ipi();
return IRQ_HANDLED;
}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 341acbb..aa458dc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2183,6 +2183,7 @@ extern void set_task_comm(struct task_struct *tsk, char *from);
extern char *get_task_comm(char *to, struct task_struct *tsk);
#ifdef CONFIG_SMP
+static inline void scheduler_ipi(void) { }
extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
#else
static inline unsigned long wait_task_inactive(struct task_struct *p,
^ permalink raw reply related
* Re: Flow Control and Port Mirroring Revisited
From: Michael S. Tsirkin @ 2011-01-17 10:38 UTC (permalink / raw)
To: Rusty Russell
Cc: Simon Horman, Jesse Gross, Eric Dumazet, virtualization, dev,
virtualization, netdev, kvm
In-Reply-To: <201101171026.26213.rusty@rustcorp.com.au>
On Mon, Jan 17, 2011 at 10:26:25AM +1030, Rusty Russell wrote:
> On Mon, 17 Jan 2011 09:07:30 am Simon Horman wrote:
>
> [snip]
>
> I've been away, but what concerns me is that socket buffer limits are
> bypassed in various configurations, due to skb cloning. We should probably
> drop such limits altogether, or fix them to be consistent.
Further, it looks like when the limits are not bypassed, they
easily result in deadlocks. For example, with
multiple tun devices attached to a single bridge in host,
if a number of these have their queues blocked,
others will reach the socket buffer limit and
traffic on the bridge will get blocked altogether.
It might be better to drop the limits altogether
unless we can fix them. Happily, as the limits are off by
default, doing so does not require kernel changes.
> Simple fix is as someone suggested here, to attach the clone. That might
> seriously reduce your sk limit, though. I haven't thought about it hard,
> but might it make sense to move ownership into skb_shared_info; ie. the
> data, rather than the skb head?
>
> Cheers,
> Rusty.
tracking data ownership might benefit others such as various zero-copy
strategies. It might need to be done per-page, though, not per-skb.
--
MST
^ permalink raw reply
* Re: Flow Control and Port Mirroring Revisited
From: Michael S. Tsirkin @ 2011-01-17 10:26 UTC (permalink / raw)
To: Simon Horman
Cc: Jesse Gross, Eric Dumazet, Rusty Russell, virtualization, dev,
virtualization, netdev, kvm
In-Reply-To: <20110116223728.GA6279@verge.net.au>
On Mon, Jan 17, 2011 at 07:37:30AM +0900, Simon Horman wrote:
> On Fri, Jan 14, 2011 at 08:54:15AM +0200, Michael S. Tsirkin wrote:
> > On Fri, Jan 14, 2011 at 03:35:28PM +0900, Simon Horman wrote:
> > > On Fri, Jan 14, 2011 at 06:58:18AM +0200, Michael S. Tsirkin wrote:
> > > > On Fri, Jan 14, 2011 at 08:41:36AM +0900, Simon Horman wrote:
> > > > > On Thu, Jan 13, 2011 at 10:45:38AM -0500, Jesse Gross wrote:
> > > > > > On Thu, Jan 13, 2011 at 1:47 AM, Simon Horman <horms@verge.net.au> wrote:
> > > > > > > On Mon, Jan 10, 2011 at 06:31:55PM +0900, Simon Horman wrote:
> > > > > > >> On Fri, Jan 07, 2011 at 10:23:58AM +0900, Simon Horman wrote:
> > > > > > >> > On Thu, Jan 06, 2011 at 05:38:01PM -0500, Jesse Gross wrote:
> > > > > > >> >
> > > > > > >> > [ snip ]
> > > > > > >> > >
> > > > > > >> > > I know that everyone likes a nice netperf result but I agree with
> > > > > > >> > > Michael that this probably isn't the right question to be asking. I
> > > > > > >> > > don't think that socket buffers are a real solution to the flow
> > > > > > >> > > control problem: they happen to provide that functionality but it's
> > > > > > >> > > more of a side effect than anything. It's just that the amount of
> > > > > > >> > > memory consumed by packets in the queue(s) doesn't really have any
> > > > > > >> > > implicit meaning for flow control (think multiple physical adapters,
> > > > > > >> > > all with the same speed instead of a virtual device and a physical
> > > > > > >> > > device with wildly different speeds). The analog in the physical
> > > > > > >> > > world that you're looking for would be Ethernet flow control.
> > > > > > >> > > Obviously, if the question is limiting CPU or memory consumption then
> > > > > > >> > > that's a different story.
> > > > > > >> >
> > > > > > >> > Point taken. I will see if I can control CPU (and thus memory) consumption
> > > > > > >> > using cgroups and/or tc.
> > > > > > >>
> > > > > > >> I have found that I can successfully control the throughput using
> > > > > > >> the following techniques
> > > > > > >>
> > > > > > >> 1) Place a tc egress filter on dummy0
> > > > > > >>
> > > > > > >> 2) Use ovs-ofctl to add a flow that sends skbs to dummy0 and then eth1,
> > > > > > >> this is effectively the same as one of my hacks to the datapath
> > > > > > >> that I mentioned in an earlier mail. The result is that eth1
> > > > > > >> "paces" the connection.
> > > >
> > > > This is actually a bug. This means that one slow connection will affect
> > > > fast ones. I intend to change the default for qemu to sndbuf=0 : this
> > > > will fix it but break your "pacing". So pls do not count on this
> > > > behaviour.
> > >
> > > Do you have a patch I could test?
> >
> > You can (and users already can) just run qemu with sndbuf=0. But if you
> > like, below.
>
> Thanks
>
> > > > > > > Further to this, I wonder if there is any interest in providing
> > > > > > > a method to switch the action order - using ovs-ofctl is a hack imho -
> > > > > > > and/or switching the default action order for mirroring.
> > > > > >
> > > > > > I'm not sure that there is a way to do this that is correct in the
> > > > > > generic case. It's possible that the destination could be a VM while
> > > > > > packets are being mirrored to a physical device or we could be
> > > > > > multicasting or some other arbitrarily complex scenario. Just think
> > > > > > of what a physical switch would do if it has ports with two different
> > > > > > speeds.
> > > > >
> > > > > Yes, I have considered that case. And I agree that perhaps there
> > > > > is no sensible default. But perhaps we could make it configurable somehow?
> > > >
> > > > The fix is at the application level. Run netperf with -b and -w flags to
> > > > limit the speed to a sensible value.
> > >
> > > Perhaps I should have stated my goals more clearly.
> > > I'm interested in situations where I don't control the application.
> >
> > Well an application that streams UDP without any throttling
> > at the application level will break on a physical network, right?
> > So I am not sure why should one try to make it work on the virtual one.
> >
> > But let's assume that you do want to throttle the guest
> > for reasons such as QOS. The proper approach seems
> > to be to throttle the sender, not have a dummy throttled
> > receiver "pacing" it. Place the qemu process in the
> > correct net_cls cgroup, set the class id and apply a rate limit?
>
> I would like to be able to use a class to rate limit egress packets.
> That much works fine for me.
>
> What I would also like is for there to be back-pressure such that the guest
> doesn't consume lots of CPU, spinning, sending packets as fast as it can,
> almost of all of which are dropped. That does seem like a lot of wasted
> CPU to me.
>
> Unfortunately there are several problems with this and I am fast concluding
> that I will need to use a CPU cgroup. Which does make some sense, as what I
> am really trying to limit here is CPU usage not network packet rates - even
> if the test using the CPU is netperf. So long as the CPU usage can
> (mostly) be attributed to the guest using a cgroup should work fine. And
> indeed seems to in my limited testing.
>
> One scenario in which I don't think it is possible for there to be
> back-pressure in a meaningful sense is if root in the guest sets
> /proc/sys/net/core/wmem_default to a large value, say 2000000.
>
>
> I do think that to some extent there is back-pressure provided by sockbuf
> in the case where process on the host is sending directly to a physical
> interface. And to my mind it would be "nice" if the same kind of
> back-pressure was present in guests. But through our discussions of the
> past week or so I get the feeling that is not your view of things.
It might be nice. Unfortunately this is not what we have implemented:
the sockbuf backpressure blocks the socket, what we have blocks all
transmit from the guest. Another issue is that the strategy we have
seems to be broken if the target is a guest on another machine.
So it won't be all that simple to implement well, and before we try,
I'd like to know whether there are applications that are helped
by it. For example, we could try to measure latency at various
pps and see whether the backpressure helps. netperf has -b, -w
flags which might help these measurements.
> Perhaps I could characterise the guest situation by saying:
> Egress packet rates can be controlled using tc on the host;
> Guest CPU usage can be controlled using CPU cgroups on the host;
> Sockbuf controls memory usage on the host;
Not really, the memory usage on the host is controlled by the
various queue lengths in the host. E.g. if you send packets to
the physical device, they will get queued there.
> Back-pressure is irrelevant.
Or at least, broken :)
--
MST
^ permalink raw reply
* Re: [PATCH 3/3] vhost-net: use lock_sock_fast() in peek_head_len()
From: Michael S. Tsirkin @ 2011-01-17 9:57 UTC (permalink / raw)
To: Jason Wang; +Cc: virtualization, netdev, kvm, linux-kernel, eric.dumazet
In-Reply-To: <20110117081117.18900.48672.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
On Mon, Jan 17, 2011 at 04:11:17PM +0800, Jason Wang wrote:
> We can use lock_sock_fast() instead of lock_sock() in order to get
> speedup in peek_head_len().
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
Queued for 2.6.39, thanks everyone.
> ---
> drivers/vhost/net.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index c32a2e4..50b622a 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -211,12 +211,12 @@ static int peek_head_len(struct sock *sk)
> {
> struct sk_buff *head;
> int len = 0;
> + bool slow = lock_sock_fast(sk);
>
> - lock_sock(sk);
> head = skb_peek(&sk->sk_receive_queue);
> if (head)
> len = head->len;
> - release_sock(sk);
> + unlock_sock_fast(sk, slow);
> return len;
> }
>
^ permalink raw reply
* Re: [PATCH] virtio-net: fix a typo
From: Michael S. Tsirkin @ 2011-01-17 9:42 UTC (permalink / raw)
To: Aurelien Jarno; +Cc: netdev, linux-kernel, virtualization
In-Reply-To: <1295252059-27438-1-git-send-email-aurelien@aurel32.net>
On Mon, Jan 17, 2011 at 09:14:19AM +0100, Aurelien Jarno wrote:
> fitler -> filter
>
> Cc: netdev@vger.kernel.org
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
obviously.
Cc:
virtualization@lists.linux-foundation.org
rusty@rustcorp.com.au
as well.
BTW Rusty, ./scripts/get_maintainer.pl doesn't work
for most of virtio since there is no entry in MAINTAINERS for virtio
net/block/core. Adding it will help people know whom to contact
with issues/patches. It will also help if
I am Cc'd on patches as this way I won't forget to
review them.
--->
Add MAINTAINERS entry for virtio core, net, block
Patches should keep coming through Rusty but it
helps if I'm Cc'd as well.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
----
Comments?
diff --git a/MAINTAINERS b/MAINTAINERS
index 23d0436..7de75ad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6439,6 +6439,16 @@ S: Maintained
F: drivers/char/virtio_console.c
F: include/linux/virtio_console.h
+VIRTIO CORE, NET AND BLOCK DRIVERS
+M: Rusty Russell <rusty@rustcorp.com.au>
+M: "Michael S. Tsirkin" <mst@redhat.com>
+L: virtualization@lists.linux-foundation.org
+S: Maintained
+F: drivers/virtio/
+F: drivers/net/virtio_net.c
+F: drivers/block/virtio_blk.c
+F: include/linux/virtio_*.h
+
VIRTIO HOST (VHOST)
M: "Michael S. Tsirkin" <mst@redhat.com>
L: kvm@vger.kernel.org
^ permalink raw reply related
* Re: [PATCH 3/3] vhost-net: use lock_sock_fast() in peek_head_len()
From: Eric Dumazet @ 2011-01-17 9:33 UTC (permalink / raw)
To: Jason Wang; +Cc: virtualization, mst, linux-kernel, kvm, netdev
In-Reply-To: <20110117081117.18900.48672.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
Le lundi 17 janvier 2011 à 16:11 +0800, Jason Wang a écrit :
> We can use lock_sock_fast() instead of lock_sock() in order to get
> speedup in peek_head_len().
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/vhost/net.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index c32a2e4..50b622a 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -211,12 +211,12 @@ static int peek_head_len(struct sock *sk)
> {
> struct sk_buff *head;
> int len = 0;
> + bool slow = lock_sock_fast(sk);
>
> - lock_sock(sk);
> head = skb_peek(&sk->sk_receive_queue);
> if (head)
> len = head->len;
> - release_sock(sk);
> + unlock_sock_fast(sk, slow);
> return len;
> }
>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH 1/3] vhost-net: check the support of mergeable buffer outside the receive loop
From: Michael S. Tsirkin @ 2011-01-17 8:46 UTC (permalink / raw)
To: Jason Wang; +Cc: virtualization, netdev, kvm, linux-kernel
In-Reply-To: <20110117081058.18900.67456.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
On Mon, Jan 17, 2011 at 04:10:59PM +0800, Jason Wang wrote:
> No need to check the support of mergeable buffer inside the recevie
> loop as the whole handle_rx()_xx is in the read critical region. So
> this patch move it ahead of the receiving loop.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
Well feature check is mostly just features & bit
so why would it be slower? Because of the rcu
adding memory barriers? Do you observe a
measureable speedup with this patch?
Apropos, I noticed that the check in vhost_has_feature
is wrong: it uses the same kind of RCU as the
private pointer. So we'll have to fix that properly
by adding more lockdep classes, but for now
we'll need to make
the check 1 || lockdep_is_held(&dev->mutex);
and add a TODO.
> ---
> drivers/vhost/net.c | 5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 14fc189..95e49de 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -411,7 +411,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
> };
>
> size_t total_len = 0;
> - int err, headcount;
> + int err, headcount, mergeable;
> size_t vhost_hlen, sock_hlen;
> size_t vhost_len, sock_len;
> struct socket *sock = rcu_dereference(vq->private_data);
> @@ -425,6 +425,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
>
> vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
> vq->log : NULL;
> + mergeable = vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF);
>
> while ((sock_len = peek_head_len(sock->sk))) {
> sock_len += sock_hlen;
> @@ -474,7 +475,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
> break;
> }
> /* TODO: Should check and handle checksum. */
> - if (vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF) &&
> + if (likely(mergeable) &&
> memcpy_toiovecend(vq->hdr, (unsigned char *)&headcount,
> offsetof(typeof(hdr), num_buffers),
> sizeof hdr.num_buffers)) {
^ permalink raw reply
* Re: [PATCH 2/3] vhost-net: Unify the code of mergeable and big buffer handling
From: Michael S. Tsirkin @ 2011-01-17 8:36 UTC (permalink / raw)
To: Jason Wang; +Cc: virtualization, netdev, kvm, linux-kernel
In-Reply-To: <20110117081108.18900.60053.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
On Mon, Jan 17, 2011 at 04:11:08PM +0800, Jason Wang wrote:
> Codes duplication were found between the handling of mergeable and big
> buffers, so this patch tries to unify them. This could be easily done
> by adding a quota to the get_rx_bufs() which is used to limit the
> number of buffers it returns (for mergeable buffer, the quota is
> simply UIO_MAXIOV, for big buffers, the quota is just 1), and then the
> previous handle_rx_mergeable() could be resued also for big buffers.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
We actually started this way. However the code turned out
to have measureable overhead when handle_rx_mergeable
is called with quota 1.
So before applying this I'd like to see some data
to show this is not the case anymore.
> ---
> drivers/vhost/net.c | 128 +++------------------------------------------------
> 1 files changed, 7 insertions(+), 121 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 95e49de..c32a2e4 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -227,6 +227,7 @@ static int peek_head_len(struct sock *sk)
> * @iovcount - returned count of io vectors we fill
> * @log - vhost log
> * @log_num - log offset
> + * @quota - headcount quota, 1 for big buffer
> * returns number of buffer heads allocated, negative on error
> */
> static int get_rx_bufs(struct vhost_virtqueue *vq,
> @@ -234,7 +235,8 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
> int datalen,
> unsigned *iovcount,
> struct vhost_log *log,
> - unsigned *log_num)
> + unsigned *log_num,
> + unsigned int quota)
> {
> unsigned int out, in;
> int seg = 0;
> @@ -242,7 +244,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
> unsigned d;
> int r, nlogs = 0;
>
> - while (datalen > 0) {
> + while (datalen > 0 && headcount < quota) {
> if (unlikely(seg >= UIO_MAXIOV)) {
> r = -ENOBUFS;
> goto err;
> @@ -282,116 +284,7 @@ err:
>
> /* Expects to be always run from workqueue - which acts as
> * read-size critical section for our kind of RCU. */
> -static void handle_rx_big(struct vhost_net *net)
> -{
> - struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
> - unsigned out, in, log, s;
> - int head;
> - struct vhost_log *vq_log;
> - struct msghdr msg = {
> - .msg_name = NULL,
> - .msg_namelen = 0,
> - .msg_control = NULL, /* FIXME: get and handle RX aux data. */
> - .msg_controllen = 0,
> - .msg_iov = vq->iov,
> - .msg_flags = MSG_DONTWAIT,
> - };
> -
> - struct virtio_net_hdr hdr = {
> - .flags = 0,
> - .gso_type = VIRTIO_NET_HDR_GSO_NONE
> - };
> -
> - size_t len, total_len = 0;
> - int err;
> - size_t hdr_size;
> - struct socket *sock = rcu_dereference(vq->private_data);
> - if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
> - return;
> -
> - mutex_lock(&vq->mutex);
> - vhost_disable_notify(vq);
> - hdr_size = vq->vhost_hlen;
> -
> - vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
> - vq->log : NULL;
> -
> - for (;;) {
> - head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
> - ARRAY_SIZE(vq->iov),
> - &out, &in,
> - vq_log, &log);
> - /* On error, stop handling until the next kick. */
> - if (unlikely(head < 0))
> - break;
> - /* OK, now we need to know about added descriptors. */
> - if (head == vq->num) {
> - if (unlikely(vhost_enable_notify(vq))) {
> - /* They have slipped one in as we were
> - * doing that: check again. */
> - vhost_disable_notify(vq);
> - continue;
> - }
> - /* Nothing new? Wait for eventfd to tell us
> - * they refilled. */
> - break;
> - }
> - /* We don't need to be notified again. */
> - if (out) {
> - vq_err(vq, "Unexpected descriptor format for RX: "
> - "out %d, int %d\n",
> - out, in);
> - break;
> - }
> - /* Skip header. TODO: support TSO/mergeable rx buffers. */
> - s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, in);
> - msg.msg_iovlen = in;
> - len = iov_length(vq->iov, in);
> - /* Sanity check */
> - if (!len) {
> - vq_err(vq, "Unexpected header len for RX: "
> - "%zd expected %zd\n",
> - iov_length(vq->hdr, s), hdr_size);
> - break;
> - }
> - err = sock->ops->recvmsg(NULL, sock, &msg,
> - len, MSG_DONTWAIT | MSG_TRUNC);
> - /* TODO: Check specific error and bomb out unless EAGAIN? */
> - if (err < 0) {
> - vhost_discard_vq_desc(vq, 1);
> - break;
> - }
> - /* TODO: Should check and handle checksum. */
> - if (err > len) {
> - pr_debug("Discarded truncated rx packet: "
> - " len %d > %zd\n", err, len);
> - vhost_discard_vq_desc(vq, 1);
> - continue;
> - }
> - len = err;
> - err = memcpy_toiovec(vq->hdr, (unsigned char *)&hdr, hdr_size);
> - if (err) {
> - vq_err(vq, "Unable to write vnet_hdr at addr %p: %d\n",
> - vq->iov->iov_base, err);
> - break;
> - }
> - len += hdr_size;
> - vhost_add_used_and_signal(&net->dev, vq, head, len);
> - if (unlikely(vq_log))
> - vhost_log_write(vq, vq_log, log, len);
> - total_len += len;
> - if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
> - vhost_poll_queue(&vq->poll);
> - break;
> - }
> - }
> -
> - mutex_unlock(&vq->mutex);
> -}
> -
> -/* Expects to be always run from workqueue - which acts as
> - * read-size critical section for our kind of RCU. */
> -static void handle_rx_mergeable(struct vhost_net *net)
> +static void handle_rx(struct vhost_net *net)
> {
> struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
> unsigned uninitialized_var(in), log;
> @@ -431,7 +324,8 @@ static void handle_rx_mergeable(struct vhost_net *net)
> sock_len += sock_hlen;
> vhost_len = sock_len + vhost_hlen;
> headcount = get_rx_bufs(vq, vq->heads, vhost_len,
> - &in, vq_log, &log);
> + &in, vq_log, &log,
> + likely(mergeable) ? UIO_MAXIOV : 1);
> /* On error, stop handling until the next kick. */
> if (unlikely(headcount < 0))
> break;
> @@ -497,14 +391,6 @@ static void handle_rx_mergeable(struct vhost_net *net)
> mutex_unlock(&vq->mutex);
> }
>
> -static void handle_rx(struct vhost_net *net)
> -{
> - if (vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF))
> - handle_rx_mergeable(net);
> - else
> - handle_rx_big(net);
> -}
> -
> static void handle_tx_kick(struct vhost_work *work)
> {
> struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
^ permalink raw reply
* [PATCH 3/3] vhost-net: use lock_sock_fast() in peek_head_len()
From: Jason Wang @ 2011-01-17 8:11 UTC (permalink / raw)
To: virtualization, netdev, kvm, mst; +Cc: linux-kernel
In-Reply-To: <20110117081058.18900.67456.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
We can use lock_sock_fast() instead of lock_sock() in order to get
speedup in peek_head_len().
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/net.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index c32a2e4..50b622a 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -211,12 +211,12 @@ static int peek_head_len(struct sock *sk)
{
struct sk_buff *head;
int len = 0;
+ bool slow = lock_sock_fast(sk);
- lock_sock(sk);
head = skb_peek(&sk->sk_receive_queue);
if (head)
len = head->len;
- release_sock(sk);
+ unlock_sock_fast(sk, slow);
return len;
}
^ permalink raw reply related
* [PATCH 2/3] vhost-net: Unify the code of mergeable and big buffer handling
From: Jason Wang @ 2011-01-17 8:11 UTC (permalink / raw)
To: virtualization, netdev, kvm, mst; +Cc: linux-kernel
In-Reply-To: <20110117081058.18900.67456.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
Codes duplication were found between the handling of mergeable and big
buffers, so this patch tries to unify them. This could be easily done
by adding a quota to the get_rx_bufs() which is used to limit the
number of buffers it returns (for mergeable buffer, the quota is
simply UIO_MAXIOV, for big buffers, the quota is just 1), and then the
previous handle_rx_mergeable() could be resued also for big buffers.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/net.c | 128 +++------------------------------------------------
1 files changed, 7 insertions(+), 121 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 95e49de..c32a2e4 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -227,6 +227,7 @@ static int peek_head_len(struct sock *sk)
* @iovcount - returned count of io vectors we fill
* @log - vhost log
* @log_num - log offset
+ * @quota - headcount quota, 1 for big buffer
* returns number of buffer heads allocated, negative on error
*/
static int get_rx_bufs(struct vhost_virtqueue *vq,
@@ -234,7 +235,8 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
int datalen,
unsigned *iovcount,
struct vhost_log *log,
- unsigned *log_num)
+ unsigned *log_num,
+ unsigned int quota)
{
unsigned int out, in;
int seg = 0;
@@ -242,7 +244,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
unsigned d;
int r, nlogs = 0;
- while (datalen > 0) {
+ while (datalen > 0 && headcount < quota) {
if (unlikely(seg >= UIO_MAXIOV)) {
r = -ENOBUFS;
goto err;
@@ -282,116 +284,7 @@ err:
/* Expects to be always run from workqueue - which acts as
* read-size critical section for our kind of RCU. */
-static void handle_rx_big(struct vhost_net *net)
-{
- struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
- unsigned out, in, log, s;
- int head;
- struct vhost_log *vq_log;
- struct msghdr msg = {
- .msg_name = NULL,
- .msg_namelen = 0,
- .msg_control = NULL, /* FIXME: get and handle RX aux data. */
- .msg_controllen = 0,
- .msg_iov = vq->iov,
- .msg_flags = MSG_DONTWAIT,
- };
-
- struct virtio_net_hdr hdr = {
- .flags = 0,
- .gso_type = VIRTIO_NET_HDR_GSO_NONE
- };
-
- size_t len, total_len = 0;
- int err;
- size_t hdr_size;
- struct socket *sock = rcu_dereference(vq->private_data);
- if (!sock || skb_queue_empty(&sock->sk->sk_receive_queue))
- return;
-
- mutex_lock(&vq->mutex);
- vhost_disable_notify(vq);
- hdr_size = vq->vhost_hlen;
-
- vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
- vq->log : NULL;
-
- for (;;) {
- head = vhost_get_vq_desc(&net->dev, vq, vq->iov,
- ARRAY_SIZE(vq->iov),
- &out, &in,
- vq_log, &log);
- /* On error, stop handling until the next kick. */
- if (unlikely(head < 0))
- break;
- /* OK, now we need to know about added descriptors. */
- if (head == vq->num) {
- if (unlikely(vhost_enable_notify(vq))) {
- /* They have slipped one in as we were
- * doing that: check again. */
- vhost_disable_notify(vq);
- continue;
- }
- /* Nothing new? Wait for eventfd to tell us
- * they refilled. */
- break;
- }
- /* We don't need to be notified again. */
- if (out) {
- vq_err(vq, "Unexpected descriptor format for RX: "
- "out %d, int %d\n",
- out, in);
- break;
- }
- /* Skip header. TODO: support TSO/mergeable rx buffers. */
- s = move_iovec_hdr(vq->iov, vq->hdr, hdr_size, in);
- msg.msg_iovlen = in;
- len = iov_length(vq->iov, in);
- /* Sanity check */
- if (!len) {
- vq_err(vq, "Unexpected header len for RX: "
- "%zd expected %zd\n",
- iov_length(vq->hdr, s), hdr_size);
- break;
- }
- err = sock->ops->recvmsg(NULL, sock, &msg,
- len, MSG_DONTWAIT | MSG_TRUNC);
- /* TODO: Check specific error and bomb out unless EAGAIN? */
- if (err < 0) {
- vhost_discard_vq_desc(vq, 1);
- break;
- }
- /* TODO: Should check and handle checksum. */
- if (err > len) {
- pr_debug("Discarded truncated rx packet: "
- " len %d > %zd\n", err, len);
- vhost_discard_vq_desc(vq, 1);
- continue;
- }
- len = err;
- err = memcpy_toiovec(vq->hdr, (unsigned char *)&hdr, hdr_size);
- if (err) {
- vq_err(vq, "Unable to write vnet_hdr at addr %p: %d\n",
- vq->iov->iov_base, err);
- break;
- }
- len += hdr_size;
- vhost_add_used_and_signal(&net->dev, vq, head, len);
- if (unlikely(vq_log))
- vhost_log_write(vq, vq_log, log, len);
- total_len += len;
- if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
- vhost_poll_queue(&vq->poll);
- break;
- }
- }
-
- mutex_unlock(&vq->mutex);
-}
-
-/* Expects to be always run from workqueue - which acts as
- * read-size critical section for our kind of RCU. */
-static void handle_rx_mergeable(struct vhost_net *net)
+static void handle_rx(struct vhost_net *net)
{
struct vhost_virtqueue *vq = &net->dev.vqs[VHOST_NET_VQ_RX];
unsigned uninitialized_var(in), log;
@@ -431,7 +324,8 @@ static void handle_rx_mergeable(struct vhost_net *net)
sock_len += sock_hlen;
vhost_len = sock_len + vhost_hlen;
headcount = get_rx_bufs(vq, vq->heads, vhost_len,
- &in, vq_log, &log);
+ &in, vq_log, &log,
+ likely(mergeable) ? UIO_MAXIOV : 1);
/* On error, stop handling until the next kick. */
if (unlikely(headcount < 0))
break;
@@ -497,14 +391,6 @@ static void handle_rx_mergeable(struct vhost_net *net)
mutex_unlock(&vq->mutex);
}
-static void handle_rx(struct vhost_net *net)
-{
- if (vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF))
- handle_rx_mergeable(net);
- else
- handle_rx_big(net);
-}
-
static void handle_tx_kick(struct vhost_work *work)
{
struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
^ permalink raw reply related
* [PATCH 1/3] vhost-net: check the support of mergeable buffer outside the receive loop
From: Jason Wang @ 2011-01-17 8:10 UTC (permalink / raw)
To: virtualization, netdev, kvm, mst; +Cc: linux-kernel
No need to check the support of mergeable buffer inside the recevie
loop as the whole handle_rx()_xx is in the read critical region. So
this patch move it ahead of the receiving loop.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/net.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 14fc189..95e49de 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -411,7 +411,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
};
size_t total_len = 0;
- int err, headcount;
+ int err, headcount, mergeable;
size_t vhost_hlen, sock_hlen;
size_t vhost_len, sock_len;
struct socket *sock = rcu_dereference(vq->private_data);
@@ -425,6 +425,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
vq_log = unlikely(vhost_has_feature(&net->dev, VHOST_F_LOG_ALL)) ?
vq->log : NULL;
+ mergeable = vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF);
while ((sock_len = peek_head_len(sock->sk))) {
sock_len += sock_hlen;
@@ -474,7 +475,7 @@ static void handle_rx_mergeable(struct vhost_net *net)
break;
}
/* TODO: Should check and handle checksum. */
- if (vhost_has_feature(&net->dev, VIRTIO_NET_F_MRG_RXBUF) &&
+ if (likely(mergeable) &&
memcpy_toiovecend(vq->hdr, (unsigned char *)&headcount,
offsetof(typeof(hdr), num_buffers),
sizeof hdr.num_buffers)) {
^ permalink raw reply related
* Re: [PATCH] virtio: remove virtio-pci root device
From: Rusty Russell @ 2011-01-17 0:33 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Anthony Liguori, Jamie Lokier, Thomas Weber, linux-kernel,
Milton Miller, virtualization
In-Reply-To: <20110110171904.GA30058@redhat.com>
On Tue, 11 Jan 2011 03:49:04 am Michael S. Tsirkin wrote:
> On Mon, Jan 10, 2011 at 07:10:46PM +0200, Gleb Natapov wrote:
> > On Fri, Jan 07, 2011 at 02:55:06AM -0600, Milton Miller wrote:
> > > We sometimes need to map between the virtio device and
> > > the given pci device. One such use is OS installer that
> > > gets the boot pci device from BIOS and needs to
> > > find the relevant block device. Since it can't,
> > > installation fails.
> > >
> > > Instead of creating a top-level devices/virtio-pci
> > > directory, create each device under the corresponding
> > > pci device node. Symlinks to all virtio-pci
> > > devices can be found under the pci driver link in
> > > bus/pci/drivers/virtio-pci/devices, and all virtio
> > > devices under drivers/bus/virtio/devices.
> > >
> > > Signed-off-by: Milton Miller <miltonm@bga.com>
> > Acked-by: Gleb Natapov <gleb@redhat.com>
>
> Rusty, any comments?
> We are going to tell the installer guys that this
> is the interface, would be nice to know that the
> patch is queued before we do.
Yep, I've applied it. Sorry, took a week off to work on my linux.conf.au
talk...
Cheers,
Rusty.
^ permalink raw reply
* Re: Flow Control and Port Mirroring Revisited
From: Rusty Russell @ 2011-01-16 23:56 UTC (permalink / raw)
To: Simon Horman
Cc: Michael S. Tsirkin, Jesse Gross, Eric Dumazet, virtualization,
dev, virtualization, netdev, kvm
In-Reply-To: <20110116223728.GA6279@verge.net.au>
On Mon, 17 Jan 2011 09:07:30 am Simon Horman wrote:
[snip]
I've been away, but what concerns me is that socket buffer limits are
bypassed in various configurations, due to skb cloning. We should probably
drop such limits altogether, or fix them to be consistent.
Simple fix is as someone suggested here, to attach the clone. That might
seriously reduce your sk limit, though. I haven't thought about it hard,
but might it make sense to move ownership into skb_shared_info; ie. the
data, rather than the skb head?
Cheers,
Rusty.
^ permalink raw reply
* Re: Flow Control and Port Mirroring Revisited
From: Simon Horman @ 2011-01-16 22:37 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jesse Gross, Eric Dumazet, Rusty Russell, virtualization, dev,
virtualization, netdev, kvm
In-Reply-To: <20110114065415.GA30300@redhat.com>
On Fri, Jan 14, 2011 at 08:54:15AM +0200, Michael S. Tsirkin wrote:
> On Fri, Jan 14, 2011 at 03:35:28PM +0900, Simon Horman wrote:
> > On Fri, Jan 14, 2011 at 06:58:18AM +0200, Michael S. Tsirkin wrote:
> > > On Fri, Jan 14, 2011 at 08:41:36AM +0900, Simon Horman wrote:
> > > > On Thu, Jan 13, 2011 at 10:45:38AM -0500, Jesse Gross wrote:
> > > > > On Thu, Jan 13, 2011 at 1:47 AM, Simon Horman <horms@verge.net.au> wrote:
> > > > > > On Mon, Jan 10, 2011 at 06:31:55PM +0900, Simon Horman wrote:
> > > > > >> On Fri, Jan 07, 2011 at 10:23:58AM +0900, Simon Horman wrote:
> > > > > >> > On Thu, Jan 06, 2011 at 05:38:01PM -0500, Jesse Gross wrote:
> > > > > >> >
> > > > > >> > [ snip ]
> > > > > >> > >
> > > > > >> > > I know that everyone likes a nice netperf result but I agree with
> > > > > >> > > Michael that this probably isn't the right question to be asking. I
> > > > > >> > > don't think that socket buffers are a real solution to the flow
> > > > > >> > > control problem: they happen to provide that functionality but it's
> > > > > >> > > more of a side effect than anything. It's just that the amount of
> > > > > >> > > memory consumed by packets in the queue(s) doesn't really have any
> > > > > >> > > implicit meaning for flow control (think multiple physical adapters,
> > > > > >> > > all with the same speed instead of a virtual device and a physical
> > > > > >> > > device with wildly different speeds). The analog in the physical
> > > > > >> > > world that you're looking for would be Ethernet flow control.
> > > > > >> > > Obviously, if the question is limiting CPU or memory consumption then
> > > > > >> > > that's a different story.
> > > > > >> >
> > > > > >> > Point taken. I will see if I can control CPU (and thus memory) consumption
> > > > > >> > using cgroups and/or tc.
> > > > > >>
> > > > > >> I have found that I can successfully control the throughput using
> > > > > >> the following techniques
> > > > > >>
> > > > > >> 1) Place a tc egress filter on dummy0
> > > > > >>
> > > > > >> 2) Use ovs-ofctl to add a flow that sends skbs to dummy0 and then eth1,
> > > > > >> this is effectively the same as one of my hacks to the datapath
> > > > > >> that I mentioned in an earlier mail. The result is that eth1
> > > > > >> "paces" the connection.
> > >
> > > This is actually a bug. This means that one slow connection will affect
> > > fast ones. I intend to change the default for qemu to sndbuf=0 : this
> > > will fix it but break your "pacing". So pls do not count on this
> > > behaviour.
> >
> > Do you have a patch I could test?
>
> You can (and users already can) just run qemu with sndbuf=0. But if you
> like, below.
Thanks
> > > > > > Further to this, I wonder if there is any interest in providing
> > > > > > a method to switch the action order - using ovs-ofctl is a hack imho -
> > > > > > and/or switching the default action order for mirroring.
> > > > >
> > > > > I'm not sure that there is a way to do this that is correct in the
> > > > > generic case. It's possible that the destination could be a VM while
> > > > > packets are being mirrored to a physical device or we could be
> > > > > multicasting or some other arbitrarily complex scenario. Just think
> > > > > of what a physical switch would do if it has ports with two different
> > > > > speeds.
> > > >
> > > > Yes, I have considered that case. And I agree that perhaps there
> > > > is no sensible default. But perhaps we could make it configurable somehow?
> > >
> > > The fix is at the application level. Run netperf with -b and -w flags to
> > > limit the speed to a sensible value.
> >
> > Perhaps I should have stated my goals more clearly.
> > I'm interested in situations where I don't control the application.
>
> Well an application that streams UDP without any throttling
> at the application level will break on a physical network, right?
> So I am not sure why should one try to make it work on the virtual one.
>
> But let's assume that you do want to throttle the guest
> for reasons such as QOS. The proper approach seems
> to be to throttle the sender, not have a dummy throttled
> receiver "pacing" it. Place the qemu process in the
> correct net_cls cgroup, set the class id and apply a rate limit?
I would like to be able to use a class to rate limit egress packets.
That much works fine for me.
What I would also like is for there to be back-pressure such that the guest
doesn't consume lots of CPU, spinning, sending packets as fast as it can,
almost of all of which are dropped. That does seem like a lot of wasted
CPU to me.
Unfortunately there are several problems with this and I am fast concluding
that I will need to use a CPU cgroup. Which does make some sense, as what I
am really trying to limit here is CPU usage not network packet rates - even
if the test using the CPU is netperf. So long as the CPU usage can
(mostly) be attributed to the guest using a cgroup should work fine. And
indeed seems to in my limited testing.
One scenario in which I don't think it is possible for there to be
back-pressure in a meaningful sense is if root in the guest sets
/proc/sys/net/core/wmem_default to a large value, say 2000000.
I do think that to some extent there is back-pressure provided by sockbuf
in the case where process on the host is sending directly to a physical
interface. And to my mind it would be "nice" if the same kind of
back-pressure was present in guests. But through our discussions of the
past week or so I get the feeling that is not your view of things.
Perhaps I could characterise the guest situation by saying:
Egress packet rates can be controlled using tc on the host;
Guest CPU usage can be controlled using CPU cgroups on the host;
Sockbuf controls memory usage on the host;
Back-pressure is irrelevant.
^ permalink raw reply
* Re: [PULL] vhost-net: 2.6.38 fix
From: David Miller @ 2011-01-14 20:41 UTC (permalink / raw)
To: mst; +Cc: kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20110114093302.GA702@redhat.com>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Fri, 14 Jan 2011 11:33:02 +0200
> Please pull the following for 2.6.38.
> Thanks!
>
> The following changes since commit 0c21e3aaf6ae85bee804a325aa29c325209180fd:
>
> Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/hfsplus (2011-01-07 17:16:27 -0800)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net
>
> Michael S. Tsirkin (1):
> vhost: fix signed/unsigned comparison
Pulled, thanks.
^ permalink raw reply
* [PULL] vhost-net: 2.6.38 fix
From: Michael S. Tsirkin @ 2011-01-14 9:33 UTC (permalink / raw)
To: David Miller; +Cc: kvm, virtualization, netdev, linux-kernel
Please pull the following for 2.6.38.
Thanks!
The following changes since commit 0c21e3aaf6ae85bee804a325aa29c325209180fd:
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/hfsplus (2011-01-07 17:16:27 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net
Michael S. Tsirkin (1):
vhost: fix signed/unsigned comparison
drivers/vhost/vhost.c | 18 +++++++++++-------
1 files changed, 11 insertions(+), 7 deletions(-)
^ permalink raw reply
* Re: Flow Control and Port Mirroring Revisited
From: Michael S. Tsirkin @ 2011-01-14 6:54 UTC (permalink / raw)
To: Simon Horman
Cc: Jesse Gross, Eric Dumazet, Rusty Russell, virtualization, dev,
virtualization, netdev, kvm
In-Reply-To: <20110114063528.GB10957@verge.net.au>
On Fri, Jan 14, 2011 at 03:35:28PM +0900, Simon Horman wrote:
> On Fri, Jan 14, 2011 at 06:58:18AM +0200, Michael S. Tsirkin wrote:
> > On Fri, Jan 14, 2011 at 08:41:36AM +0900, Simon Horman wrote:
> > > On Thu, Jan 13, 2011 at 10:45:38AM -0500, Jesse Gross wrote:
> > > > On Thu, Jan 13, 2011 at 1:47 AM, Simon Horman <horms@verge.net.au> wrote:
> > > > > On Mon, Jan 10, 2011 at 06:31:55PM +0900, Simon Horman wrote:
> > > > >> On Fri, Jan 07, 2011 at 10:23:58AM +0900, Simon Horman wrote:
> > > > >> > On Thu, Jan 06, 2011 at 05:38:01PM -0500, Jesse Gross wrote:
> > > > >> >
> > > > >> > [ snip ]
> > > > >> > >
> > > > >> > > I know that everyone likes a nice netperf result but I agree with
> > > > >> > > Michael that this probably isn't the right question to be asking. I
> > > > >> > > don't think that socket buffers are a real solution to the flow
> > > > >> > > control problem: they happen to provide that functionality but it's
> > > > >> > > more of a side effect than anything. It's just that the amount of
> > > > >> > > memory consumed by packets in the queue(s) doesn't really have any
> > > > >> > > implicit meaning for flow control (think multiple physical adapters,
> > > > >> > > all with the same speed instead of a virtual device and a physical
> > > > >> > > device with wildly different speeds). The analog in the physical
> > > > >> > > world that you're looking for would be Ethernet flow control.
> > > > >> > > Obviously, if the question is limiting CPU or memory consumption then
> > > > >> > > that's a different story.
> > > > >> >
> > > > >> > Point taken. I will see if I can control CPU (and thus memory) consumption
> > > > >> > using cgroups and/or tc.
> > > > >>
> > > > >> I have found that I can successfully control the throughput using
> > > > >> the following techniques
> > > > >>
> > > > >> 1) Place a tc egress filter on dummy0
> > > > >>
> > > > >> 2) Use ovs-ofctl to add a flow that sends skbs to dummy0 and then eth1,
> > > > >> this is effectively the same as one of my hacks to the datapath
> > > > >> that I mentioned in an earlier mail. The result is that eth1
> > > > >> "paces" the connection.
> >
> > This is actually a bug. This means that one slow connection will affect
> > fast ones. I intend to change the default for qemu to sndbuf=0 : this
> > will fix it but break your "pacing". So pls do not count on this
> > behaviour.
>
> Do you have a patch I could test?
You can (and users already can) just run qemu with sndbuf=0. But if you
like, below.
> > > > > Further to this, I wonder if there is any interest in providing
> > > > > a method to switch the action order - using ovs-ofctl is a hack imho -
> > > > > and/or switching the default action order for mirroring.
> > > >
> > > > I'm not sure that there is a way to do this that is correct in the
> > > > generic case. It's possible that the destination could be a VM while
> > > > packets are being mirrored to a physical device or we could be
> > > > multicasting or some other arbitrarily complex scenario. Just think
> > > > of what a physical switch would do if it has ports with two different
> > > > speeds.
> > >
> > > Yes, I have considered that case. And I agree that perhaps there
> > > is no sensible default. But perhaps we could make it configurable somehow?
> >
> > The fix is at the application level. Run netperf with -b and -w flags to
> > limit the speed to a sensible value.
>
> Perhaps I should have stated my goals more clearly.
> I'm interested in situations where I don't control the application.
Well an application that streams UDP without any throttling
at the application level will break on a physical network, right?
So I am not sure why should one try to make it work on the virtual one.
But let's assume that you do want to throttle the guest
for reasons such as QOS. The proper approach seems
to be to throttle the sender, not have a dummy throttled
receiver "pacing" it. Place the qemu process in the
correct net_cls cgroup, set the class id and apply a rate limit?
---
diff --git a/net/tap-linux.c b/net/tap-linux.c
index f7aa904..0dbcdd4 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -87,7 +87,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
* Ethernet NICs generally have txqueuelen=1000, so 1Mb is
* a good default, given a 1500 byte MTU.
*/
-#define TAP_DEFAULT_SNDBUF 1024*1024
+#define TAP_DEFAULT_SNDBUF 0
int tap_set_sndbuf(int fd, QemuOpts *opts)
{
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox