All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Wei Liu" <wl@xen.org>, "Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH 4/4] AMD/IOMMU: Treat head/tail pointers as byte offsets
Date: Mon, 3 Feb 2020 14:43:40 +0000	[thread overview]
Message-ID: <20200203144340.4614-5-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20200203144340.4614-1-andrew.cooper3@citrix.com>

The MMIO registers as already byte offsets.  Using them in this form removes
the need to shift their values for use.

It is also inefficient to store both entries and alloc_size (which differ by a
fixed entry_size).  Rename alloc_size to size, and drop entries entirely,
which simplifies the allocation/deallocation helpers slightly.

Mark send_iommu_command() and invalidate_iommu_all() as static, as they have
no external declaration or callers.

Overall, this simplification allows GCC to optimise sufficiently to construct
commands directly in the command ring, rather than on the stack and copying
them into place.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>

Tested on a Rome system.
---
 xen/drivers/passthrough/amd/iommu-defs.h |  1 -
 xen/drivers/passthrough/amd/iommu.h      | 18 ++----------------
 xen/drivers/passthrough/amd/iommu_cmd.c  | 20 ++++++++------------
 xen/drivers/passthrough/amd/iommu_init.c | 30 +++++++++++++-----------------
 4 files changed, 23 insertions(+), 46 deletions(-)

