TAS
TCP Acceleration as an OS Service
connect.c
1 /*
2  * Copyright 2019 University of Washington, Max Planck Institute for
3  * Software Systems, and The University of Texas at Austin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <sys/mman.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <assert.h>
35 
36 #include <tas_ll_connect.h>
37 #include <tas_memif.h>
38 
39 static void *map_region(const char *name, size_t len);
40 static void *map_region_huge(const char *name, size_t len)
41  __attribute__((used));
42 
43 static struct flexnic_info *info = NULL;
44 
45 int flexnic_driver_connect(struct flexnic_info **p_info, void **p_mem_start)
46 {
47  void *m;
48  volatile struct flexnic_info *fi;
49  int err_ret = -1;
50 
51  /* return error, if already connected */
52  if (info != NULL) {
53  fprintf(stderr, "flexnic_driver_connect: already connected\n");
54  goto error_exit;
55  }
56 
57  /* open and map flexnic info shm region */
58  if ((m = map_region(FLEXNIC_NAME_INFO, FLEXNIC_INFO_BYTES)) == NULL) {
59  perror("flexnic_driver_connect: map_region info failed");
60  goto error_exit;
61  }
62 
63  /* abort if not ready yet */
64  fi = (volatile struct flexnic_info *) m;
66  err_ret = 1;
67  goto error_unmap_info;
68  }
69 
70  /* open and map dma shm region */
72  m = map_region_huge(FLEXNIC_NAME_DMA_MEM, fi->dma_mem_size);
73  } else {
74  m = map_region(FLEXNIC_NAME_DMA_MEM, fi->dma_mem_size);
75  }
76  if (m == NULL) {
77  perror("flexnic_driver_connect: mapping dma memory failed");
78  goto error_unmap_info;
79  }
80 
81  *p_info = info = (struct flexnic_info *) fi;
82  *p_mem_start = m;
83  return 0;
84 
85 error_unmap_info:
86  munmap(m, FLEXNIC_INFO_BYTES);
87 error_exit:
88  return err_ret;
89 }
90 
91 int flexnic_driver_internal(void **int_mem_start)
92 {
93  void *m;
94 
95  if (info == NULL) {
96  fprintf(stderr, "flexnic_driver_internal: driver not connected\n");
97  return -1;
98  }
99 
100  /* open and map flexnic internal memory shm region */
102  m = map_region_huge(FLEXNIC_NAME_INTERNAL_MEM, info->internal_mem_size);
103  } else {
104  m = map_region(FLEXNIC_NAME_INTERNAL_MEM, info->internal_mem_size);
105  }
106  if (m == NULL) {
107  perror("flexnic_driver_internal: map_region failed");
108  return -1;
109  }
110 
111  *int_mem_start = m;
112  return 0;
113 }
114 
115 static void *map_region(const char *name, size_t len)
116 {
117  int fd;
118  void *m;
119 
120  if ((fd = shm_open(name, O_RDWR, 0)) == -1) {
121  perror("map_region: shm_open memory failed");
122  return NULL;
123  }
124  m = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
125  close(fd);
126  if (m == (void *) -1) {
127  perror("flexnic_driver_connect: mmap failed");
128  return NULL;
129  }
130 
131  return m;
132 }
133 
134 static void *map_region_huge(const char *name, size_t len)
135 {
136  int fd;
137  void *m;
138  char path[128];
139 
140  snprintf(path, sizeof(path), "%s/%s", FLEXNIC_HUGE_PREFIX, name);
141 
142  if ((fd = open(path, O_RDWR)) == -1) {
143  perror("map_region: shm_open memory failed");
144  return NULL;
145  }
146  m = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0);
147  close(fd);
148  if (m == (void *) -1) {
149  perror("flexnic_driver_connect: mmap failed");
150  return NULL;
151  }
152 
153  return m;
154 }
#define FLEXNIC_NAME_INFO
Definition: tas_memif.h:41
#define FLEXNIC_FLAG_READY
Definition: tas_memif.h:51
uint64_t flags
Definition: tas_memif.h:58
#define FLEXNIC_NAME_INTERNAL_MEM
Definition: tas_memif.h:45
uint64_t internal_mem_size
Definition: tas_memif.h:62
#define FLEXNIC_NAME_DMA_MEM
Definition: tas_memif.h:43
#define FLEXNIC_INFO_BYTES
Definition: tas_memif.h:48
#define FLEXNIC_FLAG_HUGEPAGES
Definition: tas_memif.h:53
uint64_t dma_mem_size
Definition: tas_memif.h:60