Skip to content

ASoC: SOF: pcm: harden PCM STOP sequence - #1169

Merged
plbossart merged 1 commit into
thesofproject:topic/sof-devfrom
xiulipan:pr/stopsequence
Sep 20, 2019
Merged

plbossart merged 1 commit into
thesofproject:topic/sof-devfrom
xiulipan:pr/stopsequence

Conversation

@xiulipan

@xiulipan xiulipan commented Aug 28, 2019 •

Copy link
Copy Markdown

The old STOP sequence is: 1. stop DMA 2. send STOP ipc
If delay happen before the step 1 and 2, the DMA buffer will be empty in
short time and cause pipeline xrun then stop the pipeline.
Then the step 2 ipc stop will return error as pipeline is already stopped.

Harden the STOP sequence by send STOP IPC before stop DMA.

Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com

@xiulipan xiulipan changed the title ASoC: SOF: pcm: harden PCM STOP sequence [RFC]ASoC: SOF: pcm: harden PCM STOP sequence Aug 28, 2019
@ranj063

ranj063 commented Aug 28, 2019

Copy link
Copy Markdown
Collaborator

@xiulipan this beats me. Where is this need coming from? Which platform are we seeing the xrun on?
Do you think sending the stop IPC and the stopping the DMA might work?

@plbossart

Copy link
Copy Markdown
Member

same comment as @ranj063, where does this come from? What issue does this solve and on which platforms?

@xiulipan

Copy link
Copy Markdown
Author

@ranj063 @plbossart
I think the issue comes from the TGL platform mouth ago. I think I can create a issue now but you can also reference the email thread we discussed about this.
Issue #1170

@tlauda @keyonjie
Could you help to check if this change fit the sequence for pipeline stop?

@tlauda

tlauda commented Aug 29, 2019

Copy link
Copy Markdown

@ranj063 @xiulipan @plbossart Please look at the #1160. I explained potential problem for the HDA Link pipelines, but getting an xrun is also a possibility, if the delay between DMA stop and IPC will be too big.

@plbossart

Copy link
Copy Markdown
Member

I am not clear on the suggested solutions here.

@xiulipan 's proposal in this PR is to send an IPC Pause followed by an IPC stop. This doesn't address handling of the RUN bits.

@tlauda 's suggestion is to send an IPC Stop followed by a DMA stop (with the RUN bits changed by the driver).

Pick one please.

@keyonjie

Copy link
Copy Markdown

@plbossart an extra TRIGGER_PAUSE IPC is from the proposed DMA stop sequence from FW team to avoid xrun happening.

With my knowledge the FW side almost handling PAUSE IPC very similar with that of STOP IPC, so will this extra pause IPC introduce any failure at double stopping? As @tlauda suggested, maybe worth to try only exchange the position of the RUN bit setting and TRIGGER_STOP IPC sending solution.

@tlauda

tlauda commented Aug 30, 2019

Copy link
Copy Markdown

@plbossart @keyonjie Extra PAUSE won't introduce any problems, but actually it's not needed. Changing the sequence of RUN and TRIGGER_STOP is enough.

@xiulipan

Copy link
Copy Markdown
Author

@plbossart
My suggestion here is to add one move pause IPC before DMA stop in our PCM STOP sequence.
Thus

  1. IPC pause
  2. DMA STOP: RUN bit 0
  3. IPC stop to make pipeline status machine right

What @tlauda means is that we should not only have DMA RUN0 then IPC PAUSE/STOP, we may have some gap between and have XRUN risk. So what he meant is we should also harden PCM PAUSE sequence with

  1. IPC pause
  2. DMA STOP: RUN bit 0

I agree with that idea to harden both DMA STOP and PIPELINE STOP/PAUSE sequence.

Now the only problem is solved by @tlauda
We can make IPC STOP before DMA STOP

I will try to make the PR update for both PCM PAUSE and STOP

@plbossart plbossart added the Unclear No agreement on problem statement and resolution label Sep 3, 2019
@plbossart

Copy link
Copy Markdown
Member

Setting the 'Unclear' label since we don't have an agreed state machine between driver and firmware teams.

@tlauda

tlauda commented Sep 3, 2019

Copy link
Copy Markdown

@plbossart I've already defined the proper state transition:

  1. Send SOF_IPC_STREAM_TRIG_STOP to the DSP.
  2. Stop DMA.

@xiulipan We don't need additional SOF_IPC_STREAM_TRIG_PAUSE.

@xiulipan

xiulipan commented Sep 4, 2019

Copy link
Copy Markdown
Author

@tlauda @plbossart
One more clarify:
We also need to refine the order for PCM PAUSE for issue #1160 right?

@tlauda

tlauda commented Sep 4, 2019

Copy link
Copy Markdown

@xiulipan Yes, it's the same situation.

@xiulipan

xiulipan commented Sep 4, 2019

Copy link
Copy Markdown
Author

@plbossart @tlauda
Update the PCM trigger sequence for STOP pipeline by

  1. STOP DMA
  2. Send STOP IPC
    Please check if this is the right solution.

@xiulipan

xiulipan commented Sep 4, 2019

Copy link
Copy Markdown
Author

@tlauda
From the CI logs, it seems we still have issue #1160, could you check what do I miss here?

=== PAUSE ===                                                            arecord: do_pause:1497: pause push error: Invalid argument
                                                                          
 
#+                                                 | 00%
=== PAUSE ===                                                            arecord: do_pause:1497: pause push error: Invalid argument

https://sof-ci.01.org/linuxpr/PR1169/build1801/devicetest/CML_RVP_HDA/check-pause-resume-capture-10.sh/check-pause-resume-capture-10.sh.txt

[  182.418691 <    0.418128>] sof-audio-pci 0000:00:1f.3: pcm: trigger stream 6 dir 1 cmd 3
[  182.418699 <    0.000008>] sof-audio-pci 0000:00:1f.3: ipc tx: 0x60060000: GLB_STREAM_MSG: TRIG_PAUSE
[  182.418889 <    0.000190>] sof-audio-pci 0000:00:1f.3: error: ipc error for 0x60060000 size 12
[  182.418896 <    0.000007>]  DMIC48kHz: ASoC: trigger FE failed -22
[  182.418900 <    0.000004>] sof-audio-pci 0000:00:1f.3: pcm: trigger stream 6 dir 1 cmd 4
[  182.418913 <    0.000013>] sof-audio-pci 0000:00:1f.3: FW Poll Status: reg=0x2024001e successful
[  182.418916 <    0.000003>] sof-audio-pci 0000:00:1f.3: ipc tx: 0x60070000: GLB_STREAM_MSG: TRIG_RELEASE
[  182.419135 <    0.000219>] sof-audio-pci 0000:00:1f.3: error: ipc error for 0x60070000 size 12
[  182.419142 <    0.000007>]  DMIC48kHz: ASoC: trigger FE failed -22

https://sof-ci.01.org/linuxpr/PR1169/build1801/devicetest/CML_RVP_HDA/check-pause-resume-capture-10.sh/dmesg.txt

    0      2          DMA         227292124.687500    355041.156250 src/drivers/dw/dma.c:1339	dw_dma_avail_data_size() size is 0! Channel enable = 1.
    0      1          DAI 10.66   227292129.479167         4.791667      src/audio/dai.c:580 	dai_check_for_xrun() error: overrun due to no data available
    0      1         COMP         227292134.947917         5.468750 of/audio/component.h:758 	comp_overrun() error: dev->comp.id = 66, sink->free = 128, copy_bytes = 0
    0      2         PIPE 10.67   227292142.239583         7.291667 src/audio/pipeline.c:634 	pipeline_trigger()
    0      2          DAI 10.66   227292146.354167         4.114583      src/audio/dai.c:483 	dai_comp_trigger(), command = 8
    0      2          DAI 10.66   227292150.520833         4.166667      src/audio/dai.c:541 	dai_comp_trigger(), XRUN
    0      2          DAI 10.66   227292154.166667         3.645833      src/audio/dai.c:547 	dai_comp_trigger(), PAUSE/STOP
    0      2          DMA         227292157.916667         3.750000 src/drivers/dw/dma.c:465 	dw_dma_stop(): dma 0 channel 0 stop
    0      2         DMIC         227292171.197917        13.281250 rs/intel/cavs/dmic.c:1442	dmic_trigger()
    0      2         DMIC         227292174.791667         3.593750 rs/intel/cavs/dmic.c:1367	dmic_stop()
    0      2         DMIC         227292178.906250         4.114583 rs/intel/cavs/dmic.c:1393	dmic_stop(), dmic_active_fifos = 1
    0      1         PIPE         227292186.614583         7.708333 src/audio/pipeline.c:811 	pipeline_copy() error: ret = -61, start->comp.id = 66, dir = 0
    0      1         PIPE 10.67   227292193.593750         6.979167 src/audio/pipeline.c:1005	pipeline_task(): xrun recover failed! pipeline will be stopped!
    0      2          IPC         228021592.708333    729399.125000    src/ipc/handler.c:452 	ipc: comp 60 -> trigger cmd 0x60000
    0      2         PIPE 10.67   228021610.468750        17.760416 src/audio/pipeline.c:634 	pipeline_trigger()
    0      2         HOST 10.60   228021614.687500         4.218750     src/audio/host.c:323 	host_trigger()
    0      2       VOLUME         228021619.427083         4.739583 udio/volume/volume.c:531 	volume_trigger()
    0      2       EQ_IIR         228021623.593750         4.166667 udio/eq_iir/eq_iir.c:713 	eq_iir_trigger()
    0      2          DAI 10.66   228021627.916667         4.322917      src/audio/dai.c:483 	dai_comp_trigger(), command = 2
    0      1         COMP         228021631.822917         3.906250 rc/audio/component.c:182 	comp_set_state() error: wrong state = 1, COMP_TRIGGER_PAUSE
    0      1          IPC         228021638.593750         6.770833 src/audio/pipeline.c:661 	pipeline_trigger() error: ret = -22, host->comp.id = 60, cmd = 2
    0      1          IPC         228021645.625000         7.031250    src/ipc/handler.c:486 	ipc: comp 60 trigger 0x60000 failed -22

https://sof-ci.01.org/linuxpr/PR1169/build1801/devicetest/CML_RVP_HDA/check-pause-resume-capture-10.sh/slogger.txt

@tlauda

tlauda commented Sep 4, 2019

Copy link
Copy Markdown

#1160 is related to HDA Link render pipelines. Pause/release problem on capture is totally different issue. Also I've never said it will for sure fix #1160, but this change of sequence is needed anyway.

@xiulipan

xiulipan commented Sep 4, 2019

Copy link
Copy Markdown
Author

@tlauda
Thanks for the clarify, so we still have another issue for capture? Could you share the issue for the capture?

@tlauda

tlauda commented Sep 4, 2019

Copy link
Copy Markdown

thesofproject/sof#1760

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the error handling looks suspicious on stop

Comment thread sound/soc/sof/pcm.c Resolved
@ranj063

ranj063 commented Sep 4, 2019

Copy link
Copy Markdown
Collaborator

@xiulipan the commit message is so confusing. You are saying the old sequence is Stop DMA -> Stop IPC. And then you are saying you should change it to be the same?

Comment thread sound/soc/sof/pcm.c Resolved
Comment thread sound/soc/sof/pcm.c Resolved
Comment thread sound/soc/sof/pcm.c Resolved

@ranj063 ranj063 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xiulipan also another minor comment about the commit message:
"If delay happen before the step 1 and 2," should be "If delay happen between the steps 1 and 2,"

And in the end, say that the suggested change to avoid the issue is to switch the order of steps 1 and 2 for the stop sequence.

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please update the error handling and address feedback on naming

Comment thread sound/soc/sof/pcm.c Resolved
Comment thread sound/soc/sof/pcm.c Resolved
@xiulipan

xiulipan commented Sep 9, 2019

Copy link
Copy Markdown
Author

@plbossart @ranj063
Thanks for the suggestion, updated.

ranj063
ranj063 previously approved these changes Sep 9, 2019

@ranj063 ranj063 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. Thanks @xiulipan

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment below

Comment thread sound/soc/sof/pcm.c
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
sizeof(stream), &reply, sizeof(reply));