diff --git a/xen/drivers/passthrough/amd/iommu-defs.h b/xen/drivers/passthrough/amd/iommu-defs.h
index 963009de6a..50613ca150 100644
--- a/xen/drivers/passthrough/amd/iommu-defs.h
+++ b/xen/drivers/passthrough/amd/iommu-defs.h
@@ -481,7 +481,6 @@ struct amd_iommu_pte {
 #define INV_IOMMU_ALL_PAGES_ADDRESS      ((1ULL << 63) - 1)
 
 #define IOMMU_RING_BUFFER_PTR_MASK                  0x0007FFF0
-#define IOMMU_RING_BUFFER_PTR_SHIFT                 4
 
 #define IOMMU_CMD_DEVICE_ID_MASK                    0x0000FFFF
 #define IOMMU_CMD_DEVICE_ID_SHIFT                   0
diff --git a/xen/drivers/passthrough/amd/iommu.h b/xen/drivers/passthrough/amd/iommu.h
index 0b598d06f8..1abfdc685a 100644
--- a/xen/drivers/passthrough/amd/iommu.h
+++ b/xen/drivers/passthrough/amd/iommu.h
@@ -58,12 +58,11 @@ struct table_struct {
 };
 
 struct ring_buffer {
+    spinlock_t lock;    /* protect buffer pointers */
     void *buffer;
-    unsigned long entries;
-    unsigned long alloc_size;
     uint32_t tail;
     uint32_t head;
-    spinlock_t lock;    /* protect buffer pointers */
+    uint32_t size;
 };
 
 typedef struct iommu_cap {
@@ -379,19 +378,6 @@ static inline int iommu_has_cap(struct amd_iommu *iommu, uint32_t bit)
     return !!(iommu->cap.header & (1u << bit));
 }
 
-/* access tail or head pointer of ring buffer */
-static inline uint32_t iommu_get_rb_pointer(uint32_t reg)
-{
-    return get_field_from_reg_u32(reg, IOMMU_RING_BUFFER_PTR_MASK,
-                                  IOMMU_RING_BUFFER_PTR_SHIFT);
-}
-
-static inline void iommu_set_rb_pointer(uint32_t *reg, uint32_t val)
-{
-    set_field_in_reg_u32(val, *reg, IOMMU_RING_BUFFER_PTR_MASK,
-                         IOMMU_RING_BUFFER_PTR_SHIFT, reg);
-}
-
 /* access device id field from iommu cmd */
 static inline uint16_t iommu_get_devid_from_cmd(uint32_t cmd)
 {
diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c
index 166f0e7263..24ef59d436 100644
--- a/xen/drivers/passthrough/amd/iommu_cmd.c
+++ b/xen/drivers/passthrough/amd/iommu_cmd.c
@@ -24,16 +24,14 @@ static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[])
 {
     uint32_t tail, head;
 
-    tail = iommu->cmd_buffer.tail;
-    if ( ++tail == iommu->cmd_buffer.entries )
+    tail = iommu->cmd_buffer.tail + IOMMU_CMD_BUFFER_ENTRY_SIZE;
+    if ( tail == iommu->cmd_buffer.size )
         tail = 0;
 
-    head = iommu_get_rb_pointer(readl(iommu->mmio_base +
-                                      IOMMU_CMD_BUFFER_HEAD_OFFSET));
+    head = readl(iommu->mmio_base + IOMMU_CMD_BUFFER_HEAD_OFFSET);
     if ( head != tail )
     {
-        memcpy(iommu->cmd_buffer.buffer +
-               (iommu->cmd_buffer.tail * IOMMU_CMD_BUFFER_ENTRY_SIZE),
+        memcpy(iommu->cmd_buffer.buffer + iommu->cmd_buffer.tail,
                cmd, IOMMU_CMD_BUFFER_ENTRY_SIZE);
 
         iommu->cmd_buffer.tail = tail;
@@ -45,13 +43,11 @@ static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[])
 
 static void commit_iommu_command_buffer(struct amd_iommu *iommu)
 {
-    u32 tail = 0;
-
-    iommu_set_rb_pointer(&tail, iommu->cmd_buffer.tail);
-    writel(tail, iommu->mmio_base+IOMMU_CMD_BUFFER_TAIL_OFFSET);
+    writel(iommu->cmd_buffer.tail,
+           iommu->mmio_base + IOMMU_CMD_BUFFER_TAIL_OFFSET);
 }
 
-int send_iommu_command(struct amd_iommu *iommu, u32 cmd[])
+static int send_iommu_command(struct amd_iommu *iommu, u32 cmd[])
 {
     if ( queue_iommu_command(iommu, cmd) )
     {
@@ -261,7 +257,7 @@ static void invalidate_interrupt_table(struct amd_iommu *iommu, u16 device_id)
     send_iommu_command(iommu, cmd);
 }
 
-void invalidate_iommu_all(struct amd_iommu *iommu)
+static void invalidate_iommu_all(struct amd_iommu *iommu)
 {
     u32 cmd[4], entry;
 
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index 7bf6fef3ee..cfdeeefc2d 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -117,7 +117,7 @@ static void register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu)
     iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT);
     writel(entry, iommu->mmio_base + IOMMU_CMD_BUFFER_BASE_LOW_OFFSET);
 
-    power_of2_entries = get_order_from_bytes(iommu->cmd_buffer.alloc_size) +
+    power_of2_entries = get_order_from_bytes(iommu->cmd_buffer.size) +
         IOMMU_CMD_BUFFER_POWER_OF2_ENTRIES_PER_PAGE;
 
     entry = 0;
@@ -145,7 +145,7 @@ static void register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu)
     iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT);
     writel(entry, iommu->mmio_base + IOMMU_EVENT_LOG_BASE_LOW_OFFSET);
 
-    power_of2_entries = get_order_from_bytes(iommu->event_log.alloc_size) +
+    power_of2_entries = get_order_from_bytes(iommu->event_log.size) +
                         IOMMU_EVENT_LOG_POWER_OF2_ENTRIES_PER_PAGE;
 
     entry = 0;
@@ -173,7 +173,7 @@ static void register_iommu_ppr_log_in_mmio_space(struct amd_iommu *iommu)
     iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT);
     writel(entry, iommu->mmio_base + IOMMU_PPR_LOG_BASE_LOW_OFFSET);
 
-    power_of2_entries = get_order_from_bytes(iommu->ppr_log.alloc_size) +
+    power_of2_entries = get_order_from_bytes(iommu->ppr_log.size) +
                         IOMMU_PPR_LOG_POWER_OF2_ENTRIES_PER_PAGE;
 
     entry = 0;
@@ -300,7 +300,7 @@ static int iommu_read_log(struct amd_iommu *iommu,
                           unsigned int entry_size,
                           void (*parse_func)(struct amd_iommu *, u32 *))
 {
-    u32 tail, head, *entry, tail_offest, head_offset;
+    u32 tail, *entry, tail_offest, head_offset;
 
     BUG_ON(!iommu || ((log != &iommu->event_log) && (log != &iommu->ppr_log)));
     
@@ -316,22 +316,20 @@ static int iommu_read_log(struct amd_iommu *iommu,
         IOMMU_PPR_LOG_HEAD_OFFSET;
 
     tail = readl(iommu->mmio_base + tail_offest);
-    tail = iommu_get_rb_pointer(tail);
 
     while ( tail != log->head )
     {
         /* read event log entry */
-        entry = (u32 *)(log->buffer + log->head * entry_size);
+        entry = (u32 *)(log->buffer + log->head);
 
         parse_func(iommu, entry);
-        if ( ++log->head == log->entries )
+
+        log->head += entry_size;
+        if ( log->head == log->size )
             log->head = 0;
 
         /* update head pointer */
-        head = 0;
-        iommu_set_rb_pointer(&head, log->head);
-
-        writel(head, iommu->mmio_base + head_offset);
+        writel(log->head, iommu->mmio_base + head_offset);
     }
 
     spin_unlock(&log->lock);
@@ -1001,7 +999,7 @@ static void __init deallocate_buffer(void *buf, unsigned long sz)
 
 static void __init deallocate_ring_buffer(struct ring_buffer *ring_buf)
 {
-    deallocate_buffer(ring_buf->buffer, ring_buf->alloc_size);
+    deallocate_buffer(ring_buf->buffer, ring_buf->size);
     ring_buf->buffer = NULL;
     ring_buf->head = 0;
     ring_buf->tail = 0;
@@ -1036,11 +1034,9 @@ static void *__init allocate_ring_buffer(struct ring_buffer *ring_buf,
     ring_buf->tail = 0;
 
     spin_lock_init(&ring_buf->lock);
-    
-    ring_buf->alloc_size = PAGE_SIZE << get_order_from_bytes(entries *
-                                                             entry_size);
-    ring_buf->entries = ring_buf->alloc_size / entry_size;
-    ring_buf->buffer = allocate_buffer(ring_buf->alloc_size, name, clear);
+
+    ring_buf->size = PAGE_SIZE << get_order_from_bytes(entries * entry_size);
+    ring_buf->buffer = allocate_buffer(ring_buf->size, name, clear);
 
     return ring_buf->buffer;
 }
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2020-02-03 14:44 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-03 14:43 [Xen-devel] [PATCH 0/4] AMD/IOMMU: Cleanup Andrew Cooper
2020-02-03 14:43 ` [Xen-devel] [PATCH 1/4] AMD/IOMMU: Move headers to be local Andrew Cooper
2020-02-03 16:24   ` George Dunlap
2020-02-05  9:47   ` Jan Beulich
2020-02-10 14:30     ` Andrew Cooper
2020-02-10 14:56       ` Jan Beulich
2020-02-03 14:43 ` [Xen-devel] [PATCH 2/4] AMD/IOMMU: Delete iommu_{get, set, clear}_bit() helpers Andrew Cooper
2020-02-05  9:57   ` Jan Beulich
2020-02-10 14:39     ` Andrew Cooper
2020-02-10 14:59       ` Jan Beulich
2020-02-03 14:43 ` [Xen-devel] [PATCH 3/4] AMD/IOMMU: Treat guest head/tail pointers as byte offsets Andrew Cooper
2020-02-05 10:22   ` Jan Beulich
2020-02-10 15:01     ` Andrew Cooper
2020-02-03 14:43 ` Andrew Cooper [this message]
2020-02-05 10:36   ` [Xen-devel] [PATCH 4/4] AMD/IOMMU: Treat " Jan Beulich
2020-02-10 14:55     ` Andrew Cooper
2020-02-10 15:02       ` Jan Beulich
2020-02-10 15:19         ` Andrew Cooper
2020-02-10 16:38           ` Jan Beulich
2020-02-10 17:33   ` [Xen-devel] [PATCH v2 " Andrew Cooper
2020-02-11  9:23     ` Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200203144340.4614-5-andrew.cooper3@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=roger.pau@citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.