[PATCH 4/6] progressmeter: protect with a mutex

2021-05-10 Thread Emanuele Giuseppe Esposito
Progressmeter is protected by the AioContext mutex, which
is taken by the block jobs and their caller (like blockdev).

We would like to remove the dependency of block layer code on the
AioContext mutex, since most drivers and the core I/O code are already
not relying on it.

The simplest thing to do is to add a mutex to be able to provide
an accurate snapshot of the progress values to the caller.

Signed-off-by: Emanuele Giuseppe Esposito 
---
 blockjob.c| 33 +
 include/qemu/progress_meter.h | 31 +++
 job-qmp.c |  8 ++--
 job.c |  3 +++
 qemu-img.c|  9 ++---
 5 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 046c1bcd66..98bb12f015 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -306,18 +306,23 @@ int64_t block_job_ratelimit_get_delay(BlockJob *job, 
uint64_t n)
 BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
 {
 BlockJobInfo *info;
+uint64_t progress_current, progress_total;
 
 if (block_job_is_internal(job)) {
 error_setg(errp, "Cannot query QEMU internal jobs");
 return NULL;
 }
+
+progress_get_snapshot(&job->job.progress, &progress_current,
+  &progress_total);
+
 info = g_new0(BlockJobInfo, 1);
 info->type  = g_strdup(job_type_str(&job->job));
 info->device= g_strdup(job->job.id);
 info->busy  = qatomic_read(&job->job.busy);
 info->paused= job->job.pause_count > 0;
-info->offset= job->job.progress.current;
-info->len   = job->job.progress.total;
+info->offset= progress_current;
+info->len   = progress_total;
 info->speed = job->speed;
 info->io_status = job->iostatus;
 info->ready = job_is_ready(&job->job),
@@ -344,15 +349,19 @@ static void block_job_iostatus_set_err(BlockJob *job, int 
error)
 static void block_job_event_cancelled(Notifier *n, void *opaque)
 {
 BlockJob *job = opaque;
+uint64_t progress_current, progress_total;
 
 if (block_job_is_internal(job)) {
 return;
 }
 
+progress_get_snapshot(&job->job.progress, &progress_current,
+  &progress_total);
+
 qapi_event_send_block_job_cancelled(job_type(&job->job),
 job->job.id,
-job->job.progress.total,
-job->job.progress.current,
+progress_total,
+progress_current,
 job->speed);
 }
 
@@ -360,6 +369,7 @@ static void block_job_event_completed(Notifier *n, void 
*opaque)
 {
 BlockJob *job = opaque;
 const char *msg = NULL;
+uint64_t progress_current, progress_total;
 
 if (block_job_is_internal(job)) {
 return;
@@ -369,10 +379,13 @@ static void block_job_event_completed(Notifier *n, void 
*opaque)
 msg = error_get_pretty(job->job.err);
 }
 
+progress_get_snapshot(&job->job.progress, &progress_current,
+  &progress_total);
+
 qapi_event_send_block_job_completed(job_type(&job->job),
 job->job.id,
-job->job.progress.total,
-job->job.progress.current,
+progress_total,
+progress_current,
 job->speed,
 !!msg,
 msg);
@@ -393,15 +406,19 @@ static void block_job_event_pending(Notifier *n, void 
*opaque)
 static void block_job_event_ready(Notifier *n, void *opaque)
 {
 BlockJob *job = opaque;
+uint64_t progress_current, progress_total;
 
 if (block_job_is_internal(job)) {
 return;
 }
 
+progress_get_snapshot(&job->job.progress, &progress_current,
+  &progress_total);
+
 qapi_event_send_block_job_ready(job_type(&job->job),
 job->job.id,
-job->job.progress.total,
-job->job.progress.current,
+progress_total,
+progress_current,
 job->speed);
 }
 
diff --git a/include/qemu/progress_meter.h b/include/qemu/progress_meter.h
index 9a23ff071c..81f79770d2 100644
--- a/include/qemu/progress_meter.h
+++ b/include/qemu/progress_meter.h
@@ -27,6 +27,8 @@
 #ifndef QEMU_PROGRESS_METER_H
 #define QEMU_PROGRESS_METER_H
 
+#include "qemu/lockable.h"
+
 typedef struct ProgressMeter {
 /**
  * Current progress. The unit is arbitrary as long as the ratio between
@@ -37,21 +39,50 @@ typedef

Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-10 Thread Vladimir Sementsov-Ogievskiy

10.05.2021 11:59, Emanuele Giuseppe Esposito wrote:

Progressmeter is protected by the AioContext mutex, which
is taken by the block jobs and their caller (like blockdev).

We would like to remove the dependency of block layer code on the
AioContext mutex, since most drivers and the core I/O code are already
not relying on it.

The simplest thing to do is to add a mutex to be able to provide
an accurate snapshot of the progress values to the caller.

Signed-off-by: Emanuele Giuseppe Esposito 
---
  blockjob.c| 33 +


[..]


--- a/include/qemu/progress_meter.h
+++ b/include/qemu/progress_meter.h
@@ -27,6 +27,8 @@
  #ifndef QEMU_PROGRESS_METER_H
  #define QEMU_PROGRESS_METER_H
  
+#include "qemu/lockable.h"

+
  typedef struct ProgressMeter {
  /**
   * Current progress. The unit is arbitrary as long as the ratio between
@@ -37,21 +39,50 @@ typedef struct ProgressMeter {
  
  /** Estimated current value at the completion of the process */

  uint64_t total;
+
+QemuMutex lock;
  } ProgressMeter;
  
+static inline void progress_init(ProgressMeter *pm)

+{
+qemu_mutex_init(&pm->lock);
+}
+
+static inline void progress_destroy(ProgressMeter *pm)
+{
+qemu_mutex_destroy(&pm->lock);
+}



Could we instead add a c file and add the structure private? Then we'll have 
progress_new() and progress_free() APIs instead.

This way, it would be a lot simpler to control that nobady use structure fields 
directly.




+
+static inline void progress_get_snapshot(ProgressMeter *pm,
+ uint64_t *current, uint64_t *total)
+{
+QEMU_LOCK_GUARD(&pm->lock);
+
+if (current) {
+*current = pm->current;
+}
+
+if (total) {
+*total = pm->total;
+}
+}


We don't have caller that pass only one pointer. So we can just do

*current = pm->current;
*total = pm->total;

implicitly requiring both pointers to be non NULL.



--
Best regards,
Vladimir



Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-10 Thread Emanuele Giuseppe Esposito




On 10/05/2021 13:28, Vladimir Sementsov-Ogievskiy wrote:

10.05.2021 11:59, Emanuele Giuseppe Esposito wrote:

Progressmeter is protected by the AioContext mutex, which
is taken by the block jobs and their caller (like blockdev).

We would like to remove the dependency of block layer code on the
AioContext mutex, since most drivers and the core I/O code are already
not relying on it.

The simplest thing to do is to add a mutex to be able to provide
an accurate snapshot of the progress values to the caller.

Signed-off-by: Emanuele Giuseppe Esposito 
---
  blockjob.c    | 33 +


[..]


--- a/include/qemu/progress_meter.h
+++ b/include/qemu/progress_meter.h
@@ -27,6 +27,8 @@
  #ifndef QEMU_PROGRESS_METER_H
  #define QEMU_PROGRESS_METER_H
+#include "qemu/lockable.h"
+
  typedef struct ProgressMeter {
  /**
   * Current progress. The unit is arbitrary as long as the ratio 
between

@@ -37,21 +39,50 @@ typedef struct ProgressMeter {
  /** Estimated current value at the completion of the process */
  uint64_t total;
+
+    QemuMutex lock;
  } ProgressMeter;
+static inline void progress_init(ProgressMeter *pm)
+{
+    qemu_mutex_init(&pm->lock);
+}
+
+static inline void progress_destroy(ProgressMeter *pm)
+{
+    qemu_mutex_destroy(&pm->lock);
+}



Could we instead add a c file and add the structure private? Then we'll 
have progress_new() and progress_free() APIs instead.


This way, it would be a lot simpler to control that nobady use structure 
fields directly.



Makes sense, I'll do it.




+
+static inline void progress_get_snapshot(ProgressMeter *pm,
+ uint64_t *current, uint64_t 
*total)

+{
+    QEMU_LOCK_GUARD(&pm->lock);
+
+    if (current) {
+    *current = pm->current;
+    }
+
+    if (total) {
+    *total = pm->total;
+    }
+}


We don't have caller that pass only one pointer. So we can just do

*current = pm->current;
*total = pm->total;

implicitly requiring both pointers to be non NULL.


Is it so performance critical that we need to skip these safety checks?
IMHO we can keep it as it is.

Thank you,
Emanuele









Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-10 Thread Vladimir Sementsov-Ogievskiy

10.05.2021 19:52, Emanuele Giuseppe Esposito wrote:



On 10/05/2021 13:28, Vladimir Sementsov-Ogievskiy wrote:

10.05.2021 11:59, Emanuele Giuseppe Esposito wrote:

Progressmeter is protected by the AioContext mutex, which
is taken by the block jobs and their caller (like blockdev).

We would like to remove the dependency of block layer code on the
AioContext mutex, since most drivers and the core I/O code are already
not relying on it.

The simplest thing to do is to add a mutex to be able to provide
an accurate snapshot of the progress values to the caller.

Signed-off-by: Emanuele Giuseppe Esposito 
---
  blockjob.c    | 33 +


[..]


--- a/include/qemu/progress_meter.h
+++ b/include/qemu/progress_meter.h
@@ -27,6 +27,8 @@
  #ifndef QEMU_PROGRESS_METER_H
  #define QEMU_PROGRESS_METER_H
+#include "qemu/lockable.h"
+
  typedef struct ProgressMeter {
  /**
   * Current progress. The unit is arbitrary as long as the ratio between
@@ -37,21 +39,50 @@ typedef struct ProgressMeter {
  /** Estimated current value at the completion of the process */
  uint64_t total;
+
+    QemuMutex lock;
  } ProgressMeter;
+static inline void progress_init(ProgressMeter *pm)
+{
+    qemu_mutex_init(&pm->lock);
+}
+
+static inline void progress_destroy(ProgressMeter *pm)
+{
+    qemu_mutex_destroy(&pm->lock);
+}



Could we instead add a c file and add the structure private? Then we'll have 
progress_new() and progress_free() APIs instead.

This way, it would be a lot simpler to control that nobady use structure fields 
directly.


Makes sense, I'll do it.




+
+static inline void progress_get_snapshot(ProgressMeter *pm,
+ uint64_t *current, uint64_t *total)
+{
+    QEMU_LOCK_GUARD(&pm->lock);
+
+    if (current) {
+    *current = pm->current;
+    }
+
+    if (total) {
+    *total = pm->total;
+    }
+}


We don't have caller that pass only one pointer. So we can just do

*current = pm->current;
*total = pm->total;

implicitly requiring both pointers to be non NULL.


Is it so performance critical that we need to skip these safety checks?
IMHO we can keep it as it is.



Not performance. It's just less code. You propose more complex interface 
(pointers may be valid pointers or NULL), implemented by more complex code 
(extra if blocks). And there no users for this. So, I don't see any reason for 
extra logic and code lines.

What kind of safety you want? All current callers pass non-zero pointers, it's 
obvious. If someone will create new call, he should look first at function 
itself, not blindly pass NULL pointers. And if not, he will get clean crash on 
zero pointer dereference.


--
Best regards,
Vladimir



Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-10 Thread Emanuele Giuseppe Esposito





We don't have caller that pass only one pointer. So we can just do

*current = pm->current;
*total = pm->total;

implicitly requiring both pointers to be non NULL.


Is it so performance critical that we need to skip these safety checks?
IMHO we can keep it as it is.



Not performance. It's just less code. You propose more complex interface 
(pointers may be valid pointers or NULL), implemented by more complex 
code (extra if blocks). And there no users for this. So, I don't see any 
reason for extra logic and code lines.


What kind of safety you want? All current callers pass non-zero 
pointers, it's obvious. If someone will create new call, he should look 
first at function itself, not blindly pass NULL pointers. And if not, he 
will get clean crash on zero pointer dereference.


Ok, makes sense. Will remove the ifs.

Thank you,
Emanuele




Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-11 Thread Paolo Bonzini

On 10/05/21 13:28, Vladimir Sementsov-Ogievskiy wrote:



Could we instead add a c file and add the structure private? Then we'll 
have progress_new() and progress_free() APIs instead.


This way, it would be a lot simpler to control that nobady use structure 
fields directly.


I don't know...  I prefer embedding structs to heap allocation.

Paolo




Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-12 Thread Vladimir Sementsov-Ogievskiy

11.05.2021 15:28, Paolo Bonzini wrote:

On 10/05/21 13:28, Vladimir Sementsov-Ogievskiy wrote:



Could we instead add a c file and add the structure private? Then we'll have 
progress_new() and progress_free() APIs instead.

This way, it would be a lot simpler to control that nobady use structure fields 
directly.


I don't know...  I prefer embedding structs to heap allocation.




I agree that embedding looks better from allocation point of view.. But IMHO 
encapsulation guarantee of private structure is better feature. Especially when 
we have getter/setter methods. Even the patch itself is example: to review this 
carefully, I should somehow check that every use of the structure is updated 
(grepping the code, or maybe change field name and recompile, to catch every 
occurrence of it).. And if patch makes structure private and adds 
setters/getters, it can be reviewed without applying.

And we have to call _init/_destroy anyway, so it's not more complex to call 
_new/_free instead.

--
Best regards,
Vladimir



Re: [PATCH 4/6] progressmeter: protect with a mutex

2021-05-12 Thread Stefan Hajnoczi
On Mon, May 10, 2021 at 10:59:39AM +0200, Emanuele Giuseppe Esposito wrote:
> Progressmeter is protected by the AioContext mutex, which
> is taken by the block jobs and their caller (like blockdev).
> 
> We would like to remove the dependency of block layer code on the
> AioContext mutex, since most drivers and the core I/O code are already
> not relying on it.
> 
> The simplest thing to do is to add a mutex to be able to provide
> an accurate snapshot of the progress values to the caller.
> 
> Signed-off-by: Emanuele Giuseppe Esposito 
> ---
>  blockjob.c| 33 +
>  include/qemu/progress_meter.h | 31 +++
>  job-qmp.c |  8 ++--
>  job.c |  3 +++
>  qemu-img.c|  9 ++---
>  5 files changed, 71 insertions(+), 13 deletions(-)

Unlike the next two patches where I had comments, here adding the lock
makes sense to me - the point of the progress meter is to report numbers
to the monitor thread so thread-safety is a key part of the API's value.

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature