* Re: [PATCH 6/7] thermal: max77620: fix device-node reference imbalance
From: Tyrel Datwyler @ 2017-05-30 22:59 UTC (permalink / raw)
To: Johan Hovold, Greg Kroah-Hartman
Cc: Linus Walleij, Peter Chen, Rob Herring, Arnd Bergmann,
Sricharan R, Zhang Rui, Eduardo Valentin, linux-pm, linux-usb,
linux-kernel, stable, Laxman Dewangan
In-Reply-To: <20170530162554.26159-7-johan@kernel.org>
On 05/30/2017 09:25 AM, Johan Hovold wrote:
> The thermal child device reuses the parent MFD-device device-tree node
> when registering a thermal zone, but did not take a reference to the
> node.
>
> This leads to a reference imbalance, and potential use-after-free, when
> the node reference is dropped by the platform-bus device destructor
> (once for the child and later again for the parent).
>
> Fix this by dropping any reference already held to a device-tree node
> and getting a reference to the parent's node which will be balanced on
> reprobe or on platform-device release, whichever comes first.
>
> Note that simply clearing the of_node pointer on probe errors and on
> driver unbind would not allow the use of device-managed resources as
> specifically thermal_zone_of_sensor_unregister() claims that a valid
> device-tree node pointer is needed during deregistration (even if it
> currently does not seem to use it).
>
> Fixes: ec4664b3fd6d ("thermal: max77620: Add thermal driver for reporting junction temp")
> Cc: stable <stable@vger.kernel.org> # 4.9
> Cc: Laxman Dewangan <ldewangan@nvidia.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
> drivers/thermal/max77620_thermal.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
> index e9a1fe342760..71d35f3c9215 100644
> --- a/drivers/thermal/max77620_thermal.c
> +++ b/drivers/thermal/max77620_thermal.c
> @@ -104,8 +104,6 @@ static int max77620_thermal_probe(struct platform_device *pdev)
> return -EINVAL;
> }
>
> - pdev->dev.of_node = pdev->dev.parent->of_node;
> -
> mtherm->dev = &pdev->dev;
> mtherm->rmap = dev_get_regmap(pdev->dev.parent, NULL);
> if (!mtherm->rmap) {
> @@ -113,6 +111,14 @@ static int max77620_thermal_probe(struct platform_device *pdev)
> return -ENODEV;
> }
>
> + /*
> + * Drop any current reference to a device-tree node and get a
> + * reference to the parent's node which will be balanced on reprobe or
> + * on platform-device release.
> + */
> + of_node_put(pdev->dev.of_node);
> + pdev->dev.of_node = of_node_get(pdev->dev.parent->of_node);
> +
This seems like needless churn. Can't this just be squashed into patch #7?
-Tyrel
> mtherm->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
> mtherm, &max77620_thermal_ops);
> if (IS_ERR(mtherm->tz_device)) {
>
^ permalink raw reply
* Re: [PATCH 1/7] USB: core: fix device node leak
From: Tyrel Datwyler @ 2017-05-30 22:55 UTC (permalink / raw)
To: Johan Hovold, Greg Kroah-Hartman
Cc: Linus Walleij, Peter Chen, Rob Herring, Arnd Bergmann,
Sricharan R, Zhang Rui, Eduardo Valentin, linux-pm, linux-usb,
linux-kernel, stable, Peter Chen
In-Reply-To: <20170530162554.26159-2-johan@kernel.org>
On 05/30/2017 09:25 AM, Johan Hovold wrote:
> Make sure to release any OF device-node reference taken when creating
> the USB device.
>
> Note that we currently do not hold a reference to the root hub
> device-tree node (i.e. the parent controller node).
>
> Fixes: 69bec7259853 ("USB: core: let USB device know device node")
> Cc: stable <stable@vger.kernel.org> # v4.6
> Cc: Peter Chen <peter.chen@nxp.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
> drivers/usb/core/usb.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
> index 28b053cacc90..62e1906bb2f3 100644
> --- a/drivers/usb/core/usb.c
> +++ b/drivers/usb/core/usb.c
> @@ -416,6 +416,8 @@ static void usb_release_dev(struct device *dev)
>
> usb_destroy_configuration(udev);
> usb_release_bos_descriptor(udev);
> + if (udev->parent)
> + of_node_put(dev->of_node);
If I'm following the root hub doesn't hold an of_node reference, so does that guarantee
that dev->of_node is NULL for the root hub? If so of_node_put() is safely called with a
NULL reference, making the if(udev->parent) unnecessary, and further no need to remove it
in follow-up patch #5.
-Tyrel
> usb_put_hcd(hcd);
> kfree(udev->product);
> kfree(udev->manufacturer);
>
^ permalink raw reply
* Re: Fix on ipv6/dccp applicable to stable
From: Cong Wang @ 2017-05-30 20:52 UTC (permalink / raw)
To: Eduardo Valentin; +Cc: Eric Dumazet, Greg KH, stable
In-Reply-To: <20170530184340.GD7419@u40b0340c692b58f6553c.ant.amazon.com>
On Tue, May 30, 2017 at 11:43 AM, Eduardo Valentin <eduval@amazon.com> wrote:
> Folks,
>
> I was checking the CVE-2017-9076 [1], which mentions this commit:
>
> commit 83eaddab4378db256d00d295bda6ca997cd13a52
> Author: WANG Cong <xiyou.wangcong@gmail.com>
> Date: Tue May 9 16:59:54 2017 -0700
>
> ipv6/dccp: do not inherit ipv6_mc_list from parent
>
> Like commit 657831ffc38e ("dccp/tcp: do not inherit mc_list from parent")
> we should clear ipv6_mc_list etc. for IPv6 sockets too.
>
> Cc: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
> Acked-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
>
> And I was wondering if it could simply be sent to stable trees. The change
> can be cherry-picked on 4.9.y, for example.
Yes, this commit should be backported to stable releases together with
the following two commits:
commit 657831ffc38e30092a2d5f03d385d710eb88b09a
Author: Eric Dumazet <edumazet@google.com>
Date: Tue May 9 06:29:19 2017 -0700
dccp/tcp: do not inherit mc_list from parent
commit fdcee2cbb8438702ea1b328fb6e0ac5e9a40c7f8
Author: Eric Dumazet <edumazet@google.com>
Date: Wed May 17 07:16:40 2017 -0700
sctp: do not inherit ipv6_{mc|ac|fl}_list from parent
Thanks.
^ permalink raw reply
* Fix on ipv6/dccp applicable to stable
From: Eduardo Valentin @ 2017-05-30 18:43 UTC (permalink / raw)
To: Eric Dumazet, WANG Cong, Greg KH; +Cc: stable
Folks,
I was checking the CVE-2017-9076 [1], which mentions this commit:
commit 83eaddab4378db256d00d295bda6ca997cd13a52
Author: WANG Cong <xiyou.wangcong@gmail.com>
Date: Tue May 9 16:59:54 2017 -0700
ipv6/dccp: do not inherit ipv6_mc_list from parent
Like commit 657831ffc38e ("dccp/tcp: do not inherit mc_list from parent")
we should clear ipv6_mc_list etc. for IPv6 sockets too.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
And I was wondering if it could simply be sent to stable trees. The change
can be cherry-picked on 4.9.y, for example.
Greg, what do you think?
[1] - https://nvd.nist.gov/vuln/detail/CVE-2017-9076#VulnChangeHistoryDiv
--
All the best,
Eduardo Valentin
^ permalink raw reply
* Re: [PATCH] libata: Fix devres handling
From: Tejun Heo @ 2017-05-30 17:59 UTC (permalink / raw)
To: Linus Walleij; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, stable
In-Reply-To: <CACRpkdY696hTcdDwoCg6GPi_VG7Q=iC8yt8iJQMQ5FYQ_S3fqw@mail.gmail.com>
Hello, Linus.
On Tue, May 30, 2017 at 11:21:24AM +0200, Linus Walleij wrote:
> This is because my driver issues platform_set_drvdata(pdev)
> on the same struct device * overwriting the data with
> its own. That function is just an alias for dev_set_drvdata().
I see.
> Amazingly, libata survives this until release.
That is surprising given that libata does depend on that drvdata quite
a bit.
> Maybe we should print a warning if dev_get_drvdata()
> and res differ? It's a sign that something is wrong because
> someone screwed with the drvdata behind the back of
> libata.
Please feel free to submit a patch to add WARN_ON there.
> I guess I will simply make a cleanup series for these,
> making sure they use host->private_data instead and do not
> double-write the drvdata.
Great.
Thanks for working on this!
--
tejun
^ permalink raw reply
* Re: [PATCH 4.4 018/103] md: update slab_cache before releasing new stripes when stripes resizing
From: Shaohua Li @ 2017-05-30 17:27 UTC (permalink / raw)
To: Ben Hutchings
Cc: Dennis Yang, NeilBrown, Shaohua Li, linux-kernel, stable,
Greg Kroah-Hartman
In-Reply-To: <1496150213.2083.55.camel@codethink.co.uk>
On Tue, May 30, 2017 at 02:16:53PM +0100, Ben Hutchings wrote:
> On Tue, 2017-05-23 at 22:08 +0200, Greg Kroah-Hartman wrote:
> > 4.4-stable review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Dennis Yang <dennisyang@qnap.com>
> >
> > commit 583da48e388f472e8818d9bb60ef6a1d40ee9f9d upstream.
> >
> > When growing raid5 device on machine with small memory, there is chance that
> > mdadm will be killed and the following bug report can be observed. The same
> > bug could also be reproduced in linux-4.10.6.
> [...]
> > The problem is that resize_stripes() releases new stripe_heads before assigning new
> > slab cache to conf->slab_cache. If the shrinker function raid5_cache_scan() gets called
> > after resize_stripes() starting releasing new stripes but right before new slab cache
> > being assigned, it is possible that these new stripe_heads will be freed with the old
> > slab_cache which was already been destoryed and that triggers this bug.
> [...]
> > --- a/drivers/md/raid5.c
> > +++ b/drivers/md/raid5.c
> > @@ -2232,6 +2232,10 @@ static int resize_stripes(struct r5conf
> > err = -ENOMEM;
> >
> > mutex_unlock(&conf->cache_size_mutex);
> > +
> > + conf->slab_cache = sc;
> > + conf->active_name = 1-conf->active_name;
> > +
> > /* Step 4, return new stripes to service */
> > while(!list_empty(&newstripes)) {
> > nsh = list_entry(newstripes.next, struct stripe_head, lru);
> [...]
>
> The assignments are still being done after conf->cache_size_mutex is
> unlocked, so there still seems to be a race with raid5_cache_scan().
> Shouldn't they be moved above the mutex_unlock()?
Unnecessary. The raid5_cache_scan can't free any stripe to slab_cache before
the stripe is called with raid5_release_stripe.
Thanks,
SHaohua
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: Program ring for vce instance 1 at its register space
From: Leo Liu @ 2017-05-30 16:27 UTC (permalink / raw)
To: Christian König, amd-gfx; +Cc: stable
In-Reply-To: <df87fdbc-60f9-32c0-9c38-66123473cadb@vodafone.de>
On 05/30/2017 12:15 PM, Christian König wrote:
> Am 30.05.2017 um 17:56 schrieb Leo Liu:
>> We need program ring buffer on instance 1 register space domain,
>> when only if instance 1 available, with two instances or instance 0,
>> and we need only program instance 0 regsiter space domain for ring.
>>
>> Signed-off-by: Leo Liu <leo.liu@amd.com>
>> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
>> Cc: stable@vger.kernel.org
>> ---
>> drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 95
>> +++++++++++++++++++++++++----------
>> 1 file changed, 68 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
>> b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
>> index fb08193..7e39e42 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
>> @@ -77,13 +77,26 @@ static int vce_v3_0_set_clockgating_state(void
>> *handle,
>> static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
>> {
>> struct amdgpu_device *adev = ring->adev;
>> + u32 v;
>> +
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + mutex_lock(&adev->grbm_idx_mutex);
>> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
>> + }
>
> Did you missed my comment? I think we should always grab the mutex and
> program mmGRBM_GFX_INDEX.
No I haven't , I did move the programming the ring regs from "vce_start"
for Instance 0, to under mutex and mmGRBM_GFX_INDEX.
IMO, I don't think we need this here, because "mutex lock +
mmGRBM_GFX_INDEX" and "mutex unlock+mmGRBM_GFX_DEFAULT" are always
paired, So it should be always in default space when instance 0, and we
do take care the case for instance 1 only.
I can follow your comment for here and other place in my patch for
get/set w/rptr.
Thanks,
Leo
>
> Otherwise we silently rely on that it is correctly set when the
> function is called and have different code path for different
> harvested configs.
>
> Apart from that the patch looks good to me.
>
> Christian.
>
>> if (ring == &adev->vce.ring[0])
>> - return RREG32(mmVCE_RB_RPTR);
>> + v = RREG32(mmVCE_RB_RPTR);
>> else if (ring == &adev->vce.ring[1])
>> - return RREG32(mmVCE_RB_RPTR2);
>> + v = RREG32(mmVCE_RB_RPTR2);
>> else
>> - return RREG32(mmVCE_RB_RPTR3);
>> + v = RREG32(mmVCE_RB_RPTR3);
>> +
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
>> + mutex_unlock(&adev->grbm_idx_mutex);
>> + }
>> +
>> + return v;
>> }
>> /**
>> @@ -96,13 +109,26 @@ static uint64_t vce_v3_0_ring_get_rptr(struct
>> amdgpu_ring *ring)
>> static uint64_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
>> {
>> struct amdgpu_device *adev = ring->adev;
>> + u32 v;
>> +
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + mutex_lock(&adev->grbm_idx_mutex);
>> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
>> + }
>> if (ring == &adev->vce.ring[0])
>> - return RREG32(mmVCE_RB_WPTR);
>> + v = RREG32(mmVCE_RB_WPTR);
>> else if (ring == &adev->vce.ring[1])
>> - return RREG32(mmVCE_RB_WPTR2);
>> + v = RREG32(mmVCE_RB_WPTR2);
>> else
>> - return RREG32(mmVCE_RB_WPTR3);
>> + v = RREG32(mmVCE_RB_WPTR3);
>> +
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
>> + mutex_unlock(&adev->grbm_idx_mutex);
>> + }
>> +
>> + return v;
>> }
>> /**
>> @@ -116,12 +142,22 @@ static void vce_v3_0_ring_set_wptr(struct
>> amdgpu_ring *ring)
>> {
>> struct amdgpu_device *adev = ring->adev;
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + mutex_lock(&adev->grbm_idx_mutex);
>> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
>> + }
>> +
>> if (ring == &adev->vce.ring[0])
>> WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
>> else if (ring == &adev->vce.ring[1])
>> WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
>> else
>> WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
>> +
>> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
>> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
>> + mutex_unlock(&adev->grbm_idx_mutex);
>> + }
>> }
>> static void vce_v3_0_override_vce_clock_gating(struct
>> amdgpu_device *adev, bool override)
>> @@ -231,33 +267,38 @@ static int vce_v3_0_start(struct amdgpu_device
>> *adev)
>> struct amdgpu_ring *ring;
>> int idx, r;
>> - ring = &adev->vce.ring[0];
>> - WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
>> - WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
>> - WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
>> -
>> - ring = &adev->vce.ring[1];
>> - WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
>> - WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
>> - WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
>> -
>> - ring = &adev->vce.ring[2];
>> - WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
>> - WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
>> - WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
>> - WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
>> -
>> mutex_lock(&adev->grbm_idx_mutex);
>> for (idx = 0; idx < 2; ++idx) {
>> if (adev->vce.harvest_config & (1 << idx))
>> continue;
>> WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(idx));
>> +
>> + /* Program instance 0 reg space for two instances or
>> instance 0 case
>> + program instance 1 reg space for only instance 1 available
>> case */
>> + if (idx != 1 || adev->vce.harvest_config ==
>> AMDGPU_VCE_HARVEST_VCE0) {
>> + ring = &adev->vce.ring[0];
>> + WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
>> + WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
>> + WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
>> +
>> + ring = &adev->vce.ring[1];
>> + WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
>> + WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
>> + WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
>> +
>> + ring = &adev->vce.ring[2];
>> + WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
>> + WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
>> + WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
>> + WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
>> + }
>> +
>> vce_v3_0_mc_resume(adev, idx);
>> WREG32_FIELD(VCE_STATUS, JOB_BUSY, 1);
>
>
^ permalink raw reply
* [PATCH 6/7] thermal: max77620: fix device-node reference imbalance
From: Johan Hovold @ 2017-05-30 16:25 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Linus Walleij, Peter Chen, Rob Herring, Arnd Bergmann,
Sricharan R, Zhang Rui, Eduardo Valentin, linux-pm, linux-usb,
linux-kernel, Johan Hovold, stable, Laxman Dewangan
In-Reply-To: <20170530162554.26159-1-johan@kernel.org>
The thermal child device reuses the parent MFD-device device-tree node
when registering a thermal zone, but did not take a reference to the
node.
This leads to a reference imbalance, and potential use-after-free, when
the node reference is dropped by the platform-bus device destructor
(once for the child and later again for the parent).
Fix this by dropping any reference already held to a device-tree node
and getting a reference to the parent's node which will be balanced on
reprobe or on platform-device release, whichever comes first.
Note that simply clearing the of_node pointer on probe errors and on
driver unbind would not allow the use of device-managed resources as
specifically thermal_zone_of_sensor_unregister() claims that a valid
device-tree node pointer is needed during deregistration (even if it
currently does not seem to use it).
Fixes: ec4664b3fd6d ("thermal: max77620: Add thermal driver for reporting junction temp")
Cc: stable <stable@vger.kernel.org> # 4.9
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/thermal/max77620_thermal.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/max77620_thermal.c b/drivers/thermal/max77620_thermal.c
index e9a1fe342760..71d35f3c9215 100644
--- a/drivers/thermal/max77620_thermal.c
+++ b/drivers/thermal/max77620_thermal.c
@@ -104,8 +104,6 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return -EINVAL;
}
- pdev->dev.of_node = pdev->dev.parent->of_node;
-
mtherm->dev = &pdev->dev;
mtherm->rmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!mtherm->rmap) {
@@ -113,6 +111,14 @@ static int max77620_thermal_probe(struct platform_device *pdev)
return -ENODEV;
}
+ /*
+ * Drop any current reference to a device-tree node and get a
+ * reference to the parent's node which will be balanced on reprobe or
+ * on platform-device release.
+ */
+ of_node_put(pdev->dev.of_node);
+ pdev->dev.of_node = of_node_get(pdev->dev.parent->of_node);
+
mtherm->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
mtherm, &max77620_thermal_ops);
if (IS_ERR(mtherm->tz_device)) {
--
2.13.0
^ permalink raw reply related
* [PATCH 1/7] USB: core: fix device node leak
From: Johan Hovold @ 2017-05-30 16:25 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Linus Walleij, Peter Chen, Rob Herring, Arnd Bergmann,
Sricharan R, Zhang Rui, Eduardo Valentin, linux-pm, linux-usb,
linux-kernel, Johan Hovold, stable, Peter Chen
In-Reply-To: <20170530162554.26159-1-johan@kernel.org>
Make sure to release any OF device-node reference taken when creating
the USB device.
Note that we currently do not hold a reference to the root hub
device-tree node (i.e. the parent controller node).
Fixes: 69bec7259853 ("USB: core: let USB device know device node")
Cc: stable <stable@vger.kernel.org> # v4.6
Cc: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/usb/core/usb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 28b053cacc90..62e1906bb2f3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -416,6 +416,8 @@ static void usb_release_dev(struct device *dev)
usb_destroy_configuration(udev);
usb_release_bos_descriptor(udev);
+ if (udev->parent)
+ of_node_put(dev->of_node);
usb_put_hcd(hcd);
kfree(udev->product);
kfree(udev->manufacturer);
--
2.13.0
^ permalink raw reply related
* Re: [PATCH] drm/amdgpu: Program ring for vce instance 1 at its register space
From: Christian König @ 2017-05-30 16:15 UTC (permalink / raw)
To: Leo Liu, amd-gfx; +Cc: stable
In-Reply-To: <20170530155650.5775-1-leo.liu@amd.com>
Am 30.05.2017 um 17:56 schrieb Leo Liu:
> We need program ring buffer on instance 1 register space domain,
> when only if instance 1 available, with two instances or instance 0,
> and we need only program instance 0 regsiter space domain for ring.
>
> Signed-off-by: Leo Liu <leo.liu@amd.com>
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@vger.kernel.org
> ---
> drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 95 +++++++++++++++++++++++++----------
> 1 file changed, 68 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> index fb08193..7e39e42 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
> @@ -77,13 +77,26 @@ static int vce_v3_0_set_clockgating_state(void *handle,
> static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
> {
> struct amdgpu_device *adev = ring->adev;
> + u32 v;
> +
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + mutex_lock(&adev->grbm_idx_mutex);
> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
> + }
Did you missed my comment? I think we should always grab the mutex and
program mmGRBM_GFX_INDEX.
Otherwise we silently rely on that it is correctly set when the function
is called and have different code path for different harvested configs.
Apart from that the patch looks good to me.
Christian.
>
> if (ring == &adev->vce.ring[0])
> - return RREG32(mmVCE_RB_RPTR);
> + v = RREG32(mmVCE_RB_RPTR);
> else if (ring == &adev->vce.ring[1])
> - return RREG32(mmVCE_RB_RPTR2);
> + v = RREG32(mmVCE_RB_RPTR2);
> else
> - return RREG32(mmVCE_RB_RPTR3);
> + v = RREG32(mmVCE_RB_RPTR3);
> +
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
> + mutex_unlock(&adev->grbm_idx_mutex);
> + }
> +
> + return v;
> }
>
> /**
> @@ -96,13 +109,26 @@ static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
> static uint64_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
> {
> struct amdgpu_device *adev = ring->adev;
> + u32 v;
> +
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + mutex_lock(&adev->grbm_idx_mutex);
> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
> + }
>
> if (ring == &adev->vce.ring[0])
> - return RREG32(mmVCE_RB_WPTR);
> + v = RREG32(mmVCE_RB_WPTR);
> else if (ring == &adev->vce.ring[1])
> - return RREG32(mmVCE_RB_WPTR2);
> + v = RREG32(mmVCE_RB_WPTR2);
> else
> - return RREG32(mmVCE_RB_WPTR3);
> + v = RREG32(mmVCE_RB_WPTR3);
> +
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
> + mutex_unlock(&adev->grbm_idx_mutex);
> + }
> +
> + return v;
> }
>
> /**
> @@ -116,12 +142,22 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
> {
> struct amdgpu_device *adev = ring->adev;
>
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + mutex_lock(&adev->grbm_idx_mutex);
> + WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
> + }
> +
> if (ring == &adev->vce.ring[0])
> WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
> else if (ring == &adev->vce.ring[1])
> WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
> else
> WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
> +
> + if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
> + mutex_unlock(&adev->grbm_idx_mutex);
> + }
> }
>
> static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
> @@ -231,33 +267,38 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
> struct amdgpu_ring *ring;
> int idx, r;
>
> - ring = &adev->vce.ring[0];
> - WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
> - WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
> - WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
> -
> - ring = &adev->vce.ring[1];
> - WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
> - WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
> - WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
> -
> - ring = &adev->vce.ring[2];
> - WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
> - WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
> - WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
> - WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
> -
> mutex_lock(&adev->grbm_idx_mutex);
> for (idx = 0; idx < 2; ++idx) {
> if (adev->vce.harvest_config & (1 << idx))
> continue;
>
> WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(idx));
> +
> + /* Program instance 0 reg space for two instances or instance 0 case
> + program instance 1 reg space for only instance 1 available case */
> + if (idx != 1 || adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
> + ring = &adev->vce.ring[0];
> + WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
> + WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
> + WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
> +
> + ring = &adev->vce.ring[1];
> + WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
> + WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
> + WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
> +
> + ring = &adev->vce.ring[2];
> + WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
> + WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
> + WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
> + WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
> + }
> +
> vce_v3_0_mc_resume(adev, idx);
> WREG32_FIELD(VCE_STATUS, JOB_BUSY, 1);
>
^ permalink raw reply
* [PATCH] drm/amdgpu: Program ring for vce instance 1 at its register space
From: Leo Liu @ 2017-05-30 15:56 UTC (permalink / raw)
To: amd-gfx; +Cc: Leo Liu, stable
In-Reply-To: <20170529182152.7451-1-leo.liu@amd.com>
We need program ring buffer on instance 1 register space domain,
when only if instance 1 available, with two instances or instance 0,
and we need only program instance 0 regsiter space domain for ring.
Signed-off-by: Leo Liu <leo.liu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 95 +++++++++++++++++++++++++----------
1 file changed, 68 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index fb08193..7e39e42 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -77,13 +77,26 @@ static int vce_v3_0_set_clockgating_state(void *handle,
static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
+ u32 v;
+
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ mutex_lock(&adev->grbm_idx_mutex);
+ WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
+ }
if (ring == &adev->vce.ring[0])
- return RREG32(mmVCE_RB_RPTR);
+ v = RREG32(mmVCE_RB_RPTR);
else if (ring == &adev->vce.ring[1])
- return RREG32(mmVCE_RB_RPTR2);
+ v = RREG32(mmVCE_RB_RPTR2);
else
- return RREG32(mmVCE_RB_RPTR3);
+ v = RREG32(mmVCE_RB_RPTR3);
+
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
+ mutex_unlock(&adev->grbm_idx_mutex);
+ }
+
+ return v;
}
/**
@@ -96,13 +109,26 @@ static uint64_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
static uint64_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
+ u32 v;
+
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ mutex_lock(&adev->grbm_idx_mutex);
+ WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
+ }
if (ring == &adev->vce.ring[0])
- return RREG32(mmVCE_RB_WPTR);
+ v = RREG32(mmVCE_RB_WPTR);
else if (ring == &adev->vce.ring[1])
- return RREG32(mmVCE_RB_WPTR2);
+ v = RREG32(mmVCE_RB_WPTR2);
else
- return RREG32(mmVCE_RB_WPTR3);
+ v = RREG32(mmVCE_RB_WPTR3);
+
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
+ mutex_unlock(&adev->grbm_idx_mutex);
+ }
+
+ return v;
}
/**
@@ -116,12 +142,22 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ mutex_lock(&adev->grbm_idx_mutex);
+ WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(1));
+ }
+
if (ring == &adev->vce.ring[0])
WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
else if (ring == &adev->vce.ring[1])
WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
else
WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
+
+ if (adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT);
+ mutex_unlock(&adev->grbm_idx_mutex);
+ }
}
static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
@@ -231,33 +267,38 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
struct amdgpu_ring *ring;
int idx, r;
- ring = &adev->vce.ring[0];
- WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
- WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
- WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
-
- ring = &adev->vce.ring[1];
- WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
- WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
- WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
-
- ring = &adev->vce.ring[2];
- WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
- WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
- WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
- WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
-
mutex_lock(&adev->grbm_idx_mutex);
for (idx = 0; idx < 2; ++idx) {
if (adev->vce.harvest_config & (1 << idx))
continue;
WREG32(mmGRBM_GFX_INDEX, GET_VCE_INSTANCE(idx));
+
+ /* Program instance 0 reg space for two instances or instance 0 case
+ program instance 1 reg space for only instance 1 available case */
+ if (idx != 1 || adev->vce.harvest_config == AMDGPU_VCE_HARVEST_VCE0) {
+ ring = &adev->vce.ring[0];
+ WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
+ WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
+ WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
+
+ ring = &adev->vce.ring[1];
+ WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
+ WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
+ WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
+
+ ring = &adev->vce.ring[2];
+ WREG32(mmVCE_RB_RPTR3, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_WPTR3, lower_32_bits(ring->wptr));
+ WREG32(mmVCE_RB_BASE_LO3, ring->gpu_addr);
+ WREG32(mmVCE_RB_BASE_HI3, upper_32_bits(ring->gpu_addr));
+ WREG32(mmVCE_RB_SIZE3, ring->ring_size / 4);
+ }
+
vce_v3_0_mc_resume(adev, idx);
WREG32_FIELD(VCE_STATUS, JOB_BUSY, 1);
--
1.9.1
^ permalink raw reply related
* [PATCH] audit: fix the RCU locking for the auditd_connection structure
From: Paul Moore @ 2017-05-30 15:55 UTC (permalink / raw)
To: stable; +Cc: linux-audit
From: Paul Moore <paul@paul-moore.com>
This patch is the stable-4.11.y backport of commit 48d0e023af97 (same
subject) in Linus' master branch. Unfortunately the commit in Linus'
tree doesn't merge cleanly in the v4.11.y tree due to the auditd PID
conversion from an int/pid_t to the pid structure; almost all of the
merge fuzzing in this patch is due to that difference.
Original patch description:
"Cong Wang correctly pointed out that the RCU read locking of the
auditd_connection struct was wrong, this patch correct this by
adopting a more traditional, and correct RCU locking model.
This patch is heavily based on an earlier prototype by Cong Wang."
Cc: <stable@vger.kernel.org> # 4.11.x-
Reported-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
---
kernel/audit.c | 167 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 115 insertions(+), 52 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index a871bf80fde1..dd2c339c8eb9 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -110,18 +110,19 @@ struct audit_net {
* @pid: auditd PID
* @portid: netlink portid
* @net: the associated network namespace
- * @lock: spinlock to protect write access
+ * @rcu: RCU head
*
* Description:
* This struct is RCU protected; you must either hold the RCU lock for reading
- * or the included spinlock for writing.
+ * or the associated spinlock for writing.
*/
static struct auditd_connection {
int pid;
u32 portid;
struct net *net;
- spinlock_t lock;
-} auditd_conn;
+ struct rcu_head rcu;
+} *auditd_conn = NULL;
+static DEFINE_SPINLOCK(auditd_conn_lock);
/* If audit_rate_limit is non-zero, limit the rate of sending audit records
* to that number per second. This prevents DoS attacks, but results in
@@ -223,15 +224,39 @@ struct audit_reply {
int auditd_test_task(const struct task_struct *task)
{
int rc;
+ struct auditd_connection *ac;
rcu_read_lock();
- rc = (auditd_conn.pid && task->tgid == auditd_conn.pid ? 1 : 0);
+ ac = rcu_dereference(auditd_conn);
+ rc = (ac && ac->pid == task->tgid ? 1 : 0);
rcu_read_unlock();
return rc;
}
/**
+ * auditd_pid_vnr - Return the auditd PID relative to the namespace
+ *
+ * Description:
+ * Returns the PID in relation to the namespace, 0 on failure.
+ */
+static pid_t auditd_pid_vnr(void)
+{
+ pid_t pid;
+ const struct auditd_connection *ac;
+
+ rcu_read_lock();
+ ac = rcu_dereference(auditd_conn);
+ if (!ac)
+ pid = 0;
+ else
+ pid = ac->pid;
+ rcu_read_unlock();
+
+ return pid;
+}
+
+/**
* audit_get_sk - Return the audit socket for the given network namespace
* @net: the destination network namespace
*
@@ -427,6 +452,23 @@ static int audit_set_failure(u32 state)
}
/**
+ * auditd_conn_free - RCU helper to release an auditd connection struct
+ * @rcu: RCU head
+ *
+ * Description:
+ * Drop any references inside the auditd connection tracking struct and free
+ * the memory.
+ */
+static void auditd_conn_free(struct rcu_head *rcu)
+{
+ struct auditd_connection *ac;
+
+ ac = container_of(rcu, struct auditd_connection, rcu);
+ put_net(ac->net);
+ kfree(ac);
+}
+
+/**
* auditd_set - Set/Reset the auditd connection state
* @pid: auditd PID
* @portid: auditd netlink portid
@@ -434,22 +476,33 @@ static int audit_set_failure(u32 state)
*
* Description:
* This function will obtain and drop network namespace references as
- * necessary.
+ * necessary. Returns zero on success, negative values on failure.
*/
-static void auditd_set(int pid, u32 portid, struct net *net)
+static int auditd_set(int pid, u32 portid, struct net *net)
{
unsigned long flags;
+ struct auditd_connection *ac_old, *ac_new;
- spin_lock_irqsave(&auditd_conn.lock, flags);
- auditd_conn.pid = pid;
- auditd_conn.portid = portid;
- if (auditd_conn.net)
- put_net(auditd_conn.net);
- if (net)
- auditd_conn.net = get_net(net);
- else
- auditd_conn.net = NULL;
- spin_unlock_irqrestore(&auditd_conn.lock, flags);
+ if (!pid || !net)
+ return -EINVAL;
+
+ ac_new = kzalloc(sizeof(*ac_new), GFP_KERNEL);
+ if (!ac_new)
+ return -ENOMEM;
+ ac_new->pid = pid;
+ ac_new->portid = portid;
+ ac_new->net = get_net(net);
+
+ spin_lock_irqsave(&auditd_conn_lock, flags);
+ ac_old = rcu_dereference_protected(auditd_conn,
+ lockdep_is_held(&auditd_conn_lock));
+ rcu_assign_pointer(auditd_conn, ac_new);
+ spin_unlock_irqrestore(&auditd_conn_lock, flags);
+
+ if (ac_old)
+ call_rcu(&ac_old->rcu, auditd_conn_free);
+
+ return 0;
}
/**
@@ -544,13 +597,19 @@ static void kauditd_retry_skb(struct sk_buff *skb)
*/
static void auditd_reset(void)
{
+ unsigned long flags;
struct sk_buff *skb;
+ struct auditd_connection *ac_old;
/* if it isn't already broken, break the connection */
- rcu_read_lock();
- if (auditd_conn.pid)
- auditd_set(0, 0, NULL);
- rcu_read_unlock();
+ spin_lock_irqsave(&auditd_conn_lock, flags);
+ ac_old = rcu_dereference_protected(auditd_conn,
+ lockdep_is_held(&auditd_conn_lock));
+ rcu_assign_pointer(auditd_conn, NULL);
+ spin_unlock_irqrestore(&auditd_conn_lock, flags);
+
+ if (ac_old)
+ call_rcu(&ac_old->rcu, auditd_conn_free);
/* flush all of the main and retry queues to the hold queue */
while ((skb = skb_dequeue(&audit_retry_queue)))
@@ -576,6 +635,7 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
u32 portid;
struct net *net;
struct sock *sk;
+ struct auditd_connection *ac;
/* NOTE: we can't call netlink_unicast while in the RCU section so
* take a reference to the network namespace and grab local
@@ -585,15 +645,15 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
* section netlink_unicast() should safely return an error */
rcu_read_lock();
- if (!auditd_conn.pid) {
+ ac = rcu_dereference(auditd_conn);
+ if (!ac) {
rcu_read_unlock();
rc = -ECONNREFUSED;
goto err;
}
- net = auditd_conn.net;
- get_net(net);
+ net = get_net(ac->net);
sk = audit_get_sk(net);
- portid = auditd_conn.portid;
+ portid = ac->portid;
rcu_read_unlock();
rc = netlink_unicast(sk, skb, portid, 0);
@@ -728,6 +788,7 @@ static int kauditd_thread(void *dummy)
u32 portid = 0;
struct net *net = NULL;
struct sock *sk = NULL;
+ struct auditd_connection *ac;
#define UNICAST_RETRIES 5
@@ -735,14 +796,14 @@ static int kauditd_thread(void *dummy)
while (!kthread_should_stop()) {
/* NOTE: see the lock comments in auditd_send_unicast_skb() */
rcu_read_lock();
- if (!auditd_conn.pid) {
+ ac = rcu_dereference(auditd_conn);
+ if (!ac) {
rcu_read_unlock();
goto main_queue;
}
- net = auditd_conn.net;
- get_net(net);
+ net = get_net(ac->net);
sk = audit_get_sk(net);
- portid = auditd_conn.portid;
+ portid = ac->portid;
rcu_read_unlock();
/* attempt to flush the hold queue */
@@ -1102,9 +1163,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
memset(&s, 0, sizeof(s));
s.enabled = audit_enabled;
s.failure = audit_failure;
- rcu_read_lock();
- s.pid = auditd_conn.pid;
- rcu_read_unlock();
+ s.pid = auditd_pid_vnr();
s.rate_limit = audit_rate_limit;
s.backlog_limit = audit_backlog_limit;
s.lost = atomic_read(&audit_lost);
@@ -1143,38 +1202,44 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
/* test the auditd connection */
audit_replace(requesting_pid);
- rcu_read_lock();
- auditd_pid = auditd_conn.pid;
+ auditd_pid = auditd_pid_vnr();
/* only the current auditd can unregister itself */
if ((!new_pid) && (requesting_pid != auditd_pid)) {
- rcu_read_unlock();
audit_log_config_change("audit_pid", new_pid,
auditd_pid, 0);
return -EACCES;
}
/* replacing a healthy auditd is not allowed */
if (auditd_pid && new_pid) {
- rcu_read_unlock();
audit_log_config_change("audit_pid", new_pid,
auditd_pid, 0);
return -EEXIST;
}
- rcu_read_unlock();
-
- if (audit_enabled != AUDIT_OFF)
- audit_log_config_change("audit_pid", new_pid,
- auditd_pid, 1);
if (new_pid) {
/* register a new auditd connection */
- auditd_set(new_pid,
- NETLINK_CB(skb).portid,
- sock_net(NETLINK_CB(skb).sk));
+ err = auditd_set(new_pid,
+ NETLINK_CB(skb).portid,
+ sock_net(NETLINK_CB(skb).sk));
+ if (audit_enabled != AUDIT_OFF)
+ audit_log_config_change("audit_pid",
+ new_pid,
+ auditd_pid,
+ err ? 0 : 1);
+ if (err)
+ return err;
+
/* try to process any backlog */
wake_up_interruptible(&kauditd_wait);
- } else
+ } else {
+ if (audit_enabled != AUDIT_OFF)
+ audit_log_config_change("audit_pid",
+ new_pid,
+ auditd_pid, 1);
+
/* unregister the auditd connection */
auditd_reset();
+ }
}
if (s.mask & AUDIT_STATUS_RATE_LIMIT) {
err = audit_set_rate_limit(s.rate_limit);
@@ -1447,10 +1512,11 @@ static void __net_exit audit_net_exit(struct net *net)
{
struct audit_net *aunet = net_generic(net, audit_net_id);
- rcu_read_lock();
- if (net == auditd_conn.net)
- auditd_reset();
- rcu_read_unlock();
+ /* NOTE: you would think that we would want to check the auditd
+ * connection and potentially reset it here if it lives in this
+ * namespace, but since the auditd connection tracking struct holds a
+ * reference to this namespace (see auditd_set()) we are only ever
+ * going to get here after that connection has been released */
netlink_kernel_release(aunet->sk);
}
@@ -1470,9 +1536,6 @@ static int __init audit_init(void)
if (audit_initialized == AUDIT_DISABLED)
return 0;
- memset(&auditd_conn, 0, sizeof(auditd_conn));
- spin_lock_init(&auditd_conn.lock);
-
skb_queue_head_init(&audit_queue);
skb_queue_head_init(&audit_retry_queue);
skb_queue_head_init(&audit_hold_queue);
^ permalink raw reply related
* Re: [PATCH] Revert "ata: sata_mv: Convert to devm_ioremap_resource()"
From: Andy Shevchenko @ 2017-05-30 13:55 UTC (permalink / raw)
To: Linus Walleij, Tejun Heo, Bartlomiej Zolnierkiewicz; +Cc: linux-ide, stable
In-Reply-To: <20170530135256.9966-1-linus.walleij@linaro.org>
On Tue, 2017-05-30 at 15:52 +0200, Linus Walleij wrote:
> This reverts commit 368e5fbdfc60732643f34f538823ed4bc8829827.
>
> My NAS stopped to mount root when I went from some v4.10-rc1
> to v4.12-rc3. Investigation of the bootlog yields this:
>
> sata_mv f1080000.sata: can't request region for resource [mem
> 0xf1080000-0xf1084fff]
> sata_mv: probe of f1080000.sata failed with error -16
>
> Reverting this offending patch makes the sata_mv probe and
> my SATA drive can mount root again, hooray!
It's already in upstream (ata tree).
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply
* [PATCH] Revert "ata: sata_mv: Convert to devm_ioremap_resource()"
From: Linus Walleij @ 2017-05-30 13:52 UTC (permalink / raw)
To: Tejun Heo, Bartlomiej Zolnierkiewicz
Cc: linux-ide, Linus Walleij, stable, Andy Shevchenko
This reverts commit 368e5fbdfc60732643f34f538823ed4bc8829827.
My NAS stopped to mount root when I went from some v4.10-rc1
to v4.12-rc3. Investigation of the bootlog yields this:
sata_mv f1080000.sata: can't request region for resource [mem 0xf1080000-0xf1084fff]
sata_mv: probe of f1080000.sata failed with error -16
Reverting this offending patch makes the sata_mv probe and
my SATA drive can mount root again, hooray!
Cc: stable@vger.kernel.org
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
The problem is probably caused by overlapping resources in
the device tree, for which ioremap() and ioremap_resource()
have different semantics: the former allows it, the latter
does not.
A proper fix probably includes amending the device tree to
not have overlapping resources.
---
drivers/ata/sata_mv.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index b66bcda88320..3b2246dded74 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -4067,7 +4067,6 @@ static int mv_platform_probe(struct platform_device *pdev)
struct ata_host *host;
struct mv_host_priv *hpriv;
struct resource *res;
- void __iomem *mmio;
int n_ports = 0, irq = 0;
int rc;
int port;
@@ -4086,9 +4085,8 @@ static int mv_platform_probe(struct platform_device *pdev)
* Get the register base first
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mmio = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(mmio))
- return PTR_ERR(mmio);
+ if (res == NULL)
+ return -EINVAL;
/* allocate host */
if (pdev->dev.of_node) {
@@ -4132,7 +4130,12 @@ static int mv_platform_probe(struct platform_device *pdev)
hpriv->board_idx = chip_soc;
host->iomap = NULL;
- hpriv->base = mmio - SATAHC0_REG_BASE;
+ hpriv->base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!hpriv->base)
+ return -ENOMEM;
+
+ hpriv->base -= SATAHC0_REG_BASE;
hpriv->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(hpriv->clk))
--
2.9.4
^ permalink raw reply related
* Re: [PATCH v3] xfs: use ->b_state to fix buffer I/O accounting release race
From: Brian Foster @ 2017-05-30 13:26 UTC (permalink / raw)
To: linux-xfs; +Cc: stable
In-Reply-To: <1496150573-6531-1-git-send-email-bfoster@redhat.com>
Oops, fixed stable CC.
On Tue, May 30, 2017 at 09:22:53AM -0400, Brian Foster wrote:
> We've had user reports of unmount hangs in xfs_wait_buftarg() that
> analysis shows is due to btp->bt_io_count == -1. bt_io_count
> represents the count of in-flight asynchronous buffers and thus
> should always be >= 0. xfs_wait_buftarg() waits for this value to
> stabilize to zero in order to ensure that all untracked (with
> respect to the lru) buffers have completed I/O processing before
> unmount proceeds to tear down in-core data structures.
>
> The value of -1 implies an I/O accounting decrement race. Indeed,
> the fact that xfs_buf_ioacct_dec() is called from xfs_buf_rele()
> (where the buffer lock is no longer held) means that bp->b_flags can
> be updated from an unsafe context. While a user-level reproducer is
> currently not available, some intrusive hacks to run racing buffer
> lookups/ioacct/releases from multiple threads was used to
> successfully manufacture this problem.
>
> Existing callers do not expect to acquire the buffer lock from
> xfs_buf_rele(). Therefore, we can not safely update ->b_flags from
> this context. It turns out that we already have separate buffer
> state bits and associated serialization for dealing with buffer LRU
> state in the form of ->b_state and ->b_lock. Therefore, replace the
> _XBF_IN_FLIGHT flag with a ->b_state variant, update the I/O
> accounting wrappers appropriately and make sure they are used with
> the correct locking. This ensures that buffer in-flight state can be
> modified at buffer release time without racing with modifications
> from a buffer lock holder.
>
> Fixes: 9c7504aa72b6 ("xfs: track and serialize in-flight async buffers against unmount")
> CC: stable@vger.kernel.org # v4.8+
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> Reviewed-by: Nikolay Borisov <nborisov@suse.com>
> ---
>
> v3:
> - Added Fixes/Reviewed-by tags and CC stable.
> v2: http://www.spinics.net/lists/linux-xfs/msg07062.html
> - Use ->b_state and ->b_lock instead of custom atomic counter.
> v1: http://www.spinics.net/lists/linux-xfs/msg06995.html
>
> fs/xfs/xfs_buf.c | 38 ++++++++++++++++++++++++++------------
> fs/xfs/xfs_buf.h | 5 ++---
> 2 files changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index ba036c1..4e19fda 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -97,12 +97,16 @@ static inline void
> xfs_buf_ioacct_inc(
> struct xfs_buf *bp)
> {
> - if (bp->b_flags & (XBF_NO_IOACCT|_XBF_IN_FLIGHT))
> + if (bp->b_flags & XBF_NO_IOACCT)
> return;
>
> ASSERT(bp->b_flags & XBF_ASYNC);
> - bp->b_flags |= _XBF_IN_FLIGHT;
> - percpu_counter_inc(&bp->b_target->bt_io_count);
> + spin_lock(&bp->b_lock);
> + if (!(bp->b_state & XFS_BSTATE_IN_FLIGHT)) {
> + bp->b_state |= XFS_BSTATE_IN_FLIGHT;
> + percpu_counter_inc(&bp->b_target->bt_io_count);
> + }
> + spin_unlock(&bp->b_lock);
> }
>
> /*
> @@ -110,14 +114,24 @@ xfs_buf_ioacct_inc(
> * freed and unaccount from the buftarg.
> */
> static inline void
> -xfs_buf_ioacct_dec(
> +__xfs_buf_ioacct_dec(
> struct xfs_buf *bp)
> {
> - if (!(bp->b_flags & _XBF_IN_FLIGHT))
> - return;
> + ASSERT(spin_is_locked(&bp->b_lock));
>
> - bp->b_flags &= ~_XBF_IN_FLIGHT;
> - percpu_counter_dec(&bp->b_target->bt_io_count);
> + if (bp->b_state & XFS_BSTATE_IN_FLIGHT) {
> + bp->b_state &= ~XFS_BSTATE_IN_FLIGHT;
> + percpu_counter_dec(&bp->b_target->bt_io_count);
> + }
> +}
> +
> +static inline void
> +xfs_buf_ioacct_dec(
> + struct xfs_buf *bp)
> +{
> + spin_lock(&bp->b_lock);
> + __xfs_buf_ioacct_dec(bp);
> + spin_unlock(&bp->b_lock);
> }
>
> /*
> @@ -149,9 +163,9 @@ xfs_buf_stale(
> * unaccounted (released to LRU) before that occurs. Drop in-flight
> * status now to preserve accounting consistency.
> */
> - xfs_buf_ioacct_dec(bp);
> -
> spin_lock(&bp->b_lock);
> + __xfs_buf_ioacct_dec(bp);
> +
> atomic_set(&bp->b_lru_ref, 0);
> if (!(bp->b_state & XFS_BSTATE_DISPOSE) &&
> (list_lru_del(&bp->b_target->bt_lru, &bp->b_lru)))
> @@ -979,12 +993,12 @@ xfs_buf_rele(
> * ensures the decrement occurs only once per-buf.
> */
> if ((atomic_read(&bp->b_hold) == 1) && !list_empty(&bp->b_lru))
> - xfs_buf_ioacct_dec(bp);
> + __xfs_buf_ioacct_dec(bp);
> goto out_unlock;
> }
>
> /* the last reference has been dropped ... */
> - xfs_buf_ioacct_dec(bp);
> + __xfs_buf_ioacct_dec(bp);
> if (!(bp->b_flags & XBF_STALE) && atomic_read(&bp->b_lru_ref)) {
> /*
> * If the buffer is added to the LRU take a new reference to the
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 8d1d44f..1508121 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -63,7 +63,6 @@ typedef enum {
> #define _XBF_KMEM (1 << 21)/* backed by heap memory */
> #define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */
> #define _XBF_COMPOUND (1 << 23)/* compound buffer */
> -#define _XBF_IN_FLIGHT (1 << 25) /* I/O in flight, for accounting purposes */
>
> typedef unsigned int xfs_buf_flags_t;
>
> @@ -84,14 +83,14 @@ typedef unsigned int xfs_buf_flags_t;
> { _XBF_PAGES, "PAGES" }, \
> { _XBF_KMEM, "KMEM" }, \
> { _XBF_DELWRI_Q, "DELWRI_Q" }, \
> - { _XBF_COMPOUND, "COMPOUND" }, \
> - { _XBF_IN_FLIGHT, "IN_FLIGHT" }
> + { _XBF_COMPOUND, "COMPOUND" }
>
>
> /*
> * Internal state flags.
> */
> #define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */
> +#define XFS_BSTATE_IN_FLIGHT (1 << 1) /* I/O in flight */
>
> /*
> * The xfs_buftarg contains 2 notions of "sector size" -
> --
> 2.7.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 4.4 018/103] md: update slab_cache before releasing new stripes when stripes resizing
From: Ben Hutchings @ 2017-05-30 13:16 UTC (permalink / raw)
To: Dennis Yang, NeilBrown, Shaohua Li
Cc: linux-kernel, stable, Greg Kroah-Hartman
In-Reply-To: <20170523200858.992214045@linuxfoundation.org>
On Tue, 2017-05-23 at 22:08 +0200, Greg Kroah-Hartman wrote:
> 4.4-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Dennis Yang <dennisyang@qnap.com>
>
> commit 583da48e388f472e8818d9bb60ef6a1d40ee9f9d upstream.
>
> When growing raid5 device on machine with small memory, there is chance that
> mdadm will be killed and the following bug report can be observed. The same
> bug could also be reproduced in linux-4.10.6.
[...]
> The problem is that resize_stripes() releases new stripe_heads before assigning new
> slab cache to conf->slab_cache. If the shrinker function raid5_cache_scan() gets called
> after resize_stripes() starting releasing new stripes but right before new slab cache
> being assigned, it is possible that these new stripe_heads will be freed with the old
> slab_cache which was already been destoryed and that triggers this bug.
[...]
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
> @@ -2232,6 +2232,10 @@ static int resize_stripes(struct r5conf
> err = -ENOMEM;
>
> mutex_unlock(&conf->cache_size_mutex);
> +
> + conf->slab_cache = sc;
> + conf->active_name = 1-conf->active_name;
> +
> /* Step 4, return new stripes to service */
> while(!list_empty(&newstripes)) {
> nsh = list_entry(newstripes.next, struct stripe_head, lru);
[...]
The assignments are still being done after conf->cache_size_mutex is
unlocked, so there still seems to be a race with raid5_cache_scan().
Shouldn't they be moved above the mutex_unlock()?
Ben.
--
Ben Hutchings
Software Developer, Codethink Ltd.
^ permalink raw reply
* Re: [PATCH 0/2] nohz: Deal with clock reprogram skipping issues v3
From: Frederic Weisbecker @ 2017-05-30 12:51 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Peter Zijlstra, Rik van Riel, James Hartsock,
Thomas Gleixner, stable, Tim Wright, Pavel Machek
In-Reply-To: <20170530054709.hth3myap4mq5zvcp@gmail.com>
On Tue, May 30, 2017 at 07:47:09AM +0200, Ingo Molnar wrote:
>
> * Frederic Weisbecker <fweisbec@gmail.com> wrote:
>
> > > Well, this does not answer my question: between latest tip:timers/nohz and the
> > > patches you posted there's a delta, so it's not just a pure rebase.
> >
> > Yeah but like I said, you can forget the series I posted because the diff is
> > mostly cosmetic and things are actually ok as they are in tip:timers/nohz
> >
> > The only thing that bothers me is the fact that the HEAD of this branch doesn't have
> > a changelog or even just a comment.
>
> We can still amend that - is this changelog what you had in mind:
>
> nohz: Reset next_tick cache even when the timer has no regs
>
> Handle tick interrupts whose regs are NULL, out of general paranoia. It happens
> when hrtimer_interrupt() is called from non-interrupt contexts, such as hotplug
> CPU down events.
>
> ?
Yep that one is fine. Thanks!
^ permalink raw reply
* Re: [PATCH rdma-next] IB/iser: Fix connection teardown race condition
From: Sagi Grimberg @ 2017-05-30 11:50 UTC (permalink / raw)
To: Max Gurtovoy, Leon Romanovsky, Doug Ledford
Cc: linux-rdma, Vladimir Neyelov, stable
In-Reply-To: <98334f53-a7ff-d465-989f-a5ee7add2291@mellanox.com>
> Hi Sagi,
>
> what do you think on this approach ?
> we must somehow defend on the NULL deref in case dd_data in iscsi_conn
> (the iser_conn) already NULL due to conn_stop call.
Sounds like we get conn_stop duing lun scanning. Generally speaking I
don't like a global lock for this, but given the non trivial iscsi state
machine
we can do with that.
Reviewed-by: Sagi Grimberg <sagi@grimbeg.me>
^ permalink raw reply
* Re: [PATCH] libata: Fix devres handling
From: Linus Walleij @ 2017-05-30 9:21 UTC (permalink / raw)
To: Tejun Heo; +Cc: Bartlomiej Zolnierkiewicz, linux-ide, stable
In-Reply-To: <20170523211608.GJ13222@htj.duckdns.org>
On Tue, May 23, 2017 at 11:16 PM, Tejun Heo <tj@kernel.org> wrote:
>> The ATA hosts are allocated using devres with:
>> host = devres_alloc(ata_host_release, sz, GFP_KERNEL);
>> However in the ata_host_release() function the host is retrieved
>> using dev_get_drvdata() which is not what other devres handlers
>> do, instead we should probably use the passed resource.
>>
>> Before this my kernel crashes badly when I fail to start a host
>> in ata_host_start() and need to bail out, because dev_get_drvdata()
>> gets the wrong-but-almost-correct pointer (so on some systems it
>> may by chance be the right pointer what do I know).
>>
>> On ARMv4 Gemini it is not:
(...)
> This is really weird. The two can't be different, well, at least
> shouldn't.
I found the problem.
This is because my driver issues platform_set_drvdata(pdev)
on the same struct device * overwriting the data with
its own. That function is just an alias for dev_set_drvdata().
Amazingly, libata survives this until release.
Maybe we should print a warning if dev_get_drvdata()
and res differ? It's a sign that something is wrong because
someone screwed with the drvdata behind the back of
libata.
It appears further that I am in bad company: there are a few
drivers in drivers/ata that have broken errorpath because
they do exactly this or variants of this. So it turns up in my
driver too because of copypaste.
Device drivers assume that they "own" drvdata inside the
device, but with libata they do not, as shown above.
It is used more as a rule than an exception to pass a
state container from probe() over to remove().
It is a common pattern to overwrite drvdata, the following
drivers now have this bug in one way or another:
pata_bf54x.c: platform_set_drvdata(pdev, host);
pata_ep93xx.c: platform_set_drvdata(pdev, drv_data);
sata_dwc_460ex.c: dev_set_drvdata(&ofdev->dev, host);
These drivers:
pata_rb532_cf.c: platform_set_drvdata(pdev, ah);
pata_samsung_cf.c: platform_set_drvdata(pdev, host);
sata_fsl.c: platform_set_drvdata(ofdev, host);
They set the ATA host as drvdata, essentially overwriting
the drvdata pointer with the same value.
I guess I will simply make a cleanup series for these,
making sure they use host->private_data instead and do not
double-write the drvdata.
Yours,
Linus Walleij
^ permalink raw reply
* RE: [PATCH] iommu/amd: flush IOTLB for specific domains only (v3)
From: Nath, Arindam @ 2017-05-30 7:38 UTC (permalink / raw)
To: Joerg Roedel, Lendacky, Thomas
Cc: iommu@lists.linux-foundation.org, amd-gfx@lists.freedesktop.org,
Deucher, Alexander, Bridgman, John, drake@endlessm.com,
Suthikulpanit, Suravee, linux@endlessm.com, Craig Stein,
michel@daenzer.net, Kuehling, Felix, stable@vger.kernel.org
In-Reply-To: <20170529143831.GA30388@8bytes.org>
>-----Original Message-----
>From: Joerg Roedel [mailto:joro@8bytes.org]
>Sent: Monday, May 29, 2017 8:09 PM
>To: Nath, Arindam <Arindam.Nath@amd.com>; Lendacky, Thomas
><Thomas.Lendacky@amd.com>
>Cc: iommu@lists.linux-foundation.org; amd-gfx@lists.freedesktop.org;
>Deucher, Alexander <Alexander.Deucher@amd.com>; Bridgman, John
><John.Bridgman@amd.com>; drake@endlessm.com; Suthikulpanit, Suravee
><Suravee.Suthikulpanit@amd.com>; linux@endlessm.com; Craig Stein
><stein12c@gmail.com>; michel@daenzer.net; Kuehling, Felix
><Felix.Kuehling@amd.com>; stable@vger.kernel.org
>Subject: Re: [PATCH] iommu/amd: flush IOTLB for specific domains only (v3)
>
>Hi Arindam,
>
>I met Tom Lendacky last week in Nuremberg last week and he told me he is
>working on the same area of the code that this patch is for. His reason
>for touching this code was to solve some locking problems. Maybe you two
>can work together on a joint approach to improve this?
Sure Joerg, I will work with Tom.
Thanks.
>
>On Mon, May 22, 2017 at 01:18:01PM +0530, arindam.nath@amd.com wrote:
>> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
>> index 63cacf5..1edeebec 100644
>> --- a/drivers/iommu/amd_iommu.c
>> +++ b/drivers/iommu/amd_iommu.c
>> @@ -2227,15 +2227,26 @@ static struct iommu_group
>*amd_iommu_device_group(struct device *dev)
>>
>> static void __queue_flush(struct flush_queue *queue)
>> {
>> - struct protection_domain *domain;
>> - unsigned long flags;
>> int idx;
>>
>> - /* First flush TLB of all known domains */
>> - spin_lock_irqsave(&amd_iommu_pd_lock, flags);
>> - list_for_each_entry(domain, &amd_iommu_pd_list, list)
>> - domain_flush_tlb(domain);
>> - spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
>> + /* First flush TLB of all domains which were added to flush queue */
>> + for (idx = 0; idx < queue->next; ++idx) {
>> + struct flush_queue_entry *entry;
>> +
>> + entry = queue->entries + idx;
>> +
>> + /*
>> + * There might be cases where multiple IOVA entries for the
>> + * same domain are queued in the flush queue. To avoid
>> + * flushing the same domain again, we check whether the
>> + * flag is set or not. This improves the efficiency of
>> + * flush operation.
>> + */
>> + if (!entry->dma_dom->domain.already_flushed) {
>> + entry->dma_dom->domain.already_flushed = true;
>> + domain_flush_tlb(&entry->dma_dom->domain);
>> + }
>> + }
>
>There is also a race condition here I have to look into. It is not
>introduced by your patch, but needs fixing anyway. I'll look into this
>too.
>
>
>Regards,
>
> Joerg
^ permalink raw reply
* Re: [PATCH 0/2] nohz: Deal with clock reprogram skipping issues v3
From: Ingo Molnar @ 2017-05-30 5:47 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: LKML, Peter Zijlstra, Rik van Riel, James Hartsock,
Thomas Gleixner, stable, Tim Wright, Pavel Machek
In-Reply-To: <20170529135541.GA8425@lerouge>
* Frederic Weisbecker <fweisbec@gmail.com> wrote:
> > Well, this does not answer my question: between latest tip:timers/nohz and the
> > patches you posted there's a delta, so it's not just a pure rebase.
>
> Yeah but like I said, you can forget the series I posted because the diff is
> mostly cosmetic and things are actually ok as they are in tip:timers/nohz
>
> The only thing that bothers me is the fact that the HEAD of this branch doesn't have
> a changelog or even just a comment.
We can still amend that - is this changelog what you had in mind:
nohz: Reset next_tick cache even when the timer has no regs
Handle tick interrupts whose regs are NULL, out of general paranoia. It happens
when hrtimer_interrupt() is called from non-interrupt contexts, such as hotplug
CPU down events.
?
Or you can send me a longer version as well.
Thanks,
Ingo
^ permalink raw reply
* [char-misc for v4.12] mei: make sysfs modalias format similar as uevent modalias
From: Tomas Winkler @ 2017-05-29 19:08 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Alexander Usyskin, linux-kernel, Pratyush Anand, 4 . 7+,
Tomas Winkler
From: Pratyush Anand <panand@redhat.com>
modprobe is not able to resolve sysfs modalias for mei devices.
# cat
/sys/class/watchdog/watchdog0/device/watchdog/watchdog0/device/modalias
mei::05b79a6f-4628-4d7f-899d-a91514cb32ab:
# modprobe --set-version 4.9.6-200.fc25.x86_64 -R
mei::05b79a6f-4628-4d7f-899d-a91514cb32ab:
modprobe: FATAL: Module mei::05b79a6f-4628-4d7f-899d-a91514cb32ab: not
found in directory /lib/modules/4.9.6-200.fc25.x86_64
# cat /lib/modules/4.9.6-200.fc25.x86_64/modules.alias | grep
05b79a6f-4628-4d7f-899d-a91514cb32ab
alias mei:*:05b79a6f-4628-4d7f-899d-a91514cb32ab:*:* mei_wdt
commit b26864cad1c9 ("mei: bus: add client protocol
version to the device alias"), however sysfs modalias
is still in formmat mei:S:uuid:*.
This patch equates format of uevent and sysfs modalias so that modprobe
is able to resolve the aliases.
Cc: <stable@vger.kernel.org> 4.7+
Fixes: commit b26864cad1c9 ("mei: bus: add client protocol version to the device alias")
Signed-off-by: Pratyush Anand <panand@redhat.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/misc/mei/bus.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 42078e6be47f..40c79089e548 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -763,8 +763,10 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
{
struct mei_cl_device *cldev = to_mei_cl_device(dev);
const uuid_le *uuid = mei_me_cl_uuid(cldev->me_cl);
+ u8 version = mei_me_cl_ver(cldev->me_cl);
- return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:", cldev->name, uuid);
+ return scnprintf(buf, PAGE_SIZE, "mei:%s:%pUl:%02X:",
+ cldev->name, uuid, version);
}
static DEVICE_ATTR_RO(modalias);
--
2.9.4
^ permalink raw reply related
* Re: [PATCH] ext4: Fix fdatasync(2) after extent manipulation operations
From: Theodore Ts'o @ 2017-05-29 18:30 UTC (permalink / raw)
To: Jan Kara; +Cc: linux-ext4, stable
In-Reply-To: <20170525142524.18254-1-jack@suse.cz>
On Thu, May 25, 2017 at 04:25:24PM +0200, Jan Kara wrote:
> Currently, extent manipulation operations such as hole punch, range
> zeroing, or extent shifting do not record the fact that file data has
> changed and thus fdatasync(2) has a work to do. As a result if we crash
> e.g. after a punch hole and fdatasync, user can still possibly see the
> punched out data after journal replay. Test generic/392 fails due to
> these problems.
>
> Fix the problem by properly marking that file data has changed in these
> operations.
>
> CC: stable@vger.kernel.org
> Fixes: a4bb6b64e39abc0e41ca077725f2a72c868e7622
> Signed-off-by: Jan Kara <jack@suse.cz>
Thanks, applied.
- Ted
^ permalink raw reply
* Re: [PATCH] iommu/amd: flush IOTLB for specific domains only (v3)
From: Joerg Roedel @ 2017-05-29 14:38 UTC (permalink / raw)
To: arindam.nath, Tom Lendacky
Cc: iommu, amd-gfx, Alexander.Deucher, John.Bridgman, drake,
Suravee.Suthikulpanit, linux, Craig Stein, michel, Felix.Kuehling,
stable
In-Reply-To: <1495439281-24005-1-git-send-email-arindam.nath@amd.com>
Hi Arindam,
I met Tom Lendacky last week in Nuremberg last week and he told me he is
working on the same area of the code that this patch is for. His reason
for touching this code was to solve some locking problems. Maybe you two
can work together on a joint approach to improve this?
On Mon, May 22, 2017 at 01:18:01PM +0530, arindam.nath@amd.com wrote:
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index 63cacf5..1edeebec 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -2227,15 +2227,26 @@ static struct iommu_group *amd_iommu_device_group(struct device *dev)
>
> static void __queue_flush(struct flush_queue *queue)
> {
> - struct protection_domain *domain;
> - unsigned long flags;
> int idx;
>
> - /* First flush TLB of all known domains */
> - spin_lock_irqsave(&amd_iommu_pd_lock, flags);
> - list_for_each_entry(domain, &amd_iommu_pd_list, list)
> - domain_flush_tlb(domain);
> - spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
> + /* First flush TLB of all domains which were added to flush queue */
> + for (idx = 0; idx < queue->next; ++idx) {
> + struct flush_queue_entry *entry;
> +
> + entry = queue->entries + idx;
> +
> + /*
> + * There might be cases where multiple IOVA entries for the
> + * same domain are queued in the flush queue. To avoid
> + * flushing the same domain again, we check whether the
> + * flag is set or not. This improves the efficiency of
> + * flush operation.
> + */
> + if (!entry->dma_dom->domain.already_flushed) {
> + entry->dma_dom->domain.already_flushed = true;
> + domain_flush_tlb(&entry->dma_dom->domain);
> + }
> + }
There is also a race condition here I have to look into. It is not
introduced by your patch, but needs fixing anyway. I'll look into this
too.
Regards,
Joerg
^ permalink raw reply
* [PATCH 1/2] USB: core: fix device node leak
From: Johan Hovold @ 2017-05-29 14:32 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold, stable, Peter Chen
In-Reply-To: <20170529143223.7397-1-johan@kernel.org>
Make sure to release any OF device-node reference taken when creating
the USB device.
Note that we currently do not hold a reference to the root hub
device-tree node (i.e. the parent controller node).
Fixes: 69bec7259853 ("USB: core: let USB device know device node")
Cc: stable <stable@vger.kernel.org> # v4.6
Cc: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
drivers/usb/core/usb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 28b053cacc90..62e1906bb2f3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -416,6 +416,8 @@ static void usb_release_dev(struct device *dev)
usb_destroy_configuration(udev);
usb_release_bos_descriptor(udev);
+ if (udev->parent)
+ of_node_put(dev->of_node);
usb_put_hcd(hcd);
kfree(udev->product);
kfree(udev->manufacturer);
--
2.13.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox