changeset 117:f3c7e9b0c5cf

WIP on the DMA API
author Louis Opter <louis@lse.epita.fr>
date Thu, 25 Jul 2013 16:45:13 -0700
parents 2a7126613c70
children ad21d8a182ad
files rathaxes_samples_e1000_add_a_dma_abstraction.patch rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch
diffstat 2 files changed, 98 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/rathaxes_samples_e1000_add_a_dma_abstraction.patch	Mon Jul 22 16:04:12 2013 -0700
+++ b/rathaxes_samples_e1000_add_a_dma_abstraction.patch	Thu Jul 25 16:45:13 2013 -0700
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent af7a1f8589d632497e2f2574570f5153cae59b91
+# Parent 61470dc5e775a696da551b5227663bf2659f8f4b
 e1000: start a DMA allocation/mapping abstraction
 
 It currently matches a lot the Linux DMA API but it should be usable by
@@ -35,7 +35,7 @@
 new file mode 100644
 --- /dev/null
 +++ b/rathaxes/samples/e1000/dma.blt
-@@ -0,0 +1,89 @@
+@@ -0,0 +1,103 @@
 +with DMA, Builtin, LKM, Device
 +{
 +    template type   DMA::AbstractDMAHandle()
@@ -52,7 +52,21 @@
 +
 +        map
 +        {
-+            k_dma_handle: ((dma_addr_t)${self});
++            k_dma_handle: (dma_addr_t)(${self});
++        }
++    }
++
++    template type   DMA::DMAHandle()
++    {
++        decl    data_types()
++        {
++            ${DMA::AbstractDMAHandle}   data;
++        }
++
++        map
++        {
++            /* XXX: we should use ${DMA::AbstractDMAHandle} here: */
++            dma_handle: (dma_addr_t)(${self});
 +        }
 +    }
 +
@@ -65,7 +79,7 @@
 +
 +        map
 +        {
-+            k_dma_direction: ((enum dma_data_direction)${self});
++            k_dma_direction: (enum dma_data_direction)(${self});
 +        }
 +    }
 +
@@ -81,7 +95,7 @@
 +        map
 +        {
 +            /* XXX: we should use ${DMA::AbstractDMADirection} here: */
-+            dma_direction: ((enum dma_data_direction)${self});
++            dma_direction: (enum dma_data_direction)(${self});
 +        }
 +    }
 +
@@ -89,7 +103,7 @@
 +    {
 +        chunk  ::CALL()
 +        {
-+            ((${DMA::DMA::AbstractDMAHandle})dma_map_single(${dev.k_device}, ${buf}, ${size}, ${dir.dma_direction}));
++            ((${DMA::DMAHandle})dma_map_single(${dev.k_device}, ${buf}, ${size}, ${dir.dma_direction}));
 +        }
 +    }
 +
@@ -129,7 +143,7 @@
 new file mode 100644
 --- /dev/null
 +++ b/rathaxes/samples/e1000/dma.rti
-@@ -0,0 +1,48 @@
+@@ -0,0 +1,54 @@
 +interface DMA : Builtin, LKM, Device
 +{
 +    provided type   AbstractDMAHandle
@@ -139,6 +153,12 @@
 +        attribute   Builtin::symbol.scalar  k_dma_handle;
 +    }
 +
++    provided type   DMAHandle
++    {
++        decl        data_types();
++        attribute   AbstractDMAHandle.scalar    dma_handle;
++    }
++
 +    provided type   AbstractDMADirection
 +    {
 +        decl        data_types();
--- a/rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch	Mon Jul 22 16:04:12 2013 -0700
+++ b/rathaxes_samples_e1000_use_the_dma_abstraction_in_socket.patch	Thu Jul 25 16:45:13 2013 -0700
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent 22cdd951a10d1b8b06daf6448da73e738f21d2e3
+# Parent 3cea76c8dbc4e341f3ff42e42532bdbd3f06fcac
 Replace Linux specific code in Socket by DMA calls
 
 diff --git a/rathaxes/samples/e1000/socket.blt b/rathaxes/samples/e1000/socket.blt
@@ -11,6 +11,15 @@
  {
      template type Socket::AbstractSKBuff()
      {
+@@ -14,7 +14,7 @@
+ 
+         map
+         {
+-            k_sk_buff: ((struct sk_buff *)${self});
++            k_sk_buff: (struct sk_buff *)(${self});
+         }
+     }
+ 
 @@ -22,35 +22,34 @@
      {
          decl  data_types()
@@ -35,13 +44,13 @@
              static void rtx_socket_skbuff_dump_infos(${Socket::SKBuff.ref} self)
              {
 -                WARN_ON(!self->skbuff);
-+                WARN_ON(!${local.self.k_sk_buff});
++                WARN_ON(!${local.self.sk_buff});
 +
-+                ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.self.k_sk_buff}->protocol) };
++                ${Ethernet::ProtocolId} ethernet_proto = { .id = be16_to_cpu(${local.self.sk_buff.k_sk_buff}->protocol) };
 +                static const char * const ip_summed_values[] = {
 +                    "none", "unnecessary", "complete", "partial"
 +                };
-+                struct skb_shared_info *shinfo = skb_shinfo(${local.self.k_sk_buff});
++                struct skb_shared_info *shinfo = skb_shinfo(${local.self.sk_buff.k_sk_buff});
  
                  /*
                   * We should use a Rathaxes log abstraction instead of pr_info here,
@@ -58,14 +67,14 @@
                  pr_info(
                          "\t protocol = %#-5x (%s) ip_summed = %d (%s)\n"
                          "\t      len = %-5u data_len = %-5u head_len = %-5u\n"
-@@ -58,30 +57,26 @@
+@@ -58,53 +57,46 @@
                          "\t gso_size = %-5u gso_segs = %-5u gso_type = %-5u",
                          /* XXX: can't use ${local.ethernet_proto.id} here (issue #52): */
                          ethernet_proto.id, ${local.ethernet_proto.str},
 -                        ${local.skb.k_sk_buff}->ip_summed, ip_summed_values[${local.skb.k_sk_buff}->ip_summed],
 -                        ${local.skb.k_sk_buff}->len, ${local.skb.k_sk_buff}->data_len, skb_headlen(${local.skb.k_sk_buff}),
-+                        ${local.self.k_sk_buff}->ip_summed, ip_summed_values[${local.self.k_sk_buff}->ip_summed],
-+                        ${local.self.k_sk_buff}->len, ${local.self.k_sk_buff}->data_len, skb_headlen(${local.self.k_sk_buff}),
++                        ${local.self.sk_buff.k_sk_buff}->ip_summed, ip_summed_values[${local.self.sk_buff.k_sk_buff}->ip_summed],
++                        ${local.self.sk_buff.k_sk_buff}->len, ${local.self.sk_buff.k_sk_buff}->data_len, skb_headlen(${local.self.sk_buff.k_sk_buff}),
                          shinfo->nr_frags, shinfo->gso_size, shinfo->gso_segs, shinfo->gso_type
                  );
              }
@@ -77,8 +86,8 @@
 +                                             ${DMA::DMADirection.scalar} direction)
              {
 -                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
-+                WARN_ON(!${local.self.k_sk_buff});
-+                WARN_ON(${local.self.k_dma_handle});
++                WARN_ON(!${local.self.sk_buff});
++                WARN_ON(${local.self.dma_handle});
  
 -                WARN_ON(!${local.skb.k_sk_buff});
 -                WARN_ON(self->dma_handle);
@@ -89,36 +98,62 @@
 -                        skb_headlen(${local.skb.k_sk_buff}),
 -                        direction);
 -                int err = dma_mapping_error(dev, self->dma_handle);
-+                unsigned int len = skb_headlen(${local.skb.k_sk_buff});
++                unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff});
 +                ${cast local.len as Builtin::number};
-+                ${local.self.k_dma_handle} = ${DMA::map(local.dev, local.skb.k_sk_buff, local.len, local.direction)};
-+                int err = ${DMA::mapping_error(local.dev, local.self.k_dma_handle)};
++                ${local.self.dma_handle} = ${DMA::map(local.dev, local.self.sk_buff.k_sk_buff, local.len, local.direction)};
++                int err = ${DMA::mapping_error(local.dev, local.self.dma_handle)};
                  if (err)
                  {
 -                    self->dma_handle = 0;
-+                    ${local.self.k_dma_handle} = 0;
++                    ${local.self.dma_handle} = 0;
                      return err;
                  }
                  return 0;
-@@ -89,7 +84,7 @@
+             }
  
              static void rtx_socket_skbuff_unmap_and_free(${Socket::SKBuff.ref} self,
-                                                          struct device *dev,
+-                                                         struct device *dev,
 -                                                         enum dma_data_direction direction)
++                                                         ${Device::AbstractDevice.ref} dev,
 +                                                         ${DMA::DMADirection} direction)
              {
-                 ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
+-                ${Socket::AbstractSKBuff.ref}   skb = self->skbuff;
++                WARN_ON(!${local.self.sk_buff});
  
-@@ -100,7 +95,7 @@
-                     dma_unmap_single(dev,
-                             self->dma_handle,
-                             skb_headlen(${local.skb.k_sk_buff}),
+-                WARN_ON(!${local.skb.k_sk_buff});
+-
+-                if (self->dma_handle)
++                if (${local.self.dma_handle})
+                 {
+-                    dma_unmap_single(dev,
+-                            self->dma_handle,
+-                            skb_headlen(${local.skb.k_sk_buff}),
 -                            direction);
-+                            ${local.direction.dma_direction});
-                     self->dma_handle = 0;
+-                    self->dma_handle = 0;
++                    unsigned int len = skb_headlen(${local.self.sk_buff.k_sk_buff});
++                    ${cast local.len as Builtin::number};
++                    ${DMA::unmap(local.dev, local.self.dma_handle, local.len, local.direction)};
++                    ${local.self.dma_handle} = 0;
                  }
-                 dev_kfree_skb_any(${local.skb.k_sk_buff});
-@@ -126,30 +121,32 @@
+-                dev_kfree_skb_any(${local.skb.k_sk_buff});
+-                self->skbuff = 0;
++                dev_kfree_skb_any(${local.self.sk_buff.k_sk_buff});
++                ${local.self.sk_buff} = NULL;
+             }
+         }
+ 
+@@ -115,8 +107,8 @@
+          */
+         method init(Socket::AbstractSKBuff kernel_skb)
+         {
+-            ${self}.skbuff = ${kernel_skb};
+-            ${self}.dma_handle = 0;
++            ${self.sk_buff} = ${kernel_skb};
++            ${self.dma_handle} = 0;
+         }
+ 
+         method dump_infos()
+@@ -126,30 +118,37 @@
  
          method   map_to(Device::AbstractDevice dev)
          {
@@ -129,19 +164,19 @@
          method   map_from(Device::AbstractDevice dev)
          {
 -            rtx_socket_skbuff_map(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
-+            rtx_socket_skbuff_map(${self}, ${dev.k_device}, RTX_DMA_FROM_DEVICE);
++            rtx_socket_skbuff_map(${self}, ${dev}, RTX_DMA_FROM_DEVICE);
          }
  
          method   unmap_to_and_free(Device::AbstractDevice dev)
          {
 -            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_TO_DEVICE);
-+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, RTX_DMA_TO_DEVICE);
++            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_TO_DEVICE);
          }
  
          method   unmap_from_and_free(Device::AbstractDevice dev)
          {
 -            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, DMA_FROM_DEVICE);
-+            rtx_socket_skbuff_unmap_and_free(${self}, ${dev.k_device}, RTX_DMA_FROM_DEVICE);
++            rtx_socket_skbuff_unmap_and_free(${self}, ${dev}, RTX_DMA_FROM_DEVICE);
          }
  
          map
@@ -154,8 +189,13 @@
 +            // field of the sk_buff. We should determine if all the sk_buff
 +            // management can be abstracted from the user. But this is at least
 +            // useful for internal use:
-+            k_sk_buff: ((struct skbuff *)(${self}->skbuff));
-+            k_dma_handle: ((dma_addr_t)(${self}->dma_handle));
++            sk_buff: (${self})->skbuff;
++            // XXX: We need to cast here so we can do things like
++            // var.dma_handle = 0; but the type shouldn't be hardcoded (at the
++            // same time ${DMA:AbstractDMAHandle} couldn't be used because that
++            // would yield to a struct type which you can't assign directly;
++            // but maybe doing the ->data in that case would be acceptable).
++            dma_handle: (dma_addr_t)((${self})->dma_handle);
          }
      }
  }
@@ -173,7 +213,7 @@
          method      unmap_to_and_free(Device::AbstractDevice);
          method      unmap_from_and_free(Device::AbstractDevice);
 +
-+        attribute   Socket::AbstractSKBuff.ref      k_sk_buff;
-+        attribute   DMA::AbstractDMAHandle.scalar   k_dma_handle;
++        attribute   Socket::AbstractSKBuff.ref      sk_buff;
++        attribute   DMA::AbstractDMAHandle.scalar   dma_handle;
      }
  }