if (ipc_first)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xiulipan in case the STOP IPC fails, is this expected that you still call platform_trigger. If yes you should make it explicit and explain why you are ignoring the return value and using it below.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart Will add comments. It seems either we fail the IPC or not we must stop the DMA stop.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart Another question. If IPC stop fails, do we need to free the PCM to make sure the pipeline can be reused?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i can you look into this? I don't recall the code changes that were committed in July and the test below for the pcm_free case looks suspicious to me.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xiulipan @plbossart The fix looks good. The test for pcm_free indeed has the same problem. My assumption was the if the IPC fails for stop, something fatal has happened and no bother sending the dsp_pcm_free(). But if stop will fail in an xrun case like @xiulipan you explained earlier, that changes things. Probably we should use different logic for start and stop -- abort with error if start fails to an intermediate step. For stopping/pausing, we should send all the IPCs still despite errors to ensure we free resources. To me it still sounds a bit fishy that stop would legitimately return an error, but if that's the FW API, then we have to follow it.

That does raise other issue. I tried to think of a nicer way to implement the "ipc_first" logic. If we now have differences in error handling, that will make the two code paths even more different. Maybe time for a different subroutines for starting data transfer and stopping it.:::?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i
So you would suggest we will always send FREE IPC no matter if IPC STOP fail
actually, we will only send IPC FREE after IPC STOP.

Actually I tried with some other way like switch case the start and stop in different code. But @ranj063 suggest to go with some simple flag. And this really looks simple but need a few comments to explain why we need do like that.

@kv2019i kv2019i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good patch! Will need some work for merging.

Comment thread sound/soc/sof/pcm.c Outdated
}

snd_sof_pcm_platform_trigger(sdev, substream, cmd);
/* DMA and IPC sequence is different for start and stop. Need to send

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: start multi-line comment with "/*\n"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix

Comment thread sound/soc/sof/pcm.c
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
sizeof(stream), &reply, sizeof(reply));

if (ipc_first)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xiulipan @plbossart The fix looks good. The test for pcm_free indeed has the same problem. My assumption was the if the IPC fails for stop, something fatal has happened and no bother sending the dsp_pcm_free(). But if stop will fail in an xrun case like @xiulipan you explained earlier, that changes things. Probably we should use different logic for start and stop -- abort with error if start fails to an intermediate step. For stopping/pausing, we should send all the IPCs still despite errors to ensure we free resources. To me it still sounds a bit fishy that stop would legitimately return an error, but if that's the FW API, then we have to follow it.

That does raise other issue. I tried to think of a nicer way to implement the "ipc_first" logic. If we now have differences in error handling, that will make the two code paths even more different. Maybe time for a different subroutines for starting data transfer and stopping it.:::?

Comment thread sound/soc/sof/pcm.c Outdated
if (ipc_first)
snd_sof_pcm_platform_trigger(sdev, substream, cmd);

/* only need to free PCM is the pipeline is stopped successfully */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "free PCM if the pipeline"

Otherwise see comments above. This logic may be wrong. It was written with the interpretation of FW API that no non-fatal error can be returned for stop. Apparently this may not be the case, in which case this code needs to be changed.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it back to IPC FREE with IPC STOP no matter what IPC STOP ret.

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confused by comment below

Comment thread sound/soc/sof/pcm.c Outdated
if (ipc_first)
snd_sof_pcm_platform_trigger(sdev, substream, cmd);

/* free PCM no matter STOP fail or success*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that comment looks wrong?
if the STOP IPC fails with a non-zero return value, you will not free the PCM.
What I am missing?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart @xiulipan Yeah, this is a bit confusing as you ignore the platform_trigger return value but do not ignore the IPC send return value. So maybe call sof_pcm_dsp_pcm_free() whenever reset_hw_params is set, independently of "ret".
To no overwrite error values, you could add "ret/err" logic I added to d6064e8 to overcome a similar situation (this design pattern for collecting error values is at least used elsewhere in ALSA).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kv2019i I agree the comment is incorrect but I suppose the sequence is like this for the STOP trigger:

  1. send STOP IPC
  2. stop DMA
  3. free pcm is step 1 is successful and reset_hw_params is set.

So Xiuli's change looks legit to me except for the comment. on line 391 which should really say /* free PCM if reset_hw_params is set and the STOP IPC is successful */

@kv2019i kv2019i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This some issues (see inline).

Comment thread sound/soc/sof/pcm.c Outdated
if (ipc_first)
snd_sof_pcm_platform_trigger(sdev, substream, cmd);

/* free PCM no matter STOP fail or success*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart @xiulipan Yeah, this is a bit confusing as you ignore the platform_trigger return value but do not ignore the IPC send return value. So maybe call sof_pcm_dsp_pcm_free() whenever reset_hw_params is set, independently of "ret".
To no overwrite error values, you could add "ret/err" logic I added to d6064e8 to overcome a similar situation (this design pattern for collecting error values is at least used elsewhere in ALSA).

@plbossart

Copy link
Copy Markdown
Member

@xiulipan can we try and close this PR this week? There are a couple of comments that need to be addressed and the last change was 6 days ago.

The old STOP sequence is: 1. stop DMA 2. send STOP ipc
If delay happen before the steps 1 and 2, the DMA buffer will be empty in
short time and cause pipeline xrun then stop the pipeline.
Then the step 2 ipc stop will return error as pipeline is already stopped.

Suggested change to avoid the issue is to switch the order of steps 1 and 2
for the stop sequence.

Signed-off-by: Pan Xiuli <xiuli.pan@linux.intel.com>
@xiulipan

Copy link
Copy Markdown
Author

@plbossart @ranj063 @kv2019i
I think the main problem now is about either to use

        if (!ret && reset_hw_params)
               ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);

or

        if (reset_hw_params)
               ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);

I will follow the old logic to free only if STOP success for this update.

@ranj063 ranj063 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, Thanks @xiulipan

@kv2019i

kv2019i commented Sep 19, 2019

Copy link
Copy Markdown
Collaborator

@xiulipan wrote:

I will follow the old logic to free only if STOP success for this update.

Ack, ok, good for me.

@plbossart

Copy link
Copy Markdown
Member

@xiulipan CI is stuck? I'd like to merge with actual results...

@xiulipan xiulipan changed the title [RFC]ASoC: SOF: pcm: harden PCM STOP sequence ASoC: SOF: pcm: harden PCM STOP sequence Sep 20, 2019
@xiulipan

Copy link
Copy Markdown
Author

@plbossart CI re-runed. And remove the RFC

@ranj063 ranj063 removed the Unclear No agreement on problem statement and resolution label Sep 20, 2019
@plbossart
plbossart merged commit a45d08d into thesofproject:topic/sof-dev Sep 20, 2019
plbossart pushed a commit that referenced this pull request Feb 8, 2021
With kaslr the kernel image is placed at a random place, so starting the
bottom-up allocation with the kernel_end can result in an allocation
failure and a warning like this one:

  hugetlb_cma: reserve 2048 MiB, up to 2048 MiB per node
  ------------[ cut here ]------------
  memblock: bottom-up allocation failed, memory hotremove may be affected
  WARNING: CPU: 0 PID: 0 at mm/memblock.c:332 memblock_find_in_range_node+0x178/0x25a
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.0+ #1169
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
  RIP: 0010:memblock_find_in_range_node+0x178/0x25a
  Code: e9 6d ff ff ff 48 85 c0 0f 85 da 00 00 00 80 3d 9b 35 df 00 00 75 15 48 c7 c7 c0 75 59 88 c6 05 8b 35 df 00 01 e8 25 8a fa ff <0f> 0b 48 c7 44 24 20 ff ff ff ff 44 89 e6 44 89 ea 48 c7 c1 70 5c
  RSP: 0000:ffffffff88803d18 EFLAGS: 00010086 ORIG_RAX: 0000000000000000
  RAX: 0000000000000000 RBX: 0000000240000000 RCX: 00000000ffffdfff
  RDX: 00000000ffffdfff RSI: 00000000ffffffea RDI: 0000000000000046
  RBP: 0000000100000000 R08: ffffffff88922788 R09: 0000000000009ffb
  R10: 00000000ffffe000 R11: 3fffffffffffffff R12: 0000000000000000
  R13: 0000000000000000 R14: 0000000080000000 R15: 00000001fb42c000
  FS:  0000000000000000(0000) GS:ffffffff88f71000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: ffffa080fb401000 CR3: 00000001fa80a000 CR4: 00000000000406b0
  Call Trace:
    memblock_alloc_range_nid+0x8d/0x11e
    cma_declare_contiguous_nid+0x2c4/0x38c
    hugetlb_cma_reserve+0xdc/0x128
    flush_tlb_one_kernel+0xc/0x20
    native_set_fixmap+0x82/0xd0
    flat_get_apic_id+0x5/0x10
    register_lapic_address+0x8e/0x97
    setup_arch+0x8a5/0xc3f
    start_kernel+0x66/0x547
    load_ucode_bsp+0x4c/0xcd
    secondary_startup_64_no_verify+0xb0/0xbb
  random: get_random_bytes called from __warn+0xab/0x110 with crng_init=0
  ---[ end trace f151227d0b39be70 ]---

At the same time, the kernel image is protected with memblock_reserve(),
so we can just start searching at PAGE_SIZE.  In this case the bottom-up
allocation has the same chances to success as a top-down allocation, so
there is no reason to fallback in the case of a failure.  All together it
simplifies the logic.

Link: https://lkml.kernel.org/r/20201217201214.3414100-2-guro@fb.com
Fixes: 8fabc62 ("powerpc: Ensure that swiotlb buffer is allocated from low memory")
Signed-off-by: Roman Gushchin <guro@fb.com>
Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Wonhyuk Yang <vvghjk1234@gmail.com>
Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
ranj063 pushed a commit to ranj063/linux that referenced this pull request May 24, 2021
[ Upstream commit 2dcb396 ]

With kaslr the kernel image is placed at a random place, so starting the
bottom-up allocation with the kernel_end can result in an allocation
failure and a warning like this one:

  hugetlb_cma: reserve 2048 MiB, up to 2048 MiB per node
  ------------[ cut here ]------------
  memblock: bottom-up allocation failed, memory hotremove may be affected
  WARNING: CPU: 0 PID: 0 at mm/memblock.c:332 memblock_find_in_range_node+0x178/0x25a
  Modules linked in:
  CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.0+ thesofproject#1169
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
  RIP: 0010:memblock_find_in_range_node+0x178/0x25a
  Code: e9 6d ff ff ff 48 85 c0 0f 85 da 00 00 00 80 3d 9b 35 df 00 00 75 15 48 c7 c7 c0 75 59 88 c6 05 8b 35 df 00 01 e8 25 8a fa ff <0f> 0b 48 c7 44 24 20 ff ff ff ff 44 89 e6 44 89 ea 48 c7 c1 70 5c
  RSP: 0000:ffffffff88803d18 EFLAGS: 00010086 ORIG_RAX: 0000000000000000
  RAX: 0000000000000000 RBX: 0000000240000000 RCX: 00000000ffffdfff
  RDX: 00000000ffffdfff RSI: 00000000ffffffea RDI: 0000000000000046
  RBP: 0000000100000000 R08: ffffffff88922788 R09: 0000000000009ffb
  R10: 00000000ffffe000 R11: 3fffffffffffffff R12: 0000000000000000
  R13: 0000000000000000 R14: 0000000080000000 R15: 00000001fb42c000
  FS:  0000000000000000(0000) GS:ffffffff88f71000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: ffffa080fb401000 CR3: 00000001fa80a000 CR4: 00000000000406b0
  Call Trace:
    memblock_alloc_range_nid+0x8d/0x11e
    cma_declare_contiguous_nid+0x2c4/0x38c
    hugetlb_cma_reserve+0xdc/0x128
    flush_tlb_one_kernel+0xc/0x20
    native_set_fixmap+0x82/0xd0
    flat_get_apic_id+0x5/0x10
    register_lapic_address+0x8e/0x97
    setup_arch+0x8a5/0xc3f
    start_kernel+0x66/0x547
    load_ucode_bsp+0x4c/0xcd
    secondary_startup_64_no_verify+0xb0/0xbb
  random: get_random_bytes called from __warn+0xab/0x110 with crng_init=0
  ---[ end trace f151227d0b39be70 ]---

At the same time, the kernel image is protected with memblock_reserve(),
so we can just start searching at PAGE_SIZE.  In this case the bottom-up
allocation has the same chances to success as a top-down allocation, so
there is no reason to fallback in the case of a failure.  All together it
simplifies the logic.

Link: https://lkml.kernel.org/r/20201217201214.3414100-2-guro@fb.com
Fixes: 8fabc62 ("powerpc: Ensure that swiotlb buffer is allocated from low memory")
Signed-off-by: Roman Gushchin <guro@fb.com>
Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Wonhyuk Yang <vvghjk1234@gmail.com>
Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants