Commit cee96422 authored by Juergen Gross's avatar Juergen Gross

xen/events: remove some info_for_irq() calls in pirq handling

Instead of the IRQ number user the struct irq_info pointer as parameter
in the internal pirq related functions. This allows to drop some calls
of info_for_irq().
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent 3fcdaf3d
...@@ -174,7 +174,7 @@ static int **evtchn_to_irq; ...@@ -174,7 +174,7 @@ static int **evtchn_to_irq;
#ifdef CONFIG_X86 #ifdef CONFIG_X86
static unsigned long *pirq_eoi_map; static unsigned long *pirq_eoi_map;
#endif #endif
static bool (*pirq_needs_eoi)(unsigned irq); static bool (*pirq_needs_eoi)(struct irq_info *info);
#define EVTCHN_ROW(e) (e / (PAGE_SIZE/sizeof(**evtchn_to_irq))) #define EVTCHN_ROW(e) (e / (PAGE_SIZE/sizeof(**evtchn_to_irq)))
#define EVTCHN_COL(e) (e % (PAGE_SIZE/sizeof(**evtchn_to_irq))) #define EVTCHN_COL(e) (e % (PAGE_SIZE/sizeof(**evtchn_to_irq)))
...@@ -190,7 +190,6 @@ static struct irq_chip xen_lateeoi_chip; ...@@ -190,7 +190,6 @@ static struct irq_chip xen_lateeoi_chip;
static struct irq_chip xen_percpu_chip; static struct irq_chip xen_percpu_chip;
static struct irq_chip xen_pirq_chip; static struct irq_chip xen_pirq_chip;
static void enable_dynirq(struct irq_data *data); static void enable_dynirq(struct irq_data *data);
static void disable_dynirq(struct irq_data *data);
static DEFINE_PER_CPU(unsigned int, irq_epoch); static DEFINE_PER_CPU(unsigned int, irq_epoch);
...@@ -454,10 +453,8 @@ static unsigned int virq_from_irq(struct irq_info *info) ...@@ -454,10 +453,8 @@ static unsigned int virq_from_irq(struct irq_info *info)
return info->u.virq; return info->u.virq;
} }
static unsigned pirq_from_irq(unsigned irq) static unsigned int pirq_from_irq(struct irq_info *info)
{ {
struct irq_info *info = info_for_irq(irq);
BUG_ON(info == NULL); BUG_ON(info == NULL);
BUG_ON(info->type != IRQT_PIRQ); BUG_ON(info->type != IRQT_PIRQ);
...@@ -500,15 +497,14 @@ static void do_unmask(struct irq_info *info, u8 reason) ...@@ -500,15 +497,14 @@ static void do_unmask(struct irq_info *info, u8 reason)
} }
#ifdef CONFIG_X86 #ifdef CONFIG_X86
static bool pirq_check_eoi_map(unsigned irq) static bool pirq_check_eoi_map(struct irq_info *info)
{ {
return test_bit(pirq_from_irq(irq), pirq_eoi_map); return test_bit(pirq_from_irq(info), pirq_eoi_map);
} }
#endif #endif
static bool pirq_needs_eoi_flag(unsigned irq) static bool pirq_needs_eoi_flag(struct irq_info *info)
{ {
struct irq_info *info = info_for_irq(irq);
BUG_ON(info->type != IRQT_PIRQ); BUG_ON(info->type != IRQT_PIRQ);
return info->u.pirq.flags & PIRQ_NEEDS_EOI; return info->u.pirq.flags & PIRQ_NEEDS_EOI;
...@@ -802,14 +798,11 @@ static void event_handler_exit(struct irq_info *info) ...@@ -802,14 +798,11 @@ static void event_handler_exit(struct irq_info *info)
clear_evtchn(info->evtchn); clear_evtchn(info->evtchn);
} }
static void pirq_query_unmask(int irq) static void pirq_query_unmask(struct irq_info *info)
{ {
struct physdev_irq_status_query irq_status; struct physdev_irq_status_query irq_status;
struct irq_info *info = info_for_irq(irq);
BUG_ON(info->type != IRQT_PIRQ); irq_status.irq = pirq_from_irq(info);
irq_status.irq = pirq_from_irq(irq);
if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status)) if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
irq_status.flags = 0; irq_status.flags = 0;
...@@ -818,56 +811,76 @@ static void pirq_query_unmask(int irq) ...@@ -818,56 +811,76 @@ static void pirq_query_unmask(int irq)
info->u.pirq.flags |= PIRQ_NEEDS_EOI; info->u.pirq.flags |= PIRQ_NEEDS_EOI;
} }
static void eoi_pirq(struct irq_data *data) static void do_eoi_pirq(struct irq_info *info)
{ {
struct irq_info *info = info_for_irq(data->irq); struct physdev_eoi eoi = { .irq = pirq_from_irq(info) };
evtchn_port_t evtchn = info ? info->evtchn : 0;
struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
int rc = 0; int rc = 0;
if (!VALID_EVTCHN(evtchn)) if (!VALID_EVTCHN(info->evtchn))
return; return;
event_handler_exit(info); event_handler_exit(info);
if (pirq_needs_eoi(data->irq)) { if (pirq_needs_eoi(info)) {
rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
WARN_ON(rc); WARN_ON(rc);
} }
} }
static void eoi_pirq(struct irq_data *data)
{
struct irq_info *info = info_for_irq(data->irq);
do_eoi_pirq(info);
}
static void do_disable_dynirq(struct irq_info *info)
{
if (VALID_EVTCHN(info->evtchn))
do_mask(info, EVT_MASK_REASON_EXPLICIT);
}
static void disable_dynirq(struct irq_data *data)
{
struct irq_info *info = info_for_irq(data->irq);
if (info)
do_disable_dynirq(info);
}
static void mask_ack_pirq(struct irq_data *data) static void mask_ack_pirq(struct irq_data *data)
{ {
disable_dynirq(data); struct irq_info *info = info_for_irq(data->irq);
eoi_pirq(data);
if (info) {
do_disable_dynirq(info);
do_eoi_pirq(info);
}
} }
static unsigned int __startup_pirq(unsigned int irq) static unsigned int __startup_pirq(struct irq_info *info)
{ {
struct evtchn_bind_pirq bind_pirq; struct evtchn_bind_pirq bind_pirq;
struct irq_info *info = info_for_irq(irq); evtchn_port_t evtchn = info->evtchn;
evtchn_port_t evtchn = evtchn_from_irq(irq);
int rc; int rc;
BUG_ON(info->type != IRQT_PIRQ);
if (VALID_EVTCHN(evtchn)) if (VALID_EVTCHN(evtchn))
goto out; goto out;
bind_pirq.pirq = pirq_from_irq(irq); bind_pirq.pirq = pirq_from_irq(info);
/* NB. We are happy to share unless we are probing. */ /* NB. We are happy to share unless we are probing. */
bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ? bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ?
BIND_PIRQ__WILL_SHARE : 0; BIND_PIRQ__WILL_SHARE : 0;
rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq); rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
if (rc != 0) { if (rc != 0) {
pr_warn("Failed to obtain physical IRQ %d\n", irq); pr_warn("Failed to obtain physical IRQ %d\n", info->irq);
return 0; return 0;
} }
evtchn = bind_pirq.port; evtchn = bind_pirq.port;
pirq_query_unmask(irq); pirq_query_unmask(info);
rc = set_evtchn_to_irq(evtchn, irq); rc = set_evtchn_to_irq(evtchn, info->irq);
if (rc) if (rc)
goto err; goto err;
...@@ -881,26 +894,28 @@ static unsigned int __startup_pirq(unsigned int irq) ...@@ -881,26 +894,28 @@ static unsigned int __startup_pirq(unsigned int irq)
out: out:
do_unmask(info, EVT_MASK_REASON_EXPLICIT); do_unmask(info, EVT_MASK_REASON_EXPLICIT);
eoi_pirq(irq_get_irq_data(irq)); do_eoi_pirq(info);
return 0; return 0;
err: err:
pr_err("irq%d: Failed to set port to irq mapping (%d)\n", irq, rc); pr_err("irq%d: Failed to set port to irq mapping (%d)\n", info->irq,
rc);
xen_evtchn_close(evtchn); xen_evtchn_close(evtchn);
return 0; return 0;
} }
static unsigned int startup_pirq(struct irq_data *data) static unsigned int startup_pirq(struct irq_data *data)
{ {
return __startup_pirq(data->irq); struct irq_info *info = info_for_irq(data->irq);
return __startup_pirq(info);
} }
static void shutdown_pirq(struct irq_data *data) static void shutdown_pirq(struct irq_data *data)
{ {
unsigned int irq = data->irq; struct irq_info *info = info_for_irq(data->irq);
struct irq_info *info = info_for_irq(irq); evtchn_port_t evtchn = info->evtchn;
evtchn_port_t evtchn = evtchn_from_irq(irq);
BUG_ON(info->type != IRQT_PIRQ); BUG_ON(info->type != IRQT_PIRQ);
...@@ -1035,7 +1050,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, ...@@ -1035,7 +1050,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
goto out; goto out;
} }
pirq_query_unmask(info->irq); pirq_query_unmask(info);
/* We try to use the handler with the appropriate semantic for the /* We try to use the handler with the appropriate semantic for the
* type of interrupt: if the interrupt is an edge triggered * type of interrupt: if the interrupt is an edge triggered
* interrupt we use handle_edge_irq. * interrupt we use handle_edge_irq.
...@@ -1162,7 +1177,9 @@ int xen_destroy_irq(int irq) ...@@ -1162,7 +1177,9 @@ int xen_destroy_irq(int irq)
int xen_pirq_from_irq(unsigned irq) int xen_pirq_from_irq(unsigned irq)
{ {
return pirq_from_irq(irq); struct irq_info *info = info_for_irq(irq);
return pirq_from_irq(info);
} }
EXPORT_SYMBOL_GPL(xen_pirq_from_irq); EXPORT_SYMBOL_GPL(xen_pirq_from_irq);
...@@ -1824,28 +1841,30 @@ static void enable_dynirq(struct irq_data *data) ...@@ -1824,28 +1841,30 @@ static void enable_dynirq(struct irq_data *data)
do_unmask(info, EVT_MASK_REASON_EXPLICIT); do_unmask(info, EVT_MASK_REASON_EXPLICIT);
} }
static void disable_dynirq(struct irq_data *data) static void do_ack_dynirq(struct irq_info *info)
{ {
struct irq_info *info = info_for_irq(data->irq); evtchn_port_t evtchn = info->evtchn;
evtchn_port_t evtchn = info ? info->evtchn : 0;
if (VALID_EVTCHN(evtchn)) if (VALID_EVTCHN(evtchn))
do_mask(info, EVT_MASK_REASON_EXPLICIT); event_handler_exit(info);
} }
static void ack_dynirq(struct irq_data *data) static void ack_dynirq(struct irq_data *data)
{ {
struct irq_info *info = info_for_irq(data->irq); struct irq_info *info = info_for_irq(data->irq);
evtchn_port_t evtchn = info ? info->evtchn : 0;
if (VALID_EVTCHN(evtchn)) if (info)
event_handler_exit(info); do_ack_dynirq(info);
} }
static void mask_ack_dynirq(struct irq_data *data) static void mask_ack_dynirq(struct irq_data *data)
{ {
disable_dynirq(data); struct irq_info *info = info_for_irq(data->irq);
ack_dynirq(data);
if (info) {
do_disable_dynirq(info);
do_ack_dynirq(info);
}
} }
static void lateeoi_ack_dynirq(struct irq_data *data) static void lateeoi_ack_dynirq(struct irq_data *data)
...@@ -1924,7 +1943,7 @@ static void restore_pirqs(void) ...@@ -1924,7 +1943,7 @@ static void restore_pirqs(void)
printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
__startup_pirq(irq); __startup_pirq(info);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment