diff options
Diffstat (limited to 'drivers/pci/controller/pci-hyperv.c')
| -rw-r--r-- | drivers/pci/controller/pci-hyperv.c | 11 | 
1 files changed, 7 insertions, 4 deletions
| diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 6cc5036ac83c..c00f82cc54aa 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -45,6 +45,7 @@  #include <linux/irqdomain.h>  #include <asm/irqdomain.h>  #include <asm/apic.h> +#include <linux/irq.h>  #include <linux/msi.h>  #include <linux/hyperv.h>  #include <linux/refcount.h> @@ -1073,6 +1074,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)  	struct pci_bus *pbus;  	struct pci_dev *pdev;  	struct cpumask *dest; +	unsigned long flags;  	struct compose_comp_ctxt comp;  	struct tran_int_desc *int_desc;  	struct { @@ -1164,14 +1166,15 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)  		 * the channel callback directly when channel->target_cpu is  		 * the current CPU. When the higher level interrupt code  		 * calls us with interrupt enabled, let's add the -		 * local_bh_disable()/enable() to avoid race. +		 * local_irq_save()/restore() to avoid race: +		 * hv_pci_onchannelcallback() can also run in tasklet.  		 */ -		local_bh_disable(); +		local_irq_save(flags);  		if (hbus->hdev->channel->target_cpu == smp_processor_id())  			hv_pci_onchannelcallback(hbus); -		local_bh_enable(); +		local_irq_restore(flags);  		if (hpdev->state == hv_pcichild_ejecting) {  			dev_err_once(&hbus->hdev->device, @@ -1543,7 +1546,7 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,  	unsigned long flags;  	int ret; -	hpdev = kzalloc(sizeof(*hpdev), GFP_ATOMIC); +	hpdev = kzalloc(sizeof(*hpdev), GFP_KERNEL);  	if (!hpdev)  		return NULL; |