All of lore.kernel.org
 help / color / mirror / Atom feed
From: Toshi Kani <toshi.kani@hp.com>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-pci@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>,
	Myron Stowe <myron.stowe@redhat.com>,
	Yijing Wang <wangyijing0307@gmail.com>,
	Jiang Liu <liuj97@gmail.com>
Subject: Re: [PATCH rev.2 1/6] ACPI: Separate adding ACPI device objects from probing ACPI drivers
Date: Tue, 18 Dec 2012 09:10:41 -0700	[thread overview]
Message-ID: <1355847041.18964.369.camel@misato.fc.hp.com> (raw)
In-Reply-To: <4082842.31rfDviYHK@vostro.rjw.lan>

On Tue, 2012-12-18 at 02:48 +0100, Rafael J. Wysocki wrote:
> On Monday, December 17, 2012 05:08:17 PM Toshi Kani wrote:
> > On Thu, 2012-12-13 at 23:17 +0100, Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > 
> > 
> > (snip)
> > 
> > >  struct acpi_device_ops {
> > > Index: linux/drivers/acpi/scan.c
> > > ===================================================================
> > > --- linux.orig/drivers/acpi/scan.c
> > > +++ linux/drivers/acpi/scan.c
> > > @@ -494,7 +494,8 @@ static int acpi_bus_match(struct device
> > >  	struct acpi_device *acpi_dev = to_acpi_device(dev);
> > >  	struct acpi_driver *acpi_drv = to_acpi_driver(drv);
> > >  
> > > -	return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
> > > +	return acpi_dev->bus_ops.acpi_op_match
> > > +		&& !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
> > >  }
> > >  
> > >  static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
> > > @@ -1418,6 +1419,17 @@ static int acpi_bus_remove(struct acpi_d
> > >  	return 0;
> > >  }
> > >  
> > > +/*
> > > + * acpi_hot_add_bind - Bind _ADR-based devices on hot-add.
> > > + * @device: ACPI device node to bind.
> > > + */
> > > +static void acpi_hot_add_bind(struct acpi_device *device)
> > > +{
> > > +	if (device->flags.bus_address
> > > +	    && device->parent && device->parent->ops.bind)
> > > +		device->parent->ops.bind(device);
> > > +}
> > > +
> > >  static int acpi_add_single_object(struct acpi_device **child,
> > >  				  acpi_handle handle, int type,
> > >  				  unsigned long long sta,
> > > @@ -1490,13 +1502,8 @@ static int acpi_add_single_object(struct
> > >  
> > >  	result = acpi_device_register(device);
> > >  
> > > -	/*
> > > -	 * Bind _ADR-Based Devices when hot add
> > > -	 */
> > > -	if (device->flags.bus_address) {
> > > -		if (device->parent && device->parent->ops.bind)
> > > -			device->parent->ops.bind(device);
> > > -	}
> > 
> > I think the original code above is hot-add only because ops.bind is not
> > set at boot since the acpi_pci driver has not been registered yet.  It
> > seems that acpi_pci_bridge_scan() called from acpi_pci_root_add() takes
> > care of the binding.
> 
> Ah, I see the problem.  During boot the PCI root bridge driver is not present
> yet when all struct acpi_device "devices" are registered, so their parents'
> .bind() callbacks are all empty, so the code above has no effect.
> 
> But say we're doing a PCI root bridge hotplug, in which case the driver is
> present, so acpi_pci_bind() will be executed both from acpi_pci_bridge_scan()
> and from here, won't it?

Right.


> OK, this needs to be addressed.
> 
> > This brings me a question for acpi_bus_probe_start() below...
> > 
> > 
> > > +	if (device->bus_ops.acpi_op_match)
> > > +		acpi_hot_add_bind(device);
> > >  
> > >  end:
> > >  	if (!result) {
> > > @@ -1522,6 +1529,7 @@ static void acpi_bus_add_power_resource(
> > >  	struct acpi_bus_ops ops = {
> > >  		.acpi_op_add = 1,
> > >  		.acpi_op_start = 1,
> > > +		.acpi_op_match = 1,
> > >  	};
> > >  	struct acpi_device *device = NULL;
> > >  
> > > @@ -1574,9 +1582,9 @@ static acpi_status acpi_bus_check_add(ac
> > >  				      void *context, void **return_value)
> > >  {
> > >  	struct acpi_bus_ops *ops = context;
> > > +	struct acpi_device *device = NULL;
> > >  	int type;
> > >  	unsigned long long sta;
> > > -	struct acpi_device *device;
> > >  	acpi_status status;
> > >  	int result;
> > >  
> > > @@ -1596,52 +1604,86 @@ static acpi_status acpi_bus_check_add(ac
> > >  		return AE_CTRL_DEPTH;
> > >  	}
> > >  
> > > -	/*
> > > -	 * We may already have an acpi_device from a previous enumeration.  If
> > > -	 * so, we needn't add it again, but we may still have to start it.
> > > -	 */
> > > -	device = NULL;
> > >  	acpi_bus_get_device(handle, &device);
> > >  	if (ops->acpi_op_add && !device) {
> > > -		acpi_add_single_object(&device, handle, type, sta, ops);
> > > -		/* Is the device a known good platform device? */
> > > -		if (device
> > > -		    && !acpi_match_device_ids(device, acpi_platform_device_ids))
> > > -			acpi_create_platform_device(device);
> > > -	}
> > > -
> > > -	if (!device)
> > > -		return AE_CTRL_DEPTH;
> > > +		struct acpi_bus_ops add_ops = *ops;
> > >  
> > > -	if (ops->acpi_op_start && !(ops->acpi_op_add)) {
> > > -		status = acpi_start_single_object(device);
> > > -		if (ACPI_FAILURE(status))
> > > +		add_ops.acpi_op_match = 0;
> > > +		acpi_add_single_object(&device, handle, type, sta, &add_ops);
> > > +		if (!device)
> > >  			return AE_CTRL_DEPTH;
> > > +
> > > +		device->bus_ops.acpi_op_match = 1;
> > >  	}
> > >  
> > >  	if (!*return_value)
> > >  		*return_value = device;
> > > +
> > >  	return AE_OK;
> > >  }
> > >  
> > > +static acpi_status acpi_bus_probe_start(acpi_handle handle, u32 lvl,
> > > +					void *context, void **not_used)
> > > +{
> > > +	struct acpi_bus_ops *ops = context;
> > > +	acpi_status status = AE_OK;
> > > +	struct acpi_device *device;
> > > +	unsigned long long sta_not_used;
> > > +	int type_not_used;
> > > +
> > > +	/*
> > > +	 * Ignore errors ignored by acpi_bus_check_add() to avoid terminating
> > 
> > "ignore" seems duplicated. 
>  
> It is not.  This is supposed to mean that the errors previously ignored by
> acpi_bus_check_add() should be ignored here as well.

Oh, I see.  Thanks for the clarification.


> > > +	 * namespace walks prematurely.
> > > +	 */
> > > +	if (acpi_bus_type_and_status(handle, &type_not_used, &sta_not_used))
> > > +		return AE_OK;
> > > +
> > > +	if (acpi_bus_get_device(handle, &device))
> > > +		return AE_CTRL_DEPTH;
> > > +
> > > +	if (ops->acpi_op_add) {
> > > +		if (!acpi_match_device_ids(device, acpi_platform_device_ids)) {
> > > +			/* This is a known good platform device. */
> > > +			acpi_create_platform_device(device);
> > > +		} else {
> > > +			int ret = device_attach(&device->dev);
> > > +			acpi_hot_add_bind(device);
> > 
> > Since acpi_pci_root_add() is called by device_attach(), I think this
> > acpi_hot_add_bind() calls .bind() of a device at boot since its .bind()
> > may be set.  Is that correct?  If so, how does it coordinate with the
> > bind procedure in acpi_pci_bridge_scan()?
> 
> It actually doesn't.
> 
> However, the $subject patch doesn't change this particular aspect of the
> original behavior, because with it applied the PCI root bridge driver is still
> not present when the device_attach() above is executed for all objects in the
> given namespace scope, so the .bind() callbacks should all be empty.  In other
> words, it doesn't change the boot case.
> 
> It also reproduces the original behavior in the hotplug case which may not be
> correct.  Patch [2/6], however, kind of changes the boot case into the hotplug
> case and things start to get ugly.

Yes, I was concerned with the behavior when patch [2/6] applied.  It is
actually a good thing that this hotplug issue is now exposed in the boot
path.  This means that boot and hot-add paths are consistent.  So, we
just need to fix it.


> Well, what about calling acpi_hot_add_bind() from acpi_bus_check_add(),
> right after doing the acpi_add_single_object()?  It would avoid calling
> acpi_pci_bind() twice for the same device during root bridge hotplug too,
> because in that case acpi_pci_root_add() will be called after all of these
> acpi_hot_add_bind() calls.  At the same time if a single device is
> hot-added and its parent happens to have .bind() set, it will be run
> from acpi_bus_check_add().

I may be missing something here, but in case of root bridge hot-add, I
think acpi_pci_root_add() still calls .bind() after acpi_bus_check_add()
called it.  So, it's called twice, isn't it? 

We need to decide which module is responsible for calling .bind().  I
think it should be the ACPI scan module, not the ACPI PCI root bridge
driver, because:

 - bind() needs to be called when _ADR device is added.  The ACPI scan
module can scan any devices, while the PCI root driver can only scan
when it is added.
 - acpi_bus_remove() calls unbind() at hot-remove.  The same module
should be responsible for both bind() and unbind() handling.
 - It is cleaner to keep struct acpi_device_ops interface to be called
by the ACPI core.

So, I would propose the following changes.

 - Move the acpi_hot_add_bind() call back to the original place after
the device_attach() call.
 - Rename the name of acpi_hot_add_bind() to something like
acpi_bind_adr_device() since it is no longer hot-add only (and is
specific to _ADR devices).
 - Create its pair function, acpi_unbind_adr_device(), which is called
from acpi_bus_remove().  When a constructor interface is introduced, its
destructor should be introduced as well. 
 - Remove the binding procedure from acpi_pci_root_add().  This should
be done in patch [2/6].

Thanks,
-Toshi


  reply	other threads:[~2012-12-18 16:19 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-09 22:58 [PATCH 0/6] ACPI: Change the ACPI namespace scanning code ordering Rafael J. Wysocki
2012-12-09 23:00 ` [PATCH 1/6] ACPI: Separate adding ACPI device objects from probing ACPI drivers Rafael J. Wysocki
2012-12-12 15:50   ` Jiang Liu
2012-12-12 22:34     ` Rafael J. Wysocki
2012-12-12 16:38   ` Jiang Liu
2012-12-12 22:32     ` Rafael J. Wysocki
2012-12-12 23:43       ` [update][PATCH " Rafael J. Wysocki
2012-12-13 13:05       ` [PATCH " Jiang Liu
2012-12-13 19:40         ` Rafael J. Wysocki
2012-12-13  1:00   ` Bjorn Helgaas
2012-12-13 11:41     ` Rafael J. Wysocki
2012-12-09 23:00 ` [PATCH 2/6] ACPI: Change the ordering of PCI root bridge driver registrarion Rafael J. Wysocki
2012-12-13  1:00   ` Bjorn Helgaas
2012-12-13 12:19     ` Rafael J. Wysocki
2012-12-09 23:01 ` [PATCH 3/6] ACPI: Make acpi_bus_add() and acpi_bus_start() visibly different Rafael J. Wysocki
2012-12-13  0:11   ` [Update][PATCH " Rafael J. Wysocki
2012-12-09 23:02 ` [PATCH 4/6] ACPI: Reduce the usage of struct acpi_bus_ops Rafael J. Wysocki
2012-12-09 23:03 ` [PATCH 5/6] ACPI: Replace struct acpi_bus_ops with enum type Rafael J. Wysocki
2012-12-10  5:34   ` Yinghai Lu
2012-12-10 14:46     ` Rafael J. Wysocki
2012-12-10 17:07       ` Yinghai Lu
2012-12-10 22:47         ` Rafael J. Wysocki
2012-12-10 23:09           ` Rafael J. Wysocki
2012-12-10 23:14             ` Yinghai Lu
2012-12-11  1:02               ` Rafael J. Wysocki
2012-12-11  1:28                 ` Rafael J. Wysocki
2012-12-11  2:26                   ` Yinghai Lu
2012-12-11 12:45                     ` Rafael J. Wysocki
2012-12-11 15:09                     ` Jiang Liu
2012-12-11 18:30                       ` Rafael J. Wysocki
2012-12-12 14:34                         ` Yijing Wang
2012-12-12 15:05                           ` Jiang Liu
2012-12-12 15:05                             ` Jiang Liu
2012-12-12 22:39                             ` Rafael J. Wysocki
2012-12-10 23:22           ` Yinghai Lu
2012-12-11  0:48             ` Rafael J. Wysocki
2012-12-09 23:04 ` [PATCH 6/6] ACPI: Change the ordering of acpi_bus_check_add() Rafael J. Wysocki
2012-12-13  1:00   ` Bjorn Helgaas
2012-12-13 12:20     ` Rafael J. Wysocki
2012-12-13 11:45 ` [PATCH 0/6] ACPI: Change the ACPI namespace scanning code ordering Yijing Wang
2012-12-13 11:45   ` Yijing Wang
2012-12-13 22:15 ` [PATCH rev.2 " Rafael J. Wysocki
2012-12-13 22:17   ` [PATCH rev.2 1/6] ACPI: Separate adding ACPI device objects from probing ACPI drivers Rafael J. Wysocki
2012-12-18  0:08     ` Toshi Kani
2012-12-18  1:48       ` Rafael J. Wysocki
2012-12-18 16:10         ` Toshi Kani [this message]
2012-12-18 18:59           ` Yinghai Lu
2012-12-18 20:48             ` Toshi Kani
2012-12-18 21:11               ` Yinghai Lu
2012-12-18 22:05             ` Rafael J. Wysocki
2012-12-19  1:57               ` Yinghai Lu
2012-12-18 21:57           ` Rafael J. Wysocki
2012-12-18 22:15             ` Toshi Kani
2012-12-18 23:00               ` Rafael J. Wysocki
2012-12-18 23:19                 ` Bjorn Helgaas
2012-12-19 11:13                   ` Rafael J. Wysocki
2012-12-20  1:45         ` [PATCH 0/16] ACPI: Rework ACPI namespace scanning for devices Rafael J. Wysocki
2012-12-20  1:47           ` [PATCH 1/16] ACPI: Separate adding ACPI device objects from probing ACPI drivers Rafael J. Wysocki
2013-01-11 20:00             ` Mika Westerberg
2013-01-11 20:31               ` Rafael J. Wysocki
2013-01-11 20:37                 ` Mika Westerberg
2013-01-11 20:58                   ` Rafael J. Wysocki
2013-01-11 20:59                     ` Mika Westerberg
2012-12-20  1:48           ` [PATCH 2/16] ACPI: Change the ordering of PCI root bridge driver registrarion Rafael J. Wysocki
2012-12-20  1:49           ` [PATCH 3/16] ACPI: Make acpi_bus_add() and acpi_bus_start() visibly different Rafael J. Wysocki
2012-12-20  1:50           ` [PATCH 4/16] ACPI: Reduce the usage of struct acpi_bus_ops Rafael J. Wysocki
2012-12-20  1:50           ` [PATCH 5/16] ACPI: Replace struct acpi_bus_ops with enum type Rafael J. Wysocki
2012-12-20  1:51           ` [PATCH 6/16] ACPI: Change the ordering of acpi_bus_check_add() Rafael J. Wysocki
2012-12-20  1:52           ` [PATCH 7/16] ACPI / PCI: Fold acpi_pci_root_start() into acpi_pci_root_add() Rafael J. Wysocki
2012-12-20  1:53           ` [PATCH 8/16] ACPI: Remove acpi_start_single_object() and acpi_bus_start() Rafael J. Wysocki
2012-12-20  1:54           ` [PATCH 9/16] ACPI: Remove the arguments of acpi_bus_add() that are not used Rafael J. Wysocki
2012-12-20  1:54           ` [PATCH 10/16] ACPI: Drop the second argument of acpi_bus_scan() Rafael J. Wysocki
2012-12-20  1:55           ` [PATCH 11/16] ACPI: Replace ACPI device add_type field with a match_driver flag Rafael J. Wysocki
2012-12-20  1:56           ` [PATCH 12/16] ACPI: Make acpi_bus_scan() and acpi_bus_add() take only one argument Rafael J. Wysocki
2012-12-20  1:57           ` [PATCH 13/16] ACPI: Add .setup() and .cleanup() callbacks to struct acpi_bus_type Rafael J. Wysocki
2012-12-20  1:58           ` [PATCH 14/16] ACPI / PCI: Rework the setup and cleanup of device wakeup Rafael J. Wysocki
2012-12-20  1:59           ` [PATCH 15/16] ACPI / PCI: Move the _PRT setup and cleanup code to pci-acpi.c Rafael J. Wysocki
2012-12-20  2:00           ` [PATCH 16/16] ACPI: Drop ACPI device .bind() and .unbind() callbacks Rafael J. Wysocki
2013-01-13 14:16             ` [PATCH] ACPI: remove unused acpi_op_bind and acpi_op_unbind Jiang Liu
2013-01-14 13:03               ` Rafael J. Wysocki
2012-12-20  2:06           ` [PATCH 0/16] ACPI: Rework ACPI namespace scanning for devices Yinghai Lu
2012-12-21  0:09             ` Rafael J. Wysocki
2012-12-21  3:59               ` Yinghai Lu
2012-12-21 22:23                 ` Rafael J. Wysocki
2012-12-20 21:07           ` Toshi Kani
2012-12-20 23:20             ` Rafael J. Wysocki
2012-12-13 22:18   ` [PATCH rev.2 2/6] ACPI: Change the ordering of PCI root bridge driver registrarion Rafael J. Wysocki
2012-12-13 22:21   ` [PATCH rev.2 3/6] ACPI: Make acpi_bus_add() and acpi_bus_start() visibly different Rafael J. Wysocki
2012-12-13 22:21   ` [PATCH rev.2 4/6] ACPI: Reduce the usage of struct acpi_bus_ops Rafael J. Wysocki
2012-12-13 22:22   ` [PATCH rev.2 5/6] ACPI: Replace struct acpi_bus_ops with enum type Rafael J. Wysocki
2012-12-13 22:23   ` [PATCH rev.2 6/6] ACPI: Change the ordering of acpi_bus_check_add() Rafael J. Wysocki
2012-12-14  9:56   ` [PATCH rev.2 0/6] ACPI: Change the ACPI namespace scanning code ordering Yijing Wang
2012-12-14  9:56     ` Yijing Wang
2012-12-14 22:59     ` Rafael J. Wysocki

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=1355847041.18964.369.camel@misato.fc.hp.com \
    --to=toshi.kani@hp.com \
    --cc=bhelgaas@google.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=liuj97@gmail.com \
    --cc=myron.stowe@redhat.com \
    --cc=rjw@sisk.pl \
    --cc=wangyijing0307@gmail.com \
    --cc=yinghai@kernel.org \
    /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.