Skip to content

Commit 58f9d80

Browse files
Oleksandr AndrushchenkoBoris Ostrovsky
authored andcommitted
ALSA: xen-front: Use Xen common shared buffer implementation
Use page directory based shared buffer implementation now available as common code for Xen frontend drivers. Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
1 parent 5641f19 commit 58f9d80

File tree

7 files changed

+84
-261
lines changed

7 files changed

+84
-261
lines changed

sound/xen/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ config SND_XEN_FRONTEND
55
depends on XEN
66
select SND_PCM
77
select XEN_XENBUS_FRONTEND
8+
select XEN_FRONT_PGDIR_SHBUF
89
help
910
Choose this option if you want to enable a para-virtualized
1011
frontend sound driver for Xen guest OSes.

sound/xen/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
snd_xen_front-objs := xen_snd_front.o \
44
xen_snd_front_cfg.o \
55
xen_snd_front_evtchnl.o \
6-
xen_snd_front_shbuf.o \
76
xen_snd_front_alsa.o
87

98
obj-$(CONFIG_SND_XEN_FRONTEND) += snd_xen_front.o

sound/xen/xen_snd_front.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
#include <xen/xen.h>
1717
#include <xen/xenbus.h>
1818

19+
#include <xen/xen-front-pgdir-shbuf.h>
1920
#include <xen/interface/io/sndif.h>
2021

2122
#include "xen_snd_front.h"
2223
#include "xen_snd_front_alsa.h"
2324
#include "xen_snd_front_evtchnl.h"
24-
#include "xen_snd_front_shbuf.h"
2525

2626
static struct xensnd_req *
2727
be_stream_prepare_req(struct xen_snd_front_evtchnl *evtchnl, u8 operation)
@@ -82,7 +82,7 @@ int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl,
8282
}
8383

8484
int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl,
85-
struct xen_snd_front_shbuf *sh_buf,
85+
struct xen_front_pgdir_shbuf *shbuf,
8686
u8 format, unsigned int channels,
8787
unsigned int rate, u32 buffer_sz,
8888
u32 period_sz)
@@ -99,7 +99,8 @@ int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl,
9999
req->op.open.pcm_rate = rate;
100100
req->op.open.buffer_sz = buffer_sz;
101101
req->op.open.period_sz = period_sz;
102-
req->op.open.gref_directory = xen_snd_front_shbuf_get_dir_start(sh_buf);
102+
req->op.open.gref_directory =
103+
xen_front_pgdir_shbuf_get_dir_start(shbuf);
103104
mutex_unlock(&evtchnl->ring_io_lock);
104105

105106
ret = be_stream_do_io(evtchnl);

sound/xen/xen_snd_front.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
struct xen_snd_front_card_info;
1717
struct xen_snd_front_evtchnl;
1818
struct xen_snd_front_evtchnl_pair;
19-
struct xen_snd_front_shbuf;
19+
struct xen_front_pgdir_shbuf;
2020
struct xensnd_query_hw_param;
2121

2222
struct xen_snd_front_info {
@@ -35,7 +35,7 @@ int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl,
3535
struct xensnd_query_hw_param *hw_param_resp);
3636

3737
int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl,
38-
struct xen_snd_front_shbuf *sh_buf,
38+
struct xen_front_pgdir_shbuf *shbuf,
3939
u8 format, unsigned int channels,
4040
unsigned int rate, u32 buffer_sz,
4141
u32 period_sz);

sound/xen/xen_snd_front_alsa.c

Lines changed: 77 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,24 @@
1515
#include <sound/pcm_params.h>
1616

1717
#include <xen/xenbus.h>
18+
#include <xen/xen-front-pgdir-shbuf.h>
1819

1920
#include "xen_snd_front.h"
2021
#include "xen_snd_front_alsa.h"
2122
#include "xen_snd_front_cfg.h"
2223
#include "xen_snd_front_evtchnl.h"
23-
#include "xen_snd_front_shbuf.h"
2424

2525
struct xen_snd_front_pcm_stream_info {
2626
struct xen_snd_front_info *front_info;
2727
struct xen_snd_front_evtchnl_pair *evt_pair;
28-
struct xen_snd_front_shbuf sh_buf;
28+
29+
/* This is the shared buffer with its backing storage. */
30+
struct xen_front_pgdir_shbuf shbuf;
31+
u8 *buffer;
32+
size_t buffer_sz;
33+
int num_pages;
34+
struct page **pages;
35+
2936
int index;
3037

3138
bool is_open;
@@ -214,12 +221,20 @@ static void stream_clear(struct xen_snd_front_pcm_stream_info *stream)
214221
stream->out_frames = 0;
215222
atomic_set(&stream->hw_ptr, 0);
216223
xen_snd_front_evtchnl_pair_clear(stream->evt_pair);
217-
xen_snd_front_shbuf_clear(&stream->sh_buf);
224+
memset(&stream->shbuf, 0, sizeof(stream->shbuf));
225+
stream->buffer = NULL;
226+
stream->buffer_sz = 0;
227+
stream->pages = NULL;
228+
stream->num_pages = 0;
218229
}
219230

220231
static void stream_free(struct xen_snd_front_pcm_stream_info *stream)
221232
{
222-
xen_snd_front_shbuf_free(&stream->sh_buf);
233+
xen_front_pgdir_shbuf_unmap(&stream->shbuf);
234+
xen_front_pgdir_shbuf_free(&stream->shbuf);
235+
if (stream->buffer)
236+
free_pages_exact(stream->buffer, stream->buffer_sz);
237+
kfree(stream->pages);
223238
stream_clear(stream);
224239
}
225240

@@ -421,30 +436,67 @@ static int alsa_close(struct snd_pcm_substream *substream)
421436
return 0;
422437
}
423438

439+
static int shbuf_setup_backstore(struct xen_snd_front_pcm_stream_info *stream,
440+
size_t buffer_sz)
441+
{
442+
int i;
443+
444+
stream->buffer = alloc_pages_exact(stream->buffer_sz, GFP_KERNEL);
445+
if (!stream->buffer)
446+
return -ENOMEM;
447+
448+
stream->buffer_sz = buffer_sz;
449+
stream->num_pages = DIV_ROUND_UP(stream->buffer_sz, PAGE_SIZE);
450+
stream->pages = kcalloc(stream->num_pages, sizeof(struct page *),
451+
GFP_KERNEL);
452+
if (!stream->pages)
453+
return -ENOMEM;
454+
455+
for (i = 0; i < stream->num_pages; i++)
456+
stream->pages[i] = virt_to_page(stream->buffer + i * PAGE_SIZE);
457+
458+
return 0;
459+
}
460+
424461
static int alsa_hw_params(struct snd_pcm_substream *substream,
425462
struct snd_pcm_hw_params *params)
426463
{
427464
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
465+
struct xen_snd_front_info *front_info = stream->front_info;
466+
struct xen_front_pgdir_shbuf_cfg buf_cfg;
428467
int ret;
429468

430469
/*
431470
* This callback may be called multiple times,
432471
* so free the previously allocated shared buffer if any.
433472
*/
434473
stream_free(stream);
474+
ret = shbuf_setup_backstore(stream, params_buffer_bytes(params));
475+
if (ret < 0)
476+
goto fail;
435477

436-
ret = xen_snd_front_shbuf_alloc(stream->front_info->xb_dev,
437-
&stream->sh_buf,
438-
params_buffer_bytes(params));
439-
if (ret < 0) {
440-
stream_free(stream);
441-
dev_err(&stream->front_info->xb_dev->dev,
442-
"Failed to allocate buffers for stream with index %d\n",
443-
stream->index);
444-
return ret;
445-
}
478+
memset(&buf_cfg, 0, sizeof(buf_cfg));
479+
buf_cfg.xb_dev = front_info->xb_dev;
480+
buf_cfg.pgdir = &stream->shbuf;
481+
buf_cfg.num_pages = stream->num_pages;
482+
buf_cfg.pages = stream->pages;
483+
484+
ret = xen_front_pgdir_shbuf_alloc(&buf_cfg);
485+
if (ret < 0)
486+
goto fail;
487+
488+
ret = xen_front_pgdir_shbuf_map(&stream->shbuf);
489+
if (ret < 0)
490+
goto fail;
446491

447492
return 0;
493+
494+
fail:
495+
stream_free(stream);
496+
dev_err(&front_info->xb_dev->dev,
497+
"Failed to allocate buffers for stream with index %d\n",
498+
stream->index);
499+
return ret;
448500
}
449501

450502
static int alsa_hw_free(struct snd_pcm_substream *substream)
@@ -476,7 +528,7 @@ static int alsa_prepare(struct snd_pcm_substream *substream)
476528
sndif_format = ret;
477529

478530
ret = xen_snd_front_stream_prepare(&stream->evt_pair->req,
479-
&stream->sh_buf,
531+
&stream->shbuf,
480532
sndif_format,
481533
runtime->channels,
482534
runtime->rate,
@@ -556,10 +608,10 @@ static int alsa_pb_copy_user(struct snd_pcm_substream *substream,
556608
{
557609
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
558610

559-
if (unlikely(pos + count > stream->sh_buf.buffer_sz))
611+
if (unlikely(pos + count > stream->buffer_sz))
560612
return -EINVAL;
561613

562-
if (copy_from_user(stream->sh_buf.buffer + pos, src, count))
614+
if (copy_from_user(stream->buffer + pos, src, count))
563615
return -EFAULT;
564616

565617
return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
@@ -571,10 +623,10 @@ static int alsa_pb_copy_kernel(struct snd_pcm_substream *substream,
571623
{
572624
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
573625

574-
if (unlikely(pos + count > stream->sh_buf.buffer_sz))
626+
if (unlikely(pos + count > stream->buffer_sz))
575627
return -EINVAL;
576628

577-
memcpy(stream->sh_buf.buffer + pos, src, count);
629+
memcpy(stream->buffer + pos, src, count);
578630

579631
return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
580632
}
@@ -586,14 +638,14 @@ static int alsa_cap_copy_user(struct snd_pcm_substream *substream,
586638
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
587639
int ret;
588640

589-
if (unlikely(pos + count > stream->sh_buf.buffer_sz))
641+
if (unlikely(pos + count > stream->buffer_sz))
590642
return -EINVAL;
591643

592644
ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count);
593645
if (ret < 0)
594646
return ret;
595647

596-
return copy_to_user(dst, stream->sh_buf.buffer + pos, count) ?
648+
return copy_to_user(dst, stream->buffer + pos, count) ?
597649
-EFAULT : 0;
598650
}
599651

@@ -604,14 +656,14 @@ static int alsa_cap_copy_kernel(struct snd_pcm_substream *substream,
604656
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
605657
int ret;
606658

607-
if (unlikely(pos + count > stream->sh_buf.buffer_sz))
659+
if (unlikely(pos + count > stream->buffer_sz))
608660
return -EINVAL;
609661

610662
ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count);
611663
if (ret < 0)
612664
return ret;
613665

614-
memcpy(dst, stream->sh_buf.buffer + pos, count);
666+
memcpy(dst, stream->buffer + pos, count);
615667

616668
return 0;
617669
}
@@ -622,10 +674,10 @@ static int alsa_pb_fill_silence(struct snd_pcm_substream *substream,
622674
{
623675
struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
624676

625-
if (unlikely(pos + count > stream->sh_buf.buffer_sz))
677+
if (unlikely(pos + count > stream->buffer_sz))
626678
return -EINVAL;
627679

628-
memset(stream->sh_buf.buffer + pos, 0, count);
680+
memset(stream->buffer + pos, 0, count);
629681

630682
return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
631683
}

0 commit comments

Comments
 (0)