Skip to contentSkip to conversation

sndif: add explicit back and front synchronization

PATCH Superseded Oleksandr Andrushchenko 4 participants 57 messages Feb 5, 2018 – Mar 14, 2018

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

cover sndif: add explicit back and front synchronization

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

 xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 7 lines
2.7.4


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#1 lore raw

PATCH 1/2 sndif: introduce protocol version

From: Oleksandr Andrushchenko <[email protected]>

Protocol version was referenced in the protocol description, but missed its definition. Fix this by adding a constant for current protocol version.

---
 xen/include/public/io/sndif.h | 7 +++++++
 1 file changed, 7 insertions(+)
xen/include/public/io/sndif.h +7 -0
index c5c1978406b3..b0e6ac35e131 100644
@@ -38,6 +38,13 @@
 
 /*
  ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENSND_PROTOCOL_VERSION         "1"
+
+/*
+ ******************************************************************************
  *                  Feature and Parameter Negotiation
  ******************************************************************************
  *
Signature · 7 lines
2.7.4


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
Reviewed-by on v1 1/2
#2 lore raw

Re: [Xen-devel] [PATCH 1/2] sndif: introduce protocol version

Quoted 7 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Protocol version was referenced in the protocol description, but missed its definition. Fix this by adding a constant for current protocol version.

Thank you!

Quoted 30 lines
---
 xen/include/public/io/sndif.h | 7 +++++++
 1 file changed, 7 insertions(+)
xen/include/public/io/sndif.h +7 -0
index c5c1978406b3..b0e6ac35e131 100644
@@ -38,6 +38,13 @@
 
 /*
  ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENSND_PROTOCOL_VERSION         "1"
+
+/*
+ ******************************************************************************
  *                  Feature and Parameter Negotiation
  ******************************************************************************
  *
Signature · 7 lines
2.7.4


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
Reviewed-by on v1 1/2
#3 lore raw

Re: [PATCH 1/2] sndif: introduce protocol version

In reply to Oleksandr Andrushchenko
Quoted 7 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Protocol version was referenced in the protocol description, but missed its definition. Fix this by adding a constant for current protocol version.

Thank you!

Quoted 30 lines
---
 xen/include/public/io/sndif.h | 7 +++++++
 1 file changed, 7 insertions(+)
xen/include/public/io/sndif.h +7 -0
index c5c1978406b3..b0e6ac35e131 100644
@@ -38,6 +38,13 @@
 
 /*
  ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENSND_PROTOCOL_VERSION         "1"
+
+/*
+ ******************************************************************************
  *                  Feature and Parameter Negotiation
  ******************************************************************************
  *
Signature · 7 lines
2.7.4


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#4 lore raw

PATCH 2/2 sndif: add explicit back and front synchronization

In reply to Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

In order to provide explicit synchronization between backend and frontend the following changes are introduced in the protocol:
- add new ring buffer for sending asynchronous events from backend to frontend to report number of bytes played/captured (XENSND_EVT_CUR_POS)
- introduce trigger events for playback control: start/stop/pause/resume
- bump protocol version to 2

Cc Konrad Rzeszutek Wilk <[email protected]>
Cc Takashi Iwai <[email protected]>
Cc Takashi Sakamoto <[email protected]>
Cc Clemens Ladisch <[email protected]>
---
 xen/include/public/io/sndif.h | 168 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 164 insertions(+), 4 deletions(-)
xen/include/public/io/sndif.h +164 -4
index b0e6ac35e131..b4d6c96b40b4 100644
@@ -41,7 +41,7 @@
  *                           Protocol version
  ******************************************************************************
  */
-#define XENSND_PROTOCOL_VERSION         "1"
+#define XENSND_PROTOCOL_VERSION         "2"
 
 /*
  ******************************************************************************
@@ -113,6 +113,8 @@
  *
  * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
  * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
+ * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
+ * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
  *
  *------------------------------ Stream 1, capture ----------------------------
  *
@@ -122,6 +124,8 @@
  *
  * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
  * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
+ * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"
+ * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"
  *
  *------------------------------- PCM device 1 --------------------------------
  *
@@ -135,6 +139,8 @@
  *
  * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
  * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
+ * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"
+ * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"
  *
  *------------------------------- PCM device 2 --------------------------------
  *
@@ -147,6 +153,8 @@
  *
  * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
  * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
+ * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"
+ * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"
  *
  ******************************************************************************
  *                            Backend XenBus Nodes
@@ -292,6 +300,23 @@
  *      The Xen grant reference granting permission for the backend to map
  *      a sole page in a single page sized ring buffer.
  *
+ *--------------------- Stream Event Transport Parameters ---------------------
+ *
+ * This communication path is used to deliver asynchronous events from backend
+ * to frontend, set up per stream.
+ *
+ * evt-event-channel
+ *      Values:         <uint32_t>
+ *
+ *      The identifier of the Xen event channel used to signal activity
+ *      in the ring buffer.
+ *
+ * evt-ring-ref
+ *      Values:         <uint32_t>
+ *
+ *      The Xen grant reference granting permission for the backend to map
+ *      a sole page in a single page sized ring buffer.
+ *
  ******************************************************************************
  *                               STATE DIAGRAMS
  ******************************************************************************
@@ -439,6 +464,19 @@
 #define XENSND_OP_GET_VOLUME            5
 #define XENSND_OP_MUTE                  6
 #define XENSND_OP_UNMUTE                7
+#define XENSND_OP_TRIGGER               8
+
+#define XENSND_OP_TRIGGER_START         0
+#define XENSND_OP_TRIGGER_PAUSE         1
+#define XENSND_OP_TRIGGER_STOP          2
+#define XENSND_OP_TRIGGER_RESUME        3
+
+/*
+ ******************************************************************************
+ *                                 EVENT CODES
+ ******************************************************************************
+ */
+#define XENSND_EVT_CUR_POS              0
 
 /*
  ******************************************************************************
@@ -455,6 +493,8 @@
 #define XENSND_FIELD_VCARD_LONG_NAME    "long-name"
 #define XENSND_FIELD_RING_REF           "ring-ref"
 #define XENSND_FIELD_EVT_CHNL           "event-channel"
+#define XENSND_FIELD_EVT_RING_REF       "evt-ring-ref"
+#define XENSND_FIELD_EVT_EVT_CHNL       "evt-event-channel"
 #define XENSND_FIELD_DEVICE_NAME        "name"
 #define XENSND_FIELD_TYPE               "type"
 #define XENSND_FIELD_STREAM_UNIQUE_ID   "unique-id"
@@ -566,9 +606,7 @@
  * +----------------+----------------+----------------+----------------+
  * |                           gref_directory                          | 24
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
- * +----------------+----------------+----------------+----------------+
- * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * |                             period_sz                             | 28
  * +----------------+----------------+----------------+----------------+
  * |                             reserved                              | 32
  * +----------------+----------------+----------------+----------------+
@@ -578,6 +616,14 @@
  * pcm_channels - uint8_t, number of channels of this stream,
  *   [channels-min; channels-max]
  * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, recommended event period size, octets
+ *   This is the recommended (hint) value of the period at which frontend would
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *
  * gref_directory - grant_ref_t, a reference to the first shared page
  *   describing shared buffer references. At least one page exists. If shared
  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -592,6 +638,7 @@ struct xensnd_open_req {
     uint16_t reserved;
     uint32_t buffer_sz;
     grant_ref_t gref_directory;
+    uint32_t period_sz;
 };
 
 /*
@@ -750,8 +797,36 @@ struct xensnd_rw_req {
  *
  * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
  * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
+ *
+ * Request stream running state change - trigger PCM stream running state
+ * to start, stop, pause or resume:
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _OP_TRIGGER  |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                               type                                | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, XENSND_OP_TRIGGER_XXX value
  */
 
+struct xensnd_trigger_req {
+    uint8_t type;
+};
+
 /*
  *---------------------------------- Responses --------------------------------
  *
@@ -774,8 +849,51 @@ struct xensnd_rw_req {
  * id - uint16_t, copied from the request
  * operation - uint8_t, XENSND_OP_* - copied from request
  * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *----------------------------------- Events ----------------------------------
+ *
+ * Events are sent via a shared page allocated by the front and propagated by
+ *   evt-event-channel/evt-ring-ref XenStore entries
+ * All event packets have the same length (32 octets)
+ * All event packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |      type      |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, event id, may be used by front
+ * type - uint8_t, type of the event
+ *
+ *
+ * Current stream position - event from back to front when stream's
+ *   playback/capture position has advanced:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _EVT_CUR_POS |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                         position low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                         position high 32-bit                      | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * position - current value of stream's playback/capture position, octets
+ *
  */
 
