9
9
#define PREFETCH_LAUNCH_VALVE 4
10
10
#define PREFETCH_LIFE 80
11
11
#define PREFETCH_BEGIN_PAGE_COUNT 10
12
+ #define ONLINE_SERVER 2
12
13
13
14
//#define _ATFILE_SOURCE
14
15
#include "qemu/osdep.h"
103
104
#include "uname.h"
104
105
#include "qemu.h"
105
106
#include "offload_client.h"
107
+ #define DQEMU_PAGE_BITS
108
+ #define DQEMU_PAGE_NONE 0x0 /* NONE. READ, WRITE **in local** */
109
+ #define DQEMU_PAGE_READ 0x1
110
+ #define DQEMU_PAGE_WRITE 0x2
111
+ #define DQEMU_PAGE_PROCESS_FS 0x4 /* Generating shadow pages. */
112
+ #define DQEMU_PAGE_FS 0x8 /* False sharing page in use. */
113
+ #define DQEMU_PAGE_SHADOW 0x10 /* Shadow page */
114
+
115
+
116
+ target_ulong shadow_page_base = 0xa0000000 ;
106
117
static void offload_send_mutex_verified (int );
107
118
119
+ static void offload_send_page_wakeup (int idx , target_ulong page_addr );
108
120
static void offload_process_mutex_done (void );
109
121
static void offload_send_syscall_result (int ,abi_long ,int );
110
122
static void offload_process_syscall_request (void );
@@ -123,6 +135,7 @@ int futex_table_cmp_requeue(uint32_t uaddr, int futex_op, int val, uint32_t val2
123
135
uint32_t uaddr2 , int val3 , int idx , int thread_id );
124
136
void offload_connect_online_server (int idx );
125
137
int false_sharing_flag = 0 ;
138
+ __thread char buf [TARGET_PAGE_SIZE * 2 ];
126
139
127
140
//int requestor_idx, target_ulong addr, int perm
128
141
struct info
@@ -282,9 +295,8 @@ typedef struct PageMapDesc {
282
295
int invalid_count ; /* How many we should tell to invalidate */
283
296
int cur_perm ;
284
297
req_node list_head ; /* to record request list */
285
- int is_false_sharing ;
298
+ uint32_t flag ;
286
299
uint32_t shadow_page_addr ;
287
- int is_shadow_page ;
288
300
} PageMapDesc ;
289
301
290
302
PageMapDesc page_map_table [L1_MAP_TABLE_SIZE ][L2_MAP_TABLE_SIZE ] __attribute__ ((section (".page_table_section" ))) __attribute__ ((aligned (4096 ))) = {0 };
@@ -321,7 +333,7 @@ static void offload_client_send_futex_wake_result(int result);
321
333
322
334
int offload_client_start (CPUArchState * the_env );
323
335
void * offload_center_client_start (void * );
324
- static void offload_send_page_request (int idx , target_ulong guest_addr , uint32_t perm ,int );
336
+ static void offload_send_page_request (int idx , target_ulong guest_addr , uint32_t perm ,int );
325
337
static void offload_send_page_content (int idx , target_ulong guest_addr , uint32_t perm , char * content );
326
338
327
339
static void offload_client_send_cmpxchg_ack (target_ulong );
@@ -869,6 +881,26 @@ static inline void show_pmd_list(req_node *p)
869
881
p = p -> next ;
870
882
}
871
883
}
884
+ static void wake_pmd_list (uint32_t page_addr )
885
+ {
886
+ fprintf (stderr , "[process_pmd]\twake pmd list! %p\n" , page_addr );
887
+ PageMapDesc * pmd = get_pmd (page_addr );
888
+ /* Make sure its a fs page and is processes already. */
889
+
890
+ fprintf (stderr , "[process_pmd]\tbits %p, c1 %d, c2 %d\n" , pmd -> flag ,
891
+ (pmd -> flag & DQEMU_PAGE_FS ),!(pmd -> flag & DQEMU_PAGE_PROCESS_FS ));
892
+ int is_fs_page = (pmd -> flag & DQEMU_PAGE_FS ) && !(pmd -> flag & DQEMU_PAGE_PROCESS_FS );
893
+ assert (is_fs_page == 1 );
894
+ req_node * p = pmd -> list_head .next , * tmp ;
895
+ show_pmd_list (p );
896
+ while (p ) {
897
+ offload_send_page_wakeup (p -> idx , page_addr );
898
+ tmp = p ;
899
+ p = p -> next ;
900
+ free (tmp );
901
+ }
902
+ pmd -> list_head .next = NULL ;
903
+ }
872
904
static int process_pmd (uint32_t page_addr )
873
905
{
874
906
PageMapDesc * pmd = get_pmd (page_addr );
@@ -1103,42 +1135,84 @@ static void offload_process_mutex_request(void)
1103
1135
pthread_mutex_unlock (& g_cas_mutex );
1104
1136
}
1105
1137
1106
- /* Broadcast false sharing page. */
1138
+
1139
+ static inline void dqemu_set_page_bit (uint32_t page_addr , uint32_t page_bit )
1140
+ {
1141
+ PageMapDesc * pmd = get_pmd (page_addr );
1142
+ pmd -> flag = page_bit ;
1143
+ fprintf (stderr , "[dqemu_set_page_bit]\tnow %p page bit = %p\n" , page_addr , page_bit );
1144
+ }
1145
+
1146
+ static void offload_broadcast_fs_page (uint32_t page_addr , uint32_t shadow_page_addr )
1147
+ {
1148
+ char * pp = buf + sizeof (struct tcp_msg_header );
1149
+ * ((target_ulong * ) pp ) = page_addr ;
1150
+ pp += sizeof (target_ulong );
1151
+ * ((uint32_t * )pp ) = shadow_page_addr ;
1152
+ pp += sizeof (uint32_t );
1153
+ struct tcp_msg_header * tcp_header = (struct tcp_msg_header * )buf ;
1154
+ fill_tcp_header (tcp_header , pp - buf - sizeof (struct tcp_msg_header ), TAG_OFFLOAD_FS_PAGE );
1155
+ /* Broadcast message. */
1156
+ for (int i = 0 ; i <= ONLINE_SERVER ; i ++ ) {
1157
+ autoSend (i , buf , pp - buf , 0 );
1158
+ fprintf (stderr , "[offload_broadcast_fs_page]\tsent fs page %p"
1159
+ "shadow page %p to #%d\n" , page_addr , shadow_page_addr , i );
1160
+ }
1161
+ }
1162
+ /* Process and broadcast false sharing page. */
1163
+ /* Clean up the left */
1107
1164
uint32_t offload_client_process_false_sharing_page (uint32_t page_addr )
1108
1165
{
1166
+ fprintf (stderr , "[offload_client_process_false_sharing_page]\t"
1167
+ "page addr = %p\n" ,
1168
+ page_addr );
1109
1169
PageMapDesc * pmd = get_pmd (page_addr );
1110
- //if (!g_false_sharing_flag) {
1111
- // g_false_sharing_flag = 1;
1112
- // fprintf(stderr, "[false_sharing_start]\tfalse sharing start!!\n");
1113
- //}
1114
1170
/* Create shadow page mapping. */
1115
- pmd -> is_false_sharing = 1 ;
1116
- uint32_t shadow_page_addr = page_addr - 0x60000000 ;
1117
- shadow_page_addr = target_mmap (shadow_page_addr ,
1171
+ uint32_t shadow_page_addr = shadow_page_base ;
1172
+ shadow_page_base += 64 * PAGE_SIZE ;
1173
+ assert (shadow_page_base < 0xd0000000 );
1174
+ uint32_t ret = target_mmap (shadow_page_addr ,
1118
1175
64 * PAGE_SIZE , PROT_READ |PROT_WRITE ,
1119
1176
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED , -1 , 0 );
1177
+ assert (ret == shadow_page_addr );
1178
+ //shadow_page_addr = mmap(g2h(shadow_page_addr),
1179
+ // 64*PAGE_SIZE, PROT_READ|PROT_WRITE,
1180
+ // MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
1120
1181
fprintf (stderr , "[offload_client_process_false_sharing_page]\t"
1121
- "Created shadow pages for %p, shadow page base = %p\n" ,
1122
- page_addr , shadow_page_addr );
1123
- shadow_page_addr = target_mmap (shadow_page_addr ,
1124
- 64 * PAGE_SIZE , PROT_READ |PROT_WRITE ,
1125
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED , -1 , 0 );
1126
- fprintf (stderr , "[offload_client_process_false_sharing_page]\t"
1127
- "Created shadow pages for %p, shadow page base = %p\n" ,
1182
+ "Created shadow pages for %p, shadow page base = %p, setting to zeros\n" ,
1128
1183
page_addr , shadow_page_addr );
1184
+ memset (g2h (shadow_page_addr ), 0 , 64 * PAGE_SIZE );
1129
1185
uint32_t step = PAGE_SIZE / 64 ;
1130
1186
uint32_t start = shadow_page_addr , o_start = page_addr ;
1131
1187
for (int i = 0 ; i < 64 ; i ++ ) {
1132
1188
fprintf (stderr , "[offload_client_process_false_sharing_page]\t"
1133
- "copying to %p - %p from %p - %p, step %p\n" ,
1134
- g2h (start ), g2h (start + step ),
1135
- g2h (o_start ), g2h (o_start + step ), step );
1189
+ "%d: copying to %p - %p from %p - %p, step %p\n" , i ,
1190
+ start , start + step ,
1191
+ o_start , o_start + step , step );
1192
+
1193
+ memcpy (g2h (start ), g2h (o_start ), step );
1194
+ dqemu_set_page_bit (start & 0xfffff000 , DQEMU_PAGE_NONE | DQEMU_PAGE_SHADOW );
1136
1195
start += (step + PAGE_SIZE );
1137
1196
o_start += step ;
1138
- memcpy (g2h (start ), g2h (o_start ), step );
1197
+ // TODO check SHADOW and FS bit when receive request
1198
+ // TODO don't split shadow page
1139
1199
}
1200
+ fprintf (stderr , "[offload_client_process_false_sharing_page]\tCopy done.\n" );
1201
+
1140
1202
pmd -> shadow_page_addr = shadow_page_addr ;
1141
-
1203
+ dqemu_set_page_bit (page_addr , DQEMU_PAGE_NONE | DQEMU_PAGE_FS );
1204
+ fprintf (stderr , "[offload_client_process_false_sharing_page]\tNow page %p bit %p.\n" ,
1205
+ page_addr , pmd -> flag );
1206
+
1207
+ offload_broadcast_fs_page (page_addr , shadow_page_addr );
1208
+
1209
+ // TODO wake up pmd list to let them rethink.
1210
+ /* Mark as master got the page. */
1211
+ clear (& pmd -> owner_set );
1212
+ insert (& pmd -> owner_set , 0 );
1213
+ fprintf (stderr , "[offload_client_process_false_sharing_page]\tclean set and unlock.\n" );
1214
+ pthread_mutex_unlock (& pmd -> owner_set_mutex );
1215
+ wake_pmd_list (page_addr );
1142
1216
}
1143
1217
1144
1218
/* fetch page */
@@ -1151,36 +1225,44 @@ static void offload_process_page_request(void)
1151
1225
int perm = * (uint32_t * ) p ;
1152
1226
p += sizeof (uint32_t );
1153
1227
1228
+ PageMapDesc * pmd = get_pmd (page_addr );
1154
1229
/*uint32_t got_flag = *(uint32_t *)p;
1155
1230
p += sizeof(uint32_t);*/
1156
1231
fprintf (stderr , "[offload_process_page_request client#%d]\trequested address: %x, perm: %d\n" , offload_client_idx , page_addr , perm );
1157
1232
fprintf (log , "%d\t%p\t%d\n" , offload_client_idx , page_addr , perm );
1158
1233
/* Check if already in prefetch list */
1159
1234
int isInPrefetch = (perm == 2 )? 0 : prefetch_check (page_addr , offload_client_idx );
1160
- // if (isInPrefetch<0)
1161
- // {
1162
- // sleep(0.5);
1163
- // }
1235
+ /* Hit already splited false sharing page. */
1236
+ fprintf (stderr , "[offload_process_page_request client#%d]\tpage flag %p\n" , pmd -> flag );
1237
+ if (pmd -> flag & DQEMU_PAGE_FS ) {
1238
+ offload_send_page_wakeup (offload_client_idx , page_addr );
1239
+ }
1164
1240
offload_client_fetch_page (offload_client_idx , page_addr , perm );
1165
1241
if (isInPrefetch < 0 )
1166
1242
{
1167
1243
fprintf (stderr , "[offload_process_page_request client#%d]\tIn list, prefetch stops\n" , offload_client_idx );
1168
1244
return ;
1169
1245
}
1170
1246
else {
1171
-
1172
1247
int prefetch_count = prefetch_handler (page_addr , offload_client_idx );
1173
- /* limit the prefetch count to avoid too much thread at a time */
1174
- //prefetch_count = prefetch_count > 500 ? 500 : prefetch_count;
1175
- /* We create new shadow page mappings for the false sharing page. */
1248
+ /* False sharing page. */
1176
1249
if (prefetch_count < 0 ) {
1177
- //fprintf(stderr, "[offload_process_page_request client#%d]\t"
1178
- // "Prefetch count = %d\n", offload_client_idx,
1179
- // prefetch_count);
1180
- //offload_client_process_false_sharing_page(page_addr);
1250
+ fprintf (stderr , "[offload_process_page_request client#%d]\t"
1251
+ "Prefetch count = %d, false sharing page!\n" , offload_client_idx ,
1252
+ prefetch_count );
1253
+ /* Mark the page in false sharing process. */
1254
+ if (pmd -> flag & DQEMU_PAGE_SHADOW ) {
1255
+ fprintf (stderr , "[offload_process_page_request client#%d]\t"
1256
+ "already is shadow page! wo to le! %p\n" , offload_client_idx ,
1257
+ page_addr );
1258
+ //exit(2);
1259
+ }
1260
+ if (!(pmd -> flag & DQEMU_PAGE_FS ) && !(pmd -> flag & DQEMU_PAGE_PROCESS_FS )
1261
+ && !(pmd -> flag & DQEMU_PAGE_SHADOW ))
1262
+ dqemu_set_page_bit (page_addr , DQEMU_PAGE_PROCESS_FS );
1181
1263
//exit(3);
1182
1264
}
1183
- if (prefetch_count > 0 && perm = = 2 ) {
1265
+ else if (prefetch_count > 0 && perm ! = 2 ) {
1184
1266
fprintf (stderr , "[offload_process_page_request client#%d]\tPrefetching for next %d pages\n" , offload_client_idx , prefetch_count );
1185
1267
for (int i = 0 ; i < prefetch_count ; i ++ ) {
1186
1268
offload_client_fetch_page (offload_client_idx , page_addr + (i + 1 )* PAGE_SIZE , 1 );
@@ -1908,18 +1990,21 @@ void offload_syscall_daemonize_start(CPUArchState *the_env)
1908
1990
}
1909
1991
1910
1992
1993
+ /* Send page request.
1994
+ * guest page address : 4
1995
+ * permission : 4
1996
+ * who sent this : 4
1997
+ * page for who : 4
1998
+ * is false sharing : 4
1999
+ */
1911
2000
static void offload_send_page_request (int idx , target_ulong page_addr , uint32_t perm , int forwho )
1912
2001
{
1913
-
1914
- //pthread_mutex_lock(&socket_mutex);
1915
2002
p = BUFFER_PAYLOAD_P ;
1916
2003
1917
2004
* ((target_ulong * ) p ) = page_addr ;
1918
2005
p += sizeof (target_ulong );
1919
-
1920
2006
* ((uint32_t * ) p ) = perm ;
1921
2007
p += sizeof (uint32_t );
1922
-
1923
2008
* ((int * ) p ) = offload_client_idx ;
1924
2009
p += sizeof (int );
1925
2010
* ((int * ) p ) = forwho ;
@@ -1942,12 +2027,35 @@ static void offload_send_page_request(int idx, target_ulong page_addr, uint32_t
1942
2027
fprintf (stderr , "[offload_send_page_request]\tsent page %x request to node# %d, perm: %d, packet#%d\n" , page_addr , idx , perm , get_number ());
1943
2028
//pthread_mutex_unlock(&socket_mutex);
1944
2029
}
1945
- __thread char buf [TARGET_PAGE_SIZE * 2 ];
1946
2030
2031
+ static void offload_send_page_wakeup (int idx , target_ulong page_addr )
2032
+ {
2033
+ char * pp = buf + sizeof (struct tcp_msg_header );
2034
+ * ((target_ulong * ) pp ) = page_addr ;
2035
+ pp += sizeof (target_ulong );
2036
+ struct tcp_msg_header * tcp_header = (struct tcp_msg_header * )buf ;
2037
+ fill_tcp_header (tcp_header , pp - buf - sizeof (struct tcp_msg_header ), TAG_OFFLOAD_PAGE_WAKEUP );
2038
+ autoSend (idx , buf , pp - buf , 0 );
2039
+ fprintf (stderr , "[offload_send_page_wakeup]\tsent page wakeup %x to #%d, packet#%d\n" , page_addr , idx , get_number ());
2040
+ }
1947
2041
static void offload_send_page_content (int idx , target_ulong page_addr , uint32_t perm , char * content )
1948
2042
{
1949
- //pthread_mutex_lock(&socket_mutex);
1950
- //char buf[TARGET_PAGE_SIZE * 2];
2043
+ PageMapDesc * pmd = get_pmd (page_addr );
2044
+ /* If this is a fs page need to be processed and no one but us has the page now. */
2045
+ fprintf (stderr , "[offload_send_page_content]\t%p page bit = %p perm = %d, c1 %d c2 %d\n" ,
2046
+ page_addr , pmd -> flag , perm , pmd -> flag & DQEMU_PAGE_PROCESS_FS ,
2047
+ perm == 2 );
2048
+ if ((pmd -> flag & DQEMU_PAGE_PROCESS_FS ) && (perm == 2 )) {
2049
+ pthread_mutex_lock (& master_mprotect_mutex );
2050
+ mprotect (g2h (page_addr ), TARGET_PAGE_SIZE , PROT_READ | PROT_WRITE );
2051
+ fprintf (stderr , "[offload_send_page_content]\tcopying to %p\n" , page_addr );
2052
+ memcpy (g2h (page_addr ), content , TARGET_PAGE_SIZE );
2053
+ offload_client_process_false_sharing_page (page_addr );
2054
+ pthread_mutex_unlock (& master_mprotect_mutex );
2055
+ offload_send_page_wakeup (idx , page_addr );
2056
+
2057
+ return ;
2058
+ }
1951
2059
char * pp = buf + sizeof (struct tcp_msg_header );
1952
2060
//fprintf(stderr, "[offload_send_page_content]\tp: %p, net_buffer: %p\n", p, net_buffer);
1953
2061
* ((target_ulong * ) pp ) = page_addr ;
@@ -1965,7 +2073,6 @@ static void offload_send_page_content(int idx, target_ulong page_addr, uint32_t
1965
2073
autoSend (idx , buf , pp - buf , 0 );
1966
2074
1967
2075
fprintf (stderr , "[offload_send_page_content]\tsent page content %x to #%d, perm %d, packet#%d\n" , page_addr , idx , perm , get_number ());
1968
- //pthread_mutex_unlock(&socket_mutex);
1969
2076
}
1970
2077
1971
2078
// get the imformation of mutex-done sender and remove it from MutexList
0 commit comments