qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
@ 2016-02-10 14:11 Paolo Bonzini
  2016-02-10 14:23 ` Stefan Hajnoczi
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Paolo Bonzini @ 2016-02-10 14:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, stefanha

The last two arguments to these functions are the last and first bit to
check relative to the base.  The code was using incorrectly the first
bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
and cpu_physical_memory_all_dirty.  This requires a few changes in the
iteration; change the code in cpu_physical_memory_set_dirty_range to
match.

Fixes: 5b82b70
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/exec/ram_addr.h | 55 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index b1413a1..5d33def 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -121,6 +121,7 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
 {
     DirtyMemoryBlocks *blocks;
     unsigned long end, page;
+    unsigned long idx, offset, base;
     bool dirty = false;
 
     assert(client < DIRTY_MEMORY_NUM);
@@ -132,17 +133,22 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
 
     blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
 
+    idx = page / DIRTY_MEMORY_BLOCK_SIZE;
+    offset = page % DIRTY_MEMORY_BLOCK_SIZE;
+    base = page - offset;
     while (page < end) {
-        unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long offset = page % DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long num = MIN(end - page, DIRTY_MEMORY_BLOCK_SIZE - offset);
-
-        if (find_next_bit(blocks->blocks[idx], offset, num) < num) {
+        unsigned long next = MIN(end, base + DIRTY_MEMORY_BLOCK_SIZE);
+        unsigned long num = next - base;
+        unsigned long found = find_next_bit(blocks->blocks[idx], num, offset);
+        if (found < num) {
             dirty = true;
             break;
         }
 
-        page += num;
+        page = next;
+        idx++;
+        offset = 0;
+        base += DIRTY_MEMORY_BLOCK_SIZE;
     }
 
     rcu_read_unlock();
@@ -156,6 +162,7 @@ static inline bool cpu_physical_memory_all_dirty(ram_addr_t start,
 {
     DirtyMemoryBlocks *blocks;
     unsigned long end, page;
+    unsigned long idx, offset, base;
     bool dirty = true;
 
     assert(client < DIRTY_MEMORY_NUM);
@@ -167,17 +174,22 @@ static inline bool cpu_physical_memory_all_dirty(ram_addr_t start,
 
     blocks = atomic_rcu_read(&ram_list.dirty_memory[client]);
 
+    idx = page / DIRTY_MEMORY_BLOCK_SIZE;
+    offset = page % DIRTY_MEMORY_BLOCK_SIZE;
+    base = page - offset;
     while (page < end) {
-        unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long offset = page % DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long num = MIN(end - page, DIRTY_MEMORY_BLOCK_SIZE - offset);
-
-        if (find_next_zero_bit(blocks->blocks[idx], offset, num) < num) {
+        unsigned long next = MIN(end, base + DIRTY_MEMORY_BLOCK_SIZE);
+        unsigned long num = next - base;
+        unsigned long found = find_next_zero_bit(blocks->blocks[idx], num, offset);
+        if (found < num) {
             dirty = false;
             break;
         }
 
-        page += num;
+        page = next;
+        idx++;
+        offset = 0;
+        base += DIRTY_MEMORY_BLOCK_SIZE;
     }
 
     rcu_read_unlock();
@@ -248,6 +260,7 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
 {
     DirtyMemoryBlocks *blocks[DIRTY_MEMORY_NUM];
     unsigned long end, page;
+    unsigned long idx, offset, base;
     int i;
 
     if (!mask && !xen_enabled()) {
@@ -263,25 +276,29 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
         blocks[i] = atomic_rcu_read(&ram_list.dirty_memory[i]);
     }
 
+    idx = page / DIRTY_MEMORY_BLOCK_SIZE;
+    offset = page % DIRTY_MEMORY_BLOCK_SIZE;
+    base = page - offset;
     while (page < end) {
-        unsigned long idx = page / DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long offset = page % DIRTY_MEMORY_BLOCK_SIZE;
-        unsigned long num = MIN(end - page, DIRTY_MEMORY_BLOCK_SIZE - offset);
+        unsigned long next = MIN(end, base + DIRTY_MEMORY_BLOCK_SIZE);
 
         if (likely(mask & (1 << DIRTY_MEMORY_MIGRATION))) {
             bitmap_set_atomic(blocks[DIRTY_MEMORY_MIGRATION]->blocks[idx],
-                              offset, num);
+                              offset, next - page);
         }
         if (unlikely(mask & (1 << DIRTY_MEMORY_VGA))) {
             bitmap_set_atomic(blocks[DIRTY_MEMORY_VGA]->blocks[idx],
-                              offset, num);
+                              offset, next - page);
         }
         if (unlikely(mask & (1 << DIRTY_MEMORY_CODE))) {
             bitmap_set_atomic(blocks[DIRTY_MEMORY_CODE]->blocks[idx],
-                              offset, num);
+                              offset, next - page);
         }
 
-        page += num;
+        page = next;
+        idx++;
+        offset = 0;
+        base += DIRTY_MEMORY_BLOCK_SIZE;
     }
 
     rcu_read_unlock();
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 14:11 [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit Paolo Bonzini
@ 2016-02-10 14:23 ` Stefan Hajnoczi
  2016-02-10 17:29 ` Leon Alrae
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2016-02-10 14:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, qemu-devel

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

On Wed, Feb 10, 2016 at 03:11:45PM +0100, Paolo Bonzini wrote:
> The last two arguments to these functions are the last and first bit to
> check relative to the base.  The code was using incorrectly the first
> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
> and cpu_physical_memory_all_dirty.  This requires a few changes in the
> iteration; change the code in cpu_physical_memory_set_dirty_range to
> match.
> 
> Fixes: 5b82b70
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/exec/ram_addr.h | 55 ++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 36 insertions(+), 19 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 14:11 [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit Paolo Bonzini
  2016-02-10 14:23 ` Stefan Hajnoczi
@ 2016-02-10 17:29 ` Leon Alrae
  2016-02-10 17:44 ` Thomas Huth
  2016-02-10 22:40 ` Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Leon Alrae @ 2016-02-10 17:29 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: peter.maydell, stefanha

On 10/02/16 14:11, Paolo Bonzini wrote:
> The last two arguments to these functions are the last and first bit to
> check relative to the base.  The code was using incorrectly the first
> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
> and cpu_physical_memory_all_dirty.  This requires a few changes in the
> iteration; change the code in cpu_physical_memory_set_dirty_range to
> match.
> 
> Fixes: 5b82b70
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/exec/ram_addr.h | 55 ++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 36 insertions(+), 19 deletions(-)

It fixes the performance problem I was seeing:

Tested-by: Leon Alrae <leon.alrae@imgtec.com>

Thanks,
Leon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 14:11 [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit Paolo Bonzini
  2016-02-10 14:23 ` Stefan Hajnoczi
  2016-02-10 17:29 ` Leon Alrae
@ 2016-02-10 17:44 ` Thomas Huth
  2016-02-10 22:40 ` Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Thomas Huth @ 2016-02-10 17:44 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: peter.maydell, stefanha

On 10.02.2016 15:11, Paolo Bonzini wrote:
> The last two arguments to these functions are the last and first bit to
> check relative to the base.  The code was using incorrectly the first
> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
> and cpu_physical_memory_all_dirty.  This requires a few changes in the
> iteration; change the code in cpu_physical_memory_set_dirty_range to
> match.
> 
> Fixes: 5b82b70
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

That commit 5b82b70 also broke the pseries machine on qemu-ppc64:

--------------------------------- 8< --------------------------------------
$ ppc64-softmmu/qemu-system-ppc64 -net none -nographic -vga none 


SLOF **********************************************************************
QEMU Starting
 Build Date = Nov  5 2015 15:23:31
 FW Version = git-b4c93802a5b2c72f
 Press "s" to enter Open Firmware.



SLOF **********************************************************************
QEMU Starting
 Build Date = Nov  5 2015 15:23:31
 FW Version = git-b4c93802a5b2c72f
ERROR: Flatten device tree not available!
 Press "s" to enter Open Firmware.

  !!! roomfs lookup(bootinfo) = 1
Cannot find romfs file xvect
  !!! roomfs lookup(bootinfo) = 1
ERROR: Not enough memory for Open Firmware
qemu: fatal: Trying to execute code outside RAM or ROM at 0xffffffffffbf0000
--------------------------------- 8< --------------------------------------

With your patch here applied, SLOF boots fine again, so:

Tested-by: Thomas Huth <thuth@redhat.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 14:11 [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit Paolo Bonzini
                   ` (2 preceding siblings ...)
  2016-02-10 17:44 ` Thomas Huth
@ 2016-02-10 22:40 ` Peter Maydell
  2016-02-11  9:46   ` Paolo Bonzini
  2016-02-11 10:34   ` Peter Maydell
  3 siblings, 2 replies; 7+ messages in thread