+struct xensnd_cur_pos_evt {
+    uint64_t position;
+};
+
 struct xensnd_req {
     uint16_t id;
     uint8_t operation;
@@ -783,6 +901,7 @@ struct xensnd_req {
     union {
         struct xensnd_open_req open;
         struct xensnd_rw_req rw;
+        struct xensnd_trigger_req trigger;
         uint8_t reserved[24];
     } op;
 };
@@ -795,8 +914,49 @@ struct xensnd_resp {
     uint8_t reserved1[24];
 };
 
+struct xensnd_evt {
+    uint16_t id;
+    uint8_t type;
+    uint8_t reserved[5];
+    union {
+        struct xensnd_cur_pos_evt cur_pos;
+        uint8_t reserved[24];
+    } op;
+};
+
 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
 
+/*
+ ******************************************************************************
+ *                        Back to front events delivery
+ ******************************************************************************
+ * In order to deliver asynchronous events from back to front a shared page is
+ * allocated by front and its granted reference propagated to back via
+ * XenStore entries (evt-ring-ref/evt-event-channel).
+ * This page has a common header used by both front and back to synchronize
+ * access and control event's ring buffer, while back being a producer of the
+ * events and front being a consumer. The rest of the page after the header
+ * is used for event packets.
+ *
+ * Upon reception of an event(s) front may confirm its reception
+ * for either each event, group of events or none.
+ */
+
+struct xensnd_event_page {
+    uint32_t in_cons;
+    uint32_t in_prod;
+    uint8_t reserved[24];
+};
+
+#define XENSND_EVENT_PAGE_SIZE 4096
+#define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))
+#define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)
+#define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))
+#define XENSND_IN_RING(page) \
+    ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))
+#define XENSND_IN_RING_REF(page, idx) \
+    (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])
+
 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
 
 /*
Signature · 7 lines
2.7.4


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#5 lore raw
Quoted 12 lines

* +----------------+----------------+----------------+----------------+

  * |                           gref_directory                          | 24
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
- * +----------------+----------------+----------------+----------------+
- * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * |                             period_sz                             | 28
  * +----------------+----------------+----------------+----------------+
  * |                             reserved                              | 32

* +----------------+----------------+----------------+----------------+

xen/include/public/io/sndif.h +0 -0
@@ -578,6 +616,14 @@
  * pcm_channels - uint8_t, number of channels of this stream,

xen/include/public/io/sndif.h line 626

Quoted 10 lines
xen/include/public/io/sndif.h +8 -0
  *   [channels-min; channels-max]
  * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, recommended event period size, octets
+ *   This is the recommended (hint) value of the period at which frontend would
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *

I would gate this based on the version. That is if version 0 then this field does not exist.

xen/include/public/io/sndif.h struct xensnd_open_req { · line 641

Quoted 8 lines
xen/include/public/io/sndif.h +1 -0
  * gref_directory - grant_ref_t, a reference to the first shared page
  *   describing shared buffer references. At least one page exists. If shared
  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -592,6 +638,7 @@ struct xensnd_open_req {
     uint16_t reserved;
     uint32_t buffer_sz;
     grant_ref_t gref_directory;
+    uint32_t period_sz;

The same here. Just put a comment mentioning the version part.

#6 lore raw
Quoted 16 lines · Konrad Rzeszutek Wilk
Quoted 16 lines

* +----------------+----------------+----------------+----------------+

   * |                           gref_directory                          | 24
   * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
- * +----------------+----------------+----------------+----------------+
- * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * |                             period_sz                             | 28
   * +----------------+----------------+----------------+----------------+
   * |                             reserved                              | 32

* +----------------+----------------+----------------+----------------+

xen/include/public/io/sndif.h +2 -0
@@ -578,6 +616,14 @@
   * pcm_channels - uint8_t, number of channels of this stream,
   *   [channels-min; channels-max]
   * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, recommended event period size, octets
+ *   This is the recommended (hint) value of the period at which frontend would
Quoted 8 lines

xen/include/public/io/sndif.h line 626

Quoted 6 lines
xen/include/public/io/sndif.h +6 -0
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *

I would gate this based on the version. That is if version 0 then this field does not exist.

Well, by default we have all unused fields set to 0: [1] And for version 1 (or 0, initial) of the protocol it means that period_sz falls into reserved region [2]. With the comment above for version 2 it means that old behavior is in use, e.g. no XENSND_EVT_CUR_POS events are sent by the backend, so we are backward compatible in this case

Quoted 9 lines

xen/include/public/io/sndif.h struct xensnd_open_req { · line 641

Quoted 8 lines
xen/include/public/io/sndif.h +1 -0
   * gref_directory - grant_ref_t, a reference to the first shared page
   *   describing shared buffer references. At least one page exists. If shared
   *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -592,6 +638,7 @@ struct xensnd_open_req {
      uint16_t reserved;
      uint32_t buffer_sz;
      grant_ref_t gref_directory;
+    uint32_t period_sz;

The same here. Just put a comment mentioning the version part.

So, if you still want to gate it, how would you like it? XENSND_PROTOCOL_VERSION was defined as a string "1"/"2" and preprocessor won't allow comparing strings, e.g. you can't do #if XENSND_PROTOCOL_VERSION == "1" So, we might want re-defining XENSND_PROTOCOL_VERSION as an integer in the first patch, so it can be used here. Then, if it is an integer:
1.
#if XENSND_PROTOCOL_VERSION != 1
    uint32_t period_sz;
#endif
2.
#if XENSND_PROTOCOL_VERSION > 1
    uint32_t period_sz;
#endif
3.
#if XENSND_PROTOCOL_VERSION == 2
    uint32_t period_sz;
#endif

Please let me know whether we still want gating and if so in which way.

Thank you,
Oleksandr
[1] https://elixir.bootlin.com/linux/v4.16-rc3/source/include/xen/interface/io/sndif.h#L525
[2] https://elixir.bootlin.com/linux/v4.16-rc3/source/include/xen/interface/io/sndif.h#L562
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#7 lore raw
In reply to Konrad Rzeszutek Wilk
Quoted 16 lines · Konrad Rzeszutek Wilk
Quoted 16 lines

* +----------------+----------------+----------------+----------------+

   * |                           gref_directory                          | 24
   * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
- * +----------------+----------------+----------------+----------------+
- * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * |                             period_sz                             | 28
   * +----------------+----------------+----------------+----------------+
   * |                             reserved                              | 32

* +----------------+----------------+----------------+----------------+

xen/include/public/io/sndif.h +2 -0
@@ -578,6 +616,14 @@
   * pcm_channels - uint8_t, number of channels of this stream,
   *   [channels-min; channels-max]
   * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, recommended event period size, octets
+ *   This is the recommended (hint) value of the period at which frontend would
Quoted 8 lines

xen/include/public/io/sndif.h line 626

Quoted 6 lines
xen/include/public/io/sndif.h +6 -0
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *

I would gate this based on the version. That is if version 0 then this field does not exist.

Well, by default we have all unused fields set to 0: [1] And for version 1 (or 0, initial) of the protocol it means that period_sz falls into reserved region [2]. With the comment above for version 2 it means that old behavior is in use, e.g. no XENSND_EVT_CUR_POS events are sent by the backend, so we are backward compatible in this case

Quoted 9 lines

xen/include/public/io/sndif.h struct xensnd_open_req { · line 641

Quoted 8 lines
xen/include/public/io/sndif.h +1 -0
   * gref_directory - grant_ref_t, a reference to the first shared page
   *   describing shared buffer references. At least one page exists. If shared
   *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -592,6 +638,7 @@ struct xensnd_open_req {
      uint16_t reserved;
      uint32_t buffer_sz;
      grant_ref_t gref_directory;
+    uint32_t period_sz;

The same here. Just put a comment mentioning the version part.

So, if you still want to gate it, how would you like it? XENSND_PROTOCOL_VERSION was defined as a string "1"/"2" and preprocessor won't allow comparing strings, e.g. you can't do #if XENSND_PROTOCOL_VERSION == "1" So, we might want re-defining XENSND_PROTOCOL_VERSION as an integer in the first patch, so it can be used here. Then, if it is an integer:
1.
#if XENSND_PROTOCOL_VERSION != 1
    uint32_t period_sz;
#endif
2.
#if XENSND_PROTOCOL_VERSION > 1
    uint32_t period_sz;
#endif
3.
#if XENSND_PROTOCOL_VERSION == 2
    uint32_t period_sz;
#endif

Please let me know whether we still want gating and if so in which way.

Thank you,
Oleksandr
[1] https://elixir.bootlin.com/linux/v4.16-rc3/source/include/xen/interface/io/sndif.h#L525
[2] https://elixir.bootlin.com/linux/v4.16-rc3/source/include/xen/interface/io/sndif.h#L562

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#8 lore raw
In reply to Oleksandr Andrushchenko
Quoted 12 lines

* +----------------+----------------+----------------+----------------+

  * |                           gref_directory                          | 24
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
- * +----------------+----------------+----------------+----------------+
- * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * |                             period_sz                             | 28
  * +----------------+----------------+----------------+----------------+
  * |                             reserved                              | 32

* +----------------+----------------+----------------+----------------+

xen/include/public/io/sndif.h +0 -0
@@ -578,6 +616,14 @@
  * pcm_channels - uint8_t, number of channels of this stream,

xen/include/public/io/sndif.h line 626

Quoted 10 lines
xen/include/public/io/sndif.h +8 -0
  *   [channels-min; channels-max]
  * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, recommended event period size, octets
+ *   This is the recommended (hint) value of the period at which frontend would
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *

I would gate this based on the version. That is if version 0 then this field does not exist.

xen/include/public/io/sndif.h struct xensnd_open_req { · line 641

Quoted 8 lines
xen/include/public/io/sndif.h +1 -0
  * gref_directory - grant_ref_t, a reference to the first shared page
  *   describing shared buffer references. At least one page exists. If shared
  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -592,6 +638,7 @@ struct xensnd_open_req {
     uint16_t reserved;
     uint32_t buffer_sz;
     grant_ref_t gref_directory;
+    uint32_t period_sz;

The same here. Just put a comment mentioning the version part.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#9 lore raw
In reply to Oleksandr Andrushchenko

ping

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#10 lore raw
In reply to Oleksandr Andrushchenko

ping

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#11 lore raw
In reply to Oleksandr Andrushchenko

Hello,
Konrad, Takashi, Takashi and Clemens!

Could you please take a look at this series if it meets ALSA expectations on para-virtualized sound for Xen?

Thank you,
Oleksandr

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#12 lore raw
In reply to Oleksandr Andrushchenko

Hello,
Konrad, Takashi, Takashi and Clemens!

Could you please take a look at this series if it meets ALSA expectations on para-virtualized sound for Xen?

Thank you,
Oleksandr

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#13 lore raw
In reply to Oleksandr Andrushchenko

Any chance ALSA community may also review the below?

BTW, the driver, with the changes proposed, is at [1]

Thank you,

Oleksandr

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

[1] https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#14 lore raw
In reply to Oleksandr Andrushchenko

Any chance ALSA community may also review the below?

BTW, the driver, with the changes proposed, is at [1]

Thank you,

Oleksandr

Quoted 72 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 7 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)

[1] https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#15 lore raw
In reply to Oleksandr Andrushchenko
Quoted 47 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

thanks,

Takashi

Quoted 15 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 14 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

 xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#16 lore raw
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 9 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend capabilities. E.g., we usually set buffer sizes to match real HW at backend side if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

Quoted 34 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[1] https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2] https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#17 lore raw
Quoted 80 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 9 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

thanks,

Takashi

Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#18 lore raw
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request
something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested. And it is up to backend to decide.

Does that sound reasonable or you have something else on your mind?

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 33 lines
Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

   xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
   1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#19 lore raw
Quoted 111 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:
snd_pcm_hw_constraint_integer(substream->runtime,

	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

thanks,

Takashi

Quoted 47 lines
Quoted 5 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 39 lines
Quoted 39 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

   xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
   1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#20 lore raw
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
   snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 38 lines
Quoted 38 lines
Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 33 lines
Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-)

Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#21 lore raw
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
   snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

Quoted 7 lines

You are right, I saw those in other drivers

Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#22 lore raw
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
    snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 7 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 4 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#23 lore raw
Quoted 144 lines · Oleksandr Andrushchenko
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
    snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 7 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Quoted 11 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 1 line
Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#24 lore raw
Quoted 154 lines · Takashi Iwai
Quoted 142 lines · Oleksandr Andrushchenko
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
     snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

Quoted 3 lines

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?
I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

Quoted 10 lines
Quoted 10 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?
The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Quoted 2 lines

Takashi

Thank you very much for helping with this!
Oleksandr
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#25 lore raw
Quoted 29 lines · Oleksandr Andrushchenko
Quoted 26 lines
Quoted 16 lines
Quoted 9 lines
Quoted 7 lines
Quoted 5 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

Quoted 3 lines

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 6 lines

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?

The buffer, period, channels, rate and format are the basic parameters, and that should be enough for 99.9% cases.

Quoted 6 lines

I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

You don't have to list up all combinations of the parameters above at open time. For example, declaring min/max of each of them at open would suffice at first. (But this min/max might be even unnecessary if we implement the proper hw constraints. See below)

The rest fine-tuning is done via the hw constraints...

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

Quoted 7 lines
Quoted 3 lines

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?

Well, what set at the open time is only the constraint "rule". And the rule is a function call, not necessarily static. The actual parameters are determined at hw_params call time, and this is called even repeatedly.

Quoted 3 lines

The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Again, the parameter setup pretty depends on the hardware, and in this case, the backend (and its communication).

Takashi

#26 lore raw
Quoted 30 lines · Takashi Iwai
Quoted 28 lines · Oleksandr Andrushchenko
Quoted 28 lines
Quoted 15 lines
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 8 lines
Quoted 6 lines

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?

The buffer, period, channels, rate and format are the basic parameters, and that should be enough for 99.9% cases.

Excellent, will use this set as the constraint entry. Just to clarify for the upcoming Xen sound protocol change:
the values in this constraint are not ALSA specific and could be used in implementation/OS agnostic Xen protocol.

Quoted 46 lines
Quoted 6 lines

I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

You don't have to list up all combinations of the parameters above at open time. For example, declaring min/max of each of them at open would suffice at first. (But this min/max might be even unnecessary if we implement the proper hw constraints. See below)

The rest fine-tuning is done via the hw constraints...

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 10 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Quoted 8 lines
Quoted 4 lines

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?

Well, what set at the open time is only the constraint "rule". And the rule is a function call, not necessarily static. The actual parameters are determined at hw_params call time, and this is called even repeatedly.

I need some time to think about all the above ;)

Quoted 8 lines
Quoted 3 lines

The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Again, the parameter setup pretty depends on the hardware, and in this case, the backend (and its communication).

Takashi

Thank you!
Oleksandr

#27 lore raw
Quoted 34 lines · Oleksandr Andrushchenko
Quoted 34 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 8 lines
Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

This is the most difficult part, apparently :)
There are lots of codes deploying the own hw constraints, but nothing is similar like your case.

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Takashi

#28 lore raw
Quoted 121 lines · Takashi Iwai
Quoted 33 lines · Oleksandr Andrushchenko
Quoted 33 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 8 lines
Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

This is the most difficult part, apparently :)
There are lots of codes deploying the own hw constraints, but nothing is similar like your case.

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine how to do that. But what do I do if I run the backend as PulseAudio client?

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

Quoted 2 lines

Takashi

Thank you very much for helping with this,
Oleksandr

Quoted 1 line

From 267fb5f74026b8313a54c47fcecdeb8c644f3257 Mon Sep 17 00:00:00 2001

From: Oleksandr Andrushchenko <[email protected]>
Date: Wed, 7 Mar 2018 10:21:20 +0200
Subject: [PATCH] sndif: add explicit back and front parameter negotiation

In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
- add XENSND_OP_HW_PARAM_SET request to set one of the stream
parameters: frame rate, sample rate, number of channels, buffer and period sizes
- add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
- add minimum buffer size to XenStore configuration

Cc Konrad Rzeszutek Wilk <[email protected]>
Cc Takashi Iwai <[email protected]>
---
 xen/include/public/io/sndif.h | 127 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 120 insertions(+), 7 deletions(-)
xen/include/public/io/sndif.h +120 -7
index e38644423c0a..8036c5c2f212 100644
@@ -250,6 +250,11 @@
  *
  *      The maximum size in octets of the buffer to allocate per stream.
  *
+ * buffer-size-min
+ *      Values:         <uint32_t>
+ *
+ *      The minimum size in octets of the buffer to allocate per stream.
+ *
  *----------------------- Virtual sound card settings -------------------------
  * short-name
  *      Values:         <char[32]>
@@ -465,12 +470,20 @@
 #define XENSND_OP_MUTE                  6
 #define XENSND_OP_UNMUTE                7
 #define XENSND_OP_TRIGGER               8
+#define XENSND_OP_HW_PARAM_SET          9
+#define XENSND_OP_HW_PARAM_QUERY        10
 
 #define XENSND_OP_TRIGGER_START         0
 #define XENSND_OP_TRIGGER_PAUSE         1
 #define XENSND_OP_TRIGGER_STOP          2
 #define XENSND_OP_TRIGGER_RESUME        3
 
+#define XENSND_OP_HW_PARAM_FORMAT       0
+#define XENSND_OP_HW_PARAM_RATE         1
+#define XENSND_OP_HW_PARAM_BUFFER       2
+#define XENSND_OP_HW_PARAM_PERIOD       3
+#define XENSND_OP_HW_PARAM_CHANNELS     4
+
 /*
  ******************************************************************************
  *                                 EVENT CODES
@@ -503,6 +516,7 @@
 #define XENSND_FIELD_SAMPLE_RATES       "sample-rates"
 #define XENSND_FIELD_SAMPLE_FORMATS     "sample-formats"
 #define XENSND_FIELD_BUFFER_SIZE        "buffer-size"
+#define XENSND_FIELD_BUFFER_SIZE_MIN    "buffer-size-min"
 
 /* Stream type field values. */
 #define XENSND_STREAM_TYPE_PLAYBACK     "p"
