* [PATCH v5 4/8] vringh: introduce vringh_is_little_endian() helper
From: Greg Kurz @ 2015-04-23 15:26 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150423152608.11795.4373.stgit@bahia.local>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
include/linux/vringh.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index a3fa537..3ed62ef 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -226,33 +226,38 @@ static inline void vringh_notify(struct vringh *vrh)
vrh->notify(vrh);
}
+static inline bool vringh_is_little_endian(const struct vringh *vrh)
+{
+ return vrh->little_endian;
+}
+
static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
{
- return __virtio16_to_cpu(vrh->little_endian, val);
+ return __virtio16_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio16 cpu_to_vringh16(const struct vringh *vrh, u16 val)
{
- return __cpu_to_virtio16(vrh->little_endian, val);
+ return __cpu_to_virtio16(vringh_is_little_endian(vrh), val);
}
static inline u32 vringh32_to_cpu(const struct vringh *vrh, __virtio32 val)
{
- return __virtio32_to_cpu(vrh->little_endian, val);
+ return __virtio32_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio32 cpu_to_vringh32(const struct vringh *vrh, u32 val)
{
- return __cpu_to_virtio32(vrh->little_endian, val);
+ return __cpu_to_virtio32(vringh_is_little_endian(vrh), val);
}
static inline u64 vringh64_to_cpu(const struct vringh *vrh, __virtio64 val)
{
- return __virtio64_to_cpu(vrh->little_endian, val);
+ return __virtio64_to_cpu(vringh_is_little_endian(vrh), val);
}
static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
{
- return __cpu_to_virtio64(vrh->little_endian, val);
+ return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
}
#endif /* _LINUX_VRINGH_H */
^ permalink raw reply related
* [PATCH v5 5/8] vhost: introduce vhost_is_little_endian() helper
From: Greg Kurz @ 2015-04-23 15:27 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150423152608.11795.4373.stgit@bahia.local>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
drivers/vhost/vhost.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 8c1c792..6a49960 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -173,34 +173,39 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
return vq->acked_features & (1ULL << bit);
}
+static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
+{
+ return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
+}
+
/* Memory accessors */
static inline u16 vhost16_to_cpu(struct vhost_virtqueue *vq, __virtio16 val)
{
- return __virtio16_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio16_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio16 cpu_to_vhost16(struct vhost_virtqueue *vq, u16 val)
{
- return __cpu_to_virtio16(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio16(vhost_is_little_endian(vq), val);
}
static inline u32 vhost32_to_cpu(struct vhost_virtqueue *vq, __virtio32 val)
{
- return __virtio32_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio32_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio32 cpu_to_vhost32(struct vhost_virtqueue *vq, u32 val)
{
- return __cpu_to_virtio32(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio32(vhost_is_little_endian(vq), val);
}
static inline u64 vhost64_to_cpu(struct vhost_virtqueue *vq, __virtio64 val)
{
- return __virtio64_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __virtio64_to_cpu(vhost_is_little_endian(vq), val);
}
static inline __virtio64 cpu_to_vhost64(struct vhost_virtqueue *vq, u64 val)
{
- return __cpu_to_virtio64(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
+ return __cpu_to_virtio64(vhost_is_little_endian(vq), val);
}
#endif
^ permalink raw reply related
* [PATCH v5 6/8] virtio: add explicit big-endian support to memory accessors
From: Greg Kurz @ 2015-04-23 15:29 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150423152608.11795.4373.stgit@bahia.local>
The current memory accessors logic is:
- little endian if little_endian
- native endian (i.e. no byteswap) if !little_endian
If we want to fully support cross-endian vhost, we also need to be
able to convert to big endian.
Instead of changing the little_endian argument to some 3-value enum, this
patch changes the logic to:
- little endian if little_endian
- big endian if !little_endian
The native endian case is handled by all users with a trivial helper. This
patch doesn't change any functionality, nor it does add overhead.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
Changes since v4:
- style fixes (I have chosen if ... else in most places to stay below
80 columns, with the notable exception of the vhost helper which gets
shorten in a later patch)
drivers/net/macvtap.c | 5 ++++-
drivers/net/tun.c | 5 ++++-
drivers/vhost/vhost.h | 2 +-
include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
include/linux/virtio_config.h | 5 ++++-
include/linux/vringh.h | 2 +-
6 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index a2f2958..6cf6b3e 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -51,7 +51,10 @@ struct macvtap_queue {
static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
{
- return q->flags & MACVTAP_VNET_LE;
+ if (q->flags & MACVTAP_VNET_LE)
+ return true;
+ else
+ return virtio_legacy_is_little_endian();
}
static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3c3d6c0..5b044d4 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -208,7 +208,10 @@ struct tun_struct {
static inline bool tun_is_little_endian(struct tun_struct *tun)
{
- return tun->flags & TUN_VNET_LE;
+ if (tun->flags & TUN_VNET_LE)
+ return true;
+ else
+ return virtio_legacy_is_little_endian();
}
static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 6a49960..954c657 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -175,7 +175,7 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
{
- return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
+ return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ? true : virtio_legacy_is_little_endian();
}
/* Memory accessors */
diff --git a/include/linux/virtio_byteorder.h b/include/linux/virtio_byteorder.h
index 51865d0..ce63a2c 100644
--- a/include/linux/virtio_byteorder.h
+++ b/include/linux/virtio_byteorder.h
@@ -3,17 +3,21 @@
#include <linux/types.h>
#include <uapi/linux/virtio_types.h>
-/*
- * Low-level memory accessors for handling virtio in modern little endian and in
- * compatibility native endian format.
- */
+static inline bool virtio_legacy_is_little_endian(void)
+{
+#ifdef __LITTLE_ENDIAN
+ return true;
+#else
+ return false;
+#endif
+}
static inline u16 __virtio16_to_cpu(bool little_endian, __virtio16 val)
{
if (little_endian)
return le16_to_cpu((__force __le16)val);
else
- return (__force u16)val;
+ return be16_to_cpu((__force __be16)val);
}
static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
@@ -21,7 +25,7 @@ static inline __virtio16 __cpu_to_virtio16(bool little_endian, u16 val)
if (little_endian)
return (__force __virtio16)cpu_to_le16(val);
else
- return (__force __virtio16)val;
+ return (__force __virtio16)cpu_to_be16(val);
}
static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
@@ -29,7 +33,7 @@ static inline u32 __virtio32_to_cpu(bool little_endian, __virtio32 val)
if (little_endian)
return le32_to_cpu((__force __le32)val);
else
- return (__force u32)val;
+ return be32_to_cpu((__force __be32)val);
}
static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
@@ -37,7 +41,7 @@ static inline __virtio32 __cpu_to_virtio32(bool little_endian, u32 val)
if (little_endian)
return (__force __virtio32)cpu_to_le32(val);
else
- return (__force __virtio32)val;
+ return (__force __virtio32)cpu_to_be32(val);
}
static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
@@ -45,7 +49,7 @@ static inline u64 __virtio64_to_cpu(bool little_endian, __virtio64 val)
if (little_endian)
return le64_to_cpu((__force __le64)val);
else
- return (__force u64)val;
+ return be64_to_cpu((__force __be64)val);
}
static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
@@ -53,7 +57,7 @@ static inline __virtio64 __cpu_to_virtio64(bool little_endian, u64 val)
if (little_endian)
return (__force __virtio64)cpu_to_le64(val);
else
- return (__force __virtio64)val;
+ return (__force __virtio64)cpu_to_be64(val);
}
#endif /* _LINUX_VIRTIO_BYTEORDER */
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index bd1a582..743e24c 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -207,7 +207,10 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
static inline bool virtio_is_little_endian(struct virtio_device *vdev)
{
- return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
+ if (virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
+ return true;
+ else
+ return virtio_legacy_is_little_endian();
}
/* Memory accessors */
diff --git a/include/linux/vringh.h b/include/linux/vringh.h
index 3ed62ef..d070bbcd 100644
--- a/include/linux/vringh.h
+++ b/include/linux/vringh.h
@@ -228,7 +228,7 @@ static inline void vringh_notify(struct vringh *vrh)
static inline bool vringh_is_little_endian(const struct vringh *vrh)
{
- return vrh->little_endian;
+ return vrh->little_endian ? true : virtio_legacy_is_little_endian();
}
static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
^ permalink raw reply related
* [PATCH v5 7/8] vhost: cross-endian support for legacy devices
From: Greg Kurz @ 2015-04-23 15:29 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: linux-api, linux-kernel, kvm, virtualization
In-Reply-To: <20150423152608.11795.4373.stgit@bahia.local>
This patch brings cross-endian support to vhost when used to implement
legacy virtio devices. Since it is a relatively rare situation, the
feature availability is controlled by a kernel config option (not set
by default).
The vq->is_le boolean field is added to cache the endianness to be
used for ring accesses. It defaults to native endian, as expected
by legacy virtio devices. When the ring gets active, we force little
endian if the device is modern. When the ring is deactivated, we
revert to the native endian default.
If cross-endian was compiled in, a vq->user_be boolean field is added
so that userspace may request a specific endianness. This field is
used to override the default when activating the ring of a legacy
device. It has no effect on modern devices.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
---
Changes since v4:
- rewrote patch title to mention cross-endian
- renamed config to VHOST_CROSS_ENDIAN_LEGACY
- rewrote config description and help
- moved ifdefery to top of vhost.c
- added a detailed comment about the lifecycle of vq->user_be in
vhost_init_is_le()
- renamed ioctls to VHOST_[GS]ET_VRING_ENDIAN
- added LE/BE defines to the ioctl API
- rewrote ioctl sanity check with the LE/BE defines
- updated comment in <uapi/linux/vhost.h> to mention that the availibility
of both SET and GET ioctls depends on the kernel config
drivers/vhost/Kconfig | 15 ++++++++
drivers/vhost/vhost.c | 86 +++++++++++++++++++++++++++++++++++++++++++-
drivers/vhost/vhost.h | 10 +++++
include/uapi/linux/vhost.h | 12 ++++++
4 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 017a1e8..74d7380 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -32,3 +32,18 @@ config VHOST
---help---
This option is selected by any driver which needs to access
the core of vhost.
+
+config VHOST_CROSS_ENDIAN_LEGACY
+ bool "Cross-endian support for vhost"
+ default n
+ ---help---
+ This option allows vhost to support guests with a different byte
+ ordering from host.
+
+ Userspace programs can control the feature using the
+ VHOST_SET_VRING_ENDIAN and VHOST_GET_VRING_ENDIAN ioctls.
+
+ This is only useful on a few platforms (ppc64 and arm64). Since it
+ adds some overhead, it is disabled default.
+
+ If unsure, say "N".
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2ee2826..8c4390d 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -36,6 +36,78 @@ enum {
#define vhost_used_event(vq) ((__virtio16 __user *)&vq->avail->ring[vq->num])
#define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num])
+#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
+static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
+{
+ vq->user_be = !virtio_legacy_is_little_endian();
+}
+
+static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
+{
+ struct vhost_vring_state s;
+
+ if (vq->private_data)
+ return -EBUSY;
+
+ if (copy_from_user(&s, argp, sizeof(s)))
+ return -EFAULT;
+
+ if (s.num != VHOST_VRING_LITTLE_ENDIAN &&
+ s.num != VHOST_VRING_BIG_ENDIAN)
+ return -EINVAL;
+
+ vq->user_be = s.num;
+
+ return 0;
+}
+
+static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
+ int __user *argp)
+{
+ struct vhost_vring_state s = {
+ .index = idx,
+ .num = vq->user_be
+ };
+
+ if (copy_to_user(argp, &s, sizeof(s)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static void vhost_init_is_le(struct vhost_virtqueue *vq)
+{
+ /* Note for legacy virtio: user_be is initialized at reset time
+ * according to the host endianness. If userspace does not set an
+ * explicit endianness, the default behavior is native endian, as
+ * expected by legacy virtio.
+ */
+ vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) || !vq->user_be;
+}
+#else
+static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
+{
+ ;
+}
+
+static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
+{
+ return -ENOIOCTLCMD;
+}
+
+static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
+ int __user *argp)
+{
+ return -ENOIOCTLCMD;
+}
+
+static void vhost_init_is_le(struct vhost_virtqueue *vq)
+{
+ if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
+ vq->is_le = true;
+}
+#endif /* CONFIG_VHOST_CROSS_ENDIAN_LEGACY */
+
static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll_table *pt)
{
@@ -199,6 +271,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
vq->call = NULL;
vq->log_ctx = NULL;
vq->memory = NULL;
+ vq->is_le = virtio_legacy_is_little_endian();
+ vhost_vq_reset_user_be(vq);
}
static int vhost_worker(void *data)
@@ -806,6 +880,12 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
} else
filep = eventfp;
break;
+ case VHOST_SET_VRING_ENDIAN:
+ r = vhost_set_vring_endian(vq, argp);
+ break;
+ case VHOST_GET_VRING_ENDIAN:
+ r = vhost_get_vring_endian(vq, idx, argp);
+ break;
default:
r = -ENOIOCTLCMD;
}
@@ -1044,8 +1124,12 @@ int vhost_init_used(struct vhost_virtqueue *vq)
{
__virtio16 last_used_idx;
int r;
- if (!vq->private_data)
+ if (!vq->private_data) {
+ vq->is_le = virtio_legacy_is_little_endian();
return 0;
+ }
+
+ vhost_init_is_le(vq);
r = vhost_update_used_flags(vq);
if (r)
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 954c657..ce6f6da 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -106,6 +106,14 @@ struct vhost_virtqueue {
/* Log write descriptors */
void __user *log_base;
struct vhost_log *log;
+
+ /* Ring endianness. Defaults to legacy native endianness.
+ * Set to true when starting a modern virtio device. */
+ bool is_le;
+#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
+ /* Ring endianness requested by userspace for cross-endian support. */
+ bool user_be;
+#endif
};
struct vhost_dev {
@@ -175,7 +183,7 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
{
- return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ? true : virtio_legacy_is_little_endian();
+ return vq->is_le;
}
/* Memory accessors */
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index bb6a5b4..b980b53 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -103,6 +103,18 @@ struct vhost_memory {
/* Get accessor: reads index, writes value in num */
#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN
+ * or VHOST_VRING_BIG_ENDIAN (other values return EINVAL).
+ * This is a legacy only API that is simply ignored when VIRTIO_F_VERSION_1 is
+ * set.
+ * Not all kernel configurations support this ioctl, but all configurations that
+ * support SET also support GET.
+ */
+#define VHOST_VRING_LITTLE_ENDIAN 0
+#define VHOST_VRING_BIG_ENDIAN 1
+#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
+#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
+
/* The following ioctls use eventfd file descriptors to signal and poll
* for events. */
^ permalink raw reply related
* [PATCH v5 8/8] macvtap/tun: cross-endian support for little-endian hosts
From: Greg Kurz @ 2015-04-23 15:30 UTC (permalink / raw)
To: Rusty Russell, Michael S. Tsirkin
Cc: Cornelia Huck, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150423152608.11795.4373.stgit-GiB8zCg7hOfDOqzlkpFKJg@public.gmane.org>
The VNET_LE flag was introduced to fix accesses to virtio 1.0 headers
that are always little-endian. It can also be used to handle the special
case of a legacy little-endian device implemented by a big-endian host.
Let's add a flag and ioctls for big-endian devices as well. If both flags
are set, little-endian wins.
Since this is isn't a common usecase, the feature is controlled by a kernel
config option (not set by default).
Both macvtap and tun are covered by this patch since they share the same
API with userland.
Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
Changes since v4:
- rewrote patch title to mention cross-endian
- renamed config to TUN_VNET_CROSS_LE
- rewrote config description and help
- moved ifdefery to top of tun.c and macvtap.c
- updated comment in <uapi/linux/if_tun.h> to mention that the availibility
of both SET and GET ioctls depends on the kernel config
drivers/net/Kconfig | 14 ++++++++++
drivers/net/macvtap.c | 58 +++++++++++++++++++++++++++++++++++++++++-
drivers/net/tun.c | 60 ++++++++++++++++++++++++++++++++++++++++++-
include/uapi/linux/if_tun.h | 6 ++++
4 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index df51d60..71ac0ec 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -244,6 +244,20 @@ config TUN
If you don't know what to use this for, you don't need it.
+config TUN_VNET_CROSS_LE
+ bool "Support for cross-endian vnet headers on little-endian kernels"
+ default n
+ ---help---
+ This option allows TUN/TAP and MACVTAP device drivers in a
+ little-endian kernel to parse vnet headers that come from a
+ big-endian legacy virtio device.
+
+ Userspace programs can control the feature using the TUNSETVNETBE
+ and TUNGETVNETBE ioctls.
+
+ Unless you have a little-endian system hosting a big-endian virtual
+ machine with a legacy virtio NIC, you should say N.
+
config VETH
tristate "Virtual ethernet pair device"
---help---
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 6cf6b3e..460ed9f 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -48,13 +48,63 @@ struct macvtap_queue {
#define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE)
#define MACVTAP_VNET_LE 0x80000000
+#define MACVTAP_VNET_BE 0x40000000
+
+#ifdef CONFIG_TUN_VNET_CROSS_LE
+static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q)
+{
+ if (q->flags & MACVTAP_VNET_BE)
+ return false;
+ return virtio_legacy_is_little_endian();
+}
+
+static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *sp)
+{
+ int s = !!(q->flags & MACVTAP_VNET_BE);
+
+ if (put_user(s, sp))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *sp)
+{
+ int s;
+
+ if (get_user(s, sp))
+ return -EFAULT;
+
+ if (s)
+ q->flags |= MACVTAP_VNET_BE;
+ else
+ q->flags &= ~MACVTAP_VNET_BE;
+
+ return 0;
+}
+#else
+static inline bool macvtap_legacy_is_little_endian(struct macvtap_queue *q)
+{
+ return virtio_legacy_is_little_endian();
+}
+
+static long macvtap_get_vnet_be(struct macvtap_queue *q, int __user *argp)
+{
+ return -EINVAL;
+}
+
+static long macvtap_set_vnet_be(struct macvtap_queue *q, int __user *argp)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_TUN_VNET_CROSS_LE */
static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
{
if (q->flags & MACVTAP_VNET_LE)
return true;
else
- return virtio_legacy_is_little_endian();
+ return macvtap_legacy_is_little_endian(q);
}
static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
@@ -1098,6 +1148,12 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
q->flags &= ~MACVTAP_VNET_LE;
return 0;
+ case TUNGETVNETBE:
+ return macvtap_get_vnet_be(q, sp);
+
+ case TUNSETVNETBE:
+ return macvtap_set_vnet_be(q, sp);
+
case TUNSETOFFLOAD:
/* let the user check for future flags */
if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 5b044d4..1b0afa9 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -111,6 +111,7 @@ do { \
#define TUN_FASYNC IFF_ATTACH_QUEUE
/* High bits in flags field are unused. */
#define TUN_VNET_LE 0x80000000
+#define TUN_VNET_BE 0x40000000
#define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \
IFF_MULTI_QUEUE)
@@ -206,12 +207,61 @@ struct tun_struct {
u32 flow_count;
};
+#ifdef CONFIG_TUN_VNET_CROSS_LE
+static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
+{
+ if (tun->flags & TUN_VNET_BE)
+ return false;
+ return virtio_legacy_is_little_endian();
+}
+
+static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
+{
+ int be = !!(tun->flags & TUN_VNET_BE);
+
+ if (put_user(be, argp))
+ return -EFAULT;
+
+ return 0;
+}
+
+static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
+{
+ int be;
+
+ if (get_user(be, argp))
+ return -EFAULT;
+
+ if (be)
+ tun->flags |= TUN_VNET_BE;
+ else
+ tun->flags &= ~TUN_VNET_BE;
+
+ return 0;
+}
+#else
+static inline bool tun_legacy_is_little_endian(struct tun_struct *tun)
+{
+ return virtio_legacy_is_little_endian();
+}
+
+static long tun_get_vnet_be(struct tun_struct *tun, int __user *argp)
+{
+ return -EINVAL;
+}
+
+static long tun_set_vnet_be(struct tun_struct *tun, int __user *argp)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_TUN_VNET_CROSS_LE */
+
static inline bool tun_is_little_endian(struct tun_struct *tun)
{
if (tun->flags & TUN_VNET_LE)
return true;
else
- return virtio_legacy_is_little_endian();
+ return tun_legacy_is_little_endian(tun);
}
static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
@@ -2066,6 +2116,14 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
tun->flags &= ~TUN_VNET_LE;
break;
+ case TUNGETVNETBE:
+ ret = tun_get_vnet_be(tun, argp);
+ break;
+
+ case TUNSETVNETBE:
+ ret = tun_set_vnet_be(tun, argp);
+ break;
+
case TUNATTACHFILTER:
/* Can be set only for TAPs */
ret = -EINVAL;
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index 50ae243..3cb5e1d 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -50,6 +50,12 @@
#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
#define TUNSETVNETLE _IOW('T', 220, int)
#define TUNGETVNETLE _IOR('T', 221, int)
+/* The TUNSETVNETBE and TUNGETVNETBE ioctls are for cross-endian support on
+ * little-endian hosts. Not all kernel configurations support them, but all
+ * configurations that support SET also support GET.
+ */
+#define TUNSETVNETBE _IOW('T', 222, int)
+#define TUNGETVNETBE _IOR('T', 223, int)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
^ permalink raw reply related
* Re: [PATCH 10/11] coresight-etm4x: Controls pertaining to the context ID functions
From: Christopher Covington @ 2015-04-23 16:59 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Greg KH,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Kaixu Xia,
Chunyan Zhang
In-Reply-To: <CANLsYkw-XwEW9gaXVr07fqHspZU+Vo7FukN7Qz6S07L6jC5ENA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 04/23/2015 11:16 AM, Mathieu Poirier wrote:
> On 23 April 2015 at 09:08, Christopher Covington <cov-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
>> Hi Mathieu,
>>
>> On 04/22/2015 06:40 PM, Mathieu Poirier wrote:
>>> From: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>>
>>> Adding sysfs entries to access and configure specifics about the
>>> context ID comparator functions.
>>>
>>> Signed-off-by: Pratik Patel <pratikp-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>>> Signed-off-by: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> ---
>>> .../ABI/testing/sysfs-bus-coresight-devices-etm4x | 19 +++
>>> drivers/hwtracing/coresight/coresight-etm4x.c | 187 +++++++++++++++++++++
>>> 2 files changed, 206 insertions(+)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>>> index b5c0456290ab..8b32cb7b9723 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>>> @@ -254,3 +254,22 @@ Date: April 2015
>>> KernelVersion: 4.01
>>> Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> Description: (RW) Controls the selection of the resources in the trace unit.
>>> +
>>> +What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_idx
>>> +Date: April 2015
>>> +KernelVersion: 4.01
>>> +Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> +Description: (RW) Select which context ID comparator to work with.
>>> +
>>> +What: /sys/bus/coresight/devices/<memory_map>.etm/ctxid_val
>>> +Date: April 2015
>>> +KernelVersion: 4.01
>>> +Contact: Mathieu Poirier <mathieu.poirier-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> +Description: (RW) Get/Set the context ID comparator value to trigger on.
>>
>> If I'm understanding this correctly, ctxid_val is multiplexed using ctxid_idx.
>> Why not just have ctxid_val0, ctxid_val1, ...?
>
> There can be up to 8 of them on the current implementation and who
> knows how many more in the future. To me using and index to select
> the context ID to work on scaled better and is introducing less
> clutter in sysfs.
In theory there's a race condition if two tasks are trying to set the index
and then the value, which having individually addressable values solves, but I
don't anticipate trying to use more than one task to configure tracing.
Chris
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v5 1/8] virtio: introduce virtio_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 17:22 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck, linux-api,
linux-kernel, kvm, virtualization
In-Reply-To: <20150423152617.11795.13272.stgit@bahia.local>
Am Thu, 23 Apr 2015 17:26:20 +0200
schrieb Greg Kurz <gkurz@linux.vnet.ibm.com>:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> include/linux/virtio_config.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index ca3ed78..bd1a582 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -205,35 +205,40 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
> return 0;
> }
>
> +static inline bool virtio_is_little_endian(struct virtio_device *vdev)
> +{
> + return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
> +}
So this function returns false when _not_ using version 1, but running
on a little endian host + guest? Sounds confusing. Maybe you could name
it "virtio_is_v1()" or so instead?
Thomas
^ permalink raw reply
* Re: [PATCH v5 1/8] virtio: introduce virtio_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 17:26 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150423192215.12182311@thh440s>
Am Thu, 23 Apr 2015 19:22:15 +0200
schrieb Thomas Huth <thuth-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>:
> Am Thu, 23 Apr 2015 17:26:20 +0200
> schrieb Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>:
>
> > Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> > ---
> > include/linux/virtio_config.h | 17 +++++++++++------
> > 1 file changed, 11 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> > index ca3ed78..bd1a582 100644
> > --- a/include/linux/virtio_config.h
> > +++ b/include/linux/virtio_config.h
> > @@ -205,35 +205,40 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
> > return 0;
> > }
> >
> > +static inline bool virtio_is_little_endian(struct virtio_device *vdev)
> > +{
> > + return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
> > +}
>
> So this function returns false when _not_ using version 1, but running
> on a little endian host + guest? Sounds confusing. Maybe you could name
> it "virtio_is_v1()" or so instead?
Ah, never mind, I should have looked at patch 6 first, then it makes
sense. (maybe you could put a note to the later patch in this patch
description?)
Thomas
^ permalink raw reply
* [PATCH V2] Test compaction of mlocked memory
From: Sri Jayaramappa @ 2015-04-23 18:21 UTC (permalink / raw)
To: Shuah Khan
Cc: Sri Jayaramappa, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton, Eric B Munson
Commit commit 5bbe3547aa3b ("mm: allow compaction of unevictable pages")
introduced a sysctl that allows userspace to enable scanning of locked
pages for compaction. This patch introduces a new test which fragments
main memory and attempts to allocate a number of huge pages to exercise
this compaction logic.
Tested on machines with up to 32 GB RAM. With the patch a much larger
number of huge pages can be allocated than on the kernel without the
patch.
Example output:
On a machine with 16 GB RAM:
sudo make run_tests vm
...
-----------------------
running compaction_test
-----------------------
No of huge pages allocated = 3834
[PASS]
...
Signed-off-by: Sri Jayaramappa <sjayaram-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
---
Changes in V2:
BINARIES in the Makefile is now one value per line.
The return value of read/write is checked against the number of
expected bytes wherever we know the number ahead in time.
Increased the threshold to 1/3 instead of 1/4 of memory to be allocated
as huge pages.
Corrected spelling "initial".
Removed a redundant variable.
tools/testing/selftests/vm/Makefile | 9 +-
tools/testing/selftests/vm/compaction_test.c | 225 ++++++++++++++++++++++++++
tools/testing/selftests/vm/run_vmtests | 12 ++
3 files changed, 244 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/vm/compaction_test.c
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index a5ce953..f6afc9e 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -1,8 +1,13 @@
# Makefile for vm selftests
CFLAGS = -Wall
-BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest
-BINARIES += transhuge-stress
+BINARIES = compaction_test
+BINARIES += hugepage-mmap
+BINARIES += hugepage-shm
+BINARIES += hugetlbfstest
+BINARIES += map_hugetlb
+BINARIES += thuge-gen
+BINARIES += transhuge-stress
all: $(BINARIES)
%: %.c
diff --git a/tools/testing/selftests/vm/compaction_test.c b/tools/testing/selftests/vm/compaction_test.c
new file mode 100644
index 0000000..82d0ba6
--- /dev/null
+++ b/tools/testing/selftests/vm/compaction_test.c
@@ -0,0 +1,225 @@
+/*
+ *
+ * A test for the patch "Allow compaction of unevictable pages".
+ * With this patch we should be able to allocate at least 1/4
+ * of RAM in huge pages. Without the patch much less is
+ * allocated.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#define MAP_SIZE 1048576
+
+struct map_list {
+ void *map;
+ struct map_list *next;
+};
+
+int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize)
+{
+ char buffer[256] = {0};
+ char *cmd = "cat /proc/meminfo | grep -i memfree | grep -o '[0-9]*'";
+ FILE *cmdfile = popen(cmd, "r");
+
+ if (!(fgets(buffer, sizeof(buffer), cmdfile))) {
+ perror("Failed to read meminfo\n");
+ return -1;
+ }
+
+ pclose(cmdfile);
+
+ *memfree = atoll(buffer);
+ cmd = "cat /proc/meminfo | grep -i hugepagesize | grep -o '[0-9]*'";
+ cmdfile = popen(cmd, "r");
+
+ if (!(fgets(buffer, sizeof(buffer), cmdfile))) {
+ perror("Failed to read meminfo\n");
+ return -1;
+ }
+
+ pclose(cmdfile);
+ *hugepagesize = atoll(buffer);
+
+ return 0;
+}
+
+int prereq(void)
+{
+ char allowed;
+ int fd;
+
+ fd = open("/proc/sys/vm/compact_unevictable_allowed",
+ O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ perror("Failed to open\n"
+ "/proc/sys/vm/compact_unevictable_allowed\n");
+ return -1;
+ }
+
+ if (read(fd, &allowed, sizeof(char)) != sizeof(char)) {
+ perror("Failed to read from\n"
+ "/proc/sys/vm/compact_unevictable_allowed\n");
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ if (allowed == '1')
+ return 0;
+
+ return -1;
+}
+
+int check_compaction(unsigned long mem_free, unsigned int hugepage_size)
+{
+ int fd;
+ int compaction_index = 0;
+ char initial_nr_hugepages[10] = {0};
+ char nr_hugepages[10] = {0};
+
+ /* We want to test with 80% of available memory. Else, OOM killer comes
+ in to play */
+ mem_free = mem_free * 0.8;
+
+ fd = open("/proc/sys/vm/nr_hugepages", O_RDWR | O_NONBLOCK);
+ if (fd < 0) {
+ perror("Failed to open /proc/sys/vm/nr_hugepages");
+ return -1;
+ }
+
+ if (read(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages)) <= 0) {
+ perror("Failed to read from /proc/sys/vm/nr_hugepages");
+ goto close_fd;
+ }
+
+ /* Start with the initial condition of 0 huge pages*/
+ if (write(fd, "0", sizeof(char)) != sizeof(char)) {
+ perror("Failed to write to /proc/sys/vm/nr_hugepages\n");
+ goto close_fd;
+ }
+
+ lseek(fd, 0, SEEK_SET);
+
+ /* Request a large number of huge pages. The Kernel will allocate
+ as much as it can */
+ if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {
+ perror("Failed to write to /proc/sys/vm/nr_hugepages\n");
+ goto close_fd;
+ }
+
+ lseek(fd, 0, SEEK_SET);
+
+ if (read(fd, nr_hugepages, sizeof(nr_hugepages)) <= 0) {
+ perror("Failed to read from /proc/sys/vm/nr_hugepages\n");
+ goto close_fd;
+ }
+
+ /* We should have been able to request at least 1/3 rd of the memory in
+ huge pages */
+ compaction_index = mem_free/(atoi(nr_hugepages) * hugepage_size);
+
+ if (compaction_index > 3) {
+ printf("No of huge pages allocated = %d\n",
+ (atoi(nr_hugepages)));
+ fprintf(stderr, "ERROR: Less that 1/%d of memory is available\n"
+ "as huge pages\n", compaction_index);
+ goto close_fd;
+ }
+
+ printf("No of huge pages allocated = %d\n",
+ (atoi(nr_hugepages)));
+
+ if (write(fd, initial_nr_hugepages, sizeof(initial_nr_hugepages))
+ != strlen(initial_nr_hugepages)) {
+ perror("Failed to write to /proc/sys/vm/nr_hugepages\n");
+ goto close_fd;
+ }
+
+ close(fd);
+ return 0;
+
+ close_fd:
+ close(fd);
+ printf("Not OK. Compaction test failed.");
+ return -1;
+}
+
+
+int main(int argc, char **argv)
+{
+ struct rlimit lim;
+ struct map_list *list, *entry;
+ size_t page_size, i;
+ void *map = NULL;
+ unsigned long mem_free = 0;
+ unsigned long hugepage_size = 0;
+ unsigned long mem_fragmentable = 0;
+
+ if (prereq() != 0) {
+ printf("Either the sysctl compact_unevictable_allowed is not\n"
+ "set to 1 or couldn't read the proc file.\n"
+ "Skipping the test\n");
+ return 0;
+ }
+
+ lim.rlim_cur = RLIM_INFINITY;
+ lim.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_MEMLOCK, &lim)) {
+ perror("Failed to set rlimit:\n");
+ return -1;
+ }
+
+ page_size = getpagesize();
+
+ list = NULL;
+
+ if (read_memory_info(&mem_free, &hugepage_size) != 0) {
+ printf("ERROR: Cannot read meminfo\n");
+ return -1;
+ }
+
+ mem_fragmentable = mem_free * 0.8 / 1024;
+
+ while (mem_fragmentable > 0) {
+ map = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_LOCKED, -1, 0);
+ if (map == MAP_FAILED)
+ break;
+
+ entry = malloc(sizeof(struct map_list));
+ if (!entry) {
+ munmap(map, MAP_SIZE);
+ break;
+ }
+ entry->map = map;
+ entry->next = list;
+ list = entry;
+
+ /* Write something (in this case the address of the map) to
+ * ensure that KSM can't merge the mapped pages
+ */
+ for (i = 0; i < MAP_SIZE; i += page_size)
+ *(unsigned long *)(map + i) = (unsigned long)map + i;
+
+ mem_fragmentable--;
+ }
+
+ for (entry = list; entry != NULL; entry = entry->next) {
+ munmap(entry->map, MAP_SIZE);
+ if (!entry->next)
+ break;
+ entry = entry->next;
+ }
+
+ if (check_compaction(mem_free, hugepage_size) == 0)
+ return 0;
+
+ return -1;
+}
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
index c87b681..49ece11 100755
--- a/tools/testing/selftests/vm/run_vmtests
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -90,4 +90,16 @@ fi
umount $mnt
rm -rf $mnt
echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
+
+echo "-----------------------"
+echo "running compaction_test"
+echo "-----------------------"
+./compaction_test
+if [ $? -ne 0 ]; then
+ echo "[FAIL]"
+ exitcode=1
+else
+ echo "[PASS]"
+fi
+
exit $exitcode
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH V2] Test compaction of mlocked memory
From: Eric B Munson @ 2015-04-23 18:41 UTC (permalink / raw)
To: Sri Jayaramappa
Cc: Shuah Khan, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Andrew Morton
In-Reply-To: <1429813301-27216-1-git-send-email-sjayaram-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1192 bytes --]
On Thu, 23 Apr 2015, Sri Jayaramappa wrote:
> Commit commit 5bbe3547aa3b ("mm: allow compaction of unevictable pages")
> introduced a sysctl that allows userspace to enable scanning of locked
> pages for compaction. This patch introduces a new test which fragments
> main memory and attempts to allocate a number of huge pages to exercise
> this compaction logic.
>
> Tested on machines with up to 32 GB RAM. With the patch a much larger
> number of huge pages can be allocated than on the kernel without the
> patch.
>
> Example output:
> On a machine with 16 GB RAM:
> sudo make run_tests vm
> ...
> -----------------------
> running compaction_test
> -----------------------
> No of huge pages allocated = 3834
> [PASS]
> ...
>
> Signed-off-by: Sri Jayaramappa <sjayaram-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
> Cc: Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH v5 1/8] virtio: introduce virtio_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 18:52 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck, linux-api,
linux-kernel, kvm, virtualization
In-Reply-To: <20150423152617.11795.13272.stgit@bahia.local>
On Thu, 23 Apr 2015 17:26:20 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> include/linux/virtio_config.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index ca3ed78..bd1a582 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -205,35 +205,40 @@ int virtqueue_set_affinity(struct virtqueue *vq, int cpu)
> return 0;
> }
>
> +static inline bool virtio_is_little_endian(struct virtio_device *vdev)
> +{
> + return virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
> +}
> +
> /* Memory accessors */
> static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
> {
> - return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __virtio16_to_cpu(virtio_is_little_endian(vdev), val);
> }
>
> static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
> {
> - return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio16(virtio_is_little_endian(vdev), val);
> }
>
> static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
> {
> - return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __virtio32_to_cpu(virtio_is_little_endian(vdev), val);
> }
>
> static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
> {
> - return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio32(virtio_is_little_endian(vdev), val);
> }
>
> static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
> {
> - return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __virtio64_to_cpu(virtio_is_little_endian(vdev), val);
> }
>
> static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
> {
> - return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio64(virtio_is_little_endian(vdev), val);
> }
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply
* Re: [PATCH v5 2/8] tun: add tun_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 18:57 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck, linux-api,
linux-kernel, kvm, virtualization
In-Reply-To: <20150423152628.11795.87340.stgit@bahia.local>
On Thu, 23 Apr 2015 17:26:30 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/net/tun.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 857dca4..3c3d6c0 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -206,14 +206,19 @@ struct tun_struct {
> u32 flow_count;
> };
>
> +static inline bool tun_is_little_endian(struct tun_struct *tun)
> +{
> + return tun->flags & TUN_VNET_LE;
> +}
> +
> static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
> {
> - return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val);
> + return __virtio16_to_cpu(tun_is_little_endian(tun), val);
> }
>
> static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val)
> {
> - return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val);
> + return __cpu_to_virtio16(tun_is_little_endian(tun), val);
> }
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply
* Re: [PATCH v5 3/8] macvtap: introduce macvtap_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 18:59 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck, linux-api,
linux-kernel, kvm, virtualization
In-Reply-To: <20150423152638.11795.37818.stgit@bahia.local>
On Thu, 23 Apr 2015 17:26:41 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> drivers/net/macvtap.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index 27ecc5c..a2f2958 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -49,14 +49,19 @@ struct macvtap_queue {
>
> #define MACVTAP_VNET_LE 0x80000000
>
> +static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
> +{
> + return q->flags & MACVTAP_VNET_LE;
> +}
> +
> static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
> {
> - return __virtio16_to_cpu(q->flags & MACVTAP_VNET_LE, val);
> + return __virtio16_to_cpu(macvtap_is_little_endian(q), val);
> }
>
> static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val)
> {
> - return __cpu_to_virtio16(q->flags & MACVTAP_VNET_LE, val);
> + return __cpu_to_virtio16(macvtap_is_little_endian(q), val);
> }
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply
* Re: [PATCH v5 4/8] vringh: introduce vringh_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 19:00 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck, linux-api,
linux-kernel, kvm, virtualization
In-Reply-To: <20150423152648.11795.30368.stgit@bahia.local>
On Thu, 23 Apr 2015 17:26:52 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
> include/linux/vringh.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/vringh.h b/include/linux/vringh.h
> index a3fa537..3ed62ef 100644
> --- a/include/linux/vringh.h
> +++ b/include/linux/vringh.h
> @@ -226,33 +226,38 @@ static inline void vringh_notify(struct vringh *vrh)
> vrh->notify(vrh);
> }
>
> +static inline bool vringh_is_little_endian(const struct vringh *vrh)
> +{
> + return vrh->little_endian;
> +}
> +
> static inline u16 vringh16_to_cpu(const struct vringh *vrh, __virtio16 val)
> {
> - return __virtio16_to_cpu(vrh->little_endian, val);
> + return __virtio16_to_cpu(vringh_is_little_endian(vrh), val);
> }
>
> static inline __virtio16 cpu_to_vringh16(const struct vringh *vrh, u16 val)
> {
> - return __cpu_to_virtio16(vrh->little_endian, val);
> + return __cpu_to_virtio16(vringh_is_little_endian(vrh), val);
> }
>
> static inline u32 vringh32_to_cpu(const struct vringh *vrh, __virtio32 val)
> {
> - return __virtio32_to_cpu(vrh->little_endian, val);
> + return __virtio32_to_cpu(vringh_is_little_endian(vrh), val);
> }
>
> static inline __virtio32 cpu_to_vringh32(const struct vringh *vrh, u32 val)
> {
> - return __cpu_to_virtio32(vrh->little_endian, val);
> + return __cpu_to_virtio32(vringh_is_little_endian(vrh), val);
> }
>
> static inline u64 vringh64_to_cpu(const struct vringh *vrh, __virtio64 val)
> {
> - return __virtio64_to_cpu(vrh->little_endian, val);
> + return __virtio64_to_cpu(vringh_is_little_endian(vrh), val);
> }
>
> static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
> {
> - return __cpu_to_virtio64(vrh->little_endian, val);
> + return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
> }
> #endif /* _LINUX_VRINGH_H */
Reviewed-by: Thomas Huth <thuth@redhat.com>
^ permalink raw reply
* Re: [PATCH v5 5/8] vhost: introduce vhost_is_little_endian() helper
From: Thomas Huth @ 2015-04-23 19:05 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150423152700.11795.9146.stgit-GiB8zCg7hOfDOqzlkpFKJg@public.gmane.org>
On Thu, 23 Apr 2015 17:27:05 +0200
Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
> drivers/vhost/vhost.h | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 8c1c792..6a49960 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -173,34 +173,39 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
> return vq->acked_features & (1ULL << bit);
> }
>
> +static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> +{
> + return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
> +}
> +
> /* Memory accessors */
> static inline u16 vhost16_to_cpu(struct vhost_virtqueue *vq, __virtio16 val)
> {
> - return __virtio16_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __virtio16_to_cpu(vhost_is_little_endian(vq), val);
> }
>
> static inline __virtio16 cpu_to_vhost16(struct vhost_virtqueue *vq, u16 val)
> {
> - return __cpu_to_virtio16(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio16(vhost_is_little_endian(vq), val);
> }
>
> static inline u32 vhost32_to_cpu(struct vhost_virtqueue *vq, __virtio32 val)
> {
> - return __virtio32_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __virtio32_to_cpu(vhost_is_little_endian(vq), val);
> }
>
> static inline __virtio32 cpu_to_vhost32(struct vhost_virtqueue *vq, u32 val)
> {
> - return __cpu_to_virtio32(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio32(vhost_is_little_endian(vq), val);
> }
>
> static inline u64 vhost64_to_cpu(struct vhost_virtqueue *vq, __virtio64 val)
> {
> - return __virtio64_to_cpu(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __virtio64_to_cpu(vhost_is_little_endian(vq), val);
> }
>
> static inline __virtio64 cpu_to_vhost64(struct vhost_virtqueue *vq, u64 val)
> {
> - return __cpu_to_virtio64(vhost_has_feature(vq, VIRTIO_F_VERSION_1), val);
> + return __cpu_to_virtio64(vhost_is_little_endian(vq), val);
> }
> #endif
Reviewed-by: Thomas Huth <thuth-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
^ permalink raw reply
* Re: [PATCH v5 6/8] virtio: add explicit big-endian support to memory accessors
From: Thomas Huth @ 2015-04-23 19:27 UTC (permalink / raw)
To: Greg Kurz
Cc: Rusty Russell, Michael S. Tsirkin, Cornelia Huck,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150423152712.11795.29245.stgit-GiB8zCg7hOfDOqzlkpFKJg@public.gmane.org>
On Thu, 23 Apr 2015 17:29:06 +0200
Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> The current memory accessors logic is:
> - little endian if little_endian
> - native endian (i.e. no byteswap) if !little_endian
>
> If we want to fully support cross-endian vhost, we also need to be
> able to convert to big endian.
>
> Instead of changing the little_endian argument to some 3-value enum, this
> patch changes the logic to:
> - little endian if little_endian
> - big endian if !little_endian
>
> The native endian case is handled by all users with a trivial helper. This
> patch doesn't change any functionality, nor it does add overhead.
>
> Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
>
> Changes since v4:
> - style fixes (I have chosen if ... else in most places to stay below
> 80 columns, with the notable exception of the vhost helper which gets
> shorten in a later patch)
>
> drivers/net/macvtap.c | 5 ++++-
> drivers/net/tun.c | 5 ++++-
> drivers/vhost/vhost.h | 2 +-
> include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
> include/linux/virtio_config.h | 5 ++++-
> include/linux/vringh.h | 2 +-
> 6 files changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index a2f2958..6cf6b3e 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -51,7 +51,10 @@ struct macvtap_queue {
>
> static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
> {
> - return q->flags & MACVTAP_VNET_LE;
> + if (q->flags & MACVTAP_VNET_LE)
> + return true;
> + else
> + return virtio_legacy_is_little_endian();
simply:
return (q->flags & MACVTAP_VNET_LE) ||
virtio_legacy_is_little_endian();
?
> }
>
> static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val)
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 3c3d6c0..5b044d4 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -208,7 +208,10 @@ struct tun_struct {
>
> static inline bool tun_is_little_endian(struct tun_struct *tun)
> {
> - return tun->flags & TUN_VNET_LE;
> + if (tun->flags & TUN_VNET_LE)
> + return true;
> + else
> + return virtio_legacy_is_little_endian();
dito?
> }
>
> static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val)
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index 6a49960..954c657 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -175,7 +175,7 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
>
> static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> {
> - return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
> + return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ? true : virtio_legacy_is_little_endian();
> }
That line is way longer than 80 characters ... may I suggest to switch
at least here to:
return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ||
virtio_legacy_is_little_endian();
?
Apart from the cosmetics, the patch looks good to me.
Thomas
^ permalink raw reply
* Re: [PATCH V2] Test compaction of mlocked memory
From: Andrew Morton @ 2015-04-23 20:23 UTC (permalink / raw)
To: Eric B Munson
Cc: Sri Jayaramappa, Shuah Khan, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20150423184134.GF2282-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
On Thu, 23 Apr 2015 14:41:34 -0400 Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org> wrote:
> On Thu, 23 Apr 2015, Sri Jayaramappa wrote:
>
> > Commit commit 5bbe3547aa3b ("mm: allow compaction of unevictable pages")
> > introduced a sysctl that allows userspace to enable scanning of locked
> > pages for compaction. This patch introduces a new test which fragments
> > main memory and attempts to allocate a number of huge pages to exercise
> > this compaction logic.
> >
> > Tested on machines with up to 32 GB RAM. With the patch a much larger
> > number of huge pages can be allocated than on the kernel without the
> > patch.
> >
> > Example output:
> > On a machine with 16 GB RAM:
> > sudo make run_tests vm
> > ...
> > -----------------------
> > running compaction_test
> > -----------------------
> > No of huge pages allocated = 3834
> > [PASS]
> > ...
> >
> > Signed-off-by: Sri Jayaramappa <sjayaram-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
> > Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
> > Cc: Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
>
> Reviewed-by: Eric B Munson <emunson-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>
Acked-by: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
I'm assuming that Shuah will process this one?
^ permalink raw reply
* Re: [PATCH V2] Test compaction of mlocked memory
From: Shuah Khan @ 2015-04-23 20:24 UTC (permalink / raw)
To: Andrew Morton, Eric B Munson
Cc: Sri Jayaramappa, linux-kernel, linux-api, Shuah Khan
In-Reply-To: <20150423132323.a3bd1dcdc94a2da3ca06a30d@linux-foundation.org>
On 04/23/2015 02:23 PM, Andrew Morton wrote:
> On Thu, 23 Apr 2015 14:41:34 -0400 Eric B Munson <emunson@akamai.com> wrote:
>
>> On Thu, 23 Apr 2015, Sri Jayaramappa wrote:
>>
>>> Commit commit 5bbe3547aa3b ("mm: allow compaction of unevictable pages")
>>> introduced a sysctl that allows userspace to enable scanning of locked
>>> pages for compaction. This patch introduces a new test which fragments
>>> main memory and attempts to allocate a number of huge pages to exercise
>>> this compaction logic.
>>>
>>> Tested on machines with up to 32 GB RAM. With the patch a much larger
>>> number of huge pages can be allocated than on the kernel without the
>>> patch.
>>>
>>> Example output:
>>> On a machine with 16 GB RAM:
>>> sudo make run_tests vm
>>> ...
>>> -----------------------
>>> running compaction_test
>>> -----------------------
>>> No of huge pages allocated = 3834
>>> [PASS]
>>> ...
>>>
>>> Signed-off-by: Sri Jayaramappa <sjayaram@akamai.com>
>>> Cc: linux-kernel@vger.kernel.org
>>> Cc: linux-api@vger.kernel.org
>>> Cc: Andrew Morton <akpm@linux-foundation.org>
>>> Cc: Eric B Munson <emunson@akamai.com>
>>
>> Reviewed-by: Eric B Munson <emunson@akamai.com>
>
> Acked-by: Andrew Morton <akpm@linux-foundation.org>
>
> I'm assuming that Shuah will process this one?
>
Yes. I will get this one after the merge window closes.
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply
* Re: [PATCH v5 6/8] virtio: add explicit big-endian support to memory accessors
From: Cornelia Huck @ 2015-04-24 7:04 UTC (permalink / raw)
To: Thomas Huth
Cc: kvm, Michael S. Tsirkin, linux-api, linux-kernel, virtualization
In-Reply-To: <20150423212719.4b7f9507@thh440s>
On Thu, 23 Apr 2015 21:27:19 +0200
Thomas Huth <thuth@redhat.com> wrote:
> On Thu, 23 Apr 2015 17:29:06 +0200
> Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
>
> > The current memory accessors logic is:
> > - little endian if little_endian
> > - native endian (i.e. no byteswap) if !little_endian
> >
> > If we want to fully support cross-endian vhost, we also need to be
> > able to convert to big endian.
> >
> > Instead of changing the little_endian argument to some 3-value enum, this
> > patch changes the logic to:
> > - little endian if little_endian
> > - big endian if !little_endian
> >
> > The native endian case is handled by all users with a trivial helper. This
> > patch doesn't change any functionality, nor it does add overhead.
> >
> > Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> > ---
> >
> > Changes since v4:
> > - style fixes (I have chosen if ... else in most places to stay below
> > 80 columns, with the notable exception of the vhost helper which gets
> > shorten in a later patch)
> >
> > drivers/net/macvtap.c | 5 ++++-
> > drivers/net/tun.c | 5 ++++-
> > drivers/vhost/vhost.h | 2 +-
> > include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
> > include/linux/virtio_config.h | 5 ++++-
> > include/linux/vringh.h | 2 +-
> > 6 files changed, 28 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> > index a2f2958..6cf6b3e 100644
> > --- a/drivers/net/macvtap.c
> > +++ b/drivers/net/macvtap.c
> > @@ -51,7 +51,10 @@ struct macvtap_queue {
> >
> > static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
> > {
> > - return q->flags & MACVTAP_VNET_LE;
> > + if (q->flags & MACVTAP_VNET_LE)
> > + return true;
> > + else
> > + return virtio_legacy_is_little_endian();
>
> simply:
>
> return (q->flags & MACVTAP_VNET_LE) ||
> virtio_legacy_is_little_endian();
>
> ?
ISTR that MST preferred the current notation, but I like either your
way or ?: (with linebreak) even better.
>
> > }
> >
(...)
> > diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> > index 6a49960..954c657 100644
> > --- a/drivers/vhost/vhost.h
> > +++ b/drivers/vhost/vhost.h
> > @@ -175,7 +175,7 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
> >
> > static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> > {
> > - return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
> > + return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ? true : virtio_legacy_is_little_endian();
> > }
>
> That line is way longer than 80 characters ... may I suggest to switch
> at least here to:
>
> return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ||
> virtio_legacy_is_little_endian();
I think the line will collapse in a further patch anyway.
^ permalink raw reply
* Re: [PATCH v5 7/8] vhost: cross-endian support for legacy devices
From: Cornelia Huck @ 2015-04-24 7:19 UTC (permalink / raw)
To: Greg Kurz
Cc: kvm, Michael S. Tsirkin, linux-api, linux-kernel, virtualization
In-Reply-To: <20150423152915.11795.13921.stgit@bahia.local>
On Thu, 23 Apr 2015 17:29:42 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> This patch brings cross-endian support to vhost when used to implement
> legacy virtio devices. Since it is a relatively rare situation, the
> feature availability is controlled by a kernel config option (not set
> by default).
>
> The vq->is_le boolean field is added to cache the endianness to be
> used for ring accesses. It defaults to native endian, as expected
> by legacy virtio devices. When the ring gets active, we force little
> endian if the device is modern. When the ring is deactivated, we
> revert to the native endian default.
>
> If cross-endian was compiled in, a vq->user_be boolean field is added
> so that userspace may request a specific endianness. This field is
> used to override the default when activating the ring of a legacy
> device. It has no effect on modern devices.
>
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> ---
>
> Changes since v4:
> - rewrote patch title to mention cross-endian
> - renamed config to VHOST_CROSS_ENDIAN_LEGACY
> - rewrote config description and help
> - moved ifdefery to top of vhost.c
> - added a detailed comment about the lifecycle of vq->user_be in
> vhost_init_is_le()
> - renamed ioctls to VHOST_[GS]ET_VRING_ENDIAN
> - added LE/BE defines to the ioctl API
> - rewrote ioctl sanity check with the LE/BE defines
> - updated comment in <uapi/linux/vhost.h> to mention that the availibility
> of both SET and GET ioctls depends on the kernel config
>
> drivers/vhost/Kconfig | 15 ++++++++
> drivers/vhost/vhost.c | 86 +++++++++++++++++++++++++++++++++++++++++++-
> drivers/vhost/vhost.h | 10 +++++
> include/uapi/linux/vhost.h | 12 ++++++
> 4 files changed, 121 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> index 017a1e8..74d7380 100644
> --- a/drivers/vhost/Kconfig
> +++ b/drivers/vhost/Kconfig
> @@ -32,3 +32,18 @@ config VHOST
> ---help---
> This option is selected by any driver which needs to access
> the core of vhost.
> +
> +config VHOST_CROSS_ENDIAN_LEGACY
> + bool "Cross-endian support for vhost"
> + default n
> + ---help---
> + This option allows vhost to support guests with a different byte
> + ordering from host.
"...while using legacy virtio."
Might help to explain the "LEGACY" in the config option ;)
> +
> + Userspace programs can control the feature using the
> + VHOST_SET_VRING_ENDIAN and VHOST_GET_VRING_ENDIAN ioctls.
> +
> + This is only useful on a few platforms (ppc64 and arm64). Since it
> + adds some overhead, it is disabled default.
s/default/by default/
> +
> + If unsure, say "N".
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 2ee2826..8c4390d 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -36,6 +36,78 @@ enum {
> #define vhost_used_event(vq) ((__virtio16 __user *)&vq->avail->ring[vq->num])
> #define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num])
>
> +#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
> +static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
> +{
> + vq->user_be = !virtio_legacy_is_little_endian();
> +}
> +
> +static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
> +{
> + struct vhost_vring_state s;
> +
> + if (vq->private_data)
> + return -EBUSY;
> +
> + if (copy_from_user(&s, argp, sizeof(s)))
> + return -EFAULT;
> +
> + if (s.num != VHOST_VRING_LITTLE_ENDIAN &&
> + s.num != VHOST_VRING_BIG_ENDIAN)
> + return -EINVAL;
> +
> + vq->user_be = s.num;
> +
> + return 0;
> +}
> +
> +static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
> + int __user *argp)
> +{
> + struct vhost_vring_state s = {
> + .index = idx,
> + .num = vq->user_be
> + };
> +
> + if (copy_to_user(argp, &s, sizeof(s)))
> + return -EFAULT;
> +
> + return 0;
> +}
> +
> +static void vhost_init_is_le(struct vhost_virtqueue *vq)
> +{
> + /* Note for legacy virtio: user_be is initialized at reset time
> + * according to the host endianness. If userspace does not set an
> + * explicit endianness, the default behavior is native endian, as
> + * expected by legacy virtio.
> + */
> + vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) || !vq->user_be;
> +}
> +#else
> +static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
> +{
> + ;
Just leave the function body empty?
> +}
> +
> +static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
> +{
> + return -ENOIOCTLCMD;
> +}
> +
> +static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
> + int __user *argp)
> +{
> + return -ENOIOCTLCMD;
> +}
> +
> +static void vhost_init_is_le(struct vhost_virtqueue *vq)
> +{
> + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> + vq->is_le = true;
> +}
> +#endif /* CONFIG_VHOST_CROSS_ENDIAN_LEGACY */
> +
> static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
> poll_table *pt)
> {
(...)
> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> index bb6a5b4..b980b53 100644
> --- a/include/uapi/linux/vhost.h
> +++ b/include/uapi/linux/vhost.h
> @@ -103,6 +103,18 @@ struct vhost_memory {
> /* Get accessor: reads index, writes value in num */
> #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
>
> +/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN
> + * or VHOST_VRING_BIG_ENDIAN (other values return EINVAL).
-EINVAL?
Should you also mention when you return -EBUSY?
> + * This is a legacy only API that is simply ignored when VIRTIO_F_VERSION_1 is
> + * set.
> + * Not all kernel configurations support this ioctl, but all configurations that
> + * support SET also support GET.
> + */
> +#define VHOST_VRING_LITTLE_ENDIAN 0
> +#define VHOST_VRING_BIG_ENDIAN 1
> +#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
> +#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
> +
> /* The following ioctls use eventfd file descriptors to signal and poll
> * for events. */
Apart from style nitpicks, looks good.
^ permalink raw reply
* Re: [PATCH v5 6/8] virtio: add explicit big-endian support to memory accessors
From: Greg Kurz @ 2015-04-24 7:56 UTC (permalink / raw)
To: Cornelia Huck
Cc: Thomas Huth, Rusty Russell, Michael S. Tsirkin,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, kvm-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
In-Reply-To: <20150424090421.123d6ff6.cornelia.huck-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
On Fri, 24 Apr 2015 09:04:21 +0200
Cornelia Huck <cornelia.huck-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org> wrote:
> On Thu, 23 Apr 2015 21:27:19 +0200
> Thomas Huth <thuth-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>
Thomas's e-mail did not make it to my mailbox... weird. :-\
> > On Thu, 23 Apr 2015 17:29:06 +0200
> > Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> >
> > > The current memory accessors logic is:
> > > - little endian if little_endian
> > > - native endian (i.e. no byteswap) if !little_endian
> > >
> > > If we want to fully support cross-endian vhost, we also need to be
> > > able to convert to big endian.
> > >
> > > Instead of changing the little_endian argument to some 3-value enum, this
> > > patch changes the logic to:
> > > - little endian if little_endian
> > > - big endian if !little_endian
> > >
> > > The native endian case is handled by all users with a trivial helper. This
> > > patch doesn't change any functionality, nor it does add overhead.
> > >
> > > Signed-off-by: Greg Kurz <gkurz-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> > > ---
> > >
> > > Changes since v4:
> > > - style fixes (I have chosen if ... else in most places to stay below
> > > 80 columns, with the notable exception of the vhost helper which gets
> > > shorten in a later patch)
> > >
> > > drivers/net/macvtap.c | 5 ++++-
> > > drivers/net/tun.c | 5 ++++-
> > > drivers/vhost/vhost.h | 2 +-
> > > include/linux/virtio_byteorder.h | 24 ++++++++++++++----------
> > > include/linux/virtio_config.h | 5 ++++-
> > > include/linux/vringh.h | 2 +-
> > > 6 files changed, 28 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> > > index a2f2958..6cf6b3e 100644
> > > --- a/drivers/net/macvtap.c
> > > +++ b/drivers/net/macvtap.c
> > > @@ -51,7 +51,10 @@ struct macvtap_queue {
> > >
> > > static inline bool macvtap_is_little_endian(struct macvtap_queue *q)
> > > {
> > > - return q->flags & MACVTAP_VNET_LE;
> > > + if (q->flags & MACVTAP_VNET_LE)
> > > + return true;
> > > + else
> > > + return virtio_legacy_is_little_endian();
> >
> > simply:
> >
> > return (q->flags & MACVTAP_VNET_LE) ||
> > virtio_legacy_is_little_endian();
> >
> > ?
>
> ISTR that MST preferred the current notation, but I like either your
> way or ?: (with linebreak) even better.
>
MST did not like the initial notation I had used actually. FWIW I
like the simplicity of Thomas's suggestion... even better than ?:
which is:
some_LE_check() ? true : some_default_endianness()
> >
> > > }
> > >
> (...)
> > > diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> > > index 6a49960..954c657 100644
> > > --- a/drivers/vhost/vhost.h
> > > +++ b/drivers/vhost/vhost.h
> > > @@ -175,7 +175,7 @@ static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
> > >
> > > static inline bool vhost_is_little_endian(struct vhost_virtqueue *vq)
> > > {
> > > - return vhost_has_feature(vq, VIRTIO_F_VERSION_1);
> > > + return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ? true : virtio_legacy_is_little_endian();
> > > }
> >
> > That line is way longer than 80 characters ... may I suggest to switch
> > at least here to:
> >
> > return vhost_has_feature(vq, VIRTIO_F_VERSION_1) ||
> > virtio_legacy_is_little_endian();
>
> I think the line will collapse in a further patch anyway.
>
Yes, as mentionned in the changelog :)
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v5 7/8] vhost: cross-endian support for legacy devices
From: Greg Kurz @ 2015-04-24 8:06 UTC (permalink / raw)
To: Cornelia Huck
Cc: kvm, Michael S. Tsirkin, linux-api, linux-kernel, virtualization
In-Reply-To: <20150424091926.1f5dee0b.cornelia.huck@de.ibm.com>
On Fri, 24 Apr 2015 09:19:26 +0200
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
> On Thu, 23 Apr 2015 17:29:42 +0200
> Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
>
> > This patch brings cross-endian support to vhost when used to implement
> > legacy virtio devices. Since it is a relatively rare situation, the
> > feature availability is controlled by a kernel config option (not set
> > by default).
> >
> > The vq->is_le boolean field is added to cache the endianness to be
> > used for ring accesses. It defaults to native endian, as expected
> > by legacy virtio devices. When the ring gets active, we force little
> > endian if the device is modern. When the ring is deactivated, we
> > revert to the native endian default.
> >
> > If cross-endian was compiled in, a vq->user_be boolean field is added
> > so that userspace may request a specific endianness. This field is
> > used to override the default when activating the ring of a legacy
> > device. It has no effect on modern devices.
> >
> > Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> > ---
> >
> > Changes since v4:
> > - rewrote patch title to mention cross-endian
> > - renamed config to VHOST_CROSS_ENDIAN_LEGACY
> > - rewrote config description and help
> > - moved ifdefery to top of vhost.c
> > - added a detailed comment about the lifecycle of vq->user_be in
> > vhost_init_is_le()
> > - renamed ioctls to VHOST_[GS]ET_VRING_ENDIAN
> > - added LE/BE defines to the ioctl API
> > - rewrote ioctl sanity check with the LE/BE defines
> > - updated comment in <uapi/linux/vhost.h> to mention that the availibility
> > of both SET and GET ioctls depends on the kernel config
> >
> > drivers/vhost/Kconfig | 15 ++++++++
> > drivers/vhost/vhost.c | 86 +++++++++++++++++++++++++++++++++++++++++++-
> > drivers/vhost/vhost.h | 10 +++++
> > include/uapi/linux/vhost.h | 12 ++++++
> > 4 files changed, 121 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
> > index 017a1e8..74d7380 100644
> > --- a/drivers/vhost/Kconfig
> > +++ b/drivers/vhost/Kconfig
> > @@ -32,3 +32,18 @@ config VHOST
> > ---help---
> > This option is selected by any driver which needs to access
> > the core of vhost.
> > +
> > +config VHOST_CROSS_ENDIAN_LEGACY
> > + bool "Cross-endian support for vhost"
> > + default n
> > + ---help---
> > + This option allows vhost to support guests with a different byte
> > + ordering from host.
>
> "...while using legacy virtio."
>
> Might help to explain the "LEGACY" in the config option ;)
>
Makes sense indeed !
> > +
> > + Userspace programs can control the feature using the
> > + VHOST_SET_VRING_ENDIAN and VHOST_GET_VRING_ENDIAN ioctls.
> > +
> > + This is only useful on a few platforms (ppc64 and arm64). Since it
> > + adds some overhead, it is disabled default.
>
> s/default/by default/
>
Ok.
> > +
> > + If unsure, say "N".
> > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> > index 2ee2826..8c4390d 100644
> > --- a/drivers/vhost/vhost.c
> > +++ b/drivers/vhost/vhost.c
> > @@ -36,6 +36,78 @@ enum {
> > #define vhost_used_event(vq) ((__virtio16 __user *)&vq->avail->ring[vq->num])
> > #define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num])
> >
> > +#ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY
> > +static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
> > +{
> > + vq->user_be = !virtio_legacy_is_little_endian();
> > +}
> > +
> > +static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
> > +{
> > + struct vhost_vring_state s;
> > +
> > + if (vq->private_data)
> > + return -EBUSY;
> > +
> > + if (copy_from_user(&s, argp, sizeof(s)))
> > + return -EFAULT;
> > +
> > + if (s.num != VHOST_VRING_LITTLE_ENDIAN &&
> > + s.num != VHOST_VRING_BIG_ENDIAN)
> > + return -EINVAL;
> > +
> > + vq->user_be = s.num;
> > +
> > + return 0;
> > +}
> > +
> > +static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
> > + int __user *argp)
> > +{
> > + struct vhost_vring_state s = {
> > + .index = idx,
> > + .num = vq->user_be
> > + };
> > +
> > + if (copy_to_user(argp, &s, sizeof(s)))
> > + return -EFAULT;
> > +
> > + return 0;
> > +}
> > +
> > +static void vhost_init_is_le(struct vhost_virtqueue *vq)
> > +{
> > + /* Note for legacy virtio: user_be is initialized at reset time
> > + * according to the host endianness. If userspace does not set an
> > + * explicit endianness, the default behavior is native endian, as
> > + * expected by legacy virtio.
> > + */
> > + vq->is_le = vhost_has_feature(vq, VIRTIO_F_VERSION_1) || !vq->user_be;
> > +}
> > +#else
> > +static void vhost_vq_reset_user_be(struct vhost_virtqueue *vq)
> > +{
> > + ;
>
> Just leave the function body empty?
>
Ok.
> > +}
> > +
> > +static long vhost_set_vring_endian(struct vhost_virtqueue *vq, int __user *argp)
> > +{
> > + return -ENOIOCTLCMD;
> > +}
> > +
> > +static long vhost_get_vring_endian(struct vhost_virtqueue *vq, u32 idx,
> > + int __user *argp)
> > +{
> > + return -ENOIOCTLCMD;
> > +}
> > +
> > +static void vhost_init_is_le(struct vhost_virtqueue *vq)
> > +{
> > + if (vhost_has_feature(vq, VIRTIO_F_VERSION_1))
> > + vq->is_le = true;
> > +}
> > +#endif /* CONFIG_VHOST_CROSS_ENDIAN_LEGACY */
> > +
> > static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
> > poll_table *pt)
> > {
> (...)
> > diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> > index bb6a5b4..b980b53 100644
> > --- a/include/uapi/linux/vhost.h
> > +++ b/include/uapi/linux/vhost.h
> > @@ -103,6 +103,18 @@ struct vhost_memory {
> > /* Get accessor: reads index, writes value in num */
> > #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
> >
> > +/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN
> > + * or VHOST_VRING_BIG_ENDIAN (other values return EINVAL).
>
> -EINVAL?
>
Oops, yes. :)
> Should you also mention when you return -EBUSY?
>
Indeed... what about:
"The byte order cannot be changed when the device is active: trying to do so
returns -EBUSY."
> > + * This is a legacy only API that is simply ignored when VIRTIO_F_VERSION_1 is
> > + * set.
> > + * Not all kernel configurations support this ioctl, but all configurations that
> > + * support SET also support GET.
> > + */
> > +#define VHOST_VRING_LITTLE_ENDIAN 0
> > +#define VHOST_VRING_BIG_ENDIAN 1
> > +#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
> > +#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
> > +
> > /* The following ioctls use eventfd file descriptors to signal and poll
> > * for events. */
>
> Apart from style nitpicks, looks good.
>
Cool ! :)
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH v5 7/8] vhost: cross-endian support for legacy devices
From: Cornelia Huck @ 2015-04-24 8:09 UTC (permalink / raw)
To: Greg Kurz
Cc: kvm, Michael S. Tsirkin, linux-api, linux-kernel, virtualization
In-Reply-To: <20150424100619.665e8bf8@bahia.local>
On Fri, 24 Apr 2015 10:06:19 +0200
Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> On Fri, 24 Apr 2015 09:19:26 +0200
> Cornelia Huck <cornelia.huck@de.ibm.com> wrote:
>
> > On Thu, 23 Apr 2015 17:29:42 +0200
> > Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> > > diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> > > index bb6a5b4..b980b53 100644
> > > --- a/include/uapi/linux/vhost.h
> > > +++ b/include/uapi/linux/vhost.h
> > > @@ -103,6 +103,18 @@ struct vhost_memory {
> > > /* Get accessor: reads index, writes value in num */
> > > #define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
> > >
> > > +/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN
> > > + * or VHOST_VRING_BIG_ENDIAN (other values return EINVAL).
> >
> > -EINVAL?
> >
>
> Oops, yes. :)
>
> > Should you also mention when you return -EBUSY?
> >
>
> Indeed... what about:
>
> "The byte order cannot be changed when the device is active: trying to do so
> returns -EBUSY."
s/when/while/ ?
But sounds good.
^ permalink raw reply
* [PATCH] of: Move OF flags to be visible even when !CONFIG_OF
From: Pantelis Antoniou @ 2015-04-24 9:41 UTC (permalink / raw)
To: Rob Herring
Cc: Grant Likely, Matt Porter, Wolfram Sang, Koen Kooi, Guenter Roeck,
devicetree, linux-kernel, linux-api, Pantelis Antoniou,
Pantelis Antoniou
We need those to be visible even when compiling with CONFIG_OF
disabled, since even the empty of_node_*_flag() method use the
flag.
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
include/linux/of.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index 5f124f6..53d6bbdc 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -120,6 +120,12 @@ extern struct device_node *of_aliases;
extern struct device_node *of_stdout;
extern raw_spinlock_t devtree_lock;
+/* flag descriptions (need to be visible even when !CONFIG_OF) */
+#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
+#define OF_DETACHED 2 /* node has been detached from the device tree */
+#define OF_POPULATED 3 /* device already created for the node */
+#define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */
+
#ifdef CONFIG_OF
static inline bool is_of_node(struct fwnode_handle *fwnode)
{
@@ -217,12 +223,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif
-/* flag descriptions */
-#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
-#define OF_DETACHED 2 /* node has been detached from the device tree */
-#define OF_POPULATED 3 /* device already created for the node */
-#define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */
-
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
--
1.7.12
^ permalink raw reply related
* [PATCH] of: unittest: overlay: Keep track of created overlays
From: Pantelis Antoniou @ 2015-04-24 9:42 UTC (permalink / raw)
To: Rob Herring
Cc: Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
Guenter Roeck, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou,
Pantelis Antoniou
During the course of the overlay selftests some of them remain
applied. While this does not pose a real problem, make sure you track
them and destroy them at the end of the test.
Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
drivers/of/unittest.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index e844907..1801634 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -23,6 +23,8 @@
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
+#include <linux/bitops.h>
+
#include "of_private.h"
static struct unittest_results {
@@ -1109,6 +1111,59 @@ static const char *overlay_path(int nr)
static const char *bus_path = "/testcase-data/overlay-node/test-bus";
+/* it is guaranteed that overlay ids are assigned in sequence */
+#define MAX_UNITTEST_OVERLAYS 256
+static unsigned long overlay_id_bits[BITS_TO_LONGS(MAX_UNITTEST_OVERLAYS)];
+static int overlay_first_id = -1;
+
+static void of_unittest_track_overlay(int id)
+{
+ if (overlay_first_id < 0)
+ overlay_first_id = id;
+ id -= overlay_first_id;
+
+ /* we shouldn't need that many */
+ BUG_ON(id >= MAX_UNITTEST_OVERLAYS);
+ overlay_id_bits[BIT_WORD(id)] |= BIT_MASK(id);
+}
+
+static void of_unittest_untrack_overlay(int id)
+{
+ if (overlay_first_id < 0)
+ return;
+ id -= overlay_first_id;
+ BUG_ON(id >= MAX_UNITTEST_OVERLAYS);
+ overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
+}
+
+static void of_unittest_destroy_tracked_overlays(void)
+{
+ int id, ret, defers;
+
+ if (overlay_first_id < 0)
+ return;
+
+ /* try until no defers */
+ do {
+ defers = 0;
+ /* remove in reverse order */
+ for (id = MAX_UNITTEST_OVERLAYS - 1; id >= 0; id--) {
+ if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id)))
+ continue;
+
+ ret = of_overlay_destroy(id + overlay_first_id);
+ if (ret != 0) {
+ defers++;
+ pr_warn("%s: overlay destroy failed for #%d\n",
+ __func__, id + overlay_first_id);
+ continue;
+ }
+
+ overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
+ }
+ } while (defers > 0);
+}
+
static int of_unittest_apply_overlay(int unittest_nr, int overlay_nr,
int *overlay_id)
{
@@ -1130,6 +1185,7 @@ static int of_unittest_apply_overlay(int unittest_nr, int overlay_nr,
goto out;
}
id = ret;
+ of_unittest_track_overlay(id);
ret = 0;
@@ -1343,6 +1399,7 @@ static void of_unittest_overlay_6(void)
return;
}
ov_id[i] = ret;
+ of_unittest_track_overlay(ov_id[i]);
}
for (i = 0; i < 2; i++) {
@@ -1367,6 +1424,7 @@ static void of_unittest_overlay_6(void)
PDEV_OVERLAY));
return;
}
+ of_unittest_untrack_overlay(ov_id[i]);
}
for (i = 0; i < 2; i++) {
@@ -1411,6 +1469,7 @@ static void of_unittest_overlay_8(void)
return;
}
ov_id[i] = ret;
+ of_unittest_track_overlay(ov_id[i]);
}
/* now try to remove first overlay (it should fail) */
@@ -1433,6 +1492,7 @@ static void of_unittest_overlay_8(void)
PDEV_OVERLAY));
return;
}
+ of_unittest_untrack_overlay(ov_id[i]);
}
unittest(1, "overlay test %d passed\n", 8);
@@ -1855,6 +1915,8 @@ static void __init of_unittest_overlay(void)
of_unittest_overlay_i2c_cleanup();
#endif
+ of_unittest_destroy_tracked_overlays();
+
out:
of_node_put(bus_np);
}
--
1.7.12
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox