On 14/01/2025 at 19:46, Ming Yu wrote: > Dear Vincent, > > Thank you for your reply, > I'll add comments to describe these locks in the next patch, > > Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> 於 2025年1月14日 週二 下午4:06寫道: (...) >>> +static int nct6694_can_get_berr_counter(const struct net_device *ndev, >>> + struct can_berr_counter *bec) >>> +{ >>> + struct nct6694_can_priv *priv = netdev_priv(ndev); >>> + struct nct6694_can_event *evt = priv->rx->event; >>> + struct nct6694_cmd_header cmd_hd; >>> + u8 mask = NCT6694_CAN_EVENT_REC | NCT6694_CAN_EVENT_TEC; >>> + int ret; >>> + >>> + guard(mutex)(&priv->lock); >>> + >>> + cmd_hd = (struct nct6694_cmd_header) { >>> + .mod = NCT6694_CAN_MOD, >>> + .cmd = NCT6694_CAN_EVENT, >>> + .sel = NCT6694_CAN_EVENT_SEL(priv->can_idx, mask), >>> + .len = cpu_to_le16(sizeof(priv->rx->event)) >>> + }; >>> + >>> + ret = nct6694_read_msg(priv->nct6694, &cmd_hd, evt); >>> + if (ret < 0) >>> + return ret; >> >> You are holding the priv->lock mutex before calling >> nct6694_read_msg(). But nct6694_read_msg() then holds the >> nct6694->access_lock mutex. Why do you need a double mutex here? What >> kind of race scenario are you trying to prevent here? >> > > I think priv->lock need to be placed here to prevent priv->rx from > being assigned by other functions, and nct6694->access_lock ensures > that the nct6694_read_msg() transaction is completed. > But in this case, cmd_hd does not need to be in priv->lock's scope. So, the only reason for holding priv->lock is because priv->rx is shared between functions. struct nct6694_can_event is only 8 bytes. And you only need it for the life time of the function so it can simply be declared on the stack: struct nct6694_can_event evt; and with this, no more need to hold the lock. And the same thing also applies to the other functions. Here, by trying to optimize the memory for only a few bytes, you are getting a huge penalty on the performance by putting locks on all the functions. This is not a good tradeoff. >>> + bec->rxerr = evt[priv->can_idx].rec; >>> + bec->txerr = evt[priv->can_idx].tec; >>> + >>> + return 0; >>> +} Yours sincerely, Vincent Mailhol