@@ -828,28 +842,122 @@ struct xensnd_trigger_req {
 };
 
 /*
+ * Request stream configuration parameter selection:
+ *   Sound device configuration for a particular stream is a limited subset
+ *   of the multidimensional configuration available on XenStore, e.g.
+ *   once the frame rate has been selected there is a limited supported range
+ *   for sample rates becomes available (which might be the same set configured
+ *   on XenStore or less). For example, selecting 96kHz sample rate may limit
+ *   number of channels available for such configuration from 4 to 2 etc.
+ *   Thus, each call to XENSND_OP_SET_HW_PARAM will reduce configuration space
+ *   making it possible to iteratively get the final stream configuration,
+ *   used in XENSND_OP_OPEN request.
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_SET_HW_PARAM|    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                               value                               | 12
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * value - uint32_t, requested value of the parameter
+ * type - uint8_t, XENSND_OP_HW_PARAM_XXX value
+ */
+
+struct xensnd_set_hw_param_req {
+    uint32_t value;
+    uint8_t type;
+};
+
+/*
+ * Request stream configuration parameter interval: request interval of
+ *   supported values for the parameter given. See response format for this
+ *   request.
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _HW_PARAM_QUERY|    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, XENSND_OP_HW_PARAM_XXX value
+ */
+
+struct xensnd_query_hw_param_req {
+    uint8_t type;
+};
+
+/*
  *---------------------------------- Responses --------------------------------
  *
  * All response packets have the same length (32 octets)
  *
- * Response for all requests:
+ * All response packets have common header:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
  * |               id                |    operation   |    reserved    | 4
  * +----------------+----------------+----------------+----------------+
  * |                              status                               | 8
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 12
+ *
+ * id - uint16_t, copied from the request
+ * operation - uint8_t, XENSND_OP_* - copied from request
+ * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *
+ * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                                min                                | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                                max                                | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
  * |                             reserved                              | 32
  * +----------------+----------------+----------------+----------------+
  *
- * id - uint16_t, copied from the request
- * operation - uint8_t, XENSND_OP_* - copied from request
- * status - int32_t, response status, zero on success and -XEN_EXX on failure
- *
+ * min - uint32_t, minimum value of the parameter that can be used
+ * max - uint32_t, maximum value of the parameter that can be used
+ */
+
+struct xensnd_query_hw_param_resp {
+    uint32_t min;
+    uint32_t max;
+};
+
+/*
  *----------------------------------- Events ----------------------------------
  *
  * Events are sent via a shared page allocated by the front and propagated by
@@ -902,6 +1010,8 @@ struct xensnd_req {
         struct xensnd_open_req open;
         struct xensnd_rw_req rw;
         struct xensnd_trigger_req trigger;
+        struct xensnd_set_hw_param_req set_hw_param;
+        struct xensnd_query_hw_param_req query_hw_param;
         uint8_t reserved[24];
     } op;
 };
@@ -911,7 +1021,10 @@ struct xensnd_resp {
     uint8_t operation;
     uint8_t reserved;
     int32_t status;
-    uint8_t reserved1[24];
+    union {
+        struct xensnd_query_hw_param_resp hw_param;
+        uint8_t reserved1[24];
+    } resp;
 };
 
 struct xensnd_evt {
Signature · 1 line
2.7.4
#29 lore raw

Hi,

sorry for the long latency.

Quoted 110 lines · Oleksandr Andrushchenko
Quoted 75 lines

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side. If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though. It makes often things easier.

Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking. It's very hard to judge without the actual code.

thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#30 lore raw
Quoted 3 lines · Takashi Iwai

Hi,

sorry for the long latency.

Hi, no problem, thank you

Quoted 117 lines
Quoted 109 lines · Oleksandr Andrushchenko
Quoted 74 lines

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between
    backend and frontend the following changes are introduced in the
protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

Quoted 6 lines

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Excellent

Quoted 8 lines
Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Ok, makes sense

Quoted 9 lines
Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side. If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though. It makes often things easier.

Yes, probably I will put it by default

Quoted 6 lines
Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking. It's very hard to judge without the actual code.

Great, I will try to model these (hopefully late this week) and come back: maybe I won't need some of the protocol operations at all. I will update ASAP

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#31 lore raw

Hi,

Quoted 151 lines · Oleksandr Andrushchenko
Quoted 3 lines · Takashi Iwai

Hi,

sorry for the long latency.

Hi, no problem, thank you

Quoted 117 lines
Quoted 109 lines · Oleksandr Andrushchenko
Quoted 74 lines

Suppose that we negotiate from the frontend to the backend like

    int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like
    err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space.  In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly.  And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter.  That would be like:

    err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
{
    struct snd_interval *p = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); int min_rate = p->min;
    int max_rate = p->max;
    struct snd_interval t;
    int err;

    err = query_hw_param(PARM_RATE, &min_rate, &max_rate); if (err < 0)
        return err;

    t.min = min_rate;
    t.max = max_rate;
    t.openmin = t.openmax = 0;
    t.integer = 1;

    return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
{
    struct snd_interval *p = hw_param_interval(params, rule->var);
    int min_val = p->min;
    int max_val = p->max;
    struct snd_interval t;
    int err;

    err = query_hw_param(alsa_parm_to_xen_parm(rule->var), &min_val, &max_val);
    if (err < 0)
        return err;

    t.min = min_val;
    t.max = max_val;
    t.openmin = t.openmax = 0;
    t.integer = 1;

    return snd_interval_refine(p, &t);
}

Quoted 7 lines

and registering this via

    err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
      - add XENSND_OP_HW_PARAM_SET request to set one of the stream
        parameters: frame rate, sample rate, number of channels, buffer and period sizes
      - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
      - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

Quoted 6 lines

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Excellent

Quoted 8 lines
Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Ok, makes sense

Quoted 9 lines
Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side.  If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though.  It makes often things easier.

Yes, probably I will put it by default

Quoted 3 lines
Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

Quoted 6 lines
Quoted 3 lines

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking.  It's very hard to judge without the actual code.

Great, I will try to model these (hopefully late this week) and come back: maybe I won't need some of the protocol operations at all. I will update ASAP

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

From the previous changes to the protocol which I posted earlier I see that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations so I can move forward?

Quoted 5 lines
Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr

Thank you very much,
Oleksandr

[1] https://github.com/andr2000/linux/commit/2098a572f452d5247e538462dd1584369d3d1252
[2] https://github.com/andr2000/linux/commit/022163b2c39bf3c8cca099f5b34f599b824a045e
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#32 lore raw
Quoted 17 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#33 lore raw
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used, for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min. So, I feel I can drop that

2. Can I assume that min buffer size == period size and add such a constraint in the frontend driver?

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

instead of

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr
[1] https://github.com/andr2000/linux/commit/03e74fb23cf5baa2e252cd1e62fa9506decbca7e
[2] https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v2/include/xen/interface/io/sndif.h#L253
[3] https://elixir.bootlin.com/linux/latest/source/include/sound/pcm.h#L53
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#34 lore raw
Quoted 56 lines · Oleksandr Andrushchenko
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Quoted 6 lines

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used,
for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min.
So, I feel I can drop that

Actually with the hw_param query mechanism, this setup is moot. You can pass a fixed value that should be enough large for all cases there.

Quoted 3 lines

2. Can I assume that min buffer size == period size and add such a constraint
in the frontend driver?

The buffer sie == period size is a special case, i.e. periods=1, and this won't work most likely. It's used only for a case like PA deployment without the period interrupt. And it needs a special hw_params flag your driver doesn't deal with.

So for the sane setup, you can safely assume min_periods=2.

Quoted 5 lines

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

Quoted 8 lines

instead of

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Yeah, that's better, I suppose.

Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#35 lore raw
Quoted 63 lines · Takashi Iwai
Quoted 55 lines · Oleksandr Andrushchenko
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Quoted 6 lines

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used,
for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min.
So, I feel I can drop that

Quoted 3 lines

Actually with the hw_param query mechanism, this setup is moot. You can pass a fixed value that should be enough large for all cases there.

ok, so only buffer max as it is already defined

Quoted 9 lines
Quoted 3 lines

2. Can I assume that min buffer size == period size and add such a constraint
in the frontend driver?

The buffer sie == period size is a special case, i.e. periods=1, and this won't work most likely. It's used only for a case like PA deployment without the period interrupt. And it needs a special hw_params flag your driver doesn't deal with.

So for the sane setup, you can safely assume min_periods=2.

Thanks, will limit min to 2 periods then

Quoted 7 lines
Quoted 7 lines

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

instead of

Quoted 7 lines
Quoted 6 lines

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Yeah, that's better, I suppose.

Excellent

Quoted 2 lines

Takashi

Thank you very much for helping with this!!!
Oleksandr Andrushchenko
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

#36 lore raw
In reply to Takashi Iwai
Quoted 63 lines · Takashi Iwai
Quoted 55 lines · Oleksandr Andrushchenko
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Quoted 6 lines

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used,
for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min.
So, I feel I can drop that

Quoted 3 lines

Actually with the hw_param query mechanism, this setup is moot. You can pass a fixed value that should be enough large for all cases there.

ok, so only buffer max as it is already defined

Quoted 9 lines
Quoted 3 lines

2. Can I assume that min buffer size == period size and add such a constraint
in the frontend driver?

The buffer sie == period size is a special case, i.e. periods=1, and this won't work most likely. It's used only for a case like PA deployment without the period interrupt. And it needs a special hw_params flag your driver doesn't deal with.

So for the sane setup, you can safely assume min_periods=2.

Thanks, will limit min to 2 periods then

Quoted 7 lines
Quoted 7 lines

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

instead of

Quoted 7 lines
Quoted 6 lines

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Yeah, that's better, I suppose.

Excellent

Quoted 2 lines

Takashi

Thank you very much for helping with this!!!
Oleksandr Andrushchenko

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#37 lore raw
In reply to Oleksandr Andrushchenko
Quoted 56 lines · Oleksandr Andrushchenko
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Quoted 6 lines

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used,
for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min.
So, I feel I can drop that

Actually with the hw_param query mechanism, this setup is moot. You can pass a fixed value that should be enough large for all cases there.

Quoted 3 lines

2. Can I assume that min buffer size == period size and add such a constraint
in the frontend driver?

The buffer sie == period size is a special case, i.e. periods=1, and this won't work most likely. It's used only for a case like PA deployment without the period interrupt. And it needs a special hw_params flag your driver doesn't deal with.

So for the sane setup, you can safely assume min_periods=2.

Quoted 5 lines

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

Quoted 8 lines

instead of

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Yeah, that's better, I suppose.

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#38 lore raw
In reply to Takashi Iwai
Quoted 26 lines · Takashi Iwai
Quoted 16 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see
that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

Quoted 7 lines

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

You are correct, fixed this at [1]

Quoted 9 lines

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

Quoted 6 lines

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

Yes, let's have it step by step.
If you are ok with what we have at the moment then, after I implement both backend and frontend changes and confirm that protocol works, I will send v3 of the series (protocol changes).

Still there some questions:
1. Do we really need min buffer value as configuration [2]? I see no way it can be used, for instance at [3], we only have snd_pcm_hardware.buffer_bytes_max, but not min. So, I feel I can drop that

2. Can I assume that min buffer size == period size and add such a constraint in the frontend driver?

3. On backend side (ALSA), with current changes in the protocol I will call something like
int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *min, unsigned int *max)

instead of

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)

while servicing XENSND_OP_HW_PARAM_QUERY.XENSND_OP_HW_PARAM_CHANNELS. Does this make sense?

Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr
[1] https://github.com/andr2000/linux/commit/03e74fb23cf5baa2e252cd1e62fa9506decbca7e
[2] https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v2/include/xen/interface/io/sndif.h#L253
[3] https://elixir.bootlin.com/linux/latest/source/include/sound/pcm.h#L53

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#39 lore raw
In reply to Oleksandr Andrushchenko
Quoted 17 lines · Oleksandr Andrushchenko

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

Quoted 8 lines

From the previous changes to the protocol which I posted earlier I see that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations
so I can move forward?

This looks almost good through a quick glance.
But the mixture of SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_BUFFER_BYTES are likely confusing. The *_SIZE means in frames unit while *_BYTES means in bytes. You should align both PERIOD_ and BUFFER_ to the same units, i.e. either use SNDRV_PCM_HW_PARAM_PERIOD_BYTES and *_BUFFER_BYTES, or SNDRV_PCM_HW_PARAM_PERIOD_SIZE and *_BUFFER_SIZE.

Also, a slightly remaining concern is the use-case where hw_params is called multiple times. An application may call hw_free and hw_params freely, or even hw_params calls multiple times, in order to change the parameter.

If the backend needs to resolve some dependency between parameters (e.g. the available period size depends on the sample rate), the backend has to remember the previously passed parameters.

So, instead of passing a single parameter, you may extend the protocol always to pass the full (five) parameters, too.

OTOH, this can be considered to be a minor case, and the backend (e.g. PA) can likely support every possible combinations, so maybe a simpler code may be a better solution in the end.

thanks,

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#40 lore raw
In reply to Oleksandr Andrushchenko

Hi,

Quoted 151 lines · Oleksandr Andrushchenko
Quoted 3 lines · Takashi Iwai

Hi,

sorry for the long latency.

Hi, no problem, thank you

Quoted 117 lines
Quoted 109 lines · Oleksandr Andrushchenko
Quoted 74 lines

Suppose that we negotiate from the frontend to the backend like

    int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like
    err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space.  In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly.  And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter.  That would be like:

    err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
{
    struct snd_interval *p = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); int min_rate = p->min;
    int max_rate = p->max;
    struct snd_interval t;
    int err;

    err = query_hw_param(PARM_RATE, &min_rate, &max_rate); if (err < 0)
        return err;

    t.min = min_rate;
    t.max = max_rate;
    t.openmin = t.openmax = 0;
    t.integer = 1;

    return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
{
    struct snd_interval *p = hw_param_interval(params, rule->var);
    int min_val = p->min;
    int max_val = p->max;
    struct snd_interval t;
    int err;

    err = query_hw_param(alsa_parm_to_xen_parm(rule->var), &min_val, &max_val);
    if (err < 0)
        return err;

    t.min = min_val;
    t.max = max_val;
    t.openmin = t.openmax = 0;
    t.integer = 1;

    return snd_interval_refine(p, &t);
}

Quoted 7 lines

and registering this via

    err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
      - add XENSND_OP_HW_PARAM_SET request to set one of the stream
        parameters: frame rate, sample rate, number of channels, buffer and period sizes
      - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
      - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

Quoted 6 lines

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Excellent

Quoted 8 lines
Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Ok, makes sense

Quoted 9 lines
Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side.  If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though.  It makes often things easier.

Yes, probably I will put it by default

Quoted 3 lines
Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

Quoted 6 lines
Quoted 3 lines

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking.  It's very hard to judge without the actual code.

Great, I will try to model these (hopefully late this week) and come back: maybe I won't need some of the protocol operations at all. I will update ASAP

So, I tried to make a POC to stress the protocol changes and see what implementation of the HW parameter negotiation would look like.

Please find protocol changes at [1]:
- add XENSND_OP_HW_PARAM_QUERY request to read/update configuration space for the parameter given: request passes desired parameter interval and the response to this request returns min/max interval for the parameter to be used. Parameters supported by this request:
     - frame rate
     - sample rate
     - number of channels
     - buffer size
     - period size
 - add minimum buffer size to XenStore configuration

From the previous changes to the protocol which I posted earlier I see that XENSND_OP_HW_PARAM_SET is not really needed - removed.

The implementation in the PV frontend driver is at [2].

Takashi, could you please take a look at the above if it meets your expectations so I can move forward?

Quoted 5 lines
Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr

Thank you very much,
Oleksandr

[1] https://github.com/andr2000/linux/commit/2098a572f452d5247e538462dd1584369d3d1252
[2] https://github.com/andr2000/linux/commit/022163b2c39bf3c8cca099f5b34f599b824a045e

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#41 lore raw
In reply to Takashi Iwai
Quoted 3 lines · Takashi Iwai

Hi,

sorry for the long latency.

Hi, no problem, thank you

Quoted 117 lines
Quoted 109 lines · Oleksandr Andrushchenko
Quoted 74 lines

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between
    backend and frontend the following changes are introduced in the
protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

Quoted 6 lines

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Excellent

Quoted 8 lines
Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Ok, makes sense

Quoted 9 lines
Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side. If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though. It makes often things easier.

Yes, probably I will put it by default

Quoted 6 lines
Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking. It's very hard to judge without the actual code.

Great, I will try to model these (hopefully late this week) and come back: maybe I won't need some of the protocol operations at all. I will update ASAP

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#42 lore raw
In reply to Oleksandr Andrushchenko

Hi,

sorry for the long latency.

Quoted 110 lines · Oleksandr Andrushchenko
Quoted 75 lines

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Quoted 5 lines

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

This is exactly the purpose of hw constraint rule you'd need to add. The callback function gets called at each time the corresponding parameter is changed (or the change is asked) by applications.

The final parameter setup is done in hw_params PCM callback, but each fine-tuning / adjustment beforehand is done via hw constraints.

Quoted 4 lines

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine
how to do that. But what do I do if I run the backend as PulseAudio client?

This pretty depends on your implementation :)
I can imagine that the backend assumes a limited configuration depending on the backend application, e.g. PA can't handle the too short period.

Quoted 3 lines

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

Again it's up to your implementation of the backend side. If the backend can support such configuration (periods not aligned with buffer size), it's fine, of course.

I'd say it's safer to add this always, though. It makes often things easier.

Quoted 3 lines

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

I guess that'd be enough, but at best, give a rough version of your frontend driver code for checking. It's very hard to judge without the actual code.

thanks,

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#43 lore raw
In reply to Takashi Iwai
Quoted 121 lines · Takashi Iwai
Quoted 33 lines · Oleksandr Andrushchenko
Quoted 33 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 8 lines
Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

This is the most difficult part, apparently :)
There are lots of codes deploying the own hw constraints, but nothing is similar like your case.

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}
Quoted 7 lines

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Thank you so much for that detailed explanation and code sample!!! This is really great to see such a comprehensive response. Meanwhile, I did a yet another change to the protocol (please find attached) which will be added to those two found in this patch set already:
In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
     - add XENSND_OP_HW_PARAM_SET request to set one of the stream
       parameters: frame rate, sample rate, number of channels, buffer and period sizes
     - add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
     - add minimum buffer size to XenStore configuration

With this change:
1. Frontend sends XENSND_OP_HW_PARAM_SET to the backend in response to user space's snd_pcm_hw_params_set_XXX calls, using XenStore entries as initial configuration space (this is what returned on snd_pcm_hw_params_any)
2. Frontend uses snd_pcm_hw_rule_add to set the rules (for sample rate, format, number of channels, buffer and period sizes) as you described
above: querying is done with XENSND_OP_HW_PARAM_QUERY request
3. Finally, frontend issues XENSND_OP_OPEN request with all the negotiated configuration values

Questions:

1. For XENSND_OP_HW_PARAM_SET I will need a hook in the frontend driver so I can intercept snd_pcm_hw_params_set_XXX calls - is this available in ALSA?

2. From backend side, if it runs as ALSA client, it is almost 1:1 mapping for XENSND_OP_HW_PARAM_SET/snd_pcm_hw_params_set_XXX, so I can imagine how to do that. But what do I do if I run the backend as PulseAudio client?

3. Period size rules will not allow the check you mentioned before, e.g. require that buffer_size % period_size == 0). Can frontend driver assume that on its own? So, I simply add the rule regardless of what backend can?

4. Do you think the attached change together with the previous one ( which adds sync event) makes the protocol look good? Do we need any other change?

Quoted 2 lines

Takashi

Thank you very much for helping with this,
Oleksandr

Quoted 1 line

From 267fb5f74026b8313a54c47fcecdeb8c644f3257 Mon Sep 17 00:00:00 2001

From: Oleksandr Andrushchenko <[email protected]>
Date: Wed, 7 Mar 2018 10:21:20 +0200
Subject: [PATCH] sndif: add explicit back and front parameter negotiation

In order to provide explicit stream parameter negotiation between backend and frontend the following changes are introduced in the protocol:
- add XENSND_OP_HW_PARAM_SET request to set one of the stream
parameters: frame rate, sample rate, number of channels, buffer and period sizes
- add XENSND_OP_HW_PARAM_QUERY request to read a reduced configuration space for the parameter given: in the response to this request return min/max interval for the parameter given
- add minimum buffer size to XenStore configuration

Cc Konrad Rzeszutek Wilk <[email protected]>
Cc Takashi Iwai <[email protected]>
---
 xen/include/public/io/sndif.h | 127 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 120 insertions(+), 7 deletions(-)
xen/include/public/io/sndif.h +120 -7
index e38644423c0a..8036c5c2f212 100644
@@ -250,6 +250,11 @@
  *
  *      The maximum size in octets of the buffer to allocate per stream.
  *
+ * buffer-size-min
+ *      Values:         <uint32_t>
+ *
+ *      The minimum size in octets of the buffer to allocate per stream.
+ *
  *----------------------- Virtual sound card settings -------------------------
  * short-name
  *      Values:         <char[32]>
@@ -465,12 +470,20 @@
 #define XENSND_OP_MUTE                  6
 #define XENSND_OP_UNMUTE                7
 #define XENSND_OP_TRIGGER               8
+#define XENSND_OP_HW_PARAM_SET          9
+#define XENSND_OP_HW_PARAM_QUERY        10
 
 #define XENSND_OP_TRIGGER_START         0
 #define XENSND_OP_TRIGGER_PAUSE         1
 #define XENSND_OP_TRIGGER_STOP          2
 #define XENSND_OP_TRIGGER_RESUME        3
 
+#define XENSND_OP_HW_PARAM_FORMAT       0
+#define XENSND_OP_HW_PARAM_RATE         1
+#define XENSND_OP_HW_PARAM_BUFFER       2
+#define XENSND_OP_HW_PARAM_PERIOD       3
+#define XENSND_OP_HW_PARAM_CHANNELS     4
+
 /*
  ******************************************************************************
  *                                 EVENT CODES
@@ -503,6 +516,7 @@
 #define XENSND_FIELD_SAMPLE_RATES       "sample-rates"
 #define XENSND_FIELD_SAMPLE_FORMATS     "sample-formats"
 #define XENSND_FIELD_BUFFER_SIZE        "buffer-size"
+#define XENSND_FIELD_BUFFER_SIZE_MIN    "buffer-size-min"
 
 /* Stream type field values. */
 #define XENSND_STREAM_TYPE_PLAYBACK     "p"
@@ -828,28 +842,122 @@ struct xensnd_trigger_req {
 };
 
 /*
+ * Request stream configuration parameter selection:
+ *   Sound device configuration for a particular stream is a limited subset
+ *   of the multidimensional configuration available on XenStore, e.g.
+ *   once the frame rate has been selected there is a limited supported range
+ *   for sample rates becomes available (which might be the same set configured
+ *   on XenStore or less). For example, selecting 96kHz sample rate may limit
+ *   number of channels available for such configuration from 4 to 2 etc.
+ *   Thus, each call to XENSND_OP_SET_HW_PARAM will reduce configuration space
+ *   making it possible to iteratively get the final stream configuration,
+ *   used in XENSND_OP_OPEN request.
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |_OP_SET_HW_PARAM|    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                               value                               | 12
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * value - uint32_t, requested value of the parameter
+ * type - uint8_t, XENSND_OP_HW_PARAM_XXX value
+ */
+
+struct xensnd_set_hw_param_req {
+    uint32_t value;
+    uint8_t type;
+};
+
+/*
+ * Request stream configuration parameter interval: request interval of
+ *   supported values for the parameter given. See response format for this
+ *   request.
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _HW_PARAM_QUERY|    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, XENSND_OP_HW_PARAM_XXX value
+ */
+
+struct xensnd_query_hw_param_req {
+    uint8_t type;
+};
+
+/*
  *---------------------------------- Responses --------------------------------
  *
  * All response packets have the same length (32 octets)
  *
- * Response for all requests:
+ * All response packets have common header:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
  * |               id                |    operation   |    reserved    | 4
  * +----------------+----------------+----------------+----------------+
  * |                              status                               | 8
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 12
+ *
+ * id - uint16_t, copied from the request
+ * operation - uint8_t, XENSND_OP_* - copied from request
+ * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *
+ * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                                min                                | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                                max                                | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
  * |                             reserved                              | 32
  * +----------------+----------------+----------------+----------------+
  *
- * id - uint16_t, copied from the request
- * operation - uint8_t, XENSND_OP_* - copied from request
- * status - int32_t, response status, zero on success and -XEN_EXX on failure
- *
+ * min - uint32_t, minimum value of the parameter that can be used
+ * max - uint32_t, maximum value of the parameter that can be used
+ */
+
+struct xensnd_query_hw_param_resp {
+    uint32_t min;
+    uint32_t max;
+};
+
+/*
  *----------------------------------- Events ----------------------------------
  *
  * Events are sent via a shared page allocated by the front and propagated by
@@ -902,6 +1010,8 @@ struct xensnd_req {
         struct xensnd_open_req open;
         struct xensnd_rw_req rw;
         struct xensnd_trigger_req trigger;
+        struct xensnd_set_hw_param_req set_hw_param;
+        struct xensnd_query_hw_param_req query_hw_param;
         uint8_t reserved[24];
     } op;
 };
@@ -911,7 +1021,10 @@ struct xensnd_resp {
     uint8_t operation;
     uint8_t reserved;
     int32_t status;
-    uint8_t reserved1[24];
+    union {
+        struct xensnd_query_hw_param_resp hw_param;
+        uint8_t reserved1[24];
+    } resp;
 };
 
 struct xensnd_evt {
Signature · 1 line
2.7.4

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#44 lore raw
In reply to Oleksandr Andrushchenko
Quoted 34 lines · Oleksandr Andrushchenko
Quoted 34 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 8 lines
Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

This is the most difficult part, apparently :)
There are lots of codes deploying the own hw constraints, but nothing is similar like your case.

Suppose that we negotiate from the frontend to the backend like

	int query_hw_param(int parm, int *min_p, int *max_p);

so that you can call like

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);

This assumes that min_rate and max_rate were already filled by the values requested from frontend user-space. In query_hw_parm, the backend receives this range, checks it, and fills again the actually applicable range that satisfies the given range in return.

In that way, user-space will reduce the configuration space repeatedly. And at the last step, the configurator chooses the optimal values that fit in the given configuration space.

As mentioned in the previous post, in your driver at open, you'd need to add the hw constraint for each parameter. That would be like:

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_rate, NULL, -1);

and hw_rule_rate() would look like:

static int hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
	int min_rate = p->min;
	int max_rate = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(PARM_RATE, &min_rate, &max_rate);
	if (err < 0)
		return err;

	t.min = min_rate;
	t.max = max_rate;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

The above is simplified not to allow the open min/max and assume only integer, which should be enough for your cases, I suppose.

And the above function can be generalized like

static int hw_rule_interval(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)

{
	struct snd_interval *p =
		hw_param_interval(params, rule->var);
	int min_val = p->min;
	int max_val = p->max;
	struct snd_interval t;
	int err;

	err = query_hw_param(alsa_parm_to_xen_parm(rule->var),
			&min_val, &max_val);
	if (err < 0)
		return err;

	t.min = min_val;
	t.max = max_val;
	t.openmin = t.openmax = 0;
	t.integer = 1;

	return snd_interval_refine(p, &t);
}

and registering this via

	err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				  hw_rule_interval, NULL, -1);

In the above NULL can be referred in the callback via rule->private, if you need some closure in the function, too.

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#45 lore raw
In reply to Takashi Iwai
Quoted 30 lines · Takashi Iwai
Quoted 28 lines · Oleksandr Andrushchenko
Quoted 28 lines
Quoted 15 lines
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 8 lines
Quoted 6 lines

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?

The buffer, period, channels, rate and format are the basic parameters, and that should be enough for 99.9% cases.

Excellent, will use this set as the constraint entry. Just to clarify for the upcoming Xen sound protocol change:
the values in this constraint are not ALSA specific and could be used in implementation/OS agnostic Xen protocol.

Quoted 46 lines
Quoted 6 lines

I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

You don't have to list up all combinations of the parameters above at open time. For example, declaring min/max of each of them at open would suffice at first. (But this min/max might be even unnecessary if we implement the proper hw constraints. See below)

The rest fine-tuning is done via the hw constraints...

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

Quoted 3 lines

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Thank you very much for such a detailed explanation. Could you please give me an example of ALSA driver which code I can read in order to understand how it is supposed to be used, e.g. which meets the expectations we have for Xen PV sound driver?

Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 10 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Quoted 8 lines
Quoted 4 lines

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?

Well, what set at the open time is only the constraint "rule". And the rule is a function call, not necessarily static. The actual parameters are determined at hw_params call time, and this is called even repeatedly.

I need some time to think about all the above ;)

Quoted 8 lines
Quoted 3 lines

The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Again, the parameter setup pretty depends on the hardware, and in this case, the backend (and its communication).

Takashi

Thank you!
Oleksandr

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#46 lore raw
In reply to Oleksandr Andrushchenko
Quoted 29 lines · Oleksandr Andrushchenko
Quoted 26 lines
Quoted 16 lines
Quoted 9 lines
Quoted 7 lines
Quoted 5 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

Quoted 3 lines

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 6 lines

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?

The buffer, period, channels, rate and format are the basic parameters, and that should be enough for 99.9% cases.

Quoted 6 lines

I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

You don't have to list up all combinations of the parameters above at open time. For example, declaring min/max of each of them at open would suffice at first. (But this min/max might be even unnecessary if we implement the proper hw constraints. See below)

The rest fine-tuning is done via the hw constraints...

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 8 lines
Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

... and here comes the hw constraint into the play.

For each parameter change, for example, the frontend just passes the inquiry to the backend. The basis of the hw constraint is nothing but to reduce the range of the given parameter. It's either interval (range, used for period/buffer size or sample rate) or the list (for the format). When any parameter is changed, ALSA PCM core invokes the corresponding hw constraint function, and the function reduces the range. It's repeated until all parameters are set and settled down.

So, for your driver, the frontend just passes the hw constraint for each of basic 5 parameters to the backend. For example, at beginning, the hw constraint for the buffer size will pass the range (1,INTMAX).
Then the backend returns the range like (1024,65536). This already
gives users the min/max buffer size information. The similar procedure will be done for all other parameters.

In addition, you can put the implicit rule like the integer periods, which makes things easier.

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

Quoted 7 lines
Quoted 3 lines

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?

Well, what set at the open time is only the constraint "rule". And the rule is a function call, not necessarily static. The actual parameters are determined at hw_params call time, and this is called even repeatedly.

Quoted 3 lines

The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Again, the parameter setup pretty depends on the hardware, and in this case, the backend (and its communication).

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#47 lore raw
In reply to Takashi Iwai
Quoted 154 lines · Takashi Iwai
Quoted 142 lines · Oleksandr Andrushchenko
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
     snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 6 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

Quoted 3 lines

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Ok, if we go with a limited set of supported buffer/period sizes (and number of channels?), what could a constraint entry look like? E.g. [buffer, period, num_channels, xxx] What is that xxx in question? Sample rate, sample format, anything else? Or [buffer, period, num_channels, rate, format] is enough?
I am still thinking on having the above sent at run-time with a new protocol command, which I will call on .open, so I can apply the constraints where most of the drivers do. This way backend can also determine its capabilities at run-time and report those to the frontend, as a bonus eliminating the need for huge domain configuration file/XenStore entries.

Quoted 8 lines
Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Quoted 6 lines

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Yes, this is clear, the question here mostly was not *how* to set the constraints, but *where* to get those

Quoted 10 lines
Quoted 10 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Ok, did I understand you correctly that you see it as described above, e.g. backend communicates (limited) set of constraints to the frontend, so frontend sets these constraints at .open?
The way these are communicated could be either XenStore/ domain configuration or extension to the protocol, no preference from your side?

Quoted 2 lines

Takashi

Thank you very much for helping with this!
Oleksandr

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#48 lore raw
In reply to Oleksandr Andrushchenko
Quoted 144 lines · Oleksandr Andrushchenko
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
    snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 7 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

Quoted 10 lines

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

It depends. If we do limit the configuration intentionally to only some subsets that should suffice for most use cases, then the list would be relatively short.

Quoted 8 lines

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

The additional parameter setup can be done via hw_constraints. The hw constraint is basically a function call for each parameter change to narrow down the range of the given parameter.

snd_pcm_hw_constraint_integer() in the above is just an example. The actual function to adjust values can be freely written.

Quoted 11 lines

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 1 line
Quoted 5 lines
Quoted 3 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

But if the backend doesn't support fancy numbers like 3 channels? That's the same situation as buffer / periods. The frontend needs to know exactly what configuration the backend would allow.

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#49 lore raw
In reply to Takashi Iwai
Quoted 126 lines · Takashi Iwai
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
    snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

That is correct, but we try to be backend agnostic, though

Quoted 7 lines

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

The problem I see here is that at .open real HW driver already knows its constraints and can properly setup. So, in our case at open we should already have all the constraints available to the frontend as well.
That will lead to lots of text in domain configuration file if propagated via XenStore (e.g. you have to put all possible combinations of buffers/periods depending on number of channels, sample rates etc., you cannot use logic here as you can in a real HW driver, only values). So, such configuration doesn't seem to be an option here.

If we decide to negotiate the parameters, then it can't be done at .open stage as well, as at this moment we don't know stream parameters yet, e.g. we don't know the number of channels, PCM format etc., so we cannot explain to the backend what we want. Thus, it seems that we need to move the negotiation to .hw_params callback where stream properties are known. But this leaves the only option to ask the backend if it can handle the requested buffer/period and other parameters or not... This is what I do now :(

Am I missing something here?

Quoted 4 lines

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Thank you, this should be up to the one who sets up the domain configuration. Taking into account embedded nature of our use-cases this is almost always doable, as these are defined at system design time, e.g. we define number of channels and their properties depending on domain functionality and needs.

Quoted 4 lines

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

But if backend can implement some fancy stuff with software mixing etc... This is why I didn't limit on that

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#50 lore raw
In reply to Oleksandr Andrushchenko
Quoted 124 lines · Oleksandr Andrushchenko
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
   snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

Quoted 7 lines

You are right, I saw those in other drivers

Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Heh, that very much depends on the hardware -- and in this case, on the implementation of the backend.

Practically seen, the buffer and the period size setups are mandatory, yes. Here is the question whether you want to limit them by list (e.g. read via some XENSND_* protocol), or negotiate the size at each hw_params setup (e.g. getting only min/max at open, and at each hw_params call, negotiate with the backend for period and buffer size changes).

The format, the channels and the sample rate are already included in snd_pcm_hardware setup, so this should be OK, unless they have implicit limitations with each other (e.g. some format is available only under some rate).

Maybe the channels need to be revisited, though; usually you can't handle all number of channels between min and max but only even numbers or such.

thanks,

Takashi

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#51 lore raw
In reply to Takashi Iwai
Quoted 119 lines · Takashi Iwai
Quoted 110 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:

Quoted 3 lines
   snd_pcm_hw_constraint_integer(substream->runtime,
	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

You are right, I saw those in other drivers

Quoted 4 lines

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

Could you please give me a hint of what those restrictions could look like? E.g. map of supported buffer/period sizes, what else?

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 38 lines
Quoted 38 lines
Quoted 3 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 33 lines
Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-)

Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#52 lore raw
In reply to Oleksandr Andrushchenko
Quoted 111 lines · Oleksandr Andrushchenko
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested.
And it is up to backend to decide.

Quoted 1 line

Does that sound reasonable or you have something else on your mind?

Usually the hardware driver knows already the restrictions and sets up the rules via hw constraints at open callback. There are lots of snd_pcm_hw_constraint_*() helpers (and the relevant ones) to give more additional rules for the parameter restrictions. For example, if the periods must be aligned with the buffer size (i.e. buffer_size % period_size == 0) as on many devices, you can call like:
snd_pcm_hw_constraint_integer(substream->runtime,

	SNDRV_PCM_HW_PARAM_PERIODS);

in the open callback.

And, now an open question for XEN comes: what kind of restriction should be applied to the frontend. Obviously it depends on the backend, so there must be some communication, and the restriction must be propagated at open, i.e. *before* actually hw_params is performed.

thanks,

Takashi

Quoted 47 lines
Quoted 5 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 39 lines
Quoted 39 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

   xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
   1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#53 lore raw
In reply to Takashi Iwai
Quoted 94 lines · Takashi Iwai
Quoted 78 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 8 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

Quoted 6 lines

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

Well, so what would a real HW driver do in that case?
My understanding is that in this case SW can still request
something that HW can't do and driver will reject such configurations. In my case, the role of that HW driver code which judges on if configuration is acceptable just runs on the backend side, e.g. frontend driver is just a proxy which talks to the backend to check if the backend can do what requested. And it is up to backend to decide.

Does that sound reasonable or you have something else on your mind?

Quoted 4 lines

thanks,

Takashi

Thank you,
Oleksandr

Quoted 33 lines
Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

   xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
   1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#54 lore raw
In reply to Oleksandr Andrushchenko
Quoted 80 lines · Oleksandr Andrushchenko
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 9 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Quoted 9 lines

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend
capabilities. E.g., we usually set buffer sizes to match real HW at backend side
if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

OK, that restricts minimally. So at least there is the restriction / communication about the buffer size. But it merely means the *maximum* buffer size is set. Application may request still any shorter value than that.

And, there are no restriction about period sizes (except for the periods_max, which is calculated from buffer_bytes_max). That is, application may request any size between them; and it expects the wake up by this value.

I think that's a still missing stone in the design.

thanks,

Takashi

Quoted 33 lines
Quoted 33 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 6 lines

[1]
https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2]
https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#55 lore raw
In reply to Takashi Iwai
Quoted 59 lines · Takashi Iwai
Quoted 46 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

Quoted 4 lines

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Thank you, the driver is at [1]

Quoted 9 lines

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

Quoted 5 lines

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

Well, the frontend is not that free to decide as it might look like, e.g. please see [2]. Basically part of hw_params configuration is written to XenStore [3] as a part of domain configuration which depends on system/backend capabilities. E.g., we usually set buffer sizes to match real HW at backend side if we use ALSA and we have more freedom if we use PulseAudio there. Finally, if backend decides that the requested buffer/period sizes are not acceptable it will reject such a configuration.

Quoted 34 lines

thanks,

Takashi

Quoted 28 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

  xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[1] https://github.com/andr2000/linux/commits/tiwai_sound_for_next_pv_snd_upstream_v1
[2] https://github.com/andr2000/linux/blob/tiwai_sound_for_next_pv_snd_upstream_v1/sound/xen/xen_snd_front_cfg.c#L239
[3] https://www.mail-archive.com/[email protected]/msg124356.html

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#56 lore raw
In reply to Oleksandr Andrushchenko
Quoted 47 lines · Oleksandr Andrushchenko

From: Oleksandr Andrushchenko <[email protected]>

Hi, all!

Foreword
========

This change is aimed to add support for explicit back and front synchronization during playback and capture in response to comments raised during upstream attempt of the para-virtualized sound frontend driver for Xen [1], [2] and gather opinions from the relevant communities (ALSA, Xen) on the change.

The relevant backend is implemented as a user-space application [3] and uses accompanying helper library [4].

Both frontend driver and backend were tested on real HW running Xen hypervisor (Renesas R-Car ARM based H3/M3 boards, x86) to make sure the proposed solution does work.

Rationale
=========

During the first attempt to upstream the Linux front driver [5] number of comments and concerns were raised, one of the biggest flaws in the design were questioned by both Clemens Ladisch [6] and Takashi Sakamoto [7]: the absence of synchronization between frontend and backend during capture/playback. Two options were discussed:

“In design of ALSA PCM core, drivers are expected to synchronize to actual hardwares for semi-realtime data transmission. The synchronization is done by two points:
1) Interrupts to respond events from actual hardwares.
2) Positions of actual data transmission in any serial sound interfaces of actual hardwares.
“

and finally a change to the existing protocol was suggested:

“In 'include/xen/interface/io/sndif.h', there's no functionalities I described the above:
1. notifications from DomU to Dom0 about the size of period for interrupts from actual hardwares. Or no way from Dom0 to DomU about the configured size of the period.
2. notifications of the interrupts from actual hardwares to DomU.”

Quoted 11 lines

This is implemented as a change to the sndif protocol and allows removing period emulation:
1. Introduced a new event channel from back to front
2. New event with number of bytes played/captured (XENSND_EVT_CUR_POS, to be used for sending snd_pcm_period_elapsed at frontend (in Linux implementation). Sent in bytes, not frames to make the protocol generic and consistent)
3. New request for playback/capture control (XENSND_OP_TRIGGER) with start/pause/stop/resume sub-ops
4. Playback/capture buffer size is set on the backend side via XENSND_FIELD_BUFFER_SIZE XenStore entry

So the new addition looks serving well for the point that was suggested in the previous thread. As I see no frontend driver implementation, it's hard to tell about the details, but through a quick glance, the protocol should be OK.

Now, going back to a big picture: I took a look at the previous patchset, and wonder what about the hw_params setup. Basically the (frontend) application may request any size of buffer and periods unless the driver sets up the hw constraints at open callback. That is, app may request even the 16 bytes of buffer size, or 1GB of buffer. The periods aren't always integer, so it can be 1024 bytes of buffer with 400 bytes of periods.

And, if such parameters are set up freely in the frontend side, how the backend is supposed to behave? From the frontend POV, it expects receiving the wakeup/notification at each period processing (e.g. 400 bytes in the case above). But, the backend is another application, so how would it work for such requirements? Am I missing something here?

thanks,

Takashi

Quoted 15 lines

Waiting for your valuable comments,

Thank you,
Oleksandr

[1] https://github.com/andr2000/linux/commits/snd_upstream_v1
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/xen/interface/io/sndif.h
[3] https://github.com/xen-troops/snd_be
[4] https://github.com/xen-troops/libxenbe
[5] https://lkml.org/lkml/2017/8/7/363
[6] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123617.html
[7] http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/123744.html

Quoted 14 lines

Oleksandr Andrushchenko (2):
sndif: introduce protocol version
sndif: add explicit back and front synchronization

 xen/include/public/io/sndif.h | 173 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 3 deletions(-)
Signature · 6 lines
2.7.4

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel