summaryrefslogtreecommitdiff
path: root/xen
diff options
context:
space:
mode:
authorOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>2020-11-30 12:31:32 +0200
committerAlex Bennée <alex.bennee@linaro.org>2020-11-30 15:12:52 +0000
commitdf4392024e23497c19932d022adc8b8f5e0543ef (patch)
tree5c0609c197a5e5c636ea3f52daf5d7329d2533ed /xen
parent8bf581b907ce98008de681d4cd59d16b315f2367 (diff)
xen/ioreq: Introduce domain_has_ioreq_server()
This patch introduces a helper the main purpose of which is to check if a domain is using IOREQ server(s). On Arm the current benefit is to avoid calling vcpu_ioreq_handle_completion() (which implies iterating over all possible IOREQ servers anyway) on every return in leave_hypervisor_to_guest() if there is no active servers for the particular domain. Also this helper will be used by one of the subsequent patches on Arm. This involves adding an extra per-domain variable to store the count of servers in use. Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com> CC: Julien Grall <julien.grall@arm.com> Message-Id: <1606732298-22107-18-git-send-email-olekstysh@gmail.com>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/arm/traps.c15
-rw-r--r--xen/common/ioreq.c7
-rw-r--r--xen/include/xen/ioreq.h14
-rw-r--r--xen/include/xen/sched.h1
4 files changed, 30 insertions, 7 deletions
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 4cef43e897..b6077d2b0c 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -2262,14 +2262,17 @@ static bool check_for_vcpu_work(void)
struct vcpu *v = current;
#ifdef CONFIG_IOREQ_SERVER
- bool handled;
+ if ( domain_has_ioreq_server(v->domain) )
+ {
+ bool handled;
- local_irq_enable();
- handled = vcpu_ioreq_handle_completion(v);
- local_irq_disable();
+ local_irq_enable();
+ handled = vcpu_ioreq_handle_completion(v);
+ local_irq_disable();
- if ( !handled )
- return true;
+ if ( !handled )
+ return true;
+ }
#endif
if ( likely(!v->arch.need_flush_to_ram) )
diff --git a/xen/common/ioreq.c b/xen/common/ioreq.c
index 4855dd8362..f35dcf9810 100644
--- a/xen/common/ioreq.c
+++ b/xen/common/ioreq.c
@@ -39,9 +39,14 @@ static void set_ioreq_server(struct domain *d, unsigned int id,
struct ioreq_server *s)
{
ASSERT(id < MAX_NR_IOREQ_SERVERS);
- ASSERT(!s || !d->ioreq_server.server[id]);
+ ASSERT(!s ^ !d->ioreq_server.server[id]);
d->ioreq_server.server[id] = s;
+
+ if ( s )
+ d->ioreq_server.nr_servers++;
+ else
+ d->ioreq_server.nr_servers--;
}
#define GET_IOREQ_SERVER(d, id) \
diff --git a/xen/include/xen/ioreq.h b/xen/include/xen/ioreq.h
index 02ff998c57..2289e79aac 100644
--- a/xen/include/xen/ioreq.h
+++ b/xen/include/xen/ioreq.h
@@ -55,6 +55,20 @@ struct ioreq_server {
uint8_t bufioreq_handling;
};
+/*
+ * This should only be used when d == current->domain and it's not paused,
+ * or when they're distinct and d is paused. Otherwise the result is
+ * stale before the caller can inspect it.
+ */
+static inline bool domain_has_ioreq_server(const struct domain *d)
+{
+#ifdef CONFIG_IOREQ_SERVER
+ return d->ioreq_server.nr_servers;
+#else
+ return false;
+#endif
+}
+
static inline paddr_t ioreq_mmio_first_byte(const ioreq_t *p)
{
return unlikely(p->df) ?
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 8269f84a37..2277995045 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -550,6 +550,7 @@ struct domain
struct {
spinlock_t lock;
struct ioreq_server *server[MAX_NR_IOREQ_SERVERS];
+ unsigned int nr_servers;
} ioreq_server;
#endif
};