Set the dirty bit when the memory resource is not cleared during BO release.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Suggested-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 26 ++++++++++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 7 ++++-- 3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 73403744331a..ea6ce53c3a44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1302,28 +1302,40 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) * So when this locking here fails something is wrong with the reference * counting. */ - if (WARN_ON_ONCE(!dma_resv_trylock(&bo->base._resv))) + if (WARN_ON_ONCE(!dma_resv_trylock(&bo->base._resv))) { + if (bo->resource && bo->resource->mem_type == TTM_PL_VRAM) + amdgpu_vram_mgr_set_clear_state(bo->resource, false); + return; + }
amdgpu_amdkfd_remove_all_eviction_fences(abo);
- if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM || - !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) || - adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev))) + if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM) goto out;
+ if (!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) || + adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev))) + goto out_clear_err; + r = dma_resv_reserve_fences(&bo->base._resv, 1); if (r) - goto out; + goto out_clear_err;
r = amdgpu_fill_buffer(abo, 0, &bo->base._resv, &fence, true); if (WARN_ON(r)) - goto out; + goto out_clear_err;
- amdgpu_vram_mgr_set_cleared(bo->resource); + amdgpu_vram_mgr_set_clear_state(bo->resource, true); dma_resv_add_fence(&bo->base._resv, fence, DMA_RESV_USAGE_KERNEL); dma_fence_put(fence);
+ dma_resv_unlock(&bo->base._resv); + + return; + +out_clear_err: + amdgpu_vram_mgr_set_clear_state(bo->resource, false); out: dma_resv_unlock(&bo->base._resv); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9c5df35f05b7..9ec14ab900f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -407,9 +407,10 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, r = amdgpu_fill_buffer(abo, 0, NULL, &wipe_fence, false); if (r) { + amdgpu_vram_mgr_set_clear_state(bo->resource, false); goto error; } else if (wipe_fence) { - amdgpu_vram_mgr_set_cleared(bo->resource); + amdgpu_vram_mgr_set_clear_state(bo->resource, true); dma_fence_put(fence); fence = wipe_fence; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h index b256cbc2bc27..1019c5806ec7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h @@ -64,9 +64,12 @@ to_amdgpu_vram_mgr_resource(struct ttm_resource *res) return container_of(res, struct amdgpu_vram_mgr_resource, base); }
-static inline void amdgpu_vram_mgr_set_cleared(struct ttm_resource *res) +static inline void amdgpu_vram_mgr_set_clear_state(struct ttm_resource *res, bool is_clear) { - to_amdgpu_vram_mgr_resource(res)->flags |= DRM_BUDDY_CLEARED; + if (is_clear) + to_amdgpu_vram_mgr_resource(res)->flags |= DRM_BUDDY_CLEARED; + else + to_amdgpu_vram_mgr_resource(res)->flags &= ~DRM_BUDDY_CLEARED; }
#endif
- Added a handler in DRM buddy manager to reset the cleared flag for the blocks in the freelist.
- This is necessary because, upon resuming, the VRAM becomes cluttered with BIOS data, yet the VRAM backend manager believes that everything has been cleared.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Suggested-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3812 --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 5 ++++ drivers/gpu/drm/drm_buddy.c | 24 ++++++++++++++++++++ include/drm/drm_buddy.h | 2 ++ 4 files changed, 33 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a59f194e3360..eb67d6c97392 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5193,6 +5193,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) dev->dev->power.disable_depth--; #endif } + + amdgpu_vram_mgr_clear_reset_blocks(&adev->mman.vram_mgr.mm); adev->in_suspend = false;
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h index 1019c5806ec7..e9e2928fa4d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h @@ -58,6 +58,11 @@ static inline bool amdgpu_vram_mgr_is_cleared(struct drm_buddy_block *block) return drm_buddy_block_is_clear(block); }
+static inline void amdgpu_vram_mgr_clear_reset_blocks(struct drm_buddy *mm) +{ + drm_buddy_clear_reset_blocks(mm); +} + static inline struct amdgpu_vram_mgr_resource * to_amdgpu_vram_mgr_resource(struct ttm_resource *res) { diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index a1e652b7631d..b5e44867adf2 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -405,6 +405,30 @@ drm_get_buddy(struct drm_buddy_block *block) } EXPORT_SYMBOL(drm_get_buddy);
+/** + * drm_buddy_clear_reset_blocks - reset cleared blocks + * + * @mm: DRM buddy manager + * + * Reset all the cleared blocks in the freelist. + */ +void drm_buddy_clear_reset_blocks(struct drm_buddy *mm) +{ + unsigned int i; + + for (i = 0; i <= mm->max_order; ++i) { + struct drm_buddy_block *block; + + list_for_each_entry_reverse(block, &mm->free_list[i], link) { + if (drm_buddy_block_is_clear(block)) { + clear_reset(block); + mm->clear_avail -= drm_buddy_block_size(mm, block); + } + } + } +} +EXPORT_SYMBOL(drm_buddy_clear_reset_blocks); + /** * drm_buddy_free_block - free a block * diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9689a7c5dd36..da569dea16b7 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -160,6 +160,8 @@ int drm_buddy_block_trim(struct drm_buddy *mm, u64 new_size, struct list_head *blocks);
+void drm_buddy_clear_reset_blocks(struct drm_buddy *mm); + void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
void drm_buddy_free_list(struct drm_buddy *mm,
+Matt B who is adding clear-on-free support in xe. I'm not sure if we might also see something like this.
On 23/06/2025 06:52, Arunpravin Paneer Selvam wrote:
Added a handler in DRM buddy manager to reset the cleared flag for the blocks in the freelist.
This is necessary because, upon resuming, the VRAM becomes cluttered with BIOS data, yet the VRAM backend manager believes that everything has been cleared.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Suggested-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3812
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 5 ++++ drivers/gpu/drm/drm_buddy.c | 24 ++++++++++++++++++++ include/drm/drm_buddy.h | 2 ++ 4 files changed, 33 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a59f194e3360..eb67d6c97392 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5193,6 +5193,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) dev->dev->power.disable_depth--; #endif }
- amdgpu_vram_mgr_clear_reset_blocks(&adev->mman.vram_mgr.mm); adev->in_suspend = false;
if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h index 1019c5806ec7..e9e2928fa4d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h @@ -58,6 +58,11 @@ static inline bool amdgpu_vram_mgr_is_cleared(struct drm_buddy_block *block) return drm_buddy_block_is_clear(block); } +static inline void amdgpu_vram_mgr_clear_reset_blocks(struct drm_buddy *mm) +{
- drm_buddy_clear_reset_blocks(mm);
No lock needed?
+}
- static inline struct amdgpu_vram_mgr_resource * to_amdgpu_vram_mgr_resource(struct ttm_resource *res) {
diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index a1e652b7631d..b5e44867adf2 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -405,6 +405,30 @@ drm_get_buddy(struct drm_buddy_block *block) } EXPORT_SYMBOL(drm_get_buddy); +/**
- drm_buddy_clear_reset_blocks - reset cleared blocks
- @mm: DRM buddy manager
- Reset all the cleared blocks in the freelist.
- */
+void drm_buddy_clear_reset_blocks(struct drm_buddy *mm) +{
- unsigned int i;
This might be a good spot to also force merge freed blocks back together, for the ones that have the clear vs dirty mismatch. Otherwise with the below loop we can have two buddies that are now dirty but don't get merged back together? Fairly sure fini() can chuck a warning otherwise. Also a simple kunit test for this would be good.
- for (i = 0; i <= mm->max_order; ++i) {
struct drm_buddy_block *block;
list_for_each_entry_reverse(block, &mm->free_list[i], link) {
if (drm_buddy_block_is_clear(block)) {
clear_reset(block);
mm->clear_avail -= drm_buddy_block_size(mm, block);
}
}
- }
+} +EXPORT_SYMBOL(drm_buddy_clear_reset_blocks);
- /**
- drm_buddy_free_block - free a block
diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9689a7c5dd36..da569dea16b7 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -160,6 +160,8 @@ int drm_buddy_block_trim(struct drm_buddy *mm, u64 new_size, struct list_head *blocks); +void drm_buddy_clear_reset_blocks(struct drm_buddy *mm);
- void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
void drm_buddy_free_list(struct drm_buddy *mm,
On Mon, Jun 23, 2025 at 01:37:35PM +0100, Matthew Auld wrote:
+Matt B who is adding clear-on-free support in xe. I'm not sure if we might also see something like this.
Thanks for the heads up.
On 23/06/2025 06:52, Arunpravin Paneer Selvam wrote:
Added a handler in DRM buddy manager to reset the cleared flag for the blocks in the freelist.
This is necessary because, upon resuming, the VRAM becomes cluttered with BIOS data, yet the VRAM backend manager believes that everything has been cleared.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Suggested-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3812
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 5 ++++ drivers/gpu/drm/drm_buddy.c | 24 ++++++++++++++++++++ include/drm/drm_buddy.h | 2 ++ 4 files changed, 33 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a59f194e3360..eb67d6c97392 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5193,6 +5193,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) dev->dev->power.disable_depth--; #endif }
- amdgpu_vram_mgr_clear_reset_blocks(&adev->mman.vram_mgr.mm); adev->in_suspend = false; if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h index 1019c5806ec7..e9e2928fa4d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h @@ -58,6 +58,11 @@ static inline bool amdgpu_vram_mgr_is_cleared(struct drm_buddy_block *block) return drm_buddy_block_is_clear(block); } +static inline void amdgpu_vram_mgr_clear_reset_blocks(struct drm_buddy *mm) +{
- drm_buddy_clear_reset_blocks(mm);
No lock needed?
+}
- static inline struct amdgpu_vram_mgr_resource * to_amdgpu_vram_mgr_resource(struct ttm_resource *res) {
diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index a1e652b7631d..b5e44867adf2 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -405,6 +405,30 @@ drm_get_buddy(struct drm_buddy_block *block) } EXPORT_SYMBOL(drm_get_buddy); +/**
- drm_buddy_clear_reset_blocks - reset cleared blocks
- @mm: DRM buddy manager
- Reset all the cleared blocks in the freelist.
- */
+void drm_buddy_clear_reset_blocks(struct drm_buddy *mm) +{
- unsigned int i;
This might be a good spot to also force merge freed blocks back together, for the ones that have the clear vs dirty mismatch. Otherwise with the below loop we can have two buddies that are now dirty but don't get merged back together? Fairly sure fini() can chuck a warning otherwise. Also a simple kunit test for this would be good.
- for (i = 0; i <= mm->max_order; ++i) {
struct drm_buddy_block *block;
list_for_each_entry_reverse(block, &mm->free_list[i], link) {
if (drm_buddy_block_is_clear(block)) {
clear_reset(block);
mm->clear_avail -= drm_buddy_block_size(mm, block);
}
}
- }
+} +EXPORT_SYMBOL(drm_buddy_clear_reset_blocks);
- /**
- drm_buddy_free_block - free a block
diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9689a7c5dd36..da569dea16b7 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -160,6 +160,8 @@ int drm_buddy_block_trim(struct drm_buddy *mm, u64 new_size, struct list_head *blocks); +void drm_buddy_clear_reset_blocks(struct drm_buddy *mm);
I think a polarity argument here would be good. Following up if on Intel GPUs the inverse is true - our VRAM is entirely cleared. Either way having this function being able to flip the state either way would be good.
Matt
void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block); void drm_buddy_free_list(struct drm_buddy *mm,
On 23.06.25 07:52, Arunpravin Paneer Selvam wrote:
Set the dirty bit when the memory resource is not cleared during BO release.
Signed-off-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Suggested-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality")
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 26 ++++++++++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 7 ++++-- 3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 73403744331a..ea6ce53c3a44 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1302,28 +1302,40 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) * So when this locking here fails something is wrong with the reference * counting. */
- if (WARN_ON_ONCE(!dma_resv_trylock(&bo->base._resv)))
- if (WARN_ON_ONCE(!dma_resv_trylock(&bo->base._resv))) {
if (bo->resource && bo->resource->mem_type == TTM_PL_VRAM)
amdgpu_vram_mgr_set_clear_state(bo->resource, false);
As far as I can see this is illegal while the BO is not locked, so please drop that.
- return;
- }
amdgpu_amdkfd_remove_all_eviction_fences(abo);
- if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM ||
!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
- if (!bo->resource || bo->resource->mem_type != TTM_PL_VRAM) goto out;
- if (!(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE) ||
adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
goto out_clear_err;
- r = dma_resv_reserve_fences(&bo->base._resv, 1); if (r)
goto out;
goto out_clear_err;
r = amdgpu_fill_buffer(abo, 0, &bo->base._resv, &fence, true); if (WARN_ON(r))
goto out;
goto out_clear_err;
- amdgpu_vram_mgr_set_cleared(bo->resource);
- amdgpu_vram_mgr_set_clear_state(bo->resource, true); dma_resv_add_fence(&bo->base._resv, fence, DMA_RESV_USAGE_KERNEL); dma_fence_put(fence);
- dma_resv_unlock(&bo->base._resv);
- return;
+out_clear_err:
- amdgpu_vram_mgr_set_clear_state(bo->resource, false);
As far as I can see that is actually not a good idea. The cleared flag should not be set here in the first place.
out: dma_resv_unlock(&bo->base._resv); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9c5df35f05b7..9ec14ab900f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -407,9 +407,10 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, r = amdgpu_fill_buffer(abo, 0, NULL, &wipe_fence, false); if (r) {
} else if (wipe_fence) {amdgpu_vram_mgr_set_clear_state(bo->resource, false); goto error;
amdgpu_vram_mgr_set_cleared(bo->resource);
}amdgpu_vram_mgr_set_clear_state(bo->resource, true); dma_fence_put(fence); fence = wipe_fence;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h index b256cbc2bc27..1019c5806ec7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h @@ -64,9 +64,12 @@ to_amdgpu_vram_mgr_resource(struct ttm_resource *res) return container_of(res, struct amdgpu_vram_mgr_resource, base); } -static inline void amdgpu_vram_mgr_set_cleared(struct ttm_resource *res) +static inline void amdgpu_vram_mgr_set_clear_state(struct ttm_resource *res, bool is_clear) {
- to_amdgpu_vram_mgr_resource(res)->flags |= DRM_BUDDY_CLEARED;
- if (is_clear)
to_amdgpu_vram_mgr_resource(res)->flags |= DRM_BUDDY_CLEARED;
- else
to_amdgpu_vram_mgr_resource(res)->flags &= ~DRM_BUDDY_CLEARED;
Rather code this here like:
struct amdgpu_vram_mgr_resource *ares = to_amdgpu_vram_mgr_resource(res);
WARN_ON(ares->flags & DRM_BUDDY_CLEARED); ares->flags |= DRM_BUDDY_CLEARED;
Regards, Christian.
} #endif
linux-stable-mirror@lists.linaro.org