aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-11-22 09:55:48 -0500
committerDavid Howells <dhowells@redhat.com>2006-11-22 09:55:48 -0500
commit65f27f38446e1976cc98fd3004b110fedcddd189 (patch)
tree68f8be93feae31dfa018c22db392a05546b63ee1 /drivers/pci
parent365970a1ea76d81cb1ad2f652acb605f06dae256 (diff)
WorkStruct: Pass the work_struct pointer instead of context data
Pass the work_struct pointer to the work function rather than context data. The work function can use container_of() to work out the data. For the cases where the container of the work_struct may go away the moment the pending bit is cleared, it is made possible to defer the release of the structure by deferring the clearing of the pending bit. To make this work, an extra flag is introduced into the management side of the work_struct. This governs auto-release of the structure upon execution. Ordinarily, the work queue executor would release the work_struct for further scheduling or deallocation by clearing the pending bit prior to jumping to the work function. This means that, unless the driver makes some guarantee itself that the work_struct won't go away, the work function may not access anything else in the work_struct or its container lest they be deallocated.. This is a problem if the auxiliary data is taken away (as done by the last patch). However, if the pending bit is *not* cleared before jumping to the work function, then the work function *may* access the work_struct and its container with no problems. But then the work function must itself release the work_struct by calling work_release(). In most cases, automatic release is fine, so this is the default. Special initiators exist for the non-auto-release case (ending in _NAR). Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c8
3 files changed, 6 insertions, 6 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 04c43ef529ac..55866b6b26fa 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -160,7 +160,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
160 rpc->e_lock = SPIN_LOCK_UNLOCKED; 160 rpc->e_lock = SPIN_LOCK_UNLOCKED;
161 161
162 rpc->rpd = dev; 162 rpc->rpd = dev;
163 INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev); 163 INIT_WORK(&rpc->dpc_handler, aer_isr);
164 rpc->prod_idx = rpc->cons_idx = 0; 164 rpc->prod_idx = rpc->cons_idx = 0;
165 mutex_init(&rpc->rpc_mutex); 165 mutex_init(&rpc->rpc_mutex);
166 init_waitqueue_head(&rpc->wait_release); 166 init_waitqueue_head(&rpc->wait_release);
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index daf0cad88fc8..3c0a58f64dd8 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -118,7 +118,7 @@ extern struct bus_type pcie_port_bus_type;
118extern void aer_enable_rootport(struct aer_rpc *rpc); 118extern void aer_enable_rootport(struct aer_rpc *rpc);
119extern void aer_delete_rootport(struct aer_rpc *rpc); 119extern void aer_delete_rootport(struct aer_rpc *rpc);
120extern int aer_init(struct pcie_device *dev); 120extern int aer_init(struct pcie_device *dev);
121extern void aer_isr(void *context); 121extern void aer_isr(struct work_struct *work);
122extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); 122extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
123extern int aer_osc_setup(struct pci_dev *dev); 123extern int aer_osc_setup(struct pci_dev *dev);
124 124
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 1c7e660d6535..08e13033ced8 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -690,14 +690,14 @@ static void aer_isr_one_error(struct pcie_device *p_device,
690 690
691/** 691/**
692 * aer_isr - consume errors detected by root port 692 * aer_isr - consume errors detected by root port
693 * @context: pointer to a private data of pcie device 693 * @work: definition of this work item
694 * 694 *
695 * Invoked, as DPC, when root port records new detected error 695 * Invoked, as DPC, when root port records new detected error
696 **/ 696 **/
697void aer_isr(void *context) 697void aer_isr(struct work_struct *work)
698{ 698{
699 struct pcie_device *p_device = (struct pcie_device *) context; 699 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
700 struct aer_rpc *rpc = get_service_data(p_device); 700 struct pcie_device *p_device = rpc->rpd;
701 struct aer_err_source *e_src; 701 struct aer_err_source *e_src;
702 702
703 mutex_lock(&rpc->rpc_mutex); 703 mutex_lock(&rpc->rpc_mutex);