Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp2631426pxb; Sat, 6 Feb 2021 02:57:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJwUnE3OWk5Is+XxN2wTv6Ntmq6S4m4vsjEsHRMhFKqO204crI5pcJiEhyEaJT/25UnSgg5t X-Received: by 2002:aa7:c0cd:: with SMTP id j13mr7879379edp.156.1612609069638; Sat, 06 Feb 2021 02:57:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612609069; cv=none; d=google.com; s=arc-20160816; b=SAEIvdrIjL5UmJOVui9HnevEMtjWMhpNV/j06TKhuL3gC0mrG5bFfCuhgkO6xfLoLt ZGU0FqaFdSVl+k1WIzwecqp04AZRBrsAFDymXdJH5M8XZhG9zHmU4xyK8oJ4aCkg839I f2arKeVBUHrMn0k1ljdwpEnbcQMG4puONzPfLHgAagMori3lrWqUSAXO9qVdr7uOdZpq c0uhfE7yUhTz962WZBseWTBEDoH2stQZZWV0Xd984gtAJFWD93H6uRvy4JQmfIySp89d VHkFNsbKpQoIwpG45+jqZhgTVJd25Cj4KmSHKWUb0aQv0DY7WvaeTeUlDEZ+sIKKzGqj zfhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=+rhXTWkgbyXvV9gClvwDbgn20u/kYNFxY4GB9OVP82g=; b=wWb1Edc0YLMW4gs+urjSJkM/bf5T/iDN+g+xFNTWnFewYEu7ujMDLBvQfZCsg7l056 ffzx/u8Qwyy78shyIM9mZmfD0AzCZKu/h4CAX8KVL/bPXSSePgpPXJ9JUITx6RCFlG5x wH2sTD70HMwKPjgLHflUtEUMoWEpVFlwqbTVebuC/OJm3OyGS8hckTTJVh0tvGb7YTXE aWBcM3QHexJQ+7vj+llOST1mqSWtPKlWQglPujOsX+Oh2YNlL2k0YGdkg3vb8OnEKn0V fL4F5eVX863HByl3t0h8/yTaq0DN3zQlkq0/uH1niZcP6uCb5QlN1lGEQKbXv8gcAzmC oiZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b=RGpZWqhB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=suse.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t5si7568806edw.121.2021.02.06.02.57.24; Sat, 06 Feb 2021 02:57:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b=RGpZWqhB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=suse.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229618AbhBFKwy (ORCPT + 99 others); Sat, 6 Feb 2021 05:52:54 -0500 Received: from mx2.suse.de ([195.135.220.15]:52946 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229774AbhBFKva (ORCPT ); Sat, 6 Feb 2021 05:51:30 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1612608587; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+rhXTWkgbyXvV9gClvwDbgn20u/kYNFxY4GB9OVP82g=; b=RGpZWqhB1MjUDVT7qV5Vbs65zV+xJItgY6MdTYnW6OU8SQSOPBnnf+yTZvjl+m/ff6/cm7 /sTtzQxlR3CrNaSip17pGUzElz0mgWAMvehJRNUMQ6YaeEXd2FgGbPTd9diut4ODNqVso9 3rFOpioQlUVEVE6RoWIRlOalao/MEgE= Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id A8F2EAE55; Sat, 6 Feb 2021 10:49:47 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org Cc: Juergen Gross , Boris Ostrovsky , Stefano Stabellini Subject: [PATCH 5/7] xen/events: add per-xenbus device event statistics and settings Date: Sat, 6 Feb 2021 11:49:30 +0100 Message-Id: <20210206104932.29064-6-jgross@suse.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210206104932.29064-1-jgross@suse.com> References: <20210206104932.29064-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add sysfs nodes for each xenbus device showing event statistics (number of events and spurious events, number of associated event channels) and for setting a spurious event threshold in case a frontend is sending too many events without being rogue on purpose. Signed-off-by: Juergen Gross --- drivers/xen/events/events_base.c | 27 ++++++++++++- drivers/xen/xenbus/xenbus_probe.c | 66 +++++++++++++++++++++++++++++++ include/xen/xenbus.h | 7 ++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 8c620c11e32a..d0c57c5664c0 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -327,6 +327,8 @@ static int xen_irq_info_evtchn_setup(unsigned irq, ret = xen_irq_info_common_setup(info, irq, IRQT_EVTCHN, evtchn, 0); info->u.interdomain = dev; + if (dev) + atomic_inc(&dev->event_channels); return ret; } @@ -572,18 +574,28 @@ static void xen_irq_lateeoi_locked(struct irq_info *info, bool spurious) return; if (spurious) { + struct xenbus_device *dev = info->u.interdomain; + unsigned int threshold = 1; + + if (dev && dev->spurious_threshold) + threshold = dev->spurious_threshold; + if ((1 << info->spurious_cnt) < (HZ << 2)) { if (info->spurious_cnt != 0xFF) info->spurious_cnt++; } - if (info->spurious_cnt > 1) { - delay = 1 << (info->spurious_cnt - 2); + if (info->spurious_cnt > threshold) { + delay = 1 << (info->spurious_cnt - 1 - threshold); if (delay > HZ) delay = HZ; if (!info->eoi_time) info->eoi_cpu = smp_processor_id(); info->eoi_time = get_jiffies_64() + delay; + if (dev) + atomic_add(delay, &dev->jiffies_eoi_delayed); } + if (dev) + atomic_inc(&dev->spurious_events); } else { info->spurious_cnt = 0; } @@ -920,6 +932,7 @@ static void __unbind_from_irq(unsigned int irq) if (VALID_EVTCHN(evtchn)) { unsigned int cpu = cpu_from_irq(irq); + struct xenbus_device *dev; xen_evtchn_close(evtchn); @@ -930,6 +943,11 @@ static void __unbind_from_irq(unsigned int irq) case IRQT_IPI: per_cpu(ipi_to_irq, cpu)[ipi_from_irq(irq)] = -1; break; + case IRQT_EVTCHN: + dev = info->u.interdomain; + if (dev) + atomic_dec(&dev->event_channels); + break; default: break; } @@ -1593,6 +1611,7 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) { int irq; struct irq_info *info; + struct xenbus_device *dev; irq = get_evtchn_to_irq(port); if (irq == -1) @@ -1622,6 +1641,10 @@ void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl) info = info_for_irq(irq); + dev = (info->type == IRQT_EVTCHN) ? info->u.interdomain : NULL; + if (dev) + atomic_inc(&dev->events); + if (ctrl->defer_eoi) { info->eoi_cpu = smp_processor_id(); info->irq_epoch = __this_cpu_read(irq_epoch); diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 18ffd0551b54..9494ecad3c92 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -206,6 +206,65 @@ void xenbus_otherend_changed(struct xenbus_watch *watch, } EXPORT_SYMBOL_GPL(xenbus_otherend_changed); +#define XENBUS_SHOW_STAT(name) \ +static ssize_t show_##name(struct device *_dev, \ + struct device_attribute *attr, \ + char *buf) \ +{ \ + struct xenbus_device *dev = to_xenbus_device(_dev); \ + \ + return sprintf(buf, "%d\n", atomic_read(&dev->name)); \ +} \ +static DEVICE_ATTR(name, 0444, show_##name, NULL) + +XENBUS_SHOW_STAT(event_channels); +XENBUS_SHOW_STAT(events); +XENBUS_SHOW_STAT(spurious_events); +XENBUS_SHOW_STAT(jiffies_eoi_delayed); + +static ssize_t show_spurious_threshold(struct device *_dev, + struct device_attribute *attr, + char *buf) +{ + struct xenbus_device *dev = to_xenbus_device(_dev); + + return sprintf(buf, "%d\n", dev->spurious_threshold); +} + +static ssize_t set_spurious_threshold(struct device *_dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct xenbus_device *dev = to_xenbus_device(_dev); + unsigned int val; + ssize_t ret; + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + dev->spurious_threshold = val; + + return count; +} + +static DEVICE_ATTR(spurious_threshold, 0644, show_spurious_threshold, + set_spurious_threshold); + +static struct attribute *xenbus_attrs[] = { + &dev_attr_event_channels.attr, + &dev_attr_events.attr, + &dev_attr_spurious_events.attr, + &dev_attr_jiffies_eoi_delayed.attr, + &dev_attr_spurious_threshold.attr, + NULL +}; + +static const struct attribute_group xenbus_group = { + .name = "xenbus", + .attrs = xenbus_attrs, +}; + int xenbus_dev_probe(struct device *_dev) { struct xenbus_device *dev = to_xenbus_device(_dev); @@ -253,6 +312,11 @@ int xenbus_dev_probe(struct device *_dev) return err; } + dev->spurious_threshold = 1; + if (sysfs_create_group(&dev->dev.kobj, &xenbus_group)) + dev_warn(&dev->dev, "sysfs_create_group on %s failed.\n", + dev->nodename); + return 0; fail_put: module_put(drv->driver.owner); @@ -269,6 +333,8 @@ int xenbus_dev_remove(struct device *_dev) DPRINTK("%s", dev->nodename); + sysfs_remove_group(&dev->dev.kobj, &xenbus_group); + free_otherend_watch(dev); if (drv->remove) { diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index 2c43b0ef1e4d..13ee375a1f05 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h @@ -88,6 +88,13 @@ struct xenbus_device { struct completion down; struct work_struct work; struct semaphore reclaim_sem; + + /* Event channel based statistics and settings. */ + atomic_t event_channels; + atomic_t events; + atomic_t spurious_events; + atomic_t jiffies_eoi_delayed; + unsigned int spurious_threshold; }; static inline struct xenbus_device *to_xenbus_device(struct device *dev) -- 2.26.2