DM: virtio-gpio: add IRQ statistics

print each IRQ descriptor interrupts number and all of IRQ descriptors
interrupts when UOS requests or releases a GPIO IRQ.

Tracked-On: #2512
Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Yuan Liu 2019-03-18 16:46:30 +08:00 committed by Eddie Dong
parent 83a98acb1b
commit 014e611b14

View File

@ -254,6 +254,7 @@ struct gpio_irq_desc {
uint8_t level; /* level value */ uint8_t level; /* level value */
uint64_t mode; /* interrupt trigger mode */ uint64_t mode; /* interrupt trigger mode */
void *data; /* virtio gpio instance */ void *data; /* virtio gpio instance */
uint64_t intr_stat; /* interrupts count */
}; };
struct gpio_irq_chip { struct gpio_irq_chip {
@ -261,6 +262,7 @@ struct gpio_irq_chip {
struct gpio_irq_desc descs[VIRTIO_GPIO_MAX_VLINES]; struct gpio_irq_desc descs[VIRTIO_GPIO_MAX_VLINES];
uint64_t intr_pending; /* pending interrupts */ uint64_t intr_pending; /* pending interrupts */
uint64_t intr_service; /* service interrupts */ uint64_t intr_service; /* service interrupts */
uint64_t intr_stat; /* all interrupts count */
}; };
struct virtio_gpio { struct virtio_gpio {
@ -278,6 +280,8 @@ struct virtio_gpio {
static void print_gpio_info(struct virtio_gpio *gpio); static void print_gpio_info(struct virtio_gpio *gpio);
static void print_virtio_gpio_info(struct virtio_gpio_request *req, static void print_virtio_gpio_info(struct virtio_gpio_request *req,
struct virtio_gpio_response *rsp, bool in); struct virtio_gpio_response *rsp, bool in);
static void print_intr_statistics(struct gpio_irq_chip *chip);
static void record_intr_statistics(struct gpio_irq_chip *chip, uint64_t mask);
static void static void
native_gpio_update_line_info(struct gpio_line *line) native_gpio_update_line_info(struct gpio_line *line)
@ -868,6 +872,9 @@ gpio_irq_deliver_intr(struct virtio_gpio *gpio, uint64_t mask)
/* Generate interrupt if appropriate. */ /* Generate interrupt if appropriate. */
vq_endchains(vq, 1); vq_endchains(vq, 1);
/* interrupt statistics */
record_intr_statistics(&gpio->irq_chip, mask);
} else } else
DPRINTF("virtio gpio failed to send an IRQ, mask %lu", mask); DPRINTF("virtio gpio failed to send an IRQ, mask %lu", mask);
} }
@ -1117,12 +1124,16 @@ virtio_gpio_irq_proc(struct virtio_gpio *gpio, struct iovec *iov, uint16_t flag)
* if gpio_irq_enable failure. * if gpio_irq_enable failure.
*/ */
gpio_irq_enable(gpio, req->pin, req->mode); gpio_irq_enable(gpio, req->pin, req->mode);
/* print IRQ statistics */
print_intr_statistics(chip);
break; break;
case IRQ_ACTION_DISABLE: case IRQ_ACTION_DISABLE:
gpio_irq_disable(chip, req->pin); gpio_irq_disable(chip, req->pin);
/* reopen the GPIO */
native_gpio_open_line(desc->gpio, 0, 0); /* print IRQ statistics */
print_intr_statistics(chip);
break; break;
case IRQ_ACTION_ACK: case IRQ_ACTION_ACK:
/* /*
@ -1435,4 +1446,35 @@ print_virtio_gpio_info(struct virtio_gpio_request *req,
rsp->data); rsp->data);
} }
static void
record_intr_statistics(struct gpio_irq_chip *chip, uint64_t mask)
{
struct gpio_irq_desc *desc;
int i;
for (i = 0; i < VIRTIO_GPIO_MAX_VLINES; i++) {
desc = &chip->descs[i];
if (mask & BIT(desc->pin))
desc->intr_stat++;
}
chip->intr_stat++;
}
static void
print_intr_statistics(struct gpio_irq_chip *chip)
{
struct gpio_irq_desc *desc;
int i;
DPRINTF("virtio gpio generated interrupts %lu\n", chip->intr_stat);
for (i = 0; i < VIRTIO_GPIO_MAX_VLINES; i++) {
desc = &chip->descs[i];
if (!desc->gpio || desc->intr_stat == 0)
continue;
DPRINTF("Chip %s GPIO %d generated interrupts %lu\n",
desc->gpio->chip->dev_name, desc->gpio->offset,
desc->intr_stat);
}
}
DEFINE_PCI_DEVTYPE(pci_ops_virtio_gpio); DEFINE_PCI_DEVTYPE(pci_ops_virtio_gpio);