qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC 5/6] virtio-net: steering mode: Implement rss supp


From: Jason Wang
Subject: Re: [Qemu-devel] [RFC 5/6] virtio-net: steering mode: Implement rss support
Date: Mon, 3 Sep 2018 11:48:17 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1



On 2018年08月30日 22:27, Sameeh Jubran wrote:
From: Sameeh Jubran <address@hidden>

Signed-off-by: Sameeh Jubran <address@hidden>
---
  hw/net/virtio-net.c | 122 ++++++++++++++++++++++++++++++++++++++++++++--------
  1 file changed, 105 insertions(+), 17 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index e7c4ce6f66..4a52a6a1d0 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -972,41 +972,129 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t 
cmd,
      return VIRTIO_NET_OK;
  }
-static int virtio_net_ctrl_steering_mode(VirtIONet *n, uint8_t cmd,
+
+static int virtio_net_ctrl_sm_rss(VirtIONet *n, uint32_t cmd,
                                  struct iovec *iov, unsigned int iov_cnt,
                                  struct iovec *iov_in, unsigned int iov_cnt_in,
-        size_t *size_in)
+                                size_t *size_in)
+{
+    size_t s;
+    uint32_t supported_hash_function = 0;
+
+    switch (cmd) {
+    case VIRTIO_NET_SM_CTRL_RSS_GET_SUPPORTED_FUNCTIONS:
+        supported_hash_function |= RSS_HASH_FUNCTION_TOEPLITZ;
+        if (!size_in) {
+            return VIRTIO_NET_ERR;
+        }
+        s = iov_from_buf(iov_in, iov_cnt_in, 0,
+        &supported_hash_function,
+        supported_hash_function);

Indentation looks wrong.

+        if (s != sizeof(n->supported_modes) ||
+        !size_in) {
+            return VIRTIO_NET_ERR;
+        }
+        *size_in = s;
+        break;
+    case VIRTIO_NET_SM_CTRL_RSS_SET:
+        if (!n->rss_conf) {
+            n->rss_conf = g_malloc0(
+                    sizeof(struct virtio_net_rss_conf));
+        } else if (iov == NULL || iov_cnt == 0) {
+            g_free(n->rss_conf->ptrs.hash_key);
+            g_free(n->rss_conf->ptrs.indirection_table);
+            g_free(n->rss_conf);
+            return VIRTIO_NET_OK;
+        }
+        s = iov_to_buf(iov, iov_cnt, 0, n->rss_conf,
+                sizeof(struct virtio_net_rss_conf) -
+                sizeof(struct virtio_net_rss_conf_ptrs));
+
+        if (s != sizeof(struct virtio_net_rss_conf) -
+                sizeof(struct virtio_net_rss_conf_ptrs)) {
+            return VIRTIO_NET_ERR;
+        }
+        n->rss_conf->ptrs.hash_key = g_malloc0(sizeof(uint8_t) *
+                n->rss_conf->hash_key_length);

What happens if n->rss_conf != 0 && iov != NULL? Looks like a guest trigger-able OOM?

Btw e.g "conf_ptrs" sounds misleading, why not just embed hash key and indirection table pointers directly in rss_conf structure itself?

+        s = iov_to_buf(iov, iov_cnt, 0, n->rss_conf->ptrs.hash_key,
+                sizeof(uint8_t) * n->rss_conf->hash_key_length);
+        if (s != sizeof(uint8_t) * n->rss_conf->hash_key_length) {
+            g_free(n->rss_conf->ptrs.hash_key);
+            return VIRTIO_NET_ERR;
+        }
+        n->rss_conf->ptrs.indirection_table
+            = g_malloc0(sizeof(uint32_t) *
+                    n->rss_conf->indirection_table_length);
+        s = iov_to_buf(iov, iov_cnt, 0,
+                n->rss_conf->ptrs.indirection_table, sizeof(uint32_t) *
+                n->rss_conf->indirection_table_length);
+        if (s != sizeof(uint32_t) *
+                n->rss_conf->indirection_table_length) {
+            g_free(n->rss_conf->ptrs.hash_key);
+            g_free(n->rss_conf->ptrs.indirection_table);
+            return VIRTIO_NET_ERR;
+        }
+        /* do bpf magic */
+        break;
+    default:
+        return VIRTIO_NET_ERR;
+    }
+
+    return VIRTIO_NET_OK;
+}
+
+static int virtio_net_ctrl_steering_mode(VirtIONet *n, uint8_t cmd,
+                                struct iovec *iov, unsigned int iov_cnt,
+                                struct iovec *iov_in, unsigned int iov_in_cnt,
+                                size_t *size_in)
  {
      size_t s;
      struct virtio_net_steering_mode sm;
+    int status = 0;
+    size_t size_in_cmd = 0;
switch (cmd) {
      case VIRTIO_NET_CTRL_SM_GET_SUPPORTED_MODES:
          if (!size_in) {
              return VIRTIO_NET_ERR;
          }
-                  s = iov_from_buf(iov_in, iov_cnt_in, 0,
-          &n->supported_modes, sizeof(n->supported_modes));
+        n->supported_modes.steering_modes |= STEERING_MODE_RSS |
+            STEERING_MODE_AUTO;

We should have a property for RSS instead of hard coding it here.

Thanks

+        s = iov_from_buf(iov_in, iov_in_cnt, 0,
+        &n->supported_modes,
+        sizeof(n->supported_modes));
          if (s != sizeof(n->supported_modes) ||
-          !size_in) {
+        !size_in) {
              return VIRTIO_NET_ERR;
          }
-                  *size_in = s;
-      break;
+        *size_in = s;
+         break;
      case VIRTIO_NET_CTRL_SM_CONTROL:
-        s = iov_to_buf(iov, iov_cnt, 0, &sm, sizeof(sm) -
-                sizeof(union command_data));
-        if (s != sizeof(sm) - sizeof(union command_data)) {
+        s = iov_to_buf(iov, iov_cnt, 0, &sm, sizeof(sm));
+        if (s != sizeof(sm)) {
+            return VIRTIO_NET_ERR;
+        }
+        iov_discard_front(&iov, &iov_cnt, sizeof(sm));
+        /* TODO handle the case where we change mode, call the old */
+        /* mode function with null ptrs  should do the trick of */
+        /* freeing any resources */
+        switch (sm.steering_mode) {
+        case STEERING_MODE_AUTO:
+                    break;
+        case STEERING_MODE_RSS:
+            status = virtio_net_ctrl_sm_rss(n, sm.command,
+                   iov, iov_cnt, iov_in, iov_in_cnt,
+                   &size_in_cmd);
+            if (status == VIRTIO_NET_OK && size_in_cmd > 0) {
+                *size_in += size_in_cmd;
+            }
+            break;
+        default:
              return VIRTIO_NET_ERR;
          }
-        /* switch (cmd)
-             {
-                dafault:
-                return VIRTIO_NET_ERR;
-         } */
-      break;
+        break;
      default:
-                return VIRTIO_NET_ERR;
+        return VIRTIO_NET_ERR;
      }
return VIRTIO_NET_OK;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]