All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv5] OMAP3: Devkit8000: Change lcd power pin
From: Thomas Weber @ 2011-02-01 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1295538108-26451-1-git-send-email-weber@corscience.de>

On Thu, Jan 20, 2011 at 4:41 PM, Thomas Weber <weber@corscience.de> wrote:
> This patch fixes a wrongly used lcd enable pin.
>
> The Devkit8000 uses twl4030_ledA configured as output gpio only for
> the lcd enable line. twl4030_gpio.1 is used through the generic
> gpio functions while ledA is used via low level twl4030 calls.
>
> This patch removes the low level calls and use the generic gpio functions
> for initialization and use of ledA. This patch also fixes a bug where the
> lcd would not power down when blanking.
>
> Further this patch fixes an indentation issue. The comment line uses
> eight whitespace and is replaced with a hard tab.
>
> gpio_request + gpio_direction_output are replaced with gpio_request_one.
> The return value of gpio_request_one is used to set the value of the
> gpio to -EINVAL when unsuccessful, so that gpio_is_valid can detect the
> unsuccessful request. But already successful requested gpios are not freed.
>
> Reported-by: Daniel Morsing <daniel.morsing@gmail.com>
> Signed-off-by: Thomas Weber <weber@corscience.de>
> ---
> Changes from v4:
> ? ? ? ?Merge of two patches
> ? ? ? ?Use of gpio_request_one instead of gpio_request + gpio_direction_output
> Changes from v3:
> ? ? ? ?Use return value of gpio_request
> Changes from v2:
> ? ? ? ?Fix indention => indentation
> ? ? ? ?Better comment for removing low level functions used for twl4030 gpio
> Changes from v1:
> ? ? ? ?Pull the indentation fix into this patch
> ? ? ? ?Change the pin for lcd pwren
>
> ?arch/arm/mach-omap2/board-devkit8000.c | ? 27 ++++++++++++++++-----------
> ?1 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
> index a5eb955..e4c12fe 100644
> --- a/arch/arm/mach-omap2/board-devkit8000.c
> +++ b/arch/arm/mach-omap2/board-devkit8000.c
> @@ -115,9 +115,6 @@ static struct omap2_hsmmc_info mmc[] = {
>
> ?static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
> ?{
> - ? ? ? twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1);
> - ? ? ? twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
> -
> ? ? ? ?if (gpio_is_valid(dssdev->reset_gpio))
> ? ? ? ? ? ? ? ?gpio_set_value_cansleep(dssdev->reset_gpio, 1);
> ? ? ? ?return 0;
> @@ -247,6 +244,8 @@ static struct gpio_led gpio_leds[];
> ?static int devkit8000_twl_gpio_setup(struct device *dev,
> ? ? ? ? ? ? ? ?unsigned gpio, unsigned ngpio)
> ?{
> + ? ? ? int ret;
> +
> ? ? ? ?omap_mux_init_gpio(29, OMAP_PIN_INPUT);
> ? ? ? ?/* gpio + 0 is "mmc0_cd" (input/IRQ) */
> ? ? ? ?mmc[0].gpio_cd = gpio + 0;
> @@ -255,17 +254,23 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
> ? ? ? ?/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
> ? ? ? ?gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
>
> - ? ? ? ?/* gpio + 1 is "LCD_PWREN" (out, active high) */
> - ? ? ? devkit8000_lcd_device.reset_gpio = gpio + 1;
> - ? ? ? gpio_request(devkit8000_lcd_device.reset_gpio, "LCD_PWREN");
> - ? ? ? /* Disable until needed */
> - ? ? ? gpio_direction_output(devkit8000_lcd_device.reset_gpio, 0);
> + ? ? ? /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
> + ? ? ? devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
> + ? ? ? ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
> + ? ? ? ? ? ? ? ? ? ? ? GPIOF_DIR_OUT | GPIOF_INIT_LOW, "LCD_PWREN");
> + ? ? ? if (ret < 0) {
> + ? ? ? ? ? ? ? devkit8000_lcd_device.reset_gpio = -EINVAL;
> + ? ? ? ? ? ? ? printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
> + ? ? ? }
>
> ? ? ? ?/* gpio + 7 is "DVI_PD" (out, active low) */
> ? ? ? ?devkit8000_dvi_device.reset_gpio = gpio + 7;
> - ? ? ? gpio_request(devkit8000_dvi_device.reset_gpio, "DVI PowerDown");
> - ? ? ? /* Disable until needed */
> - ? ? ? gpio_direction_output(devkit8000_dvi_device.reset_gpio, 0);
> + ? ? ? ret = gpio_request_one(devkit8000_dvi_device.reset_gpio,
> + ? ? ? ? ? ? ? ? ? ? ? GPIOF_DIR_OUT | GPIOF_INIT_LOW, "DVI PowerDown");
> + ? ? ? if (ret < 0) {
> + ? ? ? ? ? ? ? devkit8000_dvi_device.reset_gpio = -EINVAL;
> + ? ? ? ? ? ? ? printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n");
> + ? ? ? }
>
> ? ? ? ?return 0;
> ?}
> --
> 1.7.4.rc2
>
> --

Hello Tony,
can you apply this patch?

Thomas

^ permalink raw reply

* Re: [PATCHv5] OMAP3: Devkit8000: Change lcd power pin
From: Thomas Weber @ 2011-02-01 21:24 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-omap, Russell King, open list:ARM PORT, open list,
	Daniel Morsing, charu, sshtylyov, manjugk
In-Reply-To: <1295538108-26451-1-git-send-email-weber@corscience.de>