From: Peter Maydell @ 2016-02-10 22:40 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Stefan Hajnoczi

On 10 February 2016 at 14:11, Paolo Bonzini <pbonzini@redhat.com> wrote:
> The last two arguments to these functions are the last and first bit to
> check relative to the base.  The code was using incorrectly the first
> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
> and cpu_physical_memory_all_dirty.  This requires a few changes in the
> iteration; change the code in cpu_physical_memory_set_dirty_range to
> match.
>
> Fixes: 5b82b70
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

I've set the pre-merge tests running so I should be able
to commit this to master first thing tomorrow. Was this
the only patch that needs applying to fix your pullreq?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 22:40 ` Peter Maydell
@ 2016-02-11  9:46   ` Paolo Bonzini
  2016-02-11 10:34   ` Peter Maydell
  1 sibling, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2016-02-11  9:46 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Stefan Hajnoczi



On 10/02/2016 23:40, Peter Maydell wrote:
> On 10 February 2016 at 14:11, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> The last two arguments to these functions are the last and first bit to
>> check relative to the base.  The code was using incorrectly the first
>> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
>> and cpu_physical_memory_all_dirty.  This requires a few changes in the
>> iteration; change the code in cpu_physical_memory_set_dirty_range to
>> match.
>>
>> Fixes: 5b82b70
>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> I've set the pre-merge tests running so I should be able
> to commit this to master first thing tomorrow. Was this
> the only patch that needs applying to fix your pullreq?

Nothing else.

Paolo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit
  2016-02-10 22:40 ` Peter Maydell
  2016-02-11  9:46   ` Paolo Bonzini
@ 2016-02-11 10:34   ` Peter Maydell
  1 sibling, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2016-02-11 10:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Stefan Hajnoczi

On 10 February 2016 at 22:40, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 10 February 2016 at 14:11, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> The last two arguments to these functions are the last and first bit to
>> check relative to the base.  The code was using incorrectly the first
>> bit and the number of bits.  Fix this in cpu_physical_memory_get_dirty
>> and cpu_physical_memory_all_dirty.  This requires a few changes in the
>> iteration; change the code in cpu_physical_memory_set_dirty_range to
>> match.
>>
>> Fixes: 5b82b70
>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> I've set the pre-merge tests running so I should be able
> to commit this to master first thing tomorrow.

Applied to master, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-02-11 10:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-10 14:11 [Qemu-devel] [PATCH] memory: fix usage of find_next_bit and find_next_zero_bit Paolo Bonzini
2016-02-10 14:23 ` Stefan Hajnoczi
2016-02-10 17:29 ` Leon Alrae
2016-02-10 17:44 ` Thomas Huth
2016-02-10 22:40 ` Peter Maydell
2016-02-11  9:46   ` Paolo Bonzini
2016-02-11 10:34   ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).