All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: Zijun Hu <zijun_hu@icloud.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Davidlohr Bueso <dave@stgolabs.net>,
	Jonathan Cameron <jonathan.cameron@huawei.com>,
	Dave Jiang <dave.jiang@intel.com>,
	Alison Schofield <alison.schofield@intel.com>,
	Vishal Verma <vishal.l.verma@intel.com>,
	Ira Weiny <ira.weiny@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Timur Tabi <timur@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org,
	linux1394-devel@lists.sourceforge.net, netdev@vger.kernel.org,
	Zijun Hu <quic_zijuhu@quicinc.com>
Subject: Re: [PATCH v2 3/4] firewire: core: Prevent device_find_child() from modifying caller's match data
Date: Mon, 19 Aug 2024 17:58:47 +0900	[thread overview]
Message-ID: <20240819085847.GA252819@workstation.local> (raw)
In-Reply-To: <11efcbb2-f69a-49b4-a593-34fce42d49ea@icloud.com>


Hi,

On 2024/8/18 22:34, Zijun Hu wrote:
>On 2024/8/17 17:57, Takashi Sakamoto wrote:
>> ======== 8< --------
>> 
>> From ceaa8a986ae07865eb3fec810de330e96b6d56e2 Mon Sep 17 00:00:00 2001
>> From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
>> Date: Sat, 17 Aug 2024 17:52:53 +0900
>> Subject: [PATCH] firewire: core: update fw_device outside of
>>  device_find_child()
>> 
>> When detecting updates of bus topology, the data of fw_device is newly
>> allocated and caches the content of configuration ROM from the
>> corresponding node. Then, the tree of device is sought to find the
>> previous data of fw_device corresponding to the node, since in IEEE 1394
>> specification numeric node identifier could be changed dynamically every
>> generation of bus topology. If it is found, the previous data is updated
>> and reused, then the newly allocated data is going to be released.
>> 
>> The above procedure is done in the call of device_find_child(), however it
>> is a bit abusing against the intention of the helper function, since the
>> call would not only find but also update.
>> 
>> This commit splits the update outside of the call.
>> ---
>>  drivers/firewire/core-device.c | 109 ++++++++++++++++-----------------
>>  1 file changed, 54 insertions(+), 55 deletions(-)
>> 
>> diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
>> index bc4c9e5a..62e8d839 100644
>> --- a/drivers/firewire/core-device.c
>> +++ b/drivers/firewire/core-device.c
>> ...
>> @@ -1038,6 +988,17 @@ int fw_device_set_broadcast_channel(struct device *dev, void *gen)
>>  	return 0;
>>  }
>>  
>> +static int compare_configuration_rom(struct device *dev, void *data)
>> +{
>> +	const struct fw_device *old = fw_device(dev);
>> +	const u32 *config_rom = data;
>> +
>> +	if (!is_fw_device(dev))
>> +		return 0;
>> +
>> +	return !!memcmp(old->config_rom, config_rom, 6 * 4);
>
>!memcmp(old->config_rom, config_rom, 6 * 4) ?

Indeed.

>is this extra condition old->state == FW_DEVICE_GONE required ?
>
>namely, is it okay for  below return ?
>return  !memcmp(old->config_rom, config_rom, 6 * 4) && old->state ==
>FW_DEVICE_GONE

If so, atomic_read() should be used, however I avoid it since the access
to state member happens twice in in the path to reuse the instance.

>> +}
>> +
>>  static void fw_device_init(struct work_struct *work)
>>  {
>>  	struct fw_device *device =
>> @@ -1071,13 +1032,51 @@ static void fw_device_init(struct work_struct *work)
>>  		return;
>>  	}
>>  
>> -	revived_dev = device_find_child(card->device,
>> -					device, lookup_existing_device);
>> +	// If a device was pending for deletion because its node went away but its bus info block
>> +	// and root directory header matches that of a newly discovered device, revive the
>> +	// existing fw_device. The newly allocated fw_device becomes obsolete instead.
>> +	//
>> +	// serialize config_rom access.
>> +	scoped_guard(rwsem_read, &fw_device_rwsem) {
>> +		// TODO: The cast to 'void *' could be removed if Zijun Hu's work goes well.
>
>may remove this TODO line since i will simply remove the cast with the
>other patch series as shown below:
>https://lore.kernel.org/all/20240811-const_dfc_done-v1-0-9d85e3f943cb@quicinc.com/

Of course, I won't apply this patch as is. It is just a mark to hold
your attention.

>> +		revived_dev = device_find_child(card->device, (void *)device->config_rom,
>> +						compare_configuration_rom);
>> +	}
>>  	if (revived_dev) {
>> -		put_device(revived_dev);
>> -		fw_device_release(&device->device);
>> +		struct fw_device *found = fw_device(revived_dev);
>>  
>> -		return;
>> +		// serialize node access
>> +		guard(spinlock_irq)(&card->lock);
>> +
>> +		if (atomic_cmpxchg(&found->state,
>> +				   FW_DEVICE_GONE,
>> +				   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
>> +			struct fw_node *current_node = device->node;
>> +			struct fw_node *obsolete_node = found->node;
>> +
>> +			device->node = obsolete_node;
>> +			device->node->data = device;
>> +			found->node = current_node;
>> +			found->node->data = found;
>> +
>> +			found->max_speed = device->max_speed;
>> +			found->node_id = current_node->node_id;
>> +			smp_wmb();  /* update node_id before generation */
>> +			found->generation = card->generation;
>> +			found->config_rom_retries = 0;
>> +			fw_notice(card, "rediscovered device %s\n", dev_name(revived_dev));
>> +
>> +			found->workfn = fw_device_update;
>> +			fw_schedule_device_work(found, 0);
>> +
>> +			if (current_node == card->root_node)
>> +				fw_schedule_bm_work(card, 0);
>> +
>> +			put_device(revived_dev);
>> +			fw_device_release(&device->device);
>> +
>> +			return;
>> +		}
>
>is it okay to put_device() here as well ?
>put_device(revived_dev);

Exactly. The call of put_device() should be done when the call of
device_find_child() returns non-NULL value.

Additionally, I realize that the call of fw_device_release() under
acquiring card->lock causes dead lock.

>>  	}
>>  
>>  	device_initialize(&device->device);

Anyway, I'll post take 2 and work for its evaluation.


Thanks

Takashi Sakamoto

  reply	other threads:[~2024-08-19  8:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-15 14:58 [PATCH v2 0/4] driver core: Prevent device_find_child() from modifying caller's match data Zijun Hu
2024-08-15 14:58 ` [PATCH v2 1/4] driver core: Make parameter check consistent for API cluster device_(for_each|find)_child() Zijun Hu
2024-08-20 12:53   ` Ira Weiny
2024-08-20 13:40     ` Zijun Hu
2024-08-20 14:14       ` Ira Weiny
2024-08-21 14:44         ` Zijun Hu
2024-08-23 17:19           ` Ira Weiny
2024-08-23 21:45             ` Zijun Hu
2024-08-24  3:21           ` Greg Kroah-Hartman
2024-08-24  3:23   ` Greg Kroah-Hartman
2024-08-15 14:58 ` [PATCH v2 2/4] cxl/region: Prevent device_find_child() from modifying caller's match data Zijun Hu
2024-08-20 13:59   ` Ira Weiny
2024-08-21 12:46     ` Zijun Hu
2024-08-23 18:10       ` Ira Weiny
2024-08-23 22:18         ` Zijun Hu
2024-08-24  3:29     ` Greg Kroah-Hartman
2024-08-15 14:58 ` [PATCH v2 3/4] firewire: core: " Zijun Hu
2024-08-17  9:57   ` Takashi Sakamoto
2024-08-18 14:24     ` Zijun Hu
2024-08-19  8:58       ` Takashi Sakamoto [this message]
2024-08-19 11:41         ` Zijun Hu
2024-08-21 14:29   ` Takashi Sakamoto
2024-08-21 14:51     ` Zijun Hu
2024-08-15 14:58 ` [PATCH v2 4/4] net: qcom/emac: " Zijun Hu
2024-08-24  3:29   ` Greg Kroah-Hartman
2024-08-24  7:11     ` Zijun Hu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240819085847.GA252819@workstation.local \
    --to=o-takashi@sakamocchi.jp \
    --cc=alison.schofield@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dave@stgolabs.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=ira.weiny@intel.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=kuba@kernel.org \
    --cc=linux-cxl@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux1394-devel@lists.sourceforge.net \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=quic_zijuhu@quicinc.com \
    --cc=rafael@kernel.org \
    --cc=timur@kernel.org \
    --cc=vishal.l.verma@intel.com \
    --cc=zijun_hu@icloud.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.