On Thu, Jan 20, 2011 at 4:41 PM, Thomas Weber <weber@corscience.de> wrote:
> This patch fixes a wrongly used lcd enable pin.
>
> The Devkit8000 uses twl4030_ledA configured as output gpio only for
> the lcd enable line. twl4030_gpio.1 is used through the generic
> gpio functions while ledA is used via low level twl4030 calls.
>
> This patch removes the low level calls and use the generic gpio functions
> for initialization and use of ledA. This patch also fixes a bug where the
> lcd would not power down when blanking.
>
> Further this patch fixes an indentation issue. The comment line uses
> eight whitespace and is replaced with a hard tab.
>
> gpio_request + gpio_direction_output are replaced with gpio_request_one.
> The return value of gpio_request_one is used to set the value of the
> gpio to -EINVAL when unsuccessful, so that gpio_is_valid can detect the
> unsuccessful request. But already successful requested gpios are not freed.
>
> Reported-by: Daniel Morsing <daniel.morsing@gmail.com>
> Signed-off-by: Thomas Weber <weber@corscience.de>
> ---
> Changes from v4:
>        Merge of two patches
>        Use of gpio_request_one instead of gpio_request + gpio_direction_output
> Changes from v3:
>        Use return value of gpio_request
> Changes from v2:
>        Fix indention => indentation
>        Better comment for removing low level functions used for twl4030 gpio
> Changes from v1:
>        Pull the indentation fix into this patch
>        Change the pin for lcd pwren
>
>  arch/arm/mach-omap2/board-devkit8000.c |   27 ++++++++++++++++-----------
>  1 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
> index a5eb955..e4c12fe 100644
> --- a/arch/arm/mach-omap2/board-devkit8000.c
> +++ b/arch/arm/mach-omap2/board-devkit8000.c
> @@ -115,9 +115,6 @@ static struct omap2_hsmmc_info mmc[] = {
>
>  static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
>  {
> -       twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1);
> -       twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
> -
>        if (gpio_is_valid(dssdev->reset_gpio))
>                gpio_set_value_cansleep(dssdev->reset_gpio, 1);
>        return 0;
> @@ -247,6 +244,8 @@ static struct gpio_led gpio_leds[];
>  static int devkit8000_twl_gpio_setup(struct device *dev,
>                unsigned gpio, unsigned ngpio)
>  {
> +       int ret;
> +
>        omap_mux_init_gpio(29, OMAP_PIN_INPUT);
>        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
>        mmc[0].gpio_cd = gpio + 0;
> @@ -255,17 +254,23 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
>        /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
>        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
>
> -        /* gpio + 1 is "LCD_PWREN" (out, active high) */
> -       devkit8000_lcd_device.reset_gpio = gpio + 1;
> -       gpio_request(devkit8000_lcd_device.reset_gpio, "LCD_PWREN");
> -       /* Disable until needed */
> -       gpio_direction_output(devkit8000_lcd_device.reset_gpio, 0);
> +       /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
> +       devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
> +       ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
> +                       GPIOF_DIR_OUT | GPIOF_INIT_LOW, "LCD_PWREN");
> +       if (ret < 0) {
> +               devkit8000_lcd_device.reset_gpio = -EINVAL;
> +               printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
> +       }
>
>        /* gpio + 7 is "DVI_PD" (out, active low) */
>        devkit8000_dvi_device.reset_gpio = gpio + 7;
> -       gpio_request(devkit8000_dvi_device.reset_gpio, "DVI PowerDown");
> -       /* Disable until needed */
> -       gpio_direction_output(devkit8000_dvi_device.reset_gpio, 0);
> +       ret = gpio_request_one(devkit8000_dvi_device.reset_gpio,
> +                       GPIOF_DIR_OUT | GPIOF_INIT_LOW, "DVI PowerDown");
> +       if (ret < 0) {
> +               devkit8000_dvi_device.reset_gpio = -EINVAL;
> +               printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n");
> +       }
>
>        return 0;
>  }
> --
> 1.7.4.rc2
>
> --

Hello Tony,
can you apply this patch?

Thomas

^ permalink raw reply

* [Qemu-devel] [PATCH v2 10/24] kvm: Handle kvm_init_vcpu errors
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Do not ignore errors of kvm_init_vcpu, they are fatal.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index 312c7a2..8475757 100644
--- a/cpus.c
+++ b/cpus.c
@@ -273,12 +273,18 @@ void qemu_main_loop_start(void)
 void qemu_init_vcpu(void *_env)
 {
     CPUState *env = _env;
+    int r;
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
-    return;
+
+    if (kvm_enabled()) {
+        r = kvm_init_vcpu(env);
+        if (r < 0) {
+            fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+            exit(1);
+        }
+    }
 }
 
 int qemu_cpu_self(void *env)
@@ -604,11 +610,16 @@ static int qemu_cpu_exec(CPUState *env);
 static void *kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
+    int r;
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
 
-    kvm_init_vcpu(env);
+    r = kvm_init_vcpu(env);
+    if (r < 0) {
+        fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
+        exit(1);
+    }
 
     kvm_init_ipi(env);
 
-- 
1.7.1

^ permalink raw reply related

* Re: Long time to start the ceph osd and mount
From: Gregory Farnum @ 2011-02-01 21:24 UTC (permalink / raw)
  To: DongJin Lee; +Cc: ceph-devel
In-Reply-To: <AANLkTikmrQWpYL6PhqB9w29jD=TKQQ1-U5sr0JNe=x=r@mail.gmail.com>

On Mon, Jan 31, 2011 at 9:01 PM, DongJin Lee <dongjin.lee@auckland.ac.nz> wrote:
> I'm using the unstable version dated 20th-Jan.
>
> When I was starting up multiple OSDs, e.g., 3 or more.
> iostat shows, after the start, the OSDs utilizes to 100% themselves
> (there's not much of traffic going on)
>
> If I tried to mount during this time, it fails; 'can't read superblock'
> So I have to wait until all of the OSDs become 0% utilized.
It looks like this is just because of how many PGs you have. With
almost 6200 PGs it's going to take a while for them all to go through
peering, and the initial peering process needs to complete before
you'll be able to do anything. If your OSDs have spare CPU/memory
during this time, you can let them peer more PGs simultaneously by
adjusting the osd_recovery* options. These are listed in the config.h
file and I believe you'll want to increase osd_recovery_threads and
osd_recovery_max_active.

> I made sure before restarting ceph (using 'stop.sh all'), the the OSDs
> are empty (deleted all files, remount clean), as well as cephlog
> directories, anymore to clean.
You mean you wanted a fresh ceph install? In that case you need to run
mkcephfs again (not just manually delete files), or your OSDs are
going to think that there's data they should have and lost. That would
also make startup take much longer.

> Also, Is there a way to increase some pagelimit or disk IO to max out
> the performance? any known issue?
> For example, just using 2 SSDs at 1x normal (no)replication, I can max
> out the link (using dd), including all the way to 6 (all maxed) , but
> when set at 2x, no increase I see, and slowly increases to max link
> speed by 6 SSDs.
> The SSDs are already fast enough to do all kinds of replication IO
> workloads, and so I don't understand given that there's virtually no
> CPU bottleneck I see.
> It seems that there's a clear bottleneck somewhere in the system, more
> like a system configuration issue.? I don't see MDS/MON use any
> significant amount of process or memory.
I'm not sure I quite understand your setup here. You mean that without
replication you can max out a client's network connection using any
number of OSDs, but with replication you need to get up to 6 OSDs
before you max out the client's network connection?

^ permalink raw reply

* Locking in the clk API, part 2: clk_prepare/clk_unprepare
From: Russell King - ARM Linux @ 2011-02-01 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D48741F.8060006@codeaurora.org>

On Tue, Feb 01, 2011 at 12:59:11PM -0800, Stephen Boyd wrote:
> On 02/01/2011 07:24 AM, Russell King - ARM Linux wrote:
> > I'd also be tempted at this stage to build-in a no-op dummy clock,
> > that being the NULL clk:
> >
> > int clk_prepare(struct clk *clk)
> > {
> > 	int ret = 0;
> >
> > 	if (clk) {
> > 		mutex_lock(&clk->mutex);
> > 		if (clk->prepared == 0)
> > 			ret = clk->ops->prepare(clk);
> > 		if (ret == 0)
> > 			clk->prepared++;
> > 		mutex_unlock(&clk->mutex);
> > 	}
> >
> > 	return ret;
> > }
> 
> I'm afraid this will hide enable/disable imbalances on some targets and
> then expose them on others. Maybe its not a big problem though since
> this also elegantly handles the root(s) of the tree.

You can't catch enable/disable imbalances in the prepare code, and you
can't really catch them in the unprepare code either.

Consider two drivers sharing the same struct clk.  When the second driver
prepares the clock, the enable count could well be non-zero, caused by
the first driver.  Ditto for when the second driver is removed, and it
calls unprepare - the enable count may well be non-zero.

The only thing you can check is that when the prepare count is zero,
the enable count is also zero.  You can also check in clk_enable() and
clk_disable() that the prepare count is non-zero.

If you want tigher checking than that, you need to somehow identify and
match up the clk_prepare/clk_enable/clk_disable/clk_unprepare calls from
a particular driver instance.  Addresses of the functions don't work as
you can't be certain that driver code will be co-located within a certain
range.  Adding an additional argument to these functions which is driver
instance specific seems to be horrible too.

^ permalink raw reply

* Re: Locking in the clk API, part 2: clk_prepare/clk_unprepare
From: Russell King - ARM Linux @ 2011-02-01 21:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D48741F.8060006@codeaurora.org>

On Tue, Feb 01, 2011 at 12:59:11PM -0800, Stephen Boyd wrote:
> On 02/01/2011 07:24 AM, Russell King - ARM Linux wrote:
> > I'd also be tempted at this stage to build-in a no-op dummy clock,
> > that being the NULL clk:
> >
> > int clk_prepare(struct clk *clk)
> > {
> > 	int ret = 0;
> >
> > 	if (clk) {
> > 		mutex_lock(&clk->mutex);
> > 		if (clk->prepared = 0)
> > 			ret = clk->ops->prepare(clk);
> > 		if (ret = 0)
> > 			clk->prepared++;
> > 		mutex_unlock(&clk->mutex);
> > 	}
> >
> > 	return ret;
> > }
> 
> I'm afraid this will hide enable/disable imbalances on some targets and
> then expose them on others. Maybe its not a big problem though since
> this also elegantly handles the root(s) of the tree.

You can't catch enable/disable imbalances in the prepare code, and you
can't really catch them in the unprepare code either.

Consider two drivers sharing the same struct clk.  When the second driver
prepares the clock, the enable count could well be non-zero, caused by
the first driver.  Ditto for when the second driver is removed, and it
calls unprepare - the enable count may well be non-zero.

The only thing you can check is that when the prepare count is zero,
the enable count is also zero.  You can also check in clk_enable() and
clk_disable() that the prepare count is non-zero.

If you want tigher checking than that, you need to somehow identify and
match up the clk_prepare/clk_enable/clk_disable/clk_unprepare calls from
a particular driver instance.  Addresses of the functions don't work as
you can't be certain that driver code will be co-located within a certain
range.  Adding an additional argument to these functions which is driver
instance specific seems to be horrible too.

^ permalink raw reply

* Re: khugepaged: gets stuck when writing to USB flash, 2.6.38-rc2
From: Jindřich Makovička @ 2011-02-01 21:24 UTC (permalink / raw)
  To: Andrea Arcangeli; +Cc: linux-kernel, Mel Gorman, Andrew Morton
In-Reply-To: <20110201154947.GX16981@random.random>

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

2011/2/1 Andrea Arcangeli <aarcange@redhat.com>:
>> When copying 4GB or more in one go from HDD to Flash, during the
>> copying, fork() and probably other syscalls involving VM start
>> blocking (I first observed the problem in Chrome, which refused to
>> display content in new tabs). When one lets the copying finish, the
>> system returns to a usable state.
>>
>> During the limbo, khugepaged is in D state (uninterruptible sleep).
>
> That means no hugepage could be allocated. Maybe memory compaction is
> doing an overwork because all pagecache is dirty and can't be
> migrated. This should solve it if it's memory compaction:
>
> echo never >/sys/kernel/mm/transparent_hugepage/defrag
>
> kswapd state would be interesting too. Can you sysrq+t?

With -rc2, there is

$ ps aux | grep -E "kswap|khugep"
root       474  0.0  0.0      0     0 ?        S    20:44   0:00 [kswapd0]
root       540  0.0  0.0      0     0 ?        DN   20:44   0:00 [khugepaged]

Sysrq-t output is attached.

Good news is, I don't see these issues with -rc3.

Regards,
-- 
Jindrich Makovicka

[-- Attachment #2: sysrq-t.txt.gz --]
[-- Type: application/x-gzip, Size: 14135 bytes --]

^ permalink raw reply

* [PATCH] ufs: Check if page has buffers before calling page_buffers()
From: Alessio Igor Bogani @ 2011-02-01 21:23 UTC (permalink / raw)
  To: Evgeniy Dushistov
  Cc: linux-fsdevel, linux-kernel, Tim Bird, Alessio Igor Bogani

In ufs_change_blocknr() we have called page_buffers() without checking if the
page actually had pages attached to it and this could cause a BUG oops.

This work was supported by a hardware donation from the CE Linux Forum.

Signed-off-by: Alessio Igor Bogani <abogani@kernel.org>
---
 fs/ufs/balloc.c |   62 +++++++++++++++++++++++++++---------------------------
 1 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 46f7a80..8155ccd 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -276,46 +276,46 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg,
 		} else
 			page = locked_page;
 
-		head = page_buffers(page);
-		bh = head;
-		pos = i & mask;
-		for (j = 0; j < pos; ++j)
-			bh = bh->b_this_page;
-
-
 		if (unlikely(index == last_index))
 			lblock = end & mask;
 		else
 			lblock = blks_per_page;
 
-		do {
-			if (j >= lblock)
-				break;
-			pos = (i - beg) + j;
+		if (page_has_buffers(page)) {
+			bh = head = page_buffers(page);
+			pos = i & mask;
+			for (j = 0; j < pos; ++j)
+				bh = bh->b_this_page;
 
-			if (!buffer_mapped(bh))
-					map_bh(bh, inode->i_sb, oldb + pos);
-			if (!buffer_uptodate(bh)) {
-				ll_rw_block(READ, 1, &bh);
-				wait_on_buffer(bh);
-				if (!buffer_uptodate(bh)) {
-					ufs_error(inode->i_sb, __func__,
-						  "read of block failed\n");
+			do {
+				if (j >= lblock)
 					break;
+				pos = (i - beg) + j;
+
+				if (!buffer_mapped(bh))
+						map_bh(bh, inode->i_sb, oldb + pos);
+				if (!buffer_uptodate(bh)) {
+					ll_rw_block(READ, 1, &bh);
+					wait_on_buffer(bh);
+					if (!buffer_uptodate(bh)) {
+						ufs_error(inode->i_sb, __func__,
+							  "read of block failed\n");
+						break;
+					}
 				}
-			}
 
-			UFSD(" change from %llu to %llu, pos %u\n",
-			     (unsigned long long)(pos + oldb),
-			     (unsigned long long)(pos + newb), pos);
-
-			bh->b_blocknr = newb + pos;
-			unmap_underlying_metadata(bh->b_bdev,
-						  bh->b_blocknr);
-			mark_buffer_dirty(bh);
-			++j;
-			bh = bh->b_this_page;
-		} while (bh != head);
+				UFSD(" change from %llu to %llu, pos %u\n",
+				     (unsigned long long)(pos + oldb),
+					 (unsigned long long)(pos + newb), pos);
+
+				bh->b_blocknr = newb + pos;
+				unmap_underlying_metadata(bh->b_bdev,
+							  bh->b_blocknr);
+				mark_buffer_dirty(bh);
+				++j;
+				bh = bh->b_this_page;
+			} while (bh != head);
+		}
 
 		if (likely(cur_index != index))
 			ufs_put_locked_page(page);
-- 
1.7.0.4


^ permalink raw reply related

* [Qemu-devel] [PATCH v2 06/24] Leave inner main_loop faster on pending requests
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

If there is any pending request that requires us to leave the inner loop
if main_loop, makes sure we do this as soon as possible by enforcing
non-blocking IO processing.

At this change, move variable definitions out of the inner loop to
improve readability.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/vl.c b/vl.c
index 5fad700..2ebc55b 100644
--- a/vl.c
+++ b/vl.c
@@ -1384,18 +1384,21 @@ qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
 {
+    bool nonblocking = false;
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
     int r;
 
     qemu_main_loop_start();
 
     for (;;) {
         do {
-            bool nonblocking = false;
-#ifdef CONFIG_PROFILER
-            int64_t ti;
-#endif
 #ifndef CONFIG_IOTHREAD
             nonblocking = cpu_exec_all();
+            if (!vm_can_run()) {
+                nonblocking = true;
+            }
 #endif
 #ifdef CONFIG_PROFILER
             ti = profile_getclock();
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 02/24] Prevent abortion on multiple VCPU kicks
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

If we call qemu_cpu_kick more than once before the target was able to
process the signal, pthread_kill will fail, and qemu will abort. Prevent
this by avoiding the redundant signal.

This logic can be found in qemu-kvm as well.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpu-defs.h |    1 +
 cpus.c     |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 8d4bf86..db809ed 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -205,6 +205,7 @@ typedef struct CPUWatchpoint {
     uint32_t stopped; /* Artificially stopped */                        \
     struct QemuThread *thread;                                          \
     struct QemuCond *halt_cond;                                         \
+    int thread_kicked;                                                  \
     struct qemu_work_item *queued_work_first, *queued_work_last;        \
     const char *cpu_model_str;                                          \
     struct KVMState *kvm_state;                                         \
diff --git a/cpus.c b/cpus.c
index 4c9928e..ab6e40e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -481,6 +481,7 @@ static void qemu_wait_io_event_common(CPUState *env)
         qemu_cond_signal(&qemu_pause_cond);
     }
     flush_queued_work(env);
+    env->thread_kicked = false;
 }
 
 static void qemu_tcg_wait_io_event(void)
@@ -648,7 +649,10 @@ void qemu_cpu_kick(void *_env)
 {
     CPUState *env = _env;
     qemu_cond_broadcast(env->halt_cond);
-    qemu_thread_signal(env->thread, SIG_IPI);
+    if (!env->thread_kicked) {
+        qemu_thread_signal(env->thread, SIG_IPI);
+        env->thread_kicked = true;
+    }
 }
 
 int qemu_cpu_self(void *_env)
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 05/24] Trigger exit from cpu_exec_all on pending IO events
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Except for timer events, we currently do not leave the loop over all
VCPUs if an IO event was filed. That may cause unexpected IO latencies
under !CONFIG_IOTHREAD in SMP scenarios. Fix it by setting the global
exit_request which breaks the loop.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index ceb3a83..5dfc54e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -315,6 +315,7 @@ void qemu_notify_event(void)
     if (next_cpu && env != next_cpu) {
         cpu_exit(next_cpu);
     }
+    exit_request = 1;
 }
 
 void qemu_mutex_lock_iothread(void) {}
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 19/24] Introduce VCPU self-signaling service
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU
context. First user will be kvm.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c        |   21 +++++++++++++++++++++
 qemu-common.h |    1 +
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index c4c5914..9c50a34 100644
--- a/cpus.c
+++ b/cpus.c
@@ -537,6 +537,17 @@ void qemu_cpu_kick(void *env)
     return;
 }
 
+void qemu_cpu_kick_self(void)
+{
+#ifndef _WIN32
+    assert(cpu_single_env);
+
+    raise(SIG_IPI);
+#else
+    abort();
+#endif
+}
+
 void qemu_notify_event(void)
 {
     CPUState *env = cpu_single_env;
@@ -835,6 +846,16 @@ void qemu_cpu_kick(void *_env)
     }
 }
 
+void qemu_cpu_kick_self(void)
+{
+    assert(cpu_single_env);
+
+    if (!cpu_single_env->thread_kicked) {
+        qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
+        cpu_single_env->thread_kicked = true;
+    }
+}
+
 int qemu_cpu_self(void *_env)
 {
     CPUState *env = _env;
diff --git a/qemu-common.h b/qemu-common.h
index 63d9943..220c8c8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -287,6 +287,7 @@ void qemu_notify_event(void);
 
 /* Unblock cpu */
 void qemu_cpu_kick(void *env);
+void qemu_cpu_kick_self(void);
 int qemu_cpu_self(void *env);
 
 /* work queue */
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 08/24] kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 9976762..1a55a10 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -219,6 +219,7 @@ int kvm_init_vcpu(CPUState *env)
 
     mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
     if (mmap_size < 0) {
+        ret = mmap_size;
         DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
         goto err;
     }
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 20/24] kvm: Unconditionally reenter kernel after IO exits
From: Jan Kiszka @ 2011-02-01 21:16 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: Gleb Natapov, qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

KVM requires to reenter the kernel after IO exits in order to complete
instruction emulation. Failing to do so will leave the kernel state
inconsistently behind. To ensure that we will get back ASAP, we issue a
self-signal that will cause KVM_RUN to return once the pending
operations are completed.

We can move kvm_arch_process_irqchip_events out of the inner VCPU loop.
The only state that mattered at its old place was a pending INIT
request. Catch it in kvm_arch_pre_run and also trigger a self-signal to
process the request on next kvm_cpu_exec.

This patch also fixes the missing exit_request check in kvm_cpu_exec in
the CONFIG_IOTHREAD case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Gleb Natapov <gleb@redhat.com>
---
 kvm-all.c         |   31 +++++++++++++++++--------------
 target-i386/kvm.c |    5 +++++
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 5bfa8c0..d961697 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void)
     return kvm_state->pit_in_kernel;
 }
 
-
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
@@ -892,29 +891,33 @@ int kvm_cpu_exec(CPUState *env)
 
     DPRINTF("kvm_cpu_exec()\n");
 
-    do {
-#ifndef CONFIG_IOTHREAD
-        if (env->exit_request) {
-            DPRINTF("interrupt exit requested\n");
-            ret = 0;
-            break;
-        }
-#endif
-
-        if (kvm_arch_process_irqchip_events(env)) {
-            ret = 0;
-            break;
-        }
+    if (kvm_arch_process_irqchip_events(env)) {
+        env->exit_request = 0;
+        env->exception_index = EXCP_HLT;
+        return 0;
+    }
 
+    do {
         if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
             env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
+        if (env->exit_request) {
+            DPRINTF("interrupt exit requested\n");
+            /*
+             * KVM requires us to reenter the kernel after IO exits to complete
+             * instruction emulation. This self-signal will ensure that we
+             * leave ASAP again.
+             */
+            qemu_cpu_kick_self();
+        }
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
+
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
+
         qemu_mutex_lock_iothread();
         cpu_single_env = env;
         kvm_arch_post_run(env, run);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9df8ff8..8a87244 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1426,6 +1426,11 @@ int kvm_arch_get_registers(CPUState *env)
 
 int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
 {
+    /* Force the VCPU out of its inner loop to process the INIT request */
+    if (env->interrupt_request & CPU_INTERRUPT_INIT) {
+        env->exit_request = 1;
+    }
+
     /* Inject NMI */
     if (env->interrupt_request & CPU_INTERRUPT_NMI) {
         env->interrupt_request &= ~CPU_INTERRUPT_NMI;
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 16/24] Set up signalfd under !CONFIG_IOTHREAD
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Will be required for SIGBUS handling. For obvious reasons, this will
remain a nop on Windows hosts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile.objs |    2 +-
 cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
 2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..81b9a5b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
-common-obj-$(CONFIG_IOTHREAD) += compatfd.o
+common-obj-$(CONFIG_POSIX) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 
diff --git a/cpus.c b/cpus.c
index 861e270..359361f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -235,6 +235,59 @@ static void dummy_signal(int sig)
 {
 }
 
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
+
 static void sigbus_reraise(void);
 
 static void qemu_kvm_eat_signals(CPUState *env)
@@ -338,6 +391,17 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 
 int qemu_init_main_loop(void)
 {
+#ifndef _WIN32
+    sigset_t blocked_signals;
+    int ret;
+
+    sigemptyset(&blocked_signals);
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret) {
+        return ret;
+    }
+#endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
     return qemu_event_init();
@@ -430,41 +494,6 @@ static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-/* If we have signalfd, we mask out the signals we want to handle and then
- * use signalfd to listen for them.  We rely on whatever the current signal
- * handler is to dispatch the signals when we receive them.
- */
-static void sigfd_handler(void *opaque)
-{
-    int fd = (unsigned long) opaque;
-    struct qemu_signalfd_siginfo info;
-    struct sigaction action;
-    ssize_t len;
-
-    while (1) {
-        do {
-            len = read(fd, &info, sizeof(info));
-        } while (len == -1 && errno == EINTR);
-
-        if (len == -1 && errno == EAGAIN) {
-            break;
-        }
-
-        if (len != sizeof(info)) {
-            printf("read from sigfd returned %zd: %m\n", len);
-            return;
-        }
-
-        sigaction(info.ssi_signo, NULL, &action);
-        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
-            action.sa_sigaction(info.ssi_signo,
-                                (siginfo_t *)&info, NULL);
-        } else if (action.sa_handler) {
-            action.sa_handler(info.ssi_signo);
-        }
-    }
-}
-
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -536,24 +565,6 @@ static sigset_t block_io_signals(void)
     return set;
 }
 
-static int qemu_signalfd_init(sigset_t mask)
-{
-    int sigfd;
-
-    sigfd = qemu_signalfd(&mask);
-    if (sigfd == -1) {
-        fprintf(stderr, "failed to create signalfd\n");
-        return -errno;
-    }
-
-    fcntl_setfl(sigfd, O_NONBLOCK);
-
-    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
-                         (void *)(unsigned long) sigfd);
-
-    return 0;
-}
-
 int qemu_init_main_loop(void)
 {
     int ret;
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 14/24] kvm: Refactor qemu_kvm_eat_signals
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

We do not use the timeout, so drop its logic. As we always poll our
signals, we do not need to drop the global lock. Removing those calls
allows some further simplifications. Also fix the error processing of
sigpending at this chance.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c |   23 +++++++----------------
 1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/cpus.c b/cpus.c
index a33e470..04138ba 100644
--- a/cpus.c
+++ b/cpus.c
@@ -648,31 +648,22 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
     }
 }
 
-static void qemu_kvm_eat_signal(CPUState *env, int timeout)
+static void qemu_kvm_eat_signals(CPUState *env)
 {
-    struct timespec ts;
-    int r, e;
+    struct timespec ts = { 0, 0 };
     siginfo_t siginfo;
     sigset_t waitset;
     sigset_t chkset;
-
-    ts.tv_sec = timeout / 1000;
-    ts.tv_nsec = (timeout % 1000) * 1000000;
+    int r;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
     sigaddset(&waitset, SIGBUS);
 
     do {
-        qemu_mutex_unlock(&qemu_global_mutex);
-
         r = sigtimedwait(&waitset, &siginfo, &ts);
-        e = errno;
-
-        qemu_mutex_lock(&qemu_global_mutex);
-
-        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+        if (r == -1 && !(errno == EAGAIN || errno == EINTR)) {
+            perror("sigtimedwait");
             exit(1);
         }
 
@@ -688,7 +679,7 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 
         r = sigpending(&chkset);
         if (r == -1) {
-            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            perror("sigpending");
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
@@ -699,7 +690,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
     while (!cpu_has_work(env))
         qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
 
-    qemu_kvm_eat_signal(env, 0);
+    qemu_kvm_eat_signals(env);
     qemu_wait_io_event_common(env);
 }
 
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 13/24] kvm: Set up signal mask also for !CONFIG_IOTHREAD
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode.
It's unused so far, but this infrastructure will be required for
self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As
Windows doesn't support signal services, we need to provide a stub for
the init function.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   29 +++++++++++++++++++++++++++--
 1 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 42717ba..a33e470 100644
--- a/cpus.c
+++ b/cpus.c
@@ -231,11 +231,9 @@ fail:
     return err;
 }
 
-#ifdef CONFIG_IOTHREAD
 static void dummy_signal(int sig)
 {
 }
-#endif
 
 #else /* _WIN32 */
 
@@ -267,6 +265,32 @@ static void qemu_event_increment(void)
 #endif /* _WIN32 */
 
 #ifndef CONFIG_IOTHREAD
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+#ifndef _WIN32
+    int r;
+    sigset_t set;
+    struct sigaction sigact;
+
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = dummy_signal;
+    sigaction(SIG_IPI, &sigact, NULL);
+
+    sigemptyset(&set);
+    sigaddset(&set, SIG_IPI);
+    pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+    pthread_sigmask(SIG_BLOCK, NULL, &set);
+    sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
+    r = kvm_set_signal_mask(env, &set);
+    if (r) {
+        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
+        exit(1);
+    }
+#endif
+}
+
 int qemu_init_main_loop(void)
 {
     cpu_set_debug_excp_handler(cpu_debug_handler);
@@ -292,6 +316,7 @@ void qemu_init_vcpu(void *_env)
             fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
             exit(1);
         }
+        qemu_kvm_init_cpu_signals(env);
     }
 }
 
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 07/24] Flatten the main loop
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

First of all, vm_can_run is a misnomer, it actually means "no request
pending". Moreover, there is no need to check all pending requests
twice, the first time via the inner loop check and then again when
actually processing the requests. We can simply remove the inner loop
and do the checks directly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   30 +++++++++++++++---------------
 1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/vl.c b/vl.c
index 2ebc55b..f5dec09 100644
--- a/vl.c
+++ b/vl.c
@@ -1371,14 +1371,16 @@ void main_loop_wait(int nonblocking)
 
 }
 
-static int vm_can_run(void)
+#ifndef CONFIG_IOTHREAD
+static int vm_request_pending(void)
 {
-    return !(powerdown_requested ||
-             reset_requested ||
-             shutdown_requested ||
-             debug_requested ||
-             vmstop_requested);
+    return powerdown_requested ||
+           reset_requested ||
+           shutdown_requested ||
+           debug_requested ||
+           vmstop_requested;
 }
+#endif
 
 qemu_irq qemu_system_powerdown;
 
@@ -1393,21 +1395,19 @@ static void main_loop(void)
     qemu_main_loop_start();
 
     for (;;) {
-        do {
 #ifndef CONFIG_IOTHREAD
-            nonblocking = cpu_exec_all();
-            if (!vm_can_run()) {
-                nonblocking = true;
-            }
+        nonblocking = cpu_exec_all();
+        if (vm_request_pending()) {
+            nonblocking = true;
+        }
 #endif
 #ifdef CONFIG_PROFILER
-            ti = profile_getclock();
+        ti = profile_getclock();
 #endif
-            main_loop_wait(nonblocking);
+        main_loop_wait(nonblocking);
 #ifdef CONFIG_PROFILER
-            dev_time += profile_getclock() - ti;
+        dev_time += profile_getclock() - ti;
 #endif
-        } while (vm_can_run());
 
         if ((r = qemu_debug_requested())) {
             vm_stop(r);
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 22/24] kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
From: Jan Kiszka @ 2011-02-01 21:16 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

The reset we issue on KVM_EXIT_SHUTDOWN implies that we should also
leave the VCPU loop. As we now check for exit_request which is set by
qemu_system_reset_request, this bug is no longer critical. Still it's an
unneeded extra turn.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index cf54256..35860df 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -959,7 +959,6 @@ int kvm_cpu_exec(CPUState *env)
         case KVM_EXIT_SHUTDOWN:
             DPRINTF("shutdown\n");
             qemu_system_reset_request();
-            ret = 1;
             break;
         case KVM_EXIT_UNKNOWN:
             fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 21/24] kvm: Remove static return code of kvm_handle_io
From: Jan Kiszka @ 2011-02-01 21:16 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Improve the readability of the exit dispatcher by moving the static
return value of kvm_handle_io to its caller.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index d961697..cf54256 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -770,8 +770,8 @@ err:
     return ret;
 }
 
-static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
-                         uint32_t count)
+static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
+                          uint32_t count)
 {
     int i;
     uint8_t *ptr = data;
@@ -805,8 +805,6 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
 
         ptr += size;
     }
-
-    return 1;
 }
 
 #ifdef KVM_CAP_INTERNAL_ERROR_DATA
@@ -940,11 +938,12 @@ int kvm_cpu_exec(CPUState *env)
         switch (run->exit_reason) {
         case KVM_EXIT_IO:
             DPRINTF("handle_io\n");
-            ret = kvm_handle_io(run->io.port,
-                                (uint8_t *)run + run->io.data_offset,
-                                run->io.direction,
-                                run->io.size,
-                                run->io.count);
+            kvm_handle_io(run->io.port,
+                          (uint8_t *)run + run->io.data_offset,
+                          run->io.direction,
+                          run->io.size,
+                          run->io.count);
+            ret = 1;
             break;
         case KVM_EXIT_MMIO:
             DPRINTF("handle_mmio\n");
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 01/24] kvm: x86: Fix build in absence of KVM_CAP_ASYNC_PF
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Reported by Stefan Hajnoczi.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 target-i386/kvm.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8e8880a..05010bb 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -167,7 +167,9 @@ static int get_para_features(CPUState *env)
             features |= (1 << para_features[i].feature);
         }
     }
+#ifdef KVM_CAP_ASYNC_PF
     has_msr_async_pf_en = features & (1 << KVM_FEATURE_ASYNC_PF);
+#endif
     return features;
 }
 #endif
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 18/24] kvm: Add MCE signal support for !CONFIG_IOTHREAD
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Hidetoshi Seto, Jin Dongming, qemu-devel, kvm, Huang Ying
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Currently, we only configure and process MCE-related SIGBUS events if
CONFIG_IOTHREAD is enabled. The groundwork is laid, we just need to
factor out the required handler registration and system configuration.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Huang Ying <ying.huang@intel.com>
CC: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
CC: Jin Dongming <jin.dongming@np.css.fujitsu.com>
---
 cpus.c |  107 +++++++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 65 insertions(+), 42 deletions(-)

diff --git a/cpus.c b/cpus.c
index 18caf47..c4c5914 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,9 +34,6 @@
 
 #include "cpus.h"
 #include "compatfd.h"
-#ifdef CONFIG_LINUX
-#include <sys/prctl.h>
-#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -44,10 +41,24 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifdef CONFIG_LINUX
+
+#include <sys/prctl.h>
+
 #ifndef PR_MCE_KILL
 #define PR_MCE_KILL 33
 #endif
 
+#ifndef PR_MCE_KILL_SET
+#define PR_MCE_KILL_SET 1
+#endif
+
+#ifndef PR_MCE_KILL_EARLY
+#define PR_MCE_KILL_EARLY 1
+#endif
+
+#endif /* CONFIG_LINUX */
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -166,6 +177,52 @@ static void cpu_debug_handler(CPUState *env)
     vm_stop(EXCP_DEBUG);
 }
 
+#ifdef CONFIG_LINUX
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+    if (kvm_on_sigbus(siginfo->ssi_code,
+                      (void *)(intptr_t)siginfo->ssi_addr)) {
+        sigbus_reraise();
+    }
+}
+
+static void qemu_init_sigbus(void)
+{
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+
+    prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
+}
+
+#else /* !CONFIG_LINUX */
+
+static void qemu_init_sigbus(void)
+{
+}
+#endif /* !CONFIG_LINUX */
+
 #ifndef _WIN32
 static int io_thread_fd = -1;
 
@@ -288,8 +345,6 @@ static int qemu_signalfd_init(sigset_t mask)
     return 0;
 }
 
-static void sigbus_reraise(void);
-
 static void qemu_kvm_eat_signals(CPUState *env)
 {
     struct timespec ts = { 0, 0 };
@@ -310,13 +365,11 @@ static void qemu_kvm_eat_signals(CPUState *env)
         }
 
         switch (r) {
-#ifdef CONFIG_IOTHREAD
         case SIGBUS:
             if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) {
                 sigbus_reraise();
             }
             break;
-#endif
         default:
             break;
         }
@@ -405,6 +458,7 @@ static sigset_t block_synchronous_signals(void)
     sigset_t set;
 
     sigemptyset(&set);
+    sigaddset(&set, SIGBUS);
     if (kvm_enabled()) {
         /*
          * We need to process timer signals synchronously to avoid a race
@@ -433,6 +487,8 @@ int qemu_init_main_loop(void)
 #endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     return qemu_event_init();
 }
 
@@ -565,13 +621,9 @@ static void qemu_tcg_init_cpu_signals(void)
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 }
 
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx);
-
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
-    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -585,12 +637,6 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
-    memset(&action, 0, sizeof(action));
-    action.sa_flags = SA_SIGINFO;
-    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
-    sigaction(SIGBUS, &action, NULL);
-    prctl(PR_MCE_KILL, 1, 1, 0, 0);
-
     return set;
 }
 
@@ -601,6 +647,8 @@ int qemu_init_main_loop(void)
 
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    qemu_init_sigbus();
+
     blocked_signals = block_io_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
@@ -708,31 +756,6 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
-static void sigbus_reraise(void)
-{
-    sigset_t set;
-    struct sigaction action;
-
-    memset(&action, 0, sizeof(action));
-    action.sa_handler = SIG_DFL;
-    if (!sigaction(SIGBUS, &action, NULL)) {
-        raise(SIGBUS);
-        sigemptyset(&set);
-        sigaddset(&set, SIGBUS);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
-    }
-    perror("Failed to re-raise SIGBUS!\n");
-    abort();
-}
-
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-                           void *ctx)
-{
-    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) {
-        sigbus_reraise();
-    }
-}
-
 static void qemu_kvm_wait_io_event(CPUState *env)
 {
     while (!cpu_has_work(env))
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 17/24] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm, Stefan Hajnoczi
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between
checking for exit_request on vcpu entry and timer signals arriving
before KVM starts to catch them. Plug it by blocking both timer related
signals also on !CONFIG_IOTHREAD and process those via signalfd.

As this fix depends on real signalfd support (otherwise the timer
signals only kick the compat helper thread, and the main thread hangs),
we need to detect the invalid constellation and abort configure.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
CC: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 configure |    6 ++++++
 cpus.c    |   31 ++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 4673bf0..368ca8a 100755
--- a/configure
+++ b/configure
@@ -2056,6 +2056,12 @@ EOF
 
 if compile_prog "" "" ; then
   signalfd=yes
+elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
+  echo
+  echo "ERROR: Host kernel lacks signalfd() support,"
+  echo "but KVM depends on it when the IO thread is disabled."
+  echo
+  exit 1
 fi
 
 # check if eventfd is supported
diff --git a/cpus.c b/cpus.c
index 359361f..18caf47 100644
--- a/cpus.c
+++ b/cpus.c
@@ -327,6 +327,12 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
+
+#ifndef CONFIG_IOTHREAD
+    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
+        qemu_notify_event();
+    }
+#endif
 }
 
 #else /* _WIN32 */
@@ -376,11 +382,15 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
+    sigdelset(&set, SIGIO);
+    sigdelset(&set, SIGALRM);
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
@@ -389,13 +399,32 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 #endif
 }
 
+#ifndef _WIN32
+static sigset_t block_synchronous_signals(void)
+{
+    sigset_t set;
+
+    sigemptyset(&set);
+    if (kvm_enabled()) {
+        /*
+         * We need to process timer signals synchronously to avoid a race
+         * between exit_request check and KVM vcpu entry.
+         */
+        sigaddset(&set, SIGIO);
+        sigaddset(&set, SIGALRM);
+    }
+
+    return set;
+}
+#endif
+
 int qemu_init_main_loop(void)
 {
 #ifndef _WIN32
     sigset_t blocked_signals;
     int ret;
 
-    sigemptyset(&blocked_signals);
+    blocked_signals = block_synchronous_signals();
 
     ret = qemu_signalfd_init(blocked_signals);
     if (ret) {
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 23/24] Refactor kvm&tcg function names in cpus.c
From: Jan Kiszka @ 2011-02-01 21:16 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

Pure interface cosmetics: Ensure that only kvm core services (as
declared in kvm.h) start with "kvm_". Prepend "qemu_" to those that
violate this rule in cpus.c. Also rename the corresponding tcg functions
for the sake of consistency.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 cpus.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9c50a34..0d11a20 100644
--- a/cpus.c
+++ b/cpus.c
@@ -778,7 +778,7 @@ static void qemu_kvm_wait_io_event(CPUState *env)
 
 static int qemu_cpu_exec(CPUState *env);
 
-static void *kvm_cpu_thread_fn(void *arg)
+static void *qemu_kvm_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
     int r;
@@ -811,7 +811,7 @@ static void *kvm_cpu_thread_fn(void *arg)
     return NULL;
 }
 
-static void *tcg_cpu_thread_fn(void *arg)
+static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *env = arg;
 
@@ -930,7 +930,7 @@ void resume_all_vcpus(void)
     }
 }
 
-static void tcg_init_vcpu(void *_env)
+static void qemu_tcg_init_vcpu(void *_env)
 {
     CPUState *env = _env;
     /* share a single thread for all cpus with TCG */
@@ -938,7 +938,7 @@ static void tcg_init_vcpu(void *_env)
         env->thread = qemu_mallocz(sizeof(QemuThread));
         env->halt_cond = qemu_mallocz(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
-        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
+        qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
         while (env->created == 0)
             qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
         tcg_cpu_thread = env->thread;
@@ -949,12 +949,12 @@ static void tcg_init_vcpu(void *_env)
     }
 }
 
-static void kvm_start_vcpu(CPUState *env)
+static void qemu_kvm_start_vcpu(CPUState *env)
 {
     env->thread = qemu_mallocz(sizeof(QemuThread));
     env->halt_cond = qemu_mallocz(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
-    qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
+    qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
     while (env->created == 0)
         qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
 }
@@ -966,9 +966,9 @@ void qemu_init_vcpu(void *_env)
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
     if (kvm_enabled())
-        kvm_start_vcpu(env);
+        qemu_kvm_start_vcpu(env);
     else
-        tcg_init_vcpu(env);
+        qemu_tcg_init_vcpu(env);
 }
 
 void qemu_notify_event(void)
-- 
1.7.1

^ permalink raw reply related

* [Qemu-devel] [PATCH v2 04/24] Process vmstop requests in IO thread
From: Jan Kiszka @ 2011-02-01 21:15 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: qemu-devel, kvm
In-Reply-To: <cover.1296594961.git.jan.kiszka@web.de>

From: Jan Kiszka <jan.kiszka@siemens.com>

A pending vmstop request is also a reason to leave the inner main loop.
So far we ignored it, and pending stop requests issued over VCPU threads
were simply ignored.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 vl.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/vl.c b/vl.c
index db24a05..5fad700 100644
--- a/vl.c
+++ b/vl.c
@@ -1373,15 +1373,11 @@ void main_loop_wait(int nonblocking)
 
 static int vm_can_run(void)
 {
-    if (powerdown_requested)
-        return 0;
-    if (reset_requested)
-        return 0;
-    if (shutdown_requested)
-        return 0;
-    if (debug_requested)
-        return 0;
-    return 1;
+    return !(powerdown_requested ||
+             reset_requested ||
+             shutdown_requested ||
+             debug_requested ||
+             vmstop_requested);
 }
 
 qemu_irq qemu_system_powerdown;
-- 
1.7.1

^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.