* Re: Kernel 4.17.4 lockup
From: H.J. Lu @ 2018-07-23 14:51 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Dave Hansen, Dave Jones, H. Peter Anvin, LKML, Andy Lutomirski,
Mel Gorman, Andrew Morton, Rik van Riel, Minchan Kim
In-Reply-To: <88CBCB04-43F6-4353-82F7-20A67AD49B65@amacapital.net>
On Fri, Jul 20, 2018 at 2:35 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>
>> On Jul 16, 2018, at 6:05 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>>> On Fri, Jul 13, 2018 at 7:08 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>>> I'm not at all convinced that this is the problem, but the series here
>>> will give a better diagnostic if the issue really is an IRQ stack
>>> overflow:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git/log/?h=x86/guard_pages
>>>
>>
>> This kernel won't boot with this configure file.
>
> Bah humbug. You’ll need to turn KASAN off (and maybe even compile it out entirely) if you want to test this. I need to bug the KASAN folks to unbreak their interaction with stacks in vmap space. It’s been broken literally forever, but I keep incorrectly imagining that it’s been fixed already.
>
This particular kernel oops has been fixed by kernel 4.17.7. But now
I am running into
another kernel oops:
https://bugzilla.redhat.com/show_bug.cgi?id=1597559
--
H.J.
^ permalink raw reply
* Fault injection stacktrace filter for x86-64?
From: Gal Pressman @ 2018-07-23 14:49 UTC (permalink / raw)
To: linux-kernel
According to commit [1], dwarf2 unwinder had some issues that prevented the
fault injection stacktrace filter from working on x86-64.
Does anyone know whether this issue still exists 11 years later?
Are there any objections to revert this patch?
Gal
[1] 6d690dcac92a ("fault injection: disable stacktrace filter for x86-64")
^ permalink raw reply
* Re: [PATCH 1/3] iio: adc: add support for mcp3911
From: Jonathan Cameron @ 2018-07-23 14:55 UTC (permalink / raw)
To: Marcus Folkesson
Cc: Jonathan Cameron, Peter Meerwald-Stadler, Kent Gustavsson,
Hartmut Knaack, Lars-Peter Clausen, Rob Herring, Mark Rutland,
linux-iio, devicetree, linux-kernel, Mark Brown
In-Reply-To: <20180722190051.GB27516@gmail.com>
On Sun, 22 Jul 2018 21:00:51 +0200
Marcus Folkesson <marcus.folkesson@gmail.com> wrote:
> Hi Jonathan,
>
> Thanks, all good catches.
>
> On Sun, Jul 22, 2018 at 09:08:38AM +0100, Jonathan Cameron wrote:
> > On Sat, 21 Jul 2018 23:19:48 +0200 (CEST)
> > Peter Meerwald-Stadler <pmeerw@pmeerw.net> wrote:
> >
> > > Hello,
> > >
> > > > MCP3911 is a dual channel Analog Front End (AFE) containing two
> > > > synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> > >
> > > some comments below...
> >
> > +CC Mark for the unusual SPI addressing stuff. I'm mostly interested in what
> > precedent there is for bindings etc.
> >
>
> Yep, I'm not entirely sure that the SPI framework can handle multiple
> clients on the same CS.
> The reason why we created device-addr is that the chip supports that and
> may have hardcoded chip address from factory.
> The chip address is also part of the protocol so we have to specify it.
It will certainly be 'interesting' if we ever try to support it.
>
...
...
> > > > +static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len)
> > > > +{
> > > > + dev_dbg(&adc->spi->dev, "Writing 0x%x to register 0x%x\n", val, reg);
> > > > +
> > > > + cpu_to_be32s(&val);
> > > > + val >>= (3-len)*8;
> > Hmm. It might be worth considering regmap here to handle all this stuff for
> > you rather than re rolling the same stuff.
> >
>
> We were looking at regmap, but it does not seems to support registers of
> different size.
> This chip has register values of 8, 16 and 24 bits.
Fair enough. I thought we were really looking at autoincrement, of
the address for a fixed sized register - which is fine in regmap.
Those wider registers are described as having ADDR and ADDR+1 etc.
>
> > > > + val |= REG_WRITE(reg, adc->dev_addr);
> > > > +
> > > > + return spi_write(adc->spi, &val, len+1);
> > > > +}
> > > > +
> > > > +
> > > > +static int mcp3911_read_raw(struct iio_dev *indio_dev,
> > > > + struct iio_chan_spec const *channel, int *val,
> > > > + int *val2, long mask)
> > > > +{
> > > > + struct mcp3911 *adc = iio_priv(indio_dev);
> > > > + int ret = -EINVAL;
> > > > +
> > > > + mutex_lock(&adc->lock);
> > > > + switch (mask) {
> > > > + case IIO_CHAN_INFO_RAW:
> > > > + ret = mcp3911_read(adc,
> > > > + MCP3911_CHANNEL(channel->channel), val, 3);
> > > > + if (ret)
> > > > + goto out;
> > > > +
> > > > + ret = IIO_VAL_INT;
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_OFFSET:
> > > > + ret = mcp3911_read(adc,
> > > > + MCP3911_OFFCAL(channel->channel), val, 3);
> > > > + if (ret)
> > > > + goto out;
> > > > +
> > > > + ret = IIO_VAL_INT;
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_HARDWAREGAIN:
> > > > + ret = mcp3911_get_hwgain(adc, channel->channel, val);
> >
> > I'm not convinced it's useful to expose this as it right control for this
> > is scale.
> >
>
> Hmm, all other drivers that are using HARDWAREGAIN (ina2xx-adc, stx104 +
> a few more that are not ADC:s) are, what I can tell, exposing it.
>
> But maybe it should'nt.
Yup, as ever things are a bit messy. However, best to not expose it unless
there is a very good reason.
> > > > +
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_HARDWAREGAIN:
> >
> > Default choice (by precedent) is to control variable gain
> > front ends via the scale parameter. Hardware gain
> > is not meant to have any 'visible' impact on the output
> > value - most commonly used when the thing we are measuring
> > is not amplitude of anything.
>
> Hmm, Ok. I'm not sure I understand how hardware gain is supposed to work
> then.
For this use case it isn't.
> Maybe I just remove it.
That's the best plan.
...
> > > > +
> > > > +static int mcp3911_config_of(struct mcp3911 *adc)
> > > > +{
> > > > + u32 configreg;
> > > > + u32 statuscomreg;
> > > > + int ret;
> > > > +
> > > > + of_property_read_u32(adc->np, "device-addr", &adc->dev_addr);
> > This is 'interesting' - I wonder if there is any precedence for it.
> >
>
> I guess we still need it since the device may have a hardcoded (from
> factory) address that we need to deal with.
Fair enough. Still good to hear from Mark on whether there are other similar
devices so the binding can be consistent.
> > > > +
> > > > + of_property_read_u32(adc->np, "ch0-width", &adc->width[0]);
> > > > + switch (adc->width[0]) {
> > > > + case 24:
> > > > + statuscomreg &= ~MCP3911_STATUSCOM_CH0_24WIDTH;
> > > > + dev_dbg(&adc->spi->dev, "set channel 0 into 24bit mode\n");
> > > > + break;
> > > > + case 16:
> > > > + statuscomreg |= MCP3911_STATUSCOM_CH0_24WIDTH;
> > > > + dev_dbg(&adc->spi->dev, "set channel 0 into 16bit mode\n");
> > > > + break;
> > > > + default:
> > > > + adc->width[0] = 24;
> > > > + dev_info(&adc->spi->dev, "invalid width for channel 0. Use 24bit.\n");
> > > > + break;
> > > > + }
> > This feels like something that isn't really a dt choice, as it's not down to
> > wiring but rather down to precision desired.
>
> You are right. I will remove them and stick to 24bit width.
>
That's the easiest option. If anyone 'really' wants 16bit we'll figure it out
later.
..
Thanks
Jonathan
^ permalink raw reply
* Re: [PATCH 1/3] iio: adc: add support for mcp3911
From: Jonathan Cameron @ 2018-07-23 14:55 UTC (permalink / raw)
To: Marcus Folkesson
Cc: Jonathan Cameron, Peter Meerwald-Stadler, Kent Gustavsson,
Hartmut Knaack, Lars-Peter Clausen, Rob Herring, Mark Rutland,
linux-iio, devicetree, linux-kernel, Mark Brown
In-Reply-To: <20180722190051.GB27516@gmail.com>
On Sun, 22 Jul 2018 21:00:51 +0200
Marcus Folkesson <marcus.folkesson@gmail.com> wrote:
> Hi Jonathan,
>
> Thanks, all good catches.
>
> On Sun, Jul 22, 2018 at 09:08:38AM +0100, Jonathan Cameron wrote:
> > On Sat, 21 Jul 2018 23:19:48 +0200 (CEST)
> > Peter Meerwald-Stadler <pmeerw@pmeerw.net> wrote:
> >
> > > Hello,
> > >
> > > > MCP3911 is a dual channel Analog Front End (AFE) containing two
> > > > synchronous sampling delta-sigma Analog-to-Digital Converters (ADC).
> > >
> > > some comments below...
> >
> > +CC Mark for the unusual SPI addressing stuff. I'm mostly interested in what
> > precedent there is for bindings etc.
> >
>
> Yep, I'm not entirely sure that the SPI framework can handle multiple
> clients on the same CS.
> The reason why we created device-addr is that the chip supports that and
> may have hardcoded chip address from factory.
> The chip address is also part of the protocol so we have to specify it.
It will certainly be 'interesting' if we ever try to support it.
>
...
...
> > > > +static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len)
> > > > +{
> > > > + dev_dbg(&adc->spi->dev, "Writing 0x%x to register 0x%x\n", val, reg);
> > > > +
> > > > + cpu_to_be32s(&val);
> > > > + val >>= (3-len)*8;
> > Hmm. It might be worth considering regmap here to handle all this stuff for
> > you rather than re rolling the same stuff.
> >
>
> We were looking at regmap, but it does not seems to support registers of
> different size.
> This chip has register values of 8, 16 and 24 bits.
Fair enough. I thought we were really looking at autoincrement, of
the address for a fixed sized register - which is fine in regmap.
Those wider registers are described as having ADDR and ADDR+1 etc.
>
> > > > + val |= REG_WRITE(reg, adc->dev_addr);
> > > > +
> > > > + return spi_write(adc->spi, &val, len+1);
> > > > +}
> > > > +
> > > > +
> > > > +static int mcp3911_read_raw(struct iio_dev *indio_dev,
> > > > + struct iio_chan_spec const *channel, int *val,
> > > > + int *val2, long mask)
> > > > +{
> > > > + struct mcp3911 *adc = iio_priv(indio_dev);
> > > > + int ret = -EINVAL;
> > > > +
> > > > + mutex_lock(&adc->lock);
> > > > + switch (mask) {
> > > > + case IIO_CHAN_INFO_RAW:
> > > > + ret = mcp3911_read(adc,
> > > > + MCP3911_CHANNEL(channel->channel), val, 3);
> > > > + if (ret)
> > > > + goto out;
> > > > +
> > > > + ret = IIO_VAL_INT;
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_OFFSET:
> > > > + ret = mcp3911_read(adc,
> > > > + MCP3911_OFFCAL(channel->channel), val, 3);
> > > > + if (ret)
> > > > + goto out;
> > > > +
> > > > + ret = IIO_VAL_INT;
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_HARDWAREGAIN:
> > > > + ret = mcp3911_get_hwgain(adc, channel->channel, val);
> >
> > I'm not convinced it's useful to expose this as it right control for this
> > is scale.
> >
>
> Hmm, all other drivers that are using HARDWAREGAIN (ina2xx-adc, stx104 +
> a few more that are not ADC:s) are, what I can tell, exposing it.
>
> But maybe it should'nt.
Yup, as ever things are a bit messy. However, best to not expose it unless
there is a very good reason.
> > > > +
> > > > + break;
> > > > +
> > > > + case IIO_CHAN_INFO_HARDWAREGAIN:
> >
> > Default choice (by precedent) is to control variable gain
> > front ends via the scale parameter. Hardware gain
> > is not meant to have any 'visible' impact on the output
> > value - most commonly used when the thing we are measuring
> > is not amplitude of anything.
>
> Hmm, Ok. I'm not sure I understand how hardware gain is supposed to work
> then.
For this use case it isn't.
> Maybe I just remove it.
That's the best plan.
...
> > > > +
> > > > +static int mcp3911_config_of(struct mcp3911 *adc)
> > > > +{
> > > > + u32 configreg;
> > > > + u32 statuscomreg;
> > > > + int ret;
> > > > +
> > > > + of_property_read_u32(adc->np, "device-addr", &adc->dev_addr);
> > This is 'interesting' - I wonder if there is any precedence for it.
> >
>
> I guess we still need it since the device may have a hardcoded (from
> factory) address that we need to deal with.
Fair enough. Still good to hear from Mark on whether there are other similar
devices so the binding can be consistent.
> > > > +
> > > > + of_property_read_u32(adc->np, "ch0-width", &adc->width[0]);
> > > > + switch (adc->width[0]) {
> > > > + case 24:
> > > > + statuscomreg &= ~MCP3911_STATUSCOM_CH0_24WIDTH;
> > > > + dev_dbg(&adc->spi->dev, "set channel 0 into 24bit mode\n");
> > > > + break;
> > > > + case 16:
> > > > + statuscomreg |= MCP3911_STATUSCOM_CH0_24WIDTH;
> > > > + dev_dbg(&adc->spi->dev, "set channel 0 into 16bit mode\n");
> > > > + break;
> > > > + default:
> > > > + adc->width[0] = 24;
> > > > + dev_info(&adc->spi->dev, "invalid width for channel 0. Use 24bit.\n");
> > > > + break;
> > > > + }
> > This feels like something that isn't really a dt choice, as it's not down to
> > wiring but rather down to precision desired.
>
> You are right. I will remove them and stick to 24bit width.
>
That's the easiest option. If anyone 'really' wants 16bit we'll figure it out
later.
..
Thanks
Jonathan
^ permalink raw reply
* Re: [Qemu-devel] [PATCH v5 08/10] migration: create a dedicated thread to release rdma resource
From: Gal Shachaf @ 2018-07-23 14:54 UTC (permalink / raw)
To: 858585 jemmy, Dr. David Alan Gilbert, Aviad Yehezkel
Cc: zhang.zhanghailiang@huawei.com, Juan Quintela, Daniel P. Berrange,
Paolo Bonzini, qemu-devel, Adi Dotan, Lidong Chen
In-Reply-To: <CAOGPPbcTN55ASX64rJe3iUUNmxQJvuy22Har5Lwk7qsEVBxdow@mail.gmail.com>
On Thu, Jul 5, 2018 at 10:26 PM, 858585 jemmy <jemmy858585@gmail.com> wrote:
> On Thu, Jun 28, 2018 at 2:59 AM, Dr. David Alan Gilbert
> <dgilbert@redhat.com> wrote:
>> * Lidong Chen (jemmy858585@gmail.com) wrote:
>>> ibv_dereg_mr wait for a long time for big memory size virtual server.
>>>
>>> The test result is:
>>> 10GB 326ms
>>> 20GB 699ms
>>> 30GB 1021ms
>>> 40GB 1387ms
>>> 50GB 1712ms
>>> 60GB 2034ms
>>> 70GB 2457ms
>>> 80GB 2807ms
>>> 90GB 3107ms
>>> 100GB 3474ms
>>> 110GB 3735ms
>>> 120GB 4064ms
>>> 130GB 4567ms
>>> 140GB 4886ms
>>>
>>> this will cause the guest os hang for a while when migration finished.
>>> So create a dedicated thread to release rdma resource.
>>>
>>> Signed-off-by: Lidong Chen <lidongchen@tencent.com>
>>> ---
>>> migration/rdma.c | 43 +++++++++++++++++++++++++++----------------
>>> 1 file changed, 27 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/migration/rdma.c b/migration/rdma.c index
>>> dfa4f77..f12e8d5 100644
>>> --- a/migration/rdma.c
>>> +++ b/migration/rdma.c
>>> @@ -2979,35 +2979,46 @@ static void qio_channel_rdma_set_aio_fd_handler(QIOChannel *ioc,
>>> }
>>> }
>>>
>>> -static int qio_channel_rdma_close(QIOChannel *ioc,
>>> - Error **errp)
>>> +static void *qio_channel_rdma_close_thread(void *arg)
>>> {
>>> - QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
>>> - RDMAContext *rdmain, *rdmaout;
>>> - trace_qemu_rdma_close();
>>> + RDMAContext **rdma = arg;
>>> + RDMAContext *rdmain = rdma[0];
>>> + RDMAContext *rdmaout = rdma[1];
>>>
>>> - rdmain = rioc->rdmain;
>>> - if (rdmain) {
>>> - atomic_rcu_set(&rioc->rdmain, NULL);
>>> - }
>>> -
>>> - rdmaout = rioc->rdmaout;
>>> - if (rdmaout) {
>>> - atomic_rcu_set(&rioc->rdmaout, NULL);
>>> - }
>>> + rcu_register_thread();
>>>
>>> synchronize_rcu();
>>
>> * see below
>>
>>> -
>>> if (rdmain) {
>>> qemu_rdma_cleanup(rdmain);
>>> }
>>> -
>>> if (rdmaout) {
>>> qemu_rdma_cleanup(rdmaout);
>>> }
>>>
>>> g_free(rdmain);
>>> g_free(rdmaout);
>>> + g_free(rdma);
>>> +
>>> + rcu_unregister_thread();
>>> + return NULL;
>>> +}
>>> +
>>> +static int qio_channel_rdma_close(QIOChannel *ioc,
>>> + Error **errp) {
>>> + QemuThread t;
>>> + QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
>>> + RDMAContext **rdma = g_new0(RDMAContext*, 2);
>>> +
>>> + trace_qemu_rdma_close();
>>> + if (rioc->rdmain || rioc->rdmaout) {
>>> + rdma[0] = rioc->rdmain;
>>> + rdma[1] = rioc->rdmaout;
>>> + qemu_thread_create(&t, "rdma cleanup", qio_channel_rdma_close_thread,
>>> + rdma, QEMU_THREAD_DETACHED);
>>> + atomic_rcu_set(&rioc->rdmain, NULL);
>>> + atomic_rcu_set(&rioc->rdmaout, NULL);
>>
>> I'm not sure this pair is ordered with the synchronise_rcu above;
>> Doesn't that mean, on a bad day, that you could get:
>>
>>
>> main-thread rdma_cleanup another-thread
>> qmu_thread_create
>> synchronise_rcu
>> reads rioc->rdmain
>> starts doing something with rdmain
>> atomic_rcu_set
>> rdma_cleanup
>>
>>
>> so the another-thread is using it during the cleanup?
>> Would just moving the atomic_rcu_sets before the qemu_thread_create
>> fix that?
> yes, I will fix it.
>
>>
>> However, I've got other worries as well:
>> a) qemu_rdma_cleanup does:
>> migrate_get_current()->state == MIGRATION_STATUS_CANCELLING
>>
>> which worries me a little if someone immediately tries to restart
>> the migration.
Because the current qemu version don't wait for RDMA_CM_EVENT_DISCONNECTED event after rdma_disconnect, so I think it's not necessary to send RDMA_CONTROL_ERROR.
compare to send RDMA_CONTROL_ERROR, I think use cm event to notify peer qemu is better.
maybe the rdma is already in error_state, and RDMA_CONTROL_ERROR cannot send successfully.
For peer qemu, in qemu_rdma_wait_comp_channel function, it's should not only poll rdma->comp_channel->fd, it's should also poll rdma->channel->fd.
[GS] I agree that we should poll on CM events in addition to CQ events.
for the source qemu, it's fixed by this patch.
migration: poll the cm event while wait RDMA work request completion
and for destination qemu, it's need a new patch to fix it.
so I prefer to remove MIGRATION_STATUS_CANCELLING in qemu_rdma_cleanup function.
[GS] The intention of this patch is to move the costly ibv_dereg_mr to a separate thread, so we do not actually need to also move the RDMA_CONTROL_ERROR and rdma_disconnect, that come beforehand in qemu_rdma_cleanup, to a thread. I suggest that we move them out of qemu_rdma_cleanup to a new function "qemu_rdma_disconnect" and call it on each RDMAcontext before the qemu_thread_create.
>>
>> b) I don't understand what happens if someone does try and restart
>> the migration after that, but in the ~5s it takes the ibv cleanup
>> to happen.
I prefer to add a new variable in current_migration. if the rdma cleanup thread has not exited. it's should not start a new migration.
[GS] I support this suggestion.
>
> yes, I will try to fix it.
>
>>
>> Dave
>>
>>
>>> + }
>>>
>>> return 0;
>>> }
>>> --
>>> 1.8.3.1
>>>
>> --
>> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
^ permalink raw reply
* [PATCH] drm/i915: Skip repeated calls to i915_gem_set_wedged()
From: Chris Wilson @ 2018-07-23 14:53 UTC (permalink / raw)
To: intel-gfx
If we already wedged, i915_gem_set_wedged() becomes a complicated no-op.
References: https://bugs.freedesktop.org/show_bug.cgi?id=107343
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8b52cb768a67..a4031fab57b0 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3312,8 +3312,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
intel_engine_dump(engine, &p, "%s\n", engine->name);
}
- set_bit(I915_WEDGED, &i915->gpu_error.flags);
- smp_mb__after_atomic();
+ if (test_and_set_bit(I915_WEDGED, &i915->gpu_error.flags))
+ goto out;
/*
* First, stop submission to hw, but do not yet complete requests by
@@ -3372,6 +3372,7 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
i915_gem_reset_finish_engine(engine);
}
+out:
GEM_TRACE("end\n");
wake_up_all(&i915->gpu_error.reset_queue);
--
2.18.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related
* [GIT PULL] mali-dp fixes for drm-next
From: Liviu Dudau @ 2018-07-23 14:53 UTC (permalink / raw)
To: Dave Airlie; +Cc: MaliDP Maintainers, DRI devel
Hi Dave,
I have a couple of small patches for malidp to be applied in drm-next.
They have arisen from the decision to switch the writeback connectors to
always connected.
Best regards,
Liviu
The following changes since commit 500775074f88d9cf5416bed2ca19592812d62c41:
Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next (2018-07-20 14:54:31 +1000)
are available in the Git repository at:
git://linux-arm.org/linux-ld.git for-upstream/malidp-fixes
for you to fetch changes up to 2e012e76ad59edb4a5a175c0957a44337dc39d87:
drm: mali-dp: Set encoder possible_clones (2018-07-23 15:42:17 +0100)
----------------------------------------------------------------
Alexandru Gheorghe (2):
drm: mali-dp: Report writeback connector as connected
drm: mali-dp: Set encoder possible_clones
drivers/gpu/drm/arm/malidp_drv.c | 10 ++++++++++
drivers/gpu/drm/arm/malidp_mw.c | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [LTP] [PATCH v3 1/2] lib: Factor out is_supported() && Add tst_supported_fs
From: Cyril Hrubis @ 2018-07-23 14:52 UTC (permalink / raw)
To: ltp
In-Reply-To: <1532083213-4803-1-git-send-email-yangx.jy@cn.fujitsu.com>
Hi!
Both pushed, thanks.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply
* [Intel-wired-lan] [PATCH] i40e: Remove duplicated prepare call in i40e_shutdown
From: Alexander Duyck @ 2018-07-23 14:52 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20180719112522.GA16521@gklab-81-211.igk.intel.com>
On Thu, Jul 19, 2018 at 4:25 AM, Sergey Nemov <sergey.nemov@intel.com> wrote:
> Function call to i40e_prep_for_reset() is duplicated in
> i40e_shutdown routine and gets called before
> i40e_enable_mc_magic_wake() which blocks it from being executed
> correctly on system reboot or shutdown because adminq is already
> disabled by first i40e_prep_for_reset() call.
>
> Two register write calls are also duplicated.
>
> Signed-off-by: Sergey Nemov <sergey.nemov@intel.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index b5daa5c..71c69df 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -14355,12 +14355,6 @@ static void i40e_shutdown(struct pci_dev *pdev)
>
> set_bit(__I40E_SUSPENDED, pf->state);
> set_bit(__I40E_DOWN, pf->state);
> - rtnl_lock();
> - i40e_prep_for_reset(pf, true);
> - rtnl_unlock();
> -
> - wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
> - wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
>
> del_timer_sync(&pf->service_timer);
> cancel_work_sync(&pf->service_task);
> --
> 1.8.3.1
Is there a reason for selecting to remove the first invocation of this
instead of the second? It seems to me like the service timer and
filter rules are being torn down in the lines following this. It might
make more sense to maybe split the difference and keep this call to
prep_for_reset and instead get rid of the second call, and in the case
of the wakeup registers remove the first set and wait on enabling it
until the second set.
- Alex
^ permalink raw reply
* Re: [Qemu-devel] [PATCH] qstring: Fix integer overflow
From: Eric Blake @ 2018-07-23 14:52 UTC (permalink / raw)
To: liujunjie, armbru
Cc: wangxinxin.wang, arei.gonglei, weidong.huang, qemu-devel
In-Reply-To: <20180720130928.6696-1-liujunjie23@huawei.com>
On 07/20/2018 08:09 AM, liujunjie wrote:
> From: l00425170 <liujunjie23@huawei.com>
>
> The incoming parameters "start" and "end" is int type in
> qstring_from_substr(), but this function can be called by
> qstring_from_str, which is size_t type in strlen(str).
> It may result in coredump when called g_malloc later.
> One scene to triger is to call hmp "into tlb", which may have
> too long length of string.
>
> Signed-off-by: l00425170 <liujunjie23@huawei.com>
Using what looks like a username for your Author and S-o-b designation
rather than a legal name is fishy. If 'l00425170' is really an alias
that you have frequently used in other open source projects, it might be
okay (and if so, you could back it up by pointing us to a URL of such
contributions to other projects). But in general, it's better to own
your patches with your real name (git supports UTF-8, if you would like
your name to appear in native characters instead of or in addition to a
Latin-ized form).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply
* [PATCH v4 5/5] doc: add ZLIB PMD guide
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch; +Cc: dev, pathreya, mchalla, Sunila Sahu, Ashish Gupta
In-Reply-To: <1532357474-9544-1-git-send-email-shally.verma@caviumnetworks.com>
Add zlib pmd feature support and user guide with
build and run instructions
Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
MAINTAINERS | 2 +
doc/guides/compressdevs/features/zlib.ini | 11 +++++
doc/guides/compressdevs/index.rst | 1 +
doc/guides/compressdevs/zlib.rst | 69 +++++++++++++++++++++++++++++++
4 files changed, 83 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index ca27c6f..7e3c450 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -875,6 +875,8 @@ F: drivers/common/qat/
ZLIB
M: Sunila Sahu <sunila.sahu@caviumnetworks.com>
F: drivers/compress/zlib/
+F: doc/guides/compressdevs/zlib.rst
+F: doc/guides/compressdevs/features/zlib.ini
Eventdev Drivers
----------------
diff --git a/doc/guides/compressdevs/features/zlib.ini b/doc/guides/compressdevs/features/zlib.ini
new file mode 100644
index 0000000..c794643
--- /dev/null
+++ b/doc/guides/compressdevs/features/zlib.ini
@@ -0,0 +1,11 @@
+;
+; Refer to default.ini for the full list of available PMD features.
+;
+; Supported features of 'ZLIB' compression driver.
+;
+[Features]
+Pass-through = Y
+Deflate = Y
+Fixed = Y
+Dynamic = Y
+OOP SGL In SGL Out = Y
diff --git a/doc/guides/compressdevs/index.rst b/doc/guides/compressdevs/index.rst
index 4228768..6ba6641 100644
--- a/doc/guides/compressdevs/index.rst
+++ b/doc/guides/compressdevs/index.rst
@@ -12,3 +12,4 @@ Compression Device Drivers
overview
isal
qat_comp
+ zlib
diff --git a/doc/guides/compressdevs/zlib.rst b/doc/guides/compressdevs/zlib.rst
new file mode 100644
index 0000000..c020792
--- /dev/null
+++ b/doc/guides/compressdevs/zlib.rst
@@ -0,0 +1,69 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Cavium Networks.
+
+ZLIB Compression Poll Mode Driver
+==================================
+
+The ZLIB PMD (**librte_pmd_zlib**) provides poll mode compression &
+decompression driver based on SW zlib library,
+
+Features
+--------
+
+ZLIB PMD has support for:
+
+Compression/Decompression algorithm:
+
+* DEFLATE
+
+Huffman code type:
+
+* FIXED
+* DYNAMIC
+
+Window size support:
+
+* Min - 256 bytes
+* Max - 32K
+
+Limitations
+-----------
+
+* Stateful not supported.
+
+Installation
+------------
+
+* To build DPDK with ZLIB library, the user is required to download the ``libz`` library.
+* Use following command for installation.
+
+* For Fedora users::
+ sudo yum install zlib-devel
+* For Ubuntu users::
+ sudo apt-get install zlib1g-dev
+
+* Once downloaded, the user needs to build the library.
+
+* To build from sources
+ download zlib sources from http://zlib.net/ and do following before building DPDK::
+
+ make
+ sudo make install
+
+Initialization
+--------------
+
+In order to enable this virtual compression PMD, user must:
+
+* Set ``CONFIG_RTE_LIBRTE_PMD_ZLIB=y`` in config/common_base.
+
+To use the PMD in an application, user must:
+
+* Call ``rte_vdev_init("compress_zlib")`` within the application.
+
+* Use ``--vdev="compress_zlib"`` in the EAL options, which will call ``rte_vdev_init()`` internally.
+
+The following parameter (optional) can be provided in the previous two calls:
+
+* ``socket_id:`` Specify the socket where the memory for the device is going to be allocated
+ (by default, socket_id will be the socket where the core that is creating the PMD is running on).
--
2.9.5
^ permalink raw reply related
* [PATCH v4 4/5] compress/zlib: support burst enqueue/dequeue
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch
Cc: dev, pathreya, mchalla, Sunila Sahu, Sunila Sahu, Ashish Gupta
In-Reply-To: <1532357474-9544-1-git-send-email-shally.verma@caviumnetworks.com>
From: Sunila Sahu <ssahu@caviumnetworks.com>
Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
drivers/compress/zlib/zlib_pmd.c | 255 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 254 insertions(+), 1 deletion(-)
diff --git a/drivers/compress/zlib/zlib_pmd.c b/drivers/compress/zlib/zlib_pmd.c
index 47bc73d..dc1e230 100644
--- a/drivers/compress/zlib/zlib_pmd.c
+++ b/drivers/compress/zlib/zlib_pmd.c
@@ -7,7 +7,214 @@
#include "zlib_pmd_private.h"
-/** Parse comp xform and set private xform/stream parameters */
+/** Compute next mbuf in the list, assign data buffer and length,
+ * returns 0 if mbuf is NULL
+ */
+#define COMPUTE_BUF(mbuf, data, len) \
+ ((mbuf = mbuf->next) ? \
+ (data = rte_pktmbuf_mtod(mbuf, uint8_t *)), \
+ (len = rte_pktmbuf_data_len(mbuf)) : 0)
+
+static void
+process_zlib_deflate(struct rte_comp_op *op, z_stream *strm)
+{
+ int ret, flush, fin_flush;
+ struct rte_mbuf *mbuf_src = op->m_src;
+ struct rte_mbuf *mbuf_dst = op->m_dst;
+
+ switch (op->flush_flag) {
+ case RTE_COMP_FLUSH_FULL:
+ case RTE_COMP_FLUSH_FINAL:
+ fin_flush = Z_FINISH;
+ break;
+ default:
+ op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
+ ZLIB_PMD_ERR("Invalid flush value\n");
+ }
+
+ if (unlikely(!strm)) {
+ op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
+ ZLIB_PMD_ERR("Invalid z_stream\n");
+ return;
+ }
+ /* Update z_stream with the inputs provided by application */
+ strm->next_in = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
+ op->src.offset);
+
+ strm->avail_in = rte_pktmbuf_data_len(mbuf_src) - op->src.offset;
+
+ strm->next_out = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+ op->dst.offset);
+
+ strm->avail_out = rte_pktmbuf_data_len(mbuf_dst) - op->dst.offset;
+
+ /* Set flush value to NO_FLUSH unless it is last mbuf */
+ flush = Z_NO_FLUSH;
+ /* Initialize status to SUCCESS */
+ op->status = RTE_COMP_OP_STATUS_SUCCESS;
+
+ do {
+ /* Set flush value to Z_FINISH for last block */
+ if ((op->src.length - strm->total_in) <= strm->avail_in) {
+ strm->avail_in = (op->src.length - strm->total_in);
+ flush = fin_flush;
+ }
+ do {
+ ret = deflate(strm, flush);
+ if (unlikely(ret == Z_STREAM_ERROR)) {
+ /* error return, do not process further */
+ op->status = RTE_COMP_OP_STATUS_ERROR;
+ goto def_end;
+ }
+ /* Break if Z_STREAM_END is encountered */
+ if (ret == Z_STREAM_END)
+ goto def_end;
+
+ /* Keep looping until input mbuf is consumed.
+ * Exit if destination mbuf gets exhausted.
+ */
+ } while ((strm->avail_out == 0) &&
+ COMPUTE_BUF(mbuf_dst, strm->next_out, strm->avail_out));
+
+ if (!strm->avail_out) {
+ /* there is no space for compressed output */
+ op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+ break;
+ }
+
+ /* Update source buffer to next mbuf
+ * Exit if input buffers are fully consumed
+ */
+ } while (COMPUTE_BUF(mbuf_src, strm->next_in, strm->avail_in));
+
+def_end:
+ /* Update op stats */
+ switch (op->status) {
+ case RTE_COMP_OP_STATUS_SUCCESS:
+ op->consumed += strm->total_in;
+ /* Fall-through */
+ case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
+ op->produced += strm->total_out;
+ break;
+ default:
+ ZLIB_PMD_ERR("stats not updated for status:%d\n",
+ op->status);
+ }
+
+ deflateReset(strm);
+}
+
+static void
+process_zlib_inflate(struct rte_comp_op *op, z_stream *strm)
+{
+ int ret, flush;
+ struct rte_mbuf *mbuf_src = op->m_src;
+ struct rte_mbuf *mbuf_dst = op->m_dst;
+
+ if (unlikely(!strm)) {
+ op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
+ ZLIB_PMD_ERR("Invalid z_stream\n");
+ return;
+ }
+ strm->next_in = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
+ op->src.offset);
+
+ strm->avail_in = rte_pktmbuf_data_len(mbuf_src) - op->src.offset;
+
+ strm->next_out = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+ op->dst.offset);
+
+ strm->avail_out = rte_pktmbuf_data_len(mbuf_dst) - op->dst.offset;
+
+ /** Ignoring flush value provided from application for decompression */
+ flush = Z_NO_FLUSH;
+ /* initialize status to SUCCESS */
+ op->status = RTE_COMP_OP_STATUS_SUCCESS;
+
+ do {
+ do {
+ ret = inflate(strm, flush);
+
+ switch (ret) {
+ /* Fall-through */
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ /* Fall-through */
+ case Z_DATA_ERROR:
+ /* Fall-through */
+ case Z_MEM_ERROR:
+ /* Fall-through */
+ case Z_STREAM_ERROR:
+ op->status = RTE_COMP_OP_STATUS_ERROR;
+ /* Fall-through */
+ case Z_STREAM_END:
+ /* no further computation needed if
+ * Z_STREAM_END is encountered
+ */
+ goto inf_end;
+ default:
+ /* success */
+ break;
+
+ }
+ /* Keep looping until input mbuf is consumed.
+ * Exit if destination mbuf gets exhausted.
+ */
+ } while ((strm->avail_out == 0) &&
+ COMPUTE_BUF(mbuf_dst, strm->next_out, strm->avail_out));
+
+ if (!strm->avail_out) {
+ /* there is no more space for decompressed output */
+ op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED;
+ break;
+ }
+ /* Read next input buffer to be processed, exit if compressed
+ * blocks are fully read
+ */
+ } while (COMPUTE_BUF(mbuf_src, strm->next_in, strm->avail_in));
+
+inf_end:
+ /* Update op stats */
+ switch (op->status) {
+ case RTE_COMP_OP_STATUS_SUCCESS:
+ op->consumed += strm->total_in;
+ /* Fall-through */
+ case RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED:
+ op->produced += strm->total_out;
+ break;
+ default:
+ ZLIB_PMD_ERR("stats not produced for status:%d\n",
+ op->status);
+ }
+
+ inflateReset(strm);
+}
+
+/** Process comp operation for mbuf */
+static inline int
+process_zlib_op(struct zlib_qp *qp, struct rte_comp_op *op)
+{
+ struct zlib_stream *stream;
+ struct zlib_priv_xform *private_xform;
+
+ if ((op->op_type == RTE_COMP_OP_STATEFUL) ||
+ (op->src.offset > rte_pktmbuf_data_len(op->m_src)) ||
+ (op->dst.offset > rte_pktmbuf_data_len(op->m_dst))) {
+ op->status = RTE_COMP_OP_STATUS_INVALID_ARGS;
+ ZLIB_PMD_ERR("Invalid source or destination buffers or "
+ "invalid Operation requested\n");
+ } else {
+ private_xform = (struct zlib_priv_xform *)op->private_xform;
+ stream = &private_xform->stream;
+ stream->comp(op, &stream->strm);
+ }
+ /* whatever is out of op, put it into completion queue with
+ * its status
+ */
+ return rte_ring_enqueue(qp->processed_pkts, (void *)op);
+}
+
+/** Parse comp xform and set private xform/Stream parameters */
int
zlib_set_stream_parameters(const struct rte_comp_xform *xform,
struct zlib_stream *stream)
@@ -22,6 +229,8 @@ zlib_set_stream_parameters(const struct rte_comp_xform *xform,
switch (xform->type) {
case RTE_COMP_COMPRESS:
+ stream->comp = process_zlib_deflate;
+ stream->free = deflateEnd;
/** Compression window bits */
switch (xform->compress.algo) {
case RTE_COMP_ALGO_DEFLATE:
@@ -80,6 +289,8 @@ zlib_set_stream_parameters(const struct rte_comp_xform *xform,
break;
case RTE_COMP_DECOMPRESS:
+ stream->comp = process_zlib_inflate;
+ stream->free = inflateEnd;
/** window bits */
switch (xform->decompress.algo) {
case RTE_COMP_ALGO_DEFLATE:
@@ -101,6 +312,44 @@ zlib_set_stream_parameters(const struct rte_comp_xform *xform,
return 0;
}
+static uint16_t
+zlib_pmd_enqueue_burst(void *queue_pair,
+ struct rte_comp_op **ops, uint16_t nb_ops)
+{
+ struct zlib_qp *qp = queue_pair;
+ int ret;
+ uint16_t i;
+ uint16_t enqd = 0;
+ for (i = 0; i < nb_ops; i++) {
+ ret = process_zlib_op(qp, ops[i]);
+ if (unlikely(ret < 0)) {
+ /* increment count if failed to push to completion
+ * queue
+ */
+ qp->qp_stats.enqueue_err_count++;
+ } else {
+ qp->qp_stats.enqueued_count++;
+ enqd++;
+ }
+ }
+ return enqd;
+}
+
+static uint16_t
+zlib_pmd_dequeue_burst(void *queue_pair,
+ struct rte_comp_op **ops, uint16_t nb_ops)
+{
+ struct zlib_qp *qp = queue_pair;
+
+ unsigned int nb_dequeued = 0;
+
+ nb_dequeued = rte_ring_dequeue_burst(qp->processed_pkts,
+ (void **)ops, nb_ops, NULL);
+ qp->qp_stats.dequeued_count += nb_dequeued;
+
+ return nb_dequeued;
+}
+
static int
zlib_create(const char *name,
struct rte_vdev_device *vdev,
@@ -117,6 +366,10 @@ zlib_create(const char *name,
dev->dev_ops = rte_zlib_pmd_ops;
+ /* register rx/tx burst functions for data path */
+ dev->dequeue_burst = zlib_pmd_dequeue_burst;
+ dev->enqueue_burst = zlib_pmd_enqueue_burst;
+
return 0;
}
--
2.9.5
^ permalink raw reply related
* [PATCH v4 3/5] compress/zlib: create private xform
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch
Cc: dev, pathreya, mchalla, Sunila Sahu, Sunila Sahu, Ashish Gupta
In-Reply-To: <1532357474-9544-1-git-send-email-shally.verma@caviumnetworks.com>
From: Sunila Sahu <ssahu@caviumnetworks.com>
Create non-shareable private xform for stateless
operation processing
Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
drivers/compress/zlib/zlib_pmd.c | 94 ++++++++++++++++++++++++++++++++
drivers/compress/zlib/zlib_pmd_ops.c | 74 ++++++++++++++++++++++++-
drivers/compress/zlib/zlib_pmd_private.h | 4 ++
3 files changed, 170 insertions(+), 2 deletions(-)
diff --git a/drivers/compress/zlib/zlib_pmd.c b/drivers/compress/zlib/zlib_pmd.c
index 9363808..47bc73d 100644
--- a/drivers/compress/zlib/zlib_pmd.c
+++ b/drivers/compress/zlib/zlib_pmd.c
@@ -7,6 +7,100 @@
#include "zlib_pmd_private.h"
+/** Parse comp xform and set private xform/stream parameters */
+int
+zlib_set_stream_parameters(const struct rte_comp_xform *xform,
+ struct zlib_stream *stream)
+{
+ int strategy, level, wbits;
+ z_stream *strm = &stream->strm;
+
+ /* allocate deflate state */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+
+ switch (xform->type) {
+ case RTE_COMP_COMPRESS:
+ /** Compression window bits */
+ switch (xform->compress.algo) {
+ case RTE_COMP_ALGO_DEFLATE:
+ wbits = -(xform->compress.window_size);
+ break;
+ default:
+ ZLIB_PMD_ERR("Compression algorithm not supported\n");
+ return -1;
+ }
+ /** Compression Level */
+ switch (xform->compress.level) {
+ case RTE_COMP_LEVEL_PMD_DEFAULT:
+ level = Z_DEFAULT_COMPRESSION;
+ break;
+ case RTE_COMP_LEVEL_NONE:
+ level = Z_NO_COMPRESSION;
+ break;
+ case RTE_COMP_LEVEL_MIN:
+ level = Z_BEST_SPEED;
+ break;
+ case RTE_COMP_LEVEL_MAX:
+ level = Z_BEST_COMPRESSION;
+ break;
+ default:
+ level = xform->compress.level;
+ if (level < RTE_COMP_LEVEL_MIN ||
+ level > RTE_COMP_LEVEL_MAX) {
+ ZLIB_PMD_ERR("Compression level %d "
+ "not supported\n",
+ level);
+ return -1;
+ }
+ break;
+ }
+ /** Compression strategy */
+ switch (xform->compress.deflate.huffman) {
+ case RTE_COMP_HUFFMAN_DEFAULT:
+ strategy = Z_DEFAULT_STRATEGY;
+ break;
+ case RTE_COMP_HUFFMAN_FIXED:
+ strategy = Z_FIXED;
+ break;
+ case RTE_COMP_HUFFMAN_DYNAMIC:
+ strategy = Z_DEFAULT_STRATEGY;
+ break;
+ default:
+ ZLIB_PMD_ERR("Compression strategy not supported\n");
+ return -1;
+ }
+ if (deflateInit2(strm, level,
+ Z_DEFLATED, wbits,
+ DEF_MEM_LEVEL, strategy) != Z_OK) {
+ ZLIB_PMD_ERR("Deflate init failed\n");
+ return -1;
+ }
+ break;
+
+ case RTE_COMP_DECOMPRESS:
+ /** window bits */
+ switch (xform->decompress.algo) {
+ case RTE_COMP_ALGO_DEFLATE:
+ wbits = -(xform->decompress.window_size);
+ break;
+ default:
+ ZLIB_PMD_ERR("Compression algorithm not supported\n");
+ return -1;
+ }
+
+ if (inflateInit2(strm, wbits) != Z_OK) {
+ ZLIB_PMD_ERR("Inflate init failed\n");
+ return -1;
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
static int
zlib_create(const char *name,
struct rte_vdev_device *vdev,
diff --git a/drivers/compress/zlib/zlib_pmd_ops.c b/drivers/compress/zlib/zlib_pmd_ops.c
index 645c5b1..2fb6a85 100644
--- a/drivers/compress/zlib/zlib_pmd_ops.c
+++ b/drivers/compress/zlib/zlib_pmd_ops.c
@@ -214,6 +214,76 @@ zlib_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
return -1;
}
+/** Configure stream */
+static int
+zlib_pmd_stream_create(struct rte_compressdev *dev,
+ const struct rte_comp_xform *xform,
+ void **zstream)
+{
+ int ret = 0;
+ struct zlib_stream *stream;
+ struct zlib_private *internals = dev->data->dev_private;
+
+ if (xform == NULL) {
+ ZLIB_PMD_ERR("invalid xform struct");
+ return -EINVAL;
+ }
+
+ if (rte_mempool_get(internals->mp, zstream)) {
+ ZLIB_PMD_ERR("Couldn't get object from session mempool");
+ return -ENOMEM;
+ }
+ stream = *((struct zlib_stream **)zstream);
+
+ ret = zlib_set_stream_parameters(xform, stream);
+
+ if (ret < 0) {
+ ZLIB_PMD_ERR("failed configure session parameters");
+
+ memset(stream, 0, sizeof(struct zlib_stream));
+ /* Return session to mempool */
+ rte_mempool_put(internals->mp, stream);
+ return ret;
+ }
+
+ return 0;
+}
+
+/** Configure private xform */
+static int
+zlib_pmd_private_xform_create(struct rte_compressdev *dev,
+ const struct rte_comp_xform *xform,
+ void **private_xform)
+{
+ return zlib_pmd_stream_create(dev, xform, private_xform);
+}
+
+/** Clear the memory of stream so it doesn't leave key material behind */
+static int
+zlib_pmd_stream_free(__rte_unused struct rte_compressdev *dev,
+ void *zstream)
+{
+ struct zlib_stream *stream = (struct zlib_stream *)zstream;
+ if (!stream)
+ return -EINVAL;
+
+ stream->free(&stream->strm);
+ /* Zero out the whole structure */
+ memset(stream, 0, sizeof(struct zlib_stream));
+ struct rte_mempool *mp = rte_mempool_from_obj(stream);
+ rte_mempool_put(mp, stream);
+
+ return 0;
+}
+
+/** Clear the memory of stream so it doesn't leave key material behind */
+static int
+zlib_pmd_private_xform_free(struct rte_compressdev *dev,
+ void *private_xform)
+{
+ return zlib_pmd_stream_free(dev, private_xform);
+}
+
struct rte_compressdev_ops zlib_pmd_ops = {
.dev_configure = zlib_pmd_config,
.dev_start = zlib_pmd_start,
@@ -228,8 +298,8 @@ struct rte_compressdev_ops zlib_pmd_ops = {
.queue_pair_setup = zlib_pmd_qp_setup,
.queue_pair_release = zlib_pmd_qp_release,
- .private_xform_create = NULL,
- .private_xform_free = NULL,
+ .private_xform_create = zlib_pmd_private_xform_create,
+ .private_xform_free = zlib_pmd_private_xform_free,
.stream_create = NULL,
.stream_free = NULL
diff --git a/drivers/compress/zlib/zlib_pmd_private.h b/drivers/compress/zlib/zlib_pmd_private.h
index 0e391a4..2c6e83d 100644
--- a/drivers/compress/zlib/zlib_pmd_private.h
+++ b/drivers/compress/zlib/zlib_pmd_private.h
@@ -61,6 +61,10 @@ struct zlib_priv_xform {
struct zlib_stream stream;
} __rte_cache_aligned;
+int
+zlib_set_stream_parameters(const struct rte_comp_xform *xform,
+ struct zlib_stream *stream);
+
/** Device specific operations function pointer structure */
extern struct rte_compressdev_ops *rte_zlib_pmd_ops;
--
2.9.5
^ permalink raw reply related
* [PATCH v4 2/5] compress/zlib: add device PMD ops
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch; +Cc: dev, pathreya, mchalla, Ashish Gupta, Sunila Sahu
In-Reply-To: <1532357474-9544-1-git-send-email-shally.verma@caviumnetworks.com>
From: Ashish Gupta <ashish.gupta@caviumnetworks.com>
Implement device configure and queue pair
setup PMD ops
Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
drivers/compress/zlib/Makefile | 1 +
drivers/compress/zlib/meson.build | 2 +-
drivers/compress/zlib/zlib_pmd.c | 2 +
drivers/compress/zlib/zlib_pmd_ops.c | 238 +++++++++++++++++++++++++++++++
drivers/compress/zlib/zlib_pmd_private.h | 35 +++++
5 files changed, 277 insertions(+), 1 deletion(-)
diff --git a/drivers/compress/zlib/Makefile b/drivers/compress/zlib/Makefile
index bd322c9..5cf8de6 100644
--- a/drivers/compress/zlib/Makefile
+++ b/drivers/compress/zlib/Makefile
@@ -24,5 +24,6 @@ LDLIBS += -lrte_bus_vdev
# library source files
SRCS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += zlib_pmd.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += zlib_pmd_ops.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/compress/zlib/meson.build b/drivers/compress/zlib/meson.build
index 3f0a77b..7748de2 100644
--- a/drivers/compress/zlib/meson.build
+++ b/drivers/compress/zlib/meson.build
@@ -7,7 +7,7 @@ if not dep.found()
endif
deps += 'bus_vdev'
-sources = files('zlib_pmd.c')
+sources = files('zlib_pmd.c', 'zlib_pmd_ops.c')
ext_deps += dep
pkgconfig_extra_libs += '-lz'
diff --git a/drivers/compress/zlib/zlib_pmd.c b/drivers/compress/zlib/zlib_pmd.c
index 39d3628..9363808 100644
--- a/drivers/compress/zlib/zlib_pmd.c
+++ b/drivers/compress/zlib/zlib_pmd.c
@@ -21,6 +21,8 @@ zlib_create(const char *name,
return -ENODEV;
}
+ dev->dev_ops = rte_zlib_pmd_ops;
+
return 0;
}
diff --git a/drivers/compress/zlib/zlib_pmd_ops.c b/drivers/compress/zlib/zlib_pmd_ops.c
new file mode 100644
index 0000000..645c5b1
--- /dev/null
+++ b/drivers/compress/zlib/zlib_pmd_ops.c
@@ -0,0 +1,238 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Cavium Networks
+ */
+
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+
+#include "zlib_pmd_private.h"
+
+static const struct rte_compressdev_capabilities zlib_pmd_capabilities[] = {
+ { /* Deflate */
+ .algo = RTE_COMP_ALGO_DEFLATE,
+ .comp_feature_flags = (RTE_COMP_FF_NONCOMPRESSED_BLOCKS |
+ RTE_COMP_FF_HUFFMAN_FIXED |
+ RTE_COMP_FF_HUFFMAN_DYNAMIC |
+ RTE_COMP_FF_OOP_SGL_IN_SGL_OUT),
+ .window_size = {
+ .min = 8,
+ .max = 15,
+ .increment = 1
+ },
+ },
+
+ RTE_COMP_END_OF_CAPABILITIES_LIST()
+
+};
+
+/** Configure device */
+static int
+zlib_pmd_config(struct rte_compressdev *dev,
+ struct rte_compressdev_config *config)
+{
+ struct rte_mempool *mp;
+ char mp_name[RTE_MEMPOOL_NAMESIZE];
+ struct zlib_private *internals = dev->data->dev_private;
+
+ snprintf(mp_name, RTE_MEMPOOL_NAMESIZE,
+ "stream_mp_%u", dev->data->dev_id);
+ mp = internals->mp;
+ if (mp == NULL) {
+ mp = rte_mempool_create(mp_name,
+ config->max_nb_priv_xforms +
+ config->max_nb_streams,
+ sizeof(struct zlib_priv_xform),
+ 0, 0, NULL, NULL, NULL,
+ NULL, config->socket_id,
+ 0);
+ if (mp == NULL) {
+ ZLIB_PMD_ERR("Cannot create private xform pool on "
+ "socket %d\n", config->socket_id);
+ return -ENOMEM;
+ }
+ internals->mp = mp;
+ }
+ return 0;
+}
+
+/** Start device */
+static int
+zlib_pmd_start(__rte_unused struct rte_compressdev *dev)
+{
+ return 0;
+}
+
+/** Stop device */
+static void
+zlib_pmd_stop(__rte_unused struct rte_compressdev *dev)
+{
+}
+
+/** Close device */
+static int
+zlib_pmd_close(struct rte_compressdev *dev)
+{
+ struct zlib_private *internals = dev->data->dev_private;
+ rte_mempool_free(internals->mp);
+ internals->mp = NULL;
+ return 0;
+}
+
+/** Get device statistics */
+static void
+zlib_pmd_stats_get(struct rte_compressdev *dev,
+ struct rte_compressdev_stats *stats)
+{
+ int qp_id;
+
+ for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
+ struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
+
+ stats->enqueued_count += qp->qp_stats.enqueued_count;
+ stats->dequeued_count += qp->qp_stats.dequeued_count;
+
+ stats->enqueue_err_count += qp->qp_stats.enqueue_err_count;
+ stats->dequeue_err_count += qp->qp_stats.dequeue_err_count;
+ }
+}
+
+/** Reset device statistics */
+static void
+zlib_pmd_stats_reset(struct rte_compressdev *dev)
+{
+ int qp_id;
+
+ for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
+ struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
+
+ memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
+ }
+}
+
+/** Get device info */
+static void
+zlib_pmd_info_get(struct rte_compressdev *dev,
+ struct rte_compressdev_info *dev_info)
+{
+ if (dev_info != NULL) {
+ dev_info->driver_name = dev->device->name;
+ dev_info->feature_flags = dev->feature_flags;
+ dev_info->capabilities = zlib_pmd_capabilities;
+ }
+}
+
+/** Release queue pair */
+static int
+zlib_pmd_qp_release(struct rte_compressdev *dev, uint16_t qp_id)
+{
+ struct zlib_qp *qp = dev->data->queue_pairs[qp_id];
+
+ if (qp != NULL) {
+ rte_ring_free(qp->processed_pkts);
+ rte_free(qp);
+ dev->data->queue_pairs[qp_id] = NULL;
+ }
+ return 0;
+}
+
+/** set a unique name for the queue pair based on its name, dev_id and qp_id */
+static int
+zlib_pmd_qp_set_unique_name(struct rte_compressdev *dev,
+ struct zlib_qp *qp)
+{
+ unsigned int n = snprintf(qp->name, sizeof(qp->name),
+ "zlib_pmd_%u_qp_%u",
+ dev->data->dev_id, qp->id);
+
+ if (n >= sizeof(qp->name))
+ return -1;
+
+ return 0;
+}
+
+/** Create a ring to place process packets on */
+static struct rte_ring *
+zlib_pmd_qp_create_processed_pkts_ring(struct zlib_qp *qp,
+ unsigned int ring_size, int socket_id)
+{
+ struct rte_ring *r = qp->processed_pkts;
+
+ if (r) {
+ if (rte_ring_get_size(r) >= ring_size) {
+ ZLIB_PMD_INFO("Reusing existing ring %s for processed"
+ " packets", qp->name);
+ return r;
+ }
+
+ ZLIB_PMD_ERR("Unable to reuse existing ring %s for processed"
+ " packets", qp->name);
+ return NULL;
+ }
+
+ return rte_ring_create(qp->name, ring_size, socket_id,
+ RING_F_EXACT_SZ);
+}
+
+/** Setup a queue pair */
+static int
+zlib_pmd_qp_setup(struct rte_compressdev *dev, uint16_t qp_id,
+ uint32_t max_inflight_ops, int socket_id)
+{
+ struct zlib_qp *qp = NULL;
+
+ /* Free memory prior to re-allocation if needed. */
+ if (dev->data->queue_pairs[qp_id] != NULL)
+ zlib_pmd_qp_release(dev, qp_id);
+
+ /* Allocate the queue pair data structure. */
+ qp = rte_zmalloc_socket("ZLIB PMD Queue Pair", sizeof(*qp),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (qp == NULL)
+ return (-ENOMEM);
+
+ qp->id = qp_id;
+ dev->data->queue_pairs[qp_id] = qp;
+
+ if (zlib_pmd_qp_set_unique_name(dev, qp))
+ goto qp_setup_cleanup;
+
+ qp->processed_pkts = zlib_pmd_qp_create_processed_pkts_ring(qp,
+ max_inflight_ops, socket_id);
+ if (qp->processed_pkts == NULL)
+ goto qp_setup_cleanup;
+
+ memset(&qp->qp_stats, 0, sizeof(qp->qp_stats));
+ return 0;
+
+qp_setup_cleanup:
+ if (qp) {
+ rte_free(qp);
+ qp = NULL;
+ }
+ return -1;
+}
+
+struct rte_compressdev_ops zlib_pmd_ops = {
+ .dev_configure = zlib_pmd_config,
+ .dev_start = zlib_pmd_start,
+ .dev_stop = zlib_pmd_stop,
+ .dev_close = zlib_pmd_close,
+
+ .stats_get = zlib_pmd_stats_get,
+ .stats_reset = zlib_pmd_stats_reset,
+
+ .dev_infos_get = zlib_pmd_info_get,
+
+ .queue_pair_setup = zlib_pmd_qp_setup,
+ .queue_pair_release = zlib_pmd_qp_release,
+
+ .private_xform_create = NULL,
+ .private_xform_free = NULL,
+
+ .stream_create = NULL,
+ .stream_free = NULL
+};
+
+struct rte_compressdev_ops *rte_zlib_pmd_ops = &zlib_pmd_ops;
diff --git a/drivers/compress/zlib/zlib_pmd_private.h b/drivers/compress/zlib/zlib_pmd_private.h
index d26a740..0e391a4 100644
--- a/drivers/compress/zlib/zlib_pmd_private.h
+++ b/drivers/compress/zlib/zlib_pmd_private.h
@@ -27,6 +27,41 @@ int zlib_logtype_driver;
ZLIB_PMD_LOG(WARNING, fmt, ## args)
struct zlib_private {
+ struct rte_mempool *mp;
};
+struct zlib_qp {
+ struct rte_ring *processed_pkts;
+ /**< Ring for placing process packets */
+ struct rte_compressdev_stats qp_stats;
+ /**< Queue pair statistics */
+ uint16_t id;
+ /**< Queue Pair Identifier */
+ char name[RTE_COMPRESSDEV_NAME_MAX_LEN];
+ /**< Unique Queue Pair Name */
+} __rte_cache_aligned;
+
+/* Algorithm handler function prototype */
+typedef void (*comp_func_t)(struct rte_comp_op *op, z_stream *strm);
+
+typedef int (*comp_free_t)(z_stream *strm);
+
+/** ZLIB Stream structure */
+struct zlib_stream {
+ z_stream strm;
+ /**< zlib stream structure */
+ comp_func_t comp;
+ /**< Operation (compression/decompression) */
+ comp_free_t free;
+ /**< Free Operation (compression/decompression) */
+} __rte_cache_aligned;
+
+/** ZLIB private xform structure */
+struct zlib_priv_xform {
+ struct zlib_stream stream;
+} __rte_cache_aligned;
+
+/** Device specific operations function pointer structure */
+extern struct rte_compressdev_ops *rte_zlib_pmd_ops;
+
#endif /* _RTE_ZLIB_PMD_PRIVATE_H_ */
--
2.9.5
^ permalink raw reply related
* [PATCH v4 1/5] compress/zlib: add ZLIB PMD
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch; +Cc: dev, pathreya, mchalla, Ashish Gupta, Sunila Sahu
In-Reply-To: <1532357474-9544-1-git-send-email-shally.verma@caviumnetworks.com>
From: Ashish Gupta <ashish.gupta@caviumnetworks.com>
Add initial PMD setup routines in compressdev
framework. ZLIB PMD appears as virtual compression
device. User would need to install zlib prior to
enabling this PMD.
Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com>
Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com>
Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com>
---
MAINTAINERS | 3 +
config/common_base | 5 ++
drivers/compress/Makefile | 1 +
drivers/compress/meson.build | 2 +-
drivers/compress/zlib/Makefile | 28 +++++++++
drivers/compress/zlib/meson.build | 14 +++++
drivers/compress/zlib/rte_pmd_zlib_version.map | 3 +
drivers/compress/zlib/zlib_pmd.c | 78 ++++++++++++++++++++++++++
drivers/compress/zlib/zlib_pmd_private.h | 32 +++++++++++
mk/rte.app.mk | 2 +
10 files changed, 167 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7b2414d..ca27c6f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -872,6 +872,9 @@ M: Fiona Trahe <fiona.trahe@intel.com>
F: drivers/compress/qat/
F: drivers/common/qat/
+ZLIB
+M: Sunila Sahu <sunila.sahu@caviumnetworks.com>
+F: drivers/compress/zlib/
Eventdev Drivers
----------------
diff --git a/config/common_base b/config/common_base
index a061c21..d9b238c 100644
--- a/config/common_base
+++ b/config/common_base
@@ -582,6 +582,11 @@ CONFIG_RTE_COMPRESSDEV_TEST=n
CONFIG_RTE_LIBRTE_PMD_ISAL=n
#
+# Compile PMD for ZLIB compression device
+#
+CONFIG_RTE_LIBRTE_PMD_ZLIB=n
+
+#
# Compile generic event device library
#
CONFIG_RTE_LIBRTE_EVENTDEV=y
diff --git a/drivers/compress/Makefile b/drivers/compress/Makefile
index 592497f..1f159a5 100644
--- a/drivers/compress/Makefile
+++ b/drivers/compress/Makefile
@@ -4,5 +4,6 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-$(CONFIG_RTE_LIBRTE_PMD_ISAL) += isal
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += zlib
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/compress/meson.build b/drivers/compress/meson.build
index 2352ad5..d2ca8fc 100644
--- a/drivers/compress/meson.build
+++ b/drivers/compress/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2018 Intel Corporation
-drivers = ['isal', 'qat']
+drivers = ['isal', 'qat', 'zlib']
std_deps = ['compressdev'] # compressdev pulls in all other needed deps
config_flag_fmt = 'RTE_LIBRTE_@0@_PMD'
diff --git a/drivers/compress/zlib/Makefile b/drivers/compress/zlib/Makefile
new file mode 100644
index 0000000..bd322c9
--- /dev/null
+++ b/drivers/compress/zlib/Makefile
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Cavium Networks
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pmd_zlib.a
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+# library version
+LIBABIVER := 1
+
+# versioning export map
+EXPORT_MAP := rte_pmd_zlib_version.map
+
+# external library dependencies
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring -lz
+LDLIBS += -lrte_compressdev
+LDLIBS += -lrte_bus_vdev
+
+# library source files
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += zlib_pmd.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/compress/zlib/meson.build b/drivers/compress/zlib/meson.build
new file mode 100644
index 0000000..3f0a77b
--- /dev/null
+++ b/drivers/compress/zlib/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Cavium Networks
+
+dep = dependency('zlib', required: false)
+if not dep.found()
+ build = false
+endif
+
+deps += 'bus_vdev'
+sources = files('zlib_pmd.c')
+ext_deps += dep
+pkgconfig_extra_libs += '-lz'
+
+allow_experimental_apis = true
diff --git a/drivers/compress/zlib/rte_pmd_zlib_version.map b/drivers/compress/zlib/rte_pmd_zlib_version.map
new file mode 100644
index 0000000..ad6e191
--- /dev/null
+++ b/drivers/compress/zlib/rte_pmd_zlib_version.map
@@ -0,0 +1,3 @@
+DPDK_18.08 {
+ local: *;
+};
diff --git a/drivers/compress/zlib/zlib_pmd.c b/drivers/compress/zlib/zlib_pmd.c
new file mode 100644
index 0000000..39d3628
--- /dev/null
+++ b/drivers/compress/zlib/zlib_pmd.c
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Cavium Networks
+ */
+
+#include <rte_bus_vdev.h>
+#include <rte_common.h>
+
+#include "zlib_pmd_private.h"
+
+static int
+zlib_create(const char *name,
+ struct rte_vdev_device *vdev,
+ struct rte_compressdev_pmd_init_params *init_params)
+{
+ struct rte_compressdev *dev;
+
+ dev = rte_compressdev_pmd_create(name, &vdev->device,
+ sizeof(struct zlib_private), init_params);
+ if (dev == NULL) {
+ ZLIB_PMD_ERR("driver %s: create failed", init_params->name);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int
+zlib_probe(struct rte_vdev_device *vdev)
+{
+ struct rte_compressdev_pmd_init_params init_params = {
+ "",
+ rte_socket_id()
+ };
+ const char *name;
+ const char *input_args;
+
+ name = rte_vdev_device_name(vdev);
+
+ if (name == NULL)
+ return -EINVAL;
+ input_args = rte_vdev_device_args(vdev);
+ rte_compressdev_pmd_parse_input_args(&init_params, input_args);
+
+ return zlib_create(name, vdev, &init_params);
+}
+
+static int
+zlib_remove(struct rte_vdev_device *vdev)
+{
+ struct rte_compressdev *compressdev;
+ const char *name;
+
+ name = rte_vdev_device_name(vdev);
+ if (name == NULL)
+ return -EINVAL;
+
+ compressdev = rte_compressdev_pmd_get_named_dev(name);
+ if (compressdev == NULL)
+ return -ENODEV;
+
+ return rte_compressdev_pmd_destroy(compressdev);
+}
+
+static struct rte_vdev_driver zlib_pmd_drv = {
+ .probe = zlib_probe,
+ .remove = zlib_remove
+};
+
+RTE_PMD_REGISTER_VDEV(COMPRESSDEV_NAME_ZLIB_PMD, zlib_pmd_drv);
+RTE_INIT(zlib_init_log);
+
+static void
+zlib_init_log(void)
+{
+ zlib_logtype_driver = rte_log_register("pmd.compress.zlib");
+ if (zlib_logtype_driver >= 0)
+ rte_log_set_level(zlib_logtype_driver, RTE_LOG_INFO);
+}
diff --git a/drivers/compress/zlib/zlib_pmd_private.h b/drivers/compress/zlib/zlib_pmd_private.h
new file mode 100644
index 0000000..d26a740
--- /dev/null
+++ b/drivers/compress/zlib/zlib_pmd_private.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Cavium Networks
+ */
+
+#ifndef _RTE_ZLIB_PMD_PRIVATE_H_
+#define _RTE_ZLIB_PMD_PRIVATE_H_
+
+#include <zlib.h>
+#include <rte_compressdev.h>
+#include <rte_compressdev_pmd.h>
+
+#define COMPRESSDEV_NAME_ZLIB_PMD compress_zlib
+/**< ZLIB PMD device name */
+
+#define DEF_MEM_LEVEL 8
+
+int zlib_logtype_driver;
+#define ZLIB_PMD_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, zlib_logtype_driver, "%s(): "fmt "\n", \
+ __func__, ##args)
+
+#define ZLIB_PMD_INFO(fmt, args...) \
+ ZLIB_PMD_LOG(INFO, fmt, ## args)
+#define ZLIB_PMD_ERR(fmt, args...) \
+ ZLIB_PMD_LOG(ERR, fmt, ## args)
+#define ZLIB_PMD_WARN(fmt, args...) \
+ ZLIB_PMD_LOG(WARNING, fmt, ## args)
+
+struct zlib_private {
+};
+
+#endif /* _RTE_ZLIB_PMD_PRIVATE_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 1590838..5b7c684 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -228,6 +228,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ISAL) += -lisal
ifeq ($(CONFIG_RTE_LIBRTE_PMD_QAT_SYM),n)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat
endif # CONFIG_RTE_LIBRTE_PMD_QAT_SYM
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += -lrte_pmd_zlib
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZLIB) += -lz
endif # CONFIG_RTE_LIBRTE_COMPRESSDEV
ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
--
2.9.5
^ permalink raw reply related
* [PATCH v4 0/5] compress: add ZLIB compression PMD
From: Shally Verma @ 2018-07-23 14:51 UTC (permalink / raw)
To: pablo.de.lara.guarch; +Cc: dev, pathreya, mchalla
This patch series add software zlib library (http://zlib.net/)
based compression PMD in DPDK compress drivers.
Application must need to install zlib prior to enabling
this PMD to avail compression/decompression services.
Currently driver only tested for deflate, stateless
compression and decompression.
Changes in v4:
- fixed -Wimplcit-fallthrough compilation error
with gcc-7+ toolchain
Changes in v3:
- added comp_feature_flags to compressdev_capabilities
- removed stream_create as stateful not supported
- changed compression strategy to DEFAULT_STRATEGY
- Simplified core processing logic
- fix doc build error
- other v2 feedbacks
TBDs
- No change to current qp enqueue_err stats update.
- PMD increment enqd_err stats, if it fails to push op
into completion queue. This logic to be revisited based on
further discussion
Changes in v2:
- removed unused variables
- corrected capability to reflect current support
- add lookup for internally maintained mempool during device_configure
- optimized core compression/decompression logic in enq/deq APIs
- updated documentation with correct feature support
v1 includes:
- build changes to build zlib PMD
- zlib PMD implementation
- zlib PMD documentation
- meson build support
This patchset is dependent upon compressdev API.
Ashish Gupta (2):
compress/zlib: add ZLIB PMD
compress/zlib: add device PMD ops
Shally Verma (1):
doc: add ZLIB PMD guide
Sunila Sahu (2):
compress/zlib: create private xform
compress/zlib: support burst enqueue/dequeue
MAINTAINERS | 5 +
config/common_base | 5 +
doc/guides/compressdevs/features/zlib.ini | 11 +
doc/guides/compressdevs/index.rst | 1 +
doc/guides/compressdevs/zlib.rst | 69 ++++
drivers/compress/Makefile | 1 +
drivers/compress/meson.build | 2 +-
drivers/compress/zlib/Makefile | 29 ++
drivers/compress/zlib/meson.build | 14 +
drivers/compress/zlib/rte_pmd_zlib_version.map | 3 +
drivers/compress/zlib/zlib_pmd.c | 427 +++++++++++++++++++++++++
drivers/compress/zlib/zlib_pmd_ops.c | 308 ++++++++++++++++++
drivers/compress/zlib/zlib_pmd_private.h | 71 ++++
mk/rte.app.mk | 2 +
14 files changed, 947 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/compressdevs/features/zlib.ini
create mode 100644 doc/guides/compressdevs/zlib.rst
create mode 100644 drivers/compress/zlib/Makefile
create mode 100644 drivers/compress/zlib/meson.build
create mode 100644 drivers/compress/zlib/rte_pmd_zlib_version.map
create mode 100644 drivers/compress/zlib/zlib_pmd.c
create mode 100644 drivers/compress/zlib/zlib_pmd_ops.c
create mode 100644 drivers/compress/zlib/zlib_pmd_private.h
--
2.9.5
^ permalink raw reply
* [PATCH 4/4] drm/amdgpu: Add audio component support
From: Takashi Iwai @ 2018-07-23 14:50 UTC (permalink / raw)
To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
In-Reply-To: <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>
This patch introduces the HDMI audio component binding like what i915
does to amdgpu driver. Unlike i915, we need only the hotplug
notification and the ELD query, hence the code is relatively simple,
just adding the hook at each *_audio_enable() call and giving the eld
query by copying the connector->eld contents.
This patch currently doesn't contain the component support for the new
DC codes yet.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
drivers/gpu/drm/Kconfig | 1 +
drivers/gpu/drm/amd/amdgpu/Makefile | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +
drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c | 97 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 6 ++
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 6 ++
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 6 ++
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 6 ++
9 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 2c7112ddfed4..fbe7216c5c56 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -193,6 +193,7 @@ config DRM_AMDGPU
select BACKLIGHT_LCD_SUPPORT
select INTERVAL_TREE
select CHASH
+ select SND_HDA_COMPONENT if SND_HDA_CORE
help
Choose this option if you have a recent AMD Radeon graphics card.
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index bfd332c95b61..9c26facddb17 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -52,7 +52,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o \
- amdgpu_ids.o
+ amdgpu_ids.o amdgpu_audio.o
# add asic specific block
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a59c07590cee..203d2584c989 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1957,5 +1957,9 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev );
static inline int amdgpu_dm_display_resume(struct amdgpu_device *adev) { return 0; }
#endif
+int amdgpu_audio_component_init(struct amdgpu_device *adev);
+void amdgpu_audio_component_fini(struct amdgpu_device *adev);
+void amdgpu_audio_eld_notify(struct amdgpu_device *adev, int pin);
+
#include "amdgpu_object.h"
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
new file mode 100644
index 000000000000..39256e2f84b3
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: MIT
+
+#include <linux/component.h>
+#include "amdgpu.h"
+
+static int amdgpu_audio_component_get_eld(struct device *kdev, int port,
+ int pipe, bool *enabled,
+ unsigned char *buf, int max_bytes)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct drm_encoder *encoder;
+ struct amdgpu_encoder *amdgpu_encoder;
+ struct amdgpu_encoder_atom_dig *dig;
+ struct drm_connector *connector;
+ int ret = 0;
+
+ *enabled = 0;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ amdgpu_encoder = to_amdgpu_encoder(encoder);
+ dig = amdgpu_encoder->enc_priv;
+ if (!dig || !dig->afmt || !dig->afmt->enabled)
+ continue;
+ if (!dig->afmt->pin || dig->afmt->pin->id != port)
+ continue;
+ connector = amdgpu_get_connector_for_encoder(encoder);
+ *enabled = !!connector;
+ if (connector) {
+ ret = drm_eld_size(connector->eld);
+ memcpy(buf, connector->eld, min(max_bytes, ret));
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static const struct drm_audio_component_ops amdgpu_audio_component_ops = {
+ .get_eld = amdgpu_audio_component_get_eld,
+};
+
+static int amdgpu_audio_component_bind(struct device *kdev,
+ struct device *hda_kdev, void *data)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct amdgpu_device *adev = dev->dev_private;
+ struct drm_audio_component *acomp = data;
+
+ acomp->ops = &amdgpu_audio_component_ops;
+ acomp->dev = kdev;
+ adev->mode_info.audio.component = acomp;
+ return 0;
+}
+
+static void amdgpu_audio_component_unbind(struct device *kdev,
+ struct device *hda_kdev, void *data)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct amdgpu_device *adev = dev->dev_private;
+ struct drm_audio_component *acomp = data;
+
+ acomp->ops = NULL;
+ acomp->dev = NULL;
+ adev->mode_info.audio.component = NULL;
+}
+
+static const struct component_ops amdgpu_audio_component_bind_ops = {
+ .bind = amdgpu_audio_component_bind,
+ .unbind = amdgpu_audio_component_unbind,
+};
+
+int amdgpu_audio_component_init(struct amdgpu_device *adev)
+{
+ int err;
+
+ err = component_add(adev->dev, &amdgpu_audio_component_bind_ops);
+ if (err < 0)
+ return err;
+ adev->mode_info.audio.component_registered = true;
+ return 0;
+}
+
+void amdgpu_audio_component_fini(struct amdgpu_device *adev)
+{
+ if (adev->mode_info.audio.component_registered) {
+ component_del(adev->dev, &amdgpu_audio_component_bind_ops);
+ adev->mode_info.audio.component_registered = false;
+ }
+}
+
+void amdgpu_audio_eld_notify(struct amdgpu_device *adev, int pin)
+{
+ struct drm_audio_component *acomp = adev->mode_info.audio.component;
+
+ if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
+ acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
+ pin, -1);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b9e9e8b02fb7..7cb1aa97e522 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -39,6 +39,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_fb_helper.h>
+#include <drm/drm_audio_component.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/hrtimer.h>
@@ -260,6 +261,8 @@ struct amdgpu_audio {
bool enabled;
struct amdgpu_audio_pin pin[AMDGPU_MAX_AFMT_BLOCKS];
int num_pins;
+ bool component_registered;
+ struct drm_audio_component *component;
};
struct amdgpu_display_funcs {
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index ada241bfeee9..c8471a59930f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1392,6 +1392,8 @@ static void dce_v10_0_audio_enable(struct amdgpu_device *adev,
WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+ amdgpu_audio_eld_notify(adev, pin->id);
}
static const u32 pin_offsets[] =
@@ -1430,6 +1432,8 @@ static int dce_v10_0_audio_init(struct amdgpu_device *adev)
dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
}
+ amdgpu_audio_component_init(adev);
+
return 0;
}
@@ -1443,6 +1447,8 @@ static void dce_v10_0_audio_fini(struct amdgpu_device *adev)
if (!adev->mode_info.audio.enabled)
return;
+ amdgpu_audio_component_fini(adev);
+
for (i = 0; i < adev->mode_info.audio.num_pins; i++)
dce_v10_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index a5b96eac3033..49edb74725a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -1418,6 +1418,8 @@ static void dce_v11_0_audio_enable(struct amdgpu_device *adev,
WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+ amdgpu_audio_eld_notify(adev, pin->id);
}
static const u32 pin_offsets[] =
@@ -1472,6 +1474,8 @@ static int dce_v11_0_audio_init(struct amdgpu_device *adev)
dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
}
+ amdgpu_audio_component_init(adev);
+
return 0;
}
@@ -1485,6 +1489,8 @@ static void dce_v11_0_audio_fini(struct amdgpu_device *adev)
if (!adev->mode_info.audio.enabled)
return;
+ amdgpu_audio_component_fini(adev);
+
for (i = 0; i < adev->mode_info.audio.num_pins; i++)
dce_v11_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index 394cc1e8fe20..2b7468eaacca 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1297,6 +1297,8 @@ static void dce_v6_0_audio_enable(struct amdgpu_device *adev,
WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+ amdgpu_audio_eld_notify(adev, pin->id);
}
static const u32 pin_offsets[7] =
@@ -1343,6 +1345,8 @@ static int dce_v6_0_audio_init(struct amdgpu_device *adev)
dce_v6_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
}
+ amdgpu_audio_component_init(adev);
+
return 0;
}
@@ -1356,6 +1360,8 @@ static void dce_v6_0_audio_fini(struct amdgpu_device *adev)
if (!adev->mode_info.audio.enabled)
return;
+ amdgpu_audio_component_fini(adev);
+
for (i = 0; i < adev->mode_info.audio.num_pins; i++)
dce_v6_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index c9b9ab8f1b05..c2370ea1f64f 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1348,6 +1348,8 @@ static void dce_v8_0_audio_enable(struct amdgpu_device *adev,
WREG32_AUDIO_ENDPT(pin->offset, ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
enable ? AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL__AUDIO_ENABLED_MASK : 0);
+
+ amdgpu_audio_eld_notify(adev, pin->id);
}
static const u32 pin_offsets[7] =
@@ -1395,6 +1397,8 @@ static int dce_v8_0_audio_init(struct amdgpu_device *adev)
dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
}
+ amdgpu_audio_component_init(adev);
+
return 0;
}
@@ -1408,6 +1412,8 @@ static void dce_v8_0_audio_fini(struct amdgpu_device *adev)
if (!adev->mode_info.audio.enabled)
return;
+ amdgpu_audio_component_fini(adev);
+
for (i = 0; i < adev->mode_info.audio.num_pins; i++)
dce_v8_0_audio_enable(adev, &adev->mode_info.audio.pin[i], false);
--
2.18.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH 3/4] drm/radeon: Add audio component support
From: Takashi Iwai @ 2018-07-23 14:50 UTC (permalink / raw)
To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
In-Reply-To: <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>
This patch introduces the HDMI audio component binding like what i915
does to radeon driver. Unlike i915, we need only the hotplug
notification and the ELD query, hence the code is relatively simple,
just adding the hook at radeon_audio_enable() and giving the eld query
by copying the connector->eld contents.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
drivers/gpu/drm/Kconfig | 1 +
drivers/gpu/drm/radeon/radeon.h | 3 +
drivers/gpu/drm/radeon/radeon_audio.c | 79 +++++++++++++++++++++++++++
3 files changed, 83 insertions(+)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 2a72d2feb76d..2c7112ddfed4 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -170,6 +170,7 @@ config DRM_RADEON
select BACKLIGHT_CLASS_DEVICE
select BACKLIGHT_LCD_SUPPORT
select INTERVAL_TREE
+ select SND_HDA_COMPONENT if SND_HDA_CORE
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4a2eb409aacc..fad58df0bf19 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -75,6 +75,7 @@
#include <drm/ttm/ttm_execbuf_util.h>
#include <drm/drm_gem.h>
+#include <drm/drm_audio_component.h>
#include "radeon_family.h"
#include "radeon_mode.h"
@@ -1760,6 +1761,8 @@ struct r600_audio {
struct radeon_audio_funcs *hdmi_funcs;
struct radeon_audio_funcs *dp_funcs;
struct radeon_audio_basic_funcs *funcs;
+ struct drm_audio_component *component;
+ bool component_registered;
};
/*
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index 770e31f5fd1b..58e149b7a7a4 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -23,6 +23,7 @@
*/
#include <linux/gcd.h>
+#include <linux/component.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include "radeon.h"
@@ -248,6 +249,7 @@ static void radeon_audio_enable(struct radeon_device *rdev,
struct drm_encoder *encoder;
struct radeon_encoder *radeon_encoder;
struct radeon_encoder_atom_dig *dig;
+ struct drm_audio_component *acomp = rdev->audio.component;
int pin_count = 0;
if (!pin)
@@ -269,6 +271,10 @@ static void radeon_audio_enable(struct radeon_device *rdev,
if (rdev->audio.funcs->enable)
rdev->audio.funcs->enable(rdev, pin, enable_mask);
+
+ if (acomp && acomp->audio_ops && acomp->audio_ops->pin_eld_notify)
+ acomp->audio_ops->pin_eld_notify(acomp->audio_ops->audio_ptr,
+ pin->id, -1);
}
static void radeon_audio_interface_init(struct radeon_device *rdev)
@@ -292,6 +298,71 @@ static void radeon_audio_interface_init(struct radeon_device *rdev)
}
}
+static int radeon_audio_component_get_eld(struct device *kdev, int port,
+ int pipe, bool *enabled,
+ unsigned char *buf, int max_bytes)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct drm_encoder *encoder;
+ struct radeon_encoder *radeon_encoder;
+ struct radeon_encoder_atom_dig *dig;
+ struct drm_connector *connector;
+ int ret = 0;
+
+ *enabled = 0;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (!radeon_encoder_is_digital(encoder))
+ continue;
+ radeon_encoder = to_radeon_encoder(encoder);
+ dig = radeon_encoder->enc_priv;
+ if (!dig->pin || dig->pin->id != port)
+ continue;
+ connector = radeon_get_connector_for_encoder(encoder);
+ *enabled = !!connector;
+ if (connector) {
+ ret = drm_eld_size(connector->eld);
+ memcpy(buf, connector->eld, min(max_bytes, ret));
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static const struct drm_audio_component_ops radeon_audio_component_ops = {
+ .get_eld = radeon_audio_component_get_eld,
+};
+
+static int radeon_audio_component_bind(struct device *kdev,
+ struct device *hda_kdev, void *data)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_audio_component *acomp = data;
+
+ acomp->ops = &radeon_audio_component_ops;
+ acomp->dev = kdev;
+ rdev->audio.component = acomp;
+ return 0;
+}
+
+static void radeon_audio_component_unbind(struct device *kdev,
+ struct device *hda_kdev, void *data)
+{
+ struct drm_device *dev = dev_get_drvdata(kdev);
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_audio_component *acomp = data;
+
+ acomp->ops = NULL;
+ acomp->dev = NULL;
+ rdev->audio.component = NULL;
+}
+
+static const struct component_ops radeon_audio_component_bind_ops = {
+ .bind = radeon_audio_component_bind,
+ .unbind = radeon_audio_component_unbind,
+};
+
static int radeon_audio_chipset_supported(struct radeon_device *rdev)
{
return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev);
@@ -338,6 +409,9 @@ int radeon_audio_init(struct radeon_device *rdev)
for (i = 0; i < rdev->audio.num_pins; i++)
radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
+ if (!component_add(rdev->dev, &radeon_audio_component_bind_ops))
+ rdev->audio.component_registered = true;
+
return 0;
}
@@ -490,6 +564,11 @@ void radeon_audio_fini(struct radeon_device *rdev)
radeon_audio_enable(rdev, &rdev->audio.pin[i], 0);
rdev->audio.enabled = false;
+
+ if (rdev->audio.component_registered) {
+ component_del(rdev->dev, &radeon_audio_component_bind_ops);
+ rdev->audio.component_registered = false;
+ }
}
static void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock)
--
2.18.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH 2/4] ALSA: hda/hdmi: Allow audio component for AMD/ATI HDMI
From: Takashi Iwai @ 2018-07-23 14:50 UTC (permalink / raw)
To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
In-Reply-To: <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>
AMD/ATI HDMI codec drivers didn't have the audio component binding
like i915, but it worked only with the traditional HD-audio
unsolicited event for the HDMI hotplug detection and the ELD read-up
thereafter. This has been a problem in many ways: first of all, it
goes through the hardware event transition (from GPU register write,
HD-audio controller trigger, and finally to HD-audio unsolicited event
handling), which is often unreliable and may miss some opportunities.
Second, each unsol event handling and ELD read-up need the explicit
power up / down when the codec is in the runtime suspend. Last but
not least, which is the most important, the hotplug wakeup may be
missed when the HD-audio controller is in runtime suspend. Especially
the last point is a big problem due to the recent change relevant with
vga_switcheroo that forcibly enables the runtime PM for AMD HDMI
controllers.
These issues are solved by introducing the audio component; the
hotplug notification is done by a direct function callback, which is
more accurate and reliable, and it can be processed without the actual
hardware access, i.e. no runtime PM trigger is needed, and the
HD-audio gets the event even if it's in runtime suspend. The same for
ELD query, as it's read directly from the cached ELD bytes stored in
the DRM driver, hence the whole hardware access can be skipped.
So here it is: this patch implements the audio component binding with
AMD/ATI DRM driver. The biggest difference from i915 implementation
is that this binding is fully optional and it can be enabled
asynchronously on the fly. That is, the driver will switch from the
HD-audio unsolicited event to the notify callback once when the DRM
component gets bound. Similarly, when DRM driver gets unloaded, the
HDMI event handling returns to the legacy mode, too.
Also, another difference from i915 is that AMD HDMI registers the
component in the codec driver, while i915 HDMI codec assumes the
component binding was already done. Hence AMD code does de-register
the component binding at the codec exit, too.
Some other details:
- The match component ops assumes that both VGA and HD-audio
controller PCI entries belong to the same PCI bus, and only accepts
such an entry.
- The pin2port audio_ops is implemented with assumption of the widget
NID starting from 3, with step 2 (3, 5, 7, ...).
As of this patch, the DRM component in radeon and amdgpu DRM driver
sides isn't implemented yet, so this change won't give any benefit
alone. By the following changes in DRM sides, the mission will be
completed.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/pci/hda/patch_hdmi.c | 142 +++++++++++++++++++++++++++++++++----
1 file changed, 128 insertions(+), 14 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 6750318d1c82..298d40876201 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
@@ -131,6 +132,7 @@ struct hdmi_pcm {
};
struct hdmi_spec {
+ struct hda_codec *codec;
int num_cvts;
struct snd_array cvts; /* struct hdmi_spec_per_cvt */
hda_nid_t cvt_nids[4]; /* only for haswell fix */
@@ -175,8 +177,9 @@ struct hdmi_spec {
struct hda_multi_out multiout;
struct hda_pcm_stream pcm_playback;
- /* i915/powerwell (Haswell+/Valleyview+) specific */
- bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */
+ bool use_jack_detect; /* jack detection enabled */
+ bool use_acomp_notifier; /* use eld_notify callback for hotplug */
+ bool acomp_registered; /* audio component registered in this driver */
struct drm_audio_component_audio_ops drm_audio_ops;
struct hdac_chmap chmap;
@@ -775,6 +778,10 @@ static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid,
static void jack_callback(struct hda_codec *codec,
struct hda_jack_callback *jack)
{
+ /* stop polling when notification is enabled */
+ if (codec_has_acomp(codec))
+ return;
+
/* hda_jack don't support DP MST */
check_presence_and_report(codec, jack->nid, 0);
}
@@ -833,6 +840,9 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
+ if (codec_has_acomp(codec))
+ return;
+
if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) {
codec_dbg(codec, "Unexpected HDMI event tag 0x%x\n", tag);
return;
@@ -1639,18 +1649,13 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
snd_hda_power_down_pm(codec);
return false;
}
- }
-
- if (codec_has_acomp(codec)) {
+ ret = hdmi_present_sense_via_verbs(per_pin, repoll);
+ snd_hda_power_down_pm(codec);
+ } else {
sync_eld_via_acomp(codec, per_pin);
ret = false; /* don't call snd_hda_jack_report_sync() */
- } else {
- ret = hdmi_present_sense_via_verbs(per_pin, repoll);
}
- if (!codec_has_acomp(codec))
- snd_hda_power_down_pm(codec);
-
return ret;
}
@@ -2242,6 +2247,8 @@ static int generic_hdmi_init(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec;
int pin_idx;
+ mutex_lock(&spec->pcm_lock);
+ spec->use_jack_detect = !codec->jackpoll_interval;
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
hda_nid_t pin_nid = per_pin->pin_nid;
@@ -2249,11 +2256,15 @@ static int generic_hdmi_init(struct hda_codec *codec)
snd_hda_set_dev_select(codec, pin_nid, dev_id);
hdmi_init_pin(codec, pin_nid);
- if (!codec_has_acomp(codec))
+ if (codec_has_acomp(codec))
+ continue;
+ if (spec->use_jack_detect)
+ snd_hda_jack_detect_enable(codec, pin_nid);
+ else
snd_hda_jack_detect_enable_callback(codec, pin_nid,
- codec->jackpoll_interval > 0 ?
- jack_callback : NULL);
+ jack_callback);
}
+ mutex_unlock(&spec->pcm_lock);
return 0;
}
@@ -2286,7 +2297,9 @@ static void generic_hdmi_free(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec;
int pin_idx, pcm_idx;
- if (codec_has_acomp(codec))
+ if (spec->acomp_registered)
+ snd_hdac_acomp_exit(&codec->bus->core);
+ else if (codec_has_acomp(codec))
snd_hdac_acomp_register_notifier(&codec->bus->core, NULL);
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
@@ -2352,6 +2365,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
+ spec->codec = codec;
spec->ops = generic_standard_hdmi_ops;
spec->dev_num = 1; /* initialize to 1 */
mutex_init(&spec->pcm_lock);
@@ -3459,6 +3473,63 @@ static int patch_tegra_hdmi(struct hda_codec *codec)
#define ATI_HBR_CAPABLE 0x01
#define ATI_HBR_ENABLE 0x10
+/* turn on / off the unsol event jack detection dynamically */
+static void reprogram_jack_detect(struct hda_codec *codec, hda_nid_t nid,
+ bool use_acomp)
+{
+ struct hda_jack_tbl *tbl;
+
+ tbl = snd_hda_jack_tbl_get(codec, nid);
+ if (tbl) {
+ /* clear unsol even if component notifier is used, or re-enable
+ * if notifier is cleared
+ */
+ unsigned int val = use_acomp ? 0 : (AC_USRSP_EN | tbl->tag);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE, val);
+ } else {
+ /* if no jack entry was defined beforehand, create a new one
+ * at need (i.e. only when notifier is cleared)
+ */
+ if (!use_acomp)
+ snd_hda_jack_detect_enable(codec, nid);
+ }
+}
+
+/* set up / clear component notifier dynamically */
+static void acomp_notifier_set(struct drm_audio_component *acomp,
+ bool use_acomp)
+{
+ struct hdmi_spec *spec;
+ int i;
+
+ spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops);
+ mutex_lock(&spec->pcm_lock);
+ spec->use_acomp_notifier = use_acomp;
+ /* reprogram each jack detection logic depending on the notifier */
+ if (spec->use_jack_detect) {
+ for (i = 0; i < spec->num_pins; i++)
+ reprogram_jack_detect(spec->codec,
+ get_pin(spec, i)->pin_nid,
+ use_acomp);
+ }
+ mutex_unlock(&spec->pcm_lock);
+}
+
+/* enable / disable the notifier via master bind / unbind */
+static int atihdmi_master_bind(struct device *dev,
+ struct drm_audio_component *acomp)
+{
+ acomp_notifier_set(acomp, true);
+ return 0;
+}
+
+static void atihdmi_master_unbind(struct device *dev,
+ struct drm_audio_component *acomp)
+{
+ acomp_notifier_set(acomp, false);
+}
+
static int atihdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid,
unsigned char *buf, int *eld_size)
{
@@ -3731,6 +3802,39 @@ static int atihdmi_init(struct hda_codec *codec)
return 0;
}
+/* check whether both HD-audio and DRM PCI devices belong to the same bus */
+static int match_bound_vga(struct device *dev, void *data)
+{
+ struct hdac_bus *bus = data;
+ struct pci_dev *pci, *master;
+
+ if (!dev_is_pci(dev) || !dev_is_pci(bus->dev))
+ return 0;
+ master = to_pci_dev(bus->dev);
+ pci = to_pci_dev(dev);
+ return master->bus == pci->bus;
+}
+
+/* map from pin NID to port; port is 0-based */
+static int atihdmi_pin2port(void *audio_ptr, int pin_nid)
+{
+ return pin_nid / 2 - 1;
+}
+
+/* audio component notifier for AMD codecs */
+static void atihdmi_pin_eld_notify(void *audio_ptr, int port, int dev_id)
+{
+ struct hda_codec *codec = audio_ptr;
+ hda_nid_t pin_nid = port * 2 + 3; /* 0-based port# */
+
+ /* treat notification only when system is already running and
+ * not during PM suspend/resume process itself
+ */
+ if (snd_power_get_state(codec->card) == SNDRV_CTL_POWER_D0 &&
+ !atomic_read(&(codec)->core.in_pm))
+ check_presence_and_report(codec, pin_nid, dev_id);
+}
+
static int patch_atihdmi(struct hda_codec *codec)
{
struct hdmi_spec *spec;
@@ -3779,6 +3883,16 @@ static int patch_atihdmi(struct hda_codec *codec)
*/
codec->link_down_at_suspend = 1;
+ /* set up audio component binding */
+ spec->drm_audio_ops.audio_ptr = codec;
+ spec->drm_audio_ops.pin2port = atihdmi_pin2port;
+ spec->drm_audio_ops.pin_eld_notify = atihdmi_pin_eld_notify;
+ spec->drm_audio_ops.master_bind = atihdmi_master_bind;
+ spec->drm_audio_ops.master_unbind = atihdmi_master_unbind;
+ if (!snd_hdac_acomp_init(&codec->bus->core, &spec->drm_audio_ops,
+ match_bound_vga, 0))
+ spec->acomp_registered = true;
+
return 0;
}
--
2.18.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH 1/4] ALSA: hda/hdmi: Use single mutex unlock in error paths
From: Takashi Iwai @ 2018-07-23 14:50 UTC (permalink / raw)
To: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw
Cc: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
In-Reply-To: <20180723145030.25133-1-tiwai-l3A5Bk7waGM@public.gmane.org>
Instead of calling mutex_unlock() at each error path multiple times,
take the standard goto-and-a-single-unlock approach. This will
simplify the code and make easier to find the unbalanced mutex locks.
No functional changes, but only the code readability improvement as a
preliminary work for further changes.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/pci/hda/patch_hdmi.c | 67 +++++++++++++++++++-------------------
1 file changed, 33 insertions(+), 34 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1de5491fb9bf..6750318d1c82 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -339,13 +339,13 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
if (!per_pin) {
/* no pin is bound to the pcm */
uinfo->count = 0;
- mutex_unlock(&spec->pcm_lock);
- return 0;
+ goto unlock;
}
eld = &per_pin->sink_eld;
uinfo->count = eld->eld_valid ? eld->eld_size : 0;
- mutex_unlock(&spec->pcm_lock);
+ unlock:
+ mutex_unlock(&spec->pcm_lock);
return 0;
}
@@ -357,6 +357,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
struct hdmi_spec_per_pin *per_pin;
struct hdmi_eld *eld;
int pcm_idx;
+ int err = 0;
pcm_idx = kcontrol->private_value;
mutex_lock(&spec->pcm_lock);
@@ -365,16 +366,15 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
/* no pin is bound to the pcm */
memset(ucontrol->value.bytes.data, 0,
ARRAY_SIZE(ucontrol->value.bytes.data));
- mutex_unlock(&spec->pcm_lock);
- return 0;
+ goto unlock;
}
- eld = &per_pin->sink_eld;
+ eld = &per_pin->sink_eld;
if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
eld->eld_size > ELD_MAX_SIZE) {
- mutex_unlock(&spec->pcm_lock);
snd_BUG();
- return -EINVAL;
+ err = -EINVAL;
+ goto unlock;
}
memset(ucontrol->value.bytes.data, 0,
@@ -382,9 +382,10 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
if (eld->eld_valid)
memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
eld->eld_size);
- mutex_unlock(&spec->pcm_lock);
- return 0;
+ unlock:
+ mutex_unlock(&spec->pcm_lock);
+ return err;
}
static const struct snd_kcontrol_new eld_bytes_ctl = {
@@ -1209,8 +1210,8 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
pin_idx = hinfo_to_pin_index(codec, hinfo);
if (!spec->dyn_pcm_assign) {
if (snd_BUG_ON(pin_idx < 0)) {
- mutex_unlock(&spec->pcm_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto unlock;
}
} else {
/* no pin is assigned to the PCM
@@ -1218,16 +1219,13 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
*/
if (pin_idx < 0) {
err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
- mutex_unlock(&spec->pcm_lock);
- return err;
+ goto unlock;
}
}
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
- if (err < 0) {
- mutex_unlock(&spec->pcm_lock);
- return err;
- }
+ if (err < 0)
+ goto unlock;
per_cvt = get_cvt(spec, cvt_idx);
/* Claim converter */
@@ -1264,12 +1262,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
per_cvt->assigned = 0;
hinfo->nid = 0;
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
- mutex_unlock(&spec->pcm_lock);
- return -ENODEV;
+ err = -ENODEV;
+ goto unlock;
}
}
- mutex_unlock(&spec->pcm_lock);
/* Store the updated parameters */
runtime->hw.channels_min = hinfo->channels_min;
runtime->hw.channels_max = hinfo->channels_max;
@@ -1278,7 +1275,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
- return 0;
+ unlock:
+ mutex_unlock(&spec->pcm_lock);
+ return err;
}
/*
@@ -1867,7 +1866,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct snd_pcm_runtime *runtime = substream->runtime;
bool non_pcm;
int pinctl;
- int err;
+ int err = 0;
mutex_lock(&spec->pcm_lock);
pin_idx = hinfo_to_pin_index(codec, hinfo);
@@ -1879,13 +1878,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
pin_cvt_fixup(codec, NULL, cvt_nid);
snd_hda_codec_setup_stream(codec, cvt_nid,
stream_tag, 0, format);
- mutex_unlock(&spec->pcm_lock);
- return 0;
+ goto unlock;
}
if (snd_BUG_ON(pin_idx < 0)) {
- mutex_unlock(&spec->pcm_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto unlock;
}
per_pin = get_pin(spec, pin_idx);
pin_nid = per_pin->pin_nid;
@@ -1924,6 +1922,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
/* snd_hda_set_dev_select() has been called before */
err = spec->ops.setup_stream(codec, cvt_nid, pin_nid,
stream_tag, format);
+ unlock:
mutex_unlock(&spec->pcm_lock);
return err;
}
@@ -1945,6 +1944,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
struct hdmi_spec_per_cvt *per_cvt;
struct hdmi_spec_per_pin *per_pin;
int pinctl;
+ int err = 0;
if (hinfo->nid) {
pcm_idx = hinfo_to_pcm_index(codec, hinfo);
@@ -1963,14 +1963,12 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
clear_bit(pcm_idx, &spec->pcm_in_use);
pin_idx = hinfo_to_pin_index(codec, hinfo);
- if (spec->dyn_pcm_assign && pin_idx < 0) {
- mutex_unlock(&spec->pcm_lock);
- return 0;
- }
+ if (spec->dyn_pcm_assign && pin_idx < 0)
+ goto unlock;
if (snd_BUG_ON(pin_idx < 0)) {
- mutex_unlock(&spec->pcm_lock);
- return -EINVAL;
+ err = -EINVAL;
+ goto unlock;
}
per_pin = get_pin(spec, pin_idx);
@@ -1989,10 +1987,11 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
per_pin->setup = false;
per_pin->channels = 0;
mutex_unlock(&per_pin->lock);
+ unlock:
mutex_unlock(&spec->pcm_lock);
}
- return 0;
+ return err;
}
static const struct hda_pcm_ops generic_ops = {
--
2.18.0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply related
* [PATCH 0/4] drm_audio_component support for AMD/ATI HDMI codecs
From: Takashi Iwai @ 2018-07-23 14:50 UTC (permalink / raw)
To: alsa-devel; +Cc: amd-gfx, dri-devel
Hi,
this is a patch set to add the support of drm_audio_component for
AMD/ATI HDMI codecs. With the drm_audio_component, the HDMI/DP audio
hotplug and ELD read-out can be achieved directly without the hardware
access. The best point by that is that it makes the hotplug
notification working even during runtime suspend.
The support is totally optional and dynamic, hence it still works even
if either HD-audio or DRM side isn't patched, and it'll fall back to
the existing method.
The current patch supports only radeon and a part of amdgpu; the DC
support isn't included yet.
Takashi
===
Takashi Iwai (4):
ALSA: hda/hdmi: Use single mutex unlock in error paths
ALSA: hda/hdmi: Allow audio component for AMD/ATI HDMI
drm/radeon: Add audio component support
drm/amdgpu: Add audio component support
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/amd/amdgpu/Makefile | 2 +-
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +
drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c | 97 ++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 6 +
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 6 +
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 6 +
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 6 +
drivers/gpu/drm/radeon/radeon.h | 3 +
drivers/gpu/drm/radeon/radeon_audio.c | 79 ++++++++
sound/pci/hda/patch_hdmi.c | 209 +++++++++++++++++-----
12 files changed, 374 insertions(+), 49 deletions(-)
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
--
2.18.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [PATCH v3 1/6] MIPS: Make play_dead() work for kexec
From: Dengcheng Zhu @ 2018-07-23 14:48 UTC (permalink / raw)
To: pburton, ralf; +Cc: linux-mips, rachel.mozes, Dengcheng Zhu
In-Reply-To: <1532357299-8063-1-git-send-email-dzhu@wavecomp.com>
Extract play_dead() from CONFIG_HOTPLUG_CPU and share with CONFIG_KEXEC.
Also, add one parameter to it to avoid doing unnecessary things in the case
of kexec.
This is needed to correctly support SMP new kernel in kexec. Before doing
this, all non-crashing CPUs are waiting for the reboot signal
(kexec_ready_to_reboot) to jump to kexec_start_address in kexec_smp_wait(),
which creates some problems like incorrect CPU topology upon booting from
new UP kernel, sluggish performance in MT environment during and after
reboot, new SMP kernel not able to bring up secondary CPU etc.
It would make sense to let the new (SMP) kernel manage all CPUs, instead of
crashing CPU booting from reboot_code_buffer whereas others jumping to
kexec_start_address. To do this, play_dead() is well suitable for preparing
a boot environment for the new kernel.
Tested-by: Rachel Mozes <rachel.mozes@intel.com>
Reported-by: Rachel Mozes <rachel.mozes@intel.com>
Signed-off-by: Dengcheng Zhu <dzhu@wavecomp.com>
---
Changes:
* Code style adjustments.
arch/mips/cavium-octeon/smp.c | 36 +++++++++------
arch/mips/include/asm/smp.h | 4 +-
arch/mips/kernel/process.c | 2 +-
arch/mips/kernel/smp-bmips.c | 11 +++--
arch/mips/kernel/smp-cps.c | 60 ++++++++++++++----------
arch/mips/loongson64/loongson-3/smp.c | 86 +++++++++++++++++++----------------
6 files changed, 115 insertions(+), 84 deletions(-)
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 75e7c86..6aaf4de 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -280,11 +280,31 @@ static void octeon_smp_finish(void)
local_irq_enable();
}
-#ifdef CONFIG_HOTPLUG_CPU
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
/* State of each CPU. */
DEFINE_PER_CPU(int, cpu_state);
+void play_dead(bool kexec)
+{
+ int cpu = cpu_number_map(cvmx_get_core_num());
+
+ if (!kexec)
+ idle_task_exit();
+ octeon_processor_boot = 0xff;
+ per_cpu(cpu_state, cpu) = CPU_DEAD;
+
+ /* make the change visible before going off */
+ mb();
+
+ while (1) /* core will be reset here */
+ ;
+}
+
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
+
+#ifdef CONFIG_HOTPLUG_CPU
+
static int octeon_cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
@@ -343,20 +363,6 @@ static void octeon_cpu_die(unsigned int cpu)
cvmx_write_csr(CVMX_CIU_PP_RST, 0);
}
-void play_dead(void)
-{
- int cpu = cpu_number_map(cvmx_get_core_num());
-
- idle_task_exit();
- octeon_processor_boot = 0xff;
- per_cpu(cpu_state, cpu) = CPU_DEAD;
-
- mb();
-
- while (1) /* core will be reset here */
- ;
-}
-
static void start_after_reset(void)
{
kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index 88ebd83..c8035e5 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -77,8 +77,10 @@ static inline void __cpu_die(unsigned int cpu)
mp_ops->cpu_die(cpu);
}
+#endif
-extern void play_dead(void);
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
+void play_dead(bool kexec);
#endif
/*
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 8d85046..1aa24bb 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -53,7 +53,7 @@
#ifdef CONFIG_HOTPLUG_CPU
void arch_cpu_idle_dead(void)
{
- play_dead();
+ play_dead(false);
}
#endif
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 159e83a..e1c11bd 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -381,9 +381,14 @@ static void bmips_cpu_die(unsigned int cpu)
{
}
-void __ref play_dead(void)
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
+
+void __ref play_dead(bool kexec)
{
- idle_task_exit();
+ if (!kexec)
+ idle_task_exit();
/* flush data cache */
_dma_cache_wback_inv(0, ~0);
@@ -409,7 +414,7 @@ void __ref play_dead(void)
: : : "memory");
}
-#endif /* CONFIG_HOTPLUG_CPU */
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
const struct plat_smp_ops bmips43xx_smp_ops = {
.smp_setup = bmips_smp_setup,
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 03f1026..aeade5b 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -398,27 +398,7 @@ static void cps_smp_finish(void)
local_irq_enable();
}
-#ifdef CONFIG_HOTPLUG_CPU
-
-static int cps_cpu_disable(void)
-{
- unsigned cpu = smp_processor_id();
- struct core_boot_config *core_cfg;
-
- if (!cpu)
- return -EBUSY;
-
- if (!cps_pm_support_state(CPS_PM_POWER_GATED))
- return -EINVAL;
-
- core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)];
- atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask);
- smp_mb__after_atomic();
- set_cpu_online(cpu, false);
- calculate_cpu_foreign_map();
-
- return 0;
-}
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
static unsigned cpu_death_sibling;
static enum {
@@ -426,12 +406,18 @@ static enum {
CPU_DEATH_POWER,
} cpu_death;
-void play_dead(void)
+void play_dead(bool kexec)
{
unsigned int cpu, core, vpe_id;
local_irq_disable();
- idle_task_exit();
+ /*
+ * Don't bother dealing with idle task's mm as we are executing the
+ * new kernel.
+ */
+ if (!kexec)
+ idle_task_exit();
+
cpu = smp_processor_id();
core = cpu_core(&cpu_data[cpu]);
cpu_death = CPU_DEATH_POWER;
@@ -454,7 +440,8 @@ void play_dead(void)
}
/* This CPU has chosen its way out */
- (void)cpu_report_death();
+ if (!kexec)
+ (void)cpu_report_death();
if (cpu_death == CPU_DEATH_HALT) {
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
@@ -480,6 +467,31 @@ void play_dead(void)
panic("Failed to offline CPU %u", cpu);
}
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int cps_cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct core_boot_config *core_cfg;
+
+ if (!cpu)
+ return -EBUSY;
+
+ if (!cps_pm_support_state(CPS_PM_POWER_GATED))
+ return -EINVAL;
+
+ core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)];
+ atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask);
+ /* make sure the change is perceived before setting offline */
+ smp_mb__after_atomic();
+ set_cpu_online(cpu, false);
+ calculate_cpu_foreign_map();
+
+ return 0;
+}
+
static void wait_for_sibling_halt(void *ptr_cpu)
{
unsigned cpu = (unsigned long)ptr_cpu;
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 8501109..5fcf0f8 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -455,6 +455,48 @@ static void loongson3_cpu_die(unsigned int cpu)
mb();
}
+static int loongson3_disable_clock(unsigned int cpu)
+{
+ u64 core_id = cpu_core(&cpu_data[cpu]);
+ u64 package_id = cpu_data[cpu].package;
+
+ if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
+ LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
+ } else {
+ if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
+ LOONGSON_FREQCTRL(package_id) &=
+ ~(1 << (core_id * 4 + 3));
+ }
+ return 0;
+}
+
+static int loongson3_enable_clock(unsigned int cpu)
+{
+ u64 core_id = cpu_core(&cpu_data[cpu]);
+ u64 package_id = cpu_data[cpu].package;
+
+ if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
+ LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
+ } else {
+ if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
+ LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
+ }
+ return 0;
+}
+
+static int register_loongson3_notifier(void)
+{
+ return cpuhp_setup_state_nocalls(CPUHP_MIPS_SOC_PREPARE,
+ "mips/loongson:prepare",
+ loongson3_enable_clock,
+ loongson3_disable_clock);
+}
+early_initcall(register_loongson3_notifier);
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
+
/* To shutdown a core in Loongson 3, the target core should go to CKSEG1 and
* flush all L1 entries at first. Then, another core (usually Core 0) can
* safely disable the clock of the target core. loongson3_play_dead() is
@@ -668,13 +710,14 @@ static void loongson3b_play_dead(int *state_addr)
: "a1");
}
-void play_dead(void)
+void play_dead(bool kexec)
{
int *state_addr;
unsigned int cpu = smp_processor_id();
void (*play_dead_at_ckseg1)(int *);
- idle_task_exit();
+ if (!kexec)
+ idle_task_exit();
switch (read_c0_prid() & PRID_REV_MASK) {
case PRID_REV_LOONGSON3A_R1:
default:
@@ -697,44 +740,7 @@ void play_dead(void)
play_dead_at_ckseg1(state_addr);
}
-static int loongson3_disable_clock(unsigned int cpu)
-{
- uint64_t core_id = cpu_core(&cpu_data[cpu]);
- uint64_t package_id = cpu_data[cpu].package;
-
- if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
- LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
- } else {
- if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
- LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
- }
- return 0;
-}
-
-static int loongson3_enable_clock(unsigned int cpu)
-{
- uint64_t core_id = cpu_core(&cpu_data[cpu]);
- uint64_t package_id = cpu_data[cpu].package;
-
- if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
- LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
- } else {
- if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
- LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
- }
- return 0;
-}
-
-static int register_loongson3_notifier(void)
-{
- return cpuhp_setup_state_nocalls(CPUHP_MIPS_SOC_PREPARE,
- "mips/loongson:prepare",
- loongson3_enable_clock,
- loongson3_disable_clock);
-}
-early_initcall(register_loongson3_notifier);
-
-#endif
+#endif /* CONFIG_HOTPLUG_CPU || CONFIG_KEXEC */
const struct plat_smp_ops loongson3_smp_ops = {
.send_ipi_single = loongson3_send_ipi_single,
--
2.7.4
^ permalink raw reply related
* [LTP] [PATCH v2] Rename TEST_ERRNO and TEST_RETURN for new test lib
From: Jan Stancek @ 2018-07-23 14:49 UTC (permalink / raw)
To: ltp
In-Reply-To: <20180723132450.28747-1-clanig@suse.com>
----- Original Message -----
> Signed-off-by: Christian Lanig <clanig@suse.com>
> ---
> Hi,
>
> I have changed the variables as requested. In my previous version
> I forgot that headers can include headers and made wrong assumptions
> for files that don't include "tst_test.h" directly. Sorry for the confusion.
>
> Regards,
> Christian
v2 looks good to me.
Commit message could include link/reference to github issue
(no need to re-post atm.)
Thanks,
Jan
^ permalink raw reply
* [PATCH v3 6/6] MIPS: kexec: Use prepare method from generic platform as default option
From: Dengcheng Zhu @ 2018-07-23 14:48 UTC (permalink / raw)
To: pburton, ralf; +Cc: linux-mips, rachel.mozes, Dengcheng Zhu
In-Reply-To: <1532357299-8063-1-git-send-email-dzhu@wavecomp.com>
The kexec_prepare method for the generic platform should be applicable to
other platforms. For those otherwise, like Octeon, they will use their own
_machine_kexec_prepare().
Without the default prepare work, platforms other than the generic one will
not be able to automatically set up command line correctly for the new
kernel.
Tested-by: Rachel Mozes <rachel.mozes@intel.com>
Reported-by: Rachel Mozes <rachel.mozes@intel.com>
Signed-off-by: Dengcheng Zhu <dzhu@wavecomp.com>
---
Changes:
* Add LIBFDT to CPU_LOONGSON3 for default_machine_kexec_prepare().
arch/mips/Kconfig | 1 +
arch/mips/generic/Makefile | 1 -
arch/mips/generic/kexec.c | 44 ----------------------------------------
arch/mips/kernel/machine_kexec.c | 34 ++++++++++++++++++++++++++++++-
4 files changed, 34 insertions(+), 46 deletions(-)
delete mode 100644 arch/mips/generic/kexec.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 08c10c5..df62764 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1374,6 +1374,7 @@ config CPU_LOONGSON3
select MIPS_L1_CACHE_SHIFT_6
select GPIOLIB
select SWIOTLB
+ select LIBFDT
help
The Loongson 3 processor implements the MIPS64R2 instruction
set with many extensions.
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index d03a36f..181aa13 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -15,5 +15,4 @@ obj-y += proc.o
obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o
-obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o
diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c
deleted file mode 100644
index 1ca409f..0000000
--- a/arch/mips/generic/kexec.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2016 Imagination Technologies
- * Author: Marcin Nowakowski <marcin.nowakowski@mips.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/kexec.h>
-#include <linux/libfdt.h>
-#include <linux/uaccess.h>
-
-static int generic_kexec_prepare(struct kimage *image)
-{
- int i;
-
- for (i = 0; i < image->nr_segments; i++) {
- struct fdt_header fdt;
-
- if (image->segment[i].memsz <= sizeof(fdt))
- continue;
-
- if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt)))
- continue;
-
- if (fdt_check_header(&fdt))
- continue;
-
- kexec_args[0] = -2;
- kexec_args[1] = (unsigned long)
- phys_to_virt((unsigned long)image->segment[i].mem);
- break;
- }
- return 0;
-}
-
-static int __init register_generic_kexec(void)
-{
- _machine_kexec_prepare = generic_kexec_prepare;
- return 0;
-}
-arch_initcall(register_generic_kexec);
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 6e3f7c8..e3efb64 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -9,6 +9,7 @@
#include <linux/kexec.h>
#include <linux/mm.h>
#include <linux/delay.h>
+#include <linux/libfdt.h>
#include <asm/cacheflush.h>
#include <asm/page.h>
@@ -65,6 +66,36 @@ static void kexec_image_info(const struct kimage *kimage)
}
}
+static int default_machine_kexec_prepare(struct kimage *kimage)
+{
+ int i;
+
+ /*
+ * In case DTB file is not passed to the new kernel, a flat device
+ * tree will be created by kexec tool. It holds modified command
+ * line for the new kernel.
+ */
+ for (i = 0; i < kimage->nr_segments; i++) {
+ struct fdt_header fdt;
+
+ if (kimage->segment[i].memsz <= sizeof(fdt))
+ continue;
+
+ if (copy_from_user(&fdt, kimage->segment[i].buf, sizeof(fdt)))
+ continue;
+
+ if (fdt_check_header(&fdt))
+ continue;
+
+ kexec_args[0] = -2;
+ kexec_args[1] = (unsigned long)
+ phys_to_virt((unsigned long)kimage->segment[i].mem);
+ break;
+ }
+
+ return 0;
+}
+
int
machine_kexec_prepare(struct kimage *kimage)
{
@@ -72,7 +103,8 @@ machine_kexec_prepare(struct kimage *kimage)
if (_machine_kexec_prepare)
return _machine_kexec_prepare(kimage);
- return 0;
+ else
+ return default_machine_kexec_prepare(kimage);
}
void
--
2.7.4
^ permalink raw reply related
* [PATCH v3 5/6] MIPS: kexec: Relax memory restriction
From: Dengcheng Zhu @ 2018-07-23 14:48 UTC (permalink / raw)
To: pburton, ralf; +Cc: linux-mips, rachel.mozes, Dengcheng Zhu
In-Reply-To: <1532357299-8063-1-git-send-email-dzhu@wavecomp.com>
We can rely on the system kernel and the dump capture kernel themselves in
memory usage.
Being restrictive with 512MB limit may cause kexec tool failure on some
platforms.
Tested-by: Rachel Mozes <rachel.mozes@intel.com>
Reported-by: Rachel Mozes <rachel.mozes@intel.com>
Signed-off-by: Dengcheng Zhu <dzhu@wavecomp.com>
---
arch/mips/include/asm/kexec.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/mips/include/asm/kexec.h b/arch/mips/include/asm/kexec.h
index 33f31a8..2583e6a 100644
--- a/arch/mips/include/asm/kexec.h
+++ b/arch/mips/include/asm/kexec.h
@@ -12,11 +12,11 @@
#include <asm/stacktrace.h>
/* Maximum physical address we can use pages from */
-#define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000)
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/* Maximum address we can reach in physical address mode */
-#define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000)
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
-#define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000)
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
/* Reserve 3*4096 bytes for board-specific info */
#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096)
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.