Re: [bug report] soc: qcom: rpmh-rsc: Sleep waiting for tcs slots to be free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Quoting Dan Carpenter (2024-05-08 07:49:34)
> Hello Stephen Boyd,
>
> Commit 2bc20f3c8487 ("soc: qcom: rpmh-rsc: Sleep waiting for tcs
> slots to be free") from Jul 24, 2020 (linux-next), leads to the
> following Smatch static checker warning:
>
>         drivers/soc/qcom/rpmh-rsc.c:658 rpmh_rsc_send_data()
>         warn: mixing irqsave and irq
>
> drivers/soc/qcom/rpmh-rsc.c
>     645 int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
>     646 {
>     647         struct tcs_group *tcs;
>     648         int tcs_id;
>     649         unsigned long flags;
>     650
>     651         tcs = get_tcs_for_msg(drv, msg);
>     652         if (IS_ERR(tcs))
>     653                 return PTR_ERR(tcs);
>     654
>     655         spin_lock_irqsave(&drv->lock, flags);
>
> flags saves if this is called with IRQs disabled.  I don't think it is.
>
>     656
>     657         /* Wait forever for a free tcs. It better be there eventually! */
> --> 658         wait_event_lock_irq(drv->tcs_wait,
>     659                             (tcs_id = claim_tcs_for_req(drv, tcs, msg)) >= 0,
>     660                             drv->lock);
>
> This will enable IRQs and then disable them again.  If this were called
> with IRQs disabled then this would probably be bad.  (But again, I don't
> think it is).
>
>     661
>     662         tcs->req[tcs_id - tcs->offset] = msg;
>     663         set_bit(tcs_id, drv->tcs_in_use);
>     664         if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
>     665                 /*
>     666                  * Clear previously programmed WAKE commands in selected
>     667                  * repurposed TCS to avoid triggering them. tcs->slots will be
>     668                  * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
>     669                  */
>     670                 write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
>     671                 enable_tcs_irq(drv, tcs_id, true);
>     672         }
>     673         spin_unlock_irqrestore(&drv->lock, flags);
>
> And then it sets it back to whatever it was when it was called.  So
> that's fine.
>

I see. I think you want this sort of patch so that it is clearer that
this can't be called with interrupts disabled? Would Smatch be happier?

---8<----
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index a021dc71807b..568d0b8c52d6 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -645,13 +645,14 @@ int rpmh_rsc_send_data(struct rsc_drv *drv,
const struct tcs_request *msg)
 {
 	struct tcs_group *tcs;
 	int tcs_id;
-	unsigned long flags;
+
+	might_sleep();

 	tcs = get_tcs_for_msg(drv, msg);
 	if (IS_ERR(tcs))
 		return PTR_ERR(tcs);

-	spin_lock_irqsave(&drv->lock, flags);
+	spin_lock_irq(&drv->lock);

 	/* Wait forever for a free tcs. It better be there eventually! */
 	wait_event_lock_irq(drv->tcs_wait,
@@ -669,7 +670,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const
struct tcs_request *msg)
 		write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0);
 		enable_tcs_irq(drv, tcs_id, true);
 	}
-	spin_unlock_irqrestore(&drv->lock, flags);
+	spin_unlock_irq(&drv->lock);

 	/*
 	 * These two can be done after the lock is released because:




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux