iommu/arm-smmu: use a threaded handler for context interrupts
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Context interrupts can call domain-specific handlers which might sleep. Currently we register our handler with request_irq, so our handler is called in atomic context, so domain handlers that sleep result in an invalid context BUG. Fix this by using request_threaded_irq.
This also prepares the way for doing things like enabling clocks within our interrupt handler.
--- drivers/iommu/arm-smmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/iommu/arm-smmu.c +3 -2
@@ -973,8 +973,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,spin_unlock_irqrestore (&smmu_domain->lock, flags); irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - ret =request_irq (irq, arm_smmu_context_fault,IRQF_SHARED , -"arm-smmu-context-fault" , domain); + ret =request_threaded_irq (irq,NULL , arm_smmu_context_fault, +IRQF_ONESHOT |IRQF_SHARED , +"arm-smmu-context-fault" , domain);if (IS_ERR_VALUE (ret)) {dev_err (smmu->dev,"failed to request context IRQ %d (%u)\n" , cfg->irptndx, irq);
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Hi Mitch,
Quoted 19 lines · Mitchel Humpherys
Context interrupts can call domain-specific handlers which might sleep. Currently we register our handler with
request_irq, so our handler is called in atomic context, so domain handlers that sleep result in an invalid context BUG. Fix this by usingrequest_threaded_irq.This also prepares the way for doing things like enabling clocks within our interrupt handler.
Signed-off-by Mitchel Humpherys <[email protected]>--- drivers/iommu/arm-smmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/iommu/arm-smmu.c +0
-0@@ -973,8 +973,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,spin_unlock_irqrestore (&smmu_domain->lock, flags);
drivers/iommu/arm-smmu.c static int arm_smmu_init_domain_context(struct iommu_domain *domain, · line 981
Quoted 10 lines
drivers/iommu/arm-smmu.c +3
-2irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - ret =request_irq (irq, arm_smmu_context_fault,IRQF_SHARED , -"arm-smmu-context-fault" , domain); + ret =request_threaded_irq (irq,NULL , arm_smmu_context_fault, +IRQF_ONESHOT |IRQF_SHARED , +"arm-smmu-context-fault" , domain);if (IS_ERR_VALUE (ret)) {dev_err (smmu->dev,"failed to request context IRQ %d (%u)\n" , cfg->irptndx, irq);
I think I'd rather keep a simple atomic handler, then have a threaded handler for actually issuing the report_iommu_fault. i.e. we only wake the thread when it looks like there's some work to do. That also works much better for shared interrupts.
Will
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Quoted 23 lines · Will Deacon
Hi Mitch,
Quoted 20 lines · Mitchel Humpherys
Context interrupts can call domain-specific handlers which might sleep. Currently we register our handler with
request_irq, so our handler is called in atomic context, so domain handlers that sleep result in an invalid context BUG. Fix this by usingrequest_threaded_irq.This also prepares the way for doing things like enabling clocks within our interrupt handler.
Signed-off-by Mitchel Humpherys <[email protected]>--- drivers/iommu/arm-smmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/iommu/arm-smmu.c +0
-0@@ -973,8 +973,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,spin_unlock_irqrestore (&smmu_domain->lock, flags);
Quoted 14 lines
drivers/iommu/arm-smmu.c static int arm_smmu_init_domain_context(struct iommu_domain *domain, · line 981
Quoted 9 lines
drivers/iommu/arm-smmu.c +3
-2irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - ret =request_irq (irq, arm_smmu_context_fault,IRQF_SHARED , -"arm-smmu-context-fault" , domain); + ret =request_threaded_irq (irq,NULL , arm_smmu_context_fault, +IRQF_ONESHOT |IRQF_SHARED , +"arm-smmu-context-fault" , domain);if (IS_ERR_VALUE (ret)) {dev_err (smmu->dev,"failed to request context IRQ %d (%u)\n" , cfg->irptndx, irq);I think I'd rather keep a simple atomic handler, then have a threaded handler for actually issuing the
report_iommu_fault. i.e. we only wake the thread when it looks like there's some work to do. That also works much better for shared interrupts.
Are you still against adding clock support to the driver? If not, we'll need to move to a threaded handler when clocks come in anyways...
Can you elaborate what you mean regarding shared interrupts? Even without clocks it seems like the code clarity / performance tradeoff would favor a threaded handler, given that performance isn't important here.
-Mitch
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Quoted 37 lines · Mitchel Humpherys
Quoted 21 lines · Will Deacon
Quoted 20 lines · Mitchel Humpherys
Context interrupts can call domain-specific handlers which might sleep. Currently we register our handler with
request_irq, so our handler is called in atomic context, so domain handlers that sleep result in an invalid context BUG. Fix this by usingrequest_threaded_irq.This also prepares the way for doing things like enabling clocks within our interrupt handler.
Signed-off-by Mitchel Humpherys <[email protected]>--- drivers/iommu/arm-smmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/iommu/arm-smmu.c +0
-0@@ -973,8 +973,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,spin_unlock_irqrestore (&smmu_domain->lock, flags);Quoted 14 lines
drivers/iommu/arm-smmu.c static int arm_smmu_init_domain_context(struct iommu_domain *domain, · line 981
Quoted 9 lines
drivers/iommu/arm-smmu.c +3
-2irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - ret =request_irq (irq, arm_smmu_context_fault,IRQF_SHARED , -"arm-smmu-context-fault" , domain); + ret =request_threaded_irq (irq,NULL , arm_smmu_context_fault, +IRQF_ONESHOT |IRQF_SHARED , +"arm-smmu-context-fault" , domain);if (IS_ERR_VALUE (ret)) {dev_err (smmu->dev,"failed to request context IRQ %d (%u)\n" , cfg->irptndx, irq);I think I'd rather keep a simple atomic handler, then have a threaded handler for actually issuing the
report_iommu_fault. i.e. we only wake the thread when it looks like there's some work to do. That also works much better for shared interrupts.
Quoted 7 lines
Are you still against adding clock support to the driver? If not, we'll need to move to a threaded handler when clocks come in anyways...
Can you elaborate what you mean regarding shared interrupts? Even without clocks it seems like the code clarity / performance tradeoff would favor a threaded handler, given that performance isn't important here.
With a shared handler (e.g. a bunch of context banks have the same IRQ) then I assume that we don't want to end up with multiple handler threads all tripping over each other. I'd rather have one thread that handles work queued up by multiple low-level handlers.
Do you have a preference either way?
Will
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Quoted 46 lines · Will Deacon
Quoted 37 lines · Mitchel Humpherys
Quoted 21 lines · Will Deacon
Quoted 20 lines · Mitchel Humpherys
Context interrupts can call domain-specific handlers which might sleep. Currently we register our handler with
request_irq, so our handler is called in atomic context, so domain handlers that sleep result in an invalid context BUG. Fix this by usingrequest_threaded_irq.This also prepares the way for doing things like enabling clocks within our interrupt handler.
Signed-off-by Mitchel Humpherys <[email protected]>--- drivers/iommu/arm-smmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/iommu/arm-smmu.c +0
-0@@ -973,8 +973,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,spin_unlock_irqrestore (&smmu_domain->lock, flags);Quoted 14 lines
drivers/iommu/arm-smmu.c static int arm_smmu_init_domain_context(struct iommu_domain *domain, · line 981
Quoted 9 lines
drivers/iommu/arm-smmu.c +3
-2irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - ret =request_irq (irq, arm_smmu_context_fault,IRQF_SHARED , -"arm-smmu-context-fault" , domain); + ret =request_threaded_irq (irq,NULL , arm_smmu_context_fault, +IRQF_ONESHOT |IRQF_SHARED , +"arm-smmu-context-fault" , domain);if (IS_ERR_VALUE (ret)) {dev_err (smmu->dev,"failed to request context IRQ %d (%u)\n" , cfg->irptndx, irq);I think I'd rather keep a simple atomic handler, then have a threaded handler for actually issuing the
report_iommu_fault. i.e. we only wake the thread when it looks like there's some work to do. That also works much better for shared interrupts.Quoted 7 lines
Are you still against adding clock support to the driver? If not, we'll need to move to a threaded handler when clocks come in anyways...
Can you elaborate what you mean regarding shared interrupts? Even without clocks it seems like the code clarity / performance tradeoff would favor a threaded handler, given that performance isn't important here.
Quoted 6 lines
With a shared handler (e.g. a bunch of context banks have the same IRQ) then I assume that we don't want to end up with multiple handler threads all tripping over each other. I'd rather have one thread that handles work queued up by multiple low-level handlers.
Do you have a preference either way?
Ok I think I understand the scenario you're describing. If multiple context banks are sharing an interrupt line their handlers currently execute serially, but with threaded handlers they would all be woken up and possibly execute concurrently. I hadn't really considered this because none of our targets have CBs sharing interrupts. In any case, the CBs that aren't interrupting should quickly return IRQ_NONE when they notice that !(fsr & FSR_FAULT), so is this really a concern?
Anyways, we can always hold off on this until we have a more compelling motivation for it. For example, if we need to enable clocks to read registers then threaded IRQs seem like the best solution. Hopefully I'll find time to have another go at the clocks stuff soon, which is the real reason why we're using threaded IRQs for context interrupts in our msm tree.
-Mitch
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Quoted 8 lines · Mitchel Humpherys
Quoted 6 lines · Will Deacon
With a shared handler (e.g. a bunch of context banks have the same IRQ) then I assume that we don't want to end up with multiple handler threads all tripping over each other. I'd rather have one thread that handles work queued up by multiple low-level handlers.
Do you have a preference either way?
Quoted 7 lines
Ok I think I understand the scenario you're describing. If multiple context banks are sharing an interrupt line their handlers currently execute serially, but with threaded handlers they would all be woken up and possibly execute concurrently. I hadn't really considered this because none of our targets have CBs sharing interrupts. In any case, the CBs that aren't interrupting should quickly return
IRQ_NONEwhen they notice that !(fsr &FSR_FAULT), so is this really a concern?
Well, with my stall-mode hat on, the FSR check could be done in the low-level handler, with the actual page fault handling or whatever done in the thread.
Quoted 6 lines
Anyways, we can always hold off on this until we have a more compelling motivation for it. For example, if we need to enable clocks to read registers then threaded IRQs seem like the best solution. Hopefully I'll find time to have another go at the clocks stuff soon, which is the real reason why we're using threaded IRQs for context interrupts in our msm tree.
Okey doke. Having the clocks stuff supported in iommu core would be my preference.
Will
PATCH 1/1 iommu/arm-smmu: use a threaded handler for context interrupts
Quoted 17 lines · Will Deacon
Quoted 8 lines · Mitchel Humpherys
Quoted 6 lines · Will Deacon
With a shared handler (e.g. a bunch of context banks have the same IRQ) then I assume that we don't want to end up with multiple handler threads all tripping over each other. I'd rather have one thread that handles work queued up by multiple low-level handlers.
Do you have a preference either way?
Quoted 7 lines
Ok I think I understand the scenario you're describing. If multiple context banks are sharing an interrupt line their handlers currently execute serially, but with threaded handlers they would all be woken up and possibly execute concurrently. I hadn't really considered this because none of our targets have CBs sharing interrupts. In any case, the CBs that aren't interrupting should quickly return
IRQ_NONEwhen they notice that !(fsr &FSR_FAULT), so is this really a concern?
Quoted 3 lines
Well, with my stall-mode hat on, the FSR check could be done in the low-level handler, with the actual page fault handling or whatever done in the thread.
But we'll need to turn on clocks just to read the FSR, which can't be done from atomic context.
Quoted 10 lines
Quoted 7 lines
Anyways, we can always hold off on this until we have a more compelling motivation for it. For example, if we need to enable clocks to read registers then threaded IRQs seem like the best solution. Hopefully I'll find time to have another go at the clocks stuff soon, which is the real reason why we're using threaded IRQs for context interrupts in our msm tree.
Okey doke. Having the clocks stuff supported in iommu core would be my preference.
Yeah I'll try to come up with something. In this particular case I guess we'd actually have to call out to some iommu_enable_access API so it wouldn't be completely transparent. Everywhere else I think the iommu core can wrap the various iommu_ops callbacks with the enable/disable calls.
-Mitch
Signature · 3 lines
Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project