Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c156d13

Browse files
committed
[version 2.3.0]False sharing done.
1 parent 0fce84d commit c156d13

File tree

7 files changed

+251
-61
lines changed

7 files changed

+251
-61
lines changed

linux-user/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ pthread_mutex_t main_exec_mutex;
634634
pthread_cond_t main_exec_cond;
635635
int main_exec_flag;
636636
int g_false_sharing_flag;
637+
pthread_mutex_t master_mprotect_mutex;
637638

638639
pthread_mutex_t offload_center_init_mutex; pthread_cond_t offload_center_init_cond;
639640
void offload_server_extra_init(void);
@@ -1169,6 +1170,7 @@ int main(int argc, char **argv, char **envp)
11691170

11701171

11711172
pthread_mutex_init(&offload_center_init_mutex, NULL);
1173+
pthread_mutex_init(&master_mprotect_mutex, NULL);
11721174
pthread_cond_init(&offload_center_init_cond, NULL);
11731175

11741176
pthread_create(&center_server_thread, NULL, offload_center_server_start, (void *) NULL);
@@ -1180,6 +1182,8 @@ int main(int argc, char **argv, char **envp)
11801182
for (int i = 1; i < 3; i++) {
11811183
extern void offload_connect_online_server(int idx);
11821184
offload_connect_online_server(i);
1185+
1186+
fprintf(stderr, "Target long size = %d\n", sizeof(target_ulong));
11831187
}
11841188
}
11851189
if (offload_mode == 1)

linux-user/offload_client.c

Lines changed: 151 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define PREFETCH_LAUNCH_VALVE 4
1010
#define PREFETCH_LIFE 80
1111
#define PREFETCH_BEGIN_PAGE_COUNT 10
12+
#define ONLINE_SERVER 2
1213

1314
//#define _ATFILE_SOURCE
1415
#include "qemu/osdep.h"
@@ -103,8 +104,19 @@
103104
#include "uname.h"
104105
#include "qemu.h"
105106
#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;
106117
static void offload_send_mutex_verified(int);
107118

119+
static void offload_send_page_wakeup(int idx, target_ulong page_addr);
108120
static void offload_process_mutex_done(void);
109121
static void offload_send_syscall_result(int,abi_long,int);
110122
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
123135
uint32_t uaddr2, int val3, int idx, int thread_id);
124136
void offload_connect_online_server(int idx);
125137
int false_sharing_flag = 0;
138+
__thread char buf[TARGET_PAGE_SIZE * 2];
126139

127140
//int requestor_idx, target_ulong addr, int perm
128141
struct info
@@ -282,9 +295,8 @@ typedef struct PageMapDesc {
282295
int invalid_count; /* How many we should tell to invalidate */
283296
int cur_perm;
284297
req_node list_head; /* to record request list */
285-
int is_false_sharing;
298+
uint32_t flag;
286299
uint32_t shadow_page_addr;
287-
int is_shadow_page;
288300
} PageMapDesc;
289301

290302
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);
321333

322334
int offload_client_start(CPUArchState *the_env);
323335
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);
325337
static void offload_send_page_content(int idx, target_ulong guest_addr, uint32_t perm, char *content);
326338

327339
static void offload_client_send_cmpxchg_ack(target_ulong);
@@ -869,6 +881,26 @@ static inline void show_pmd_list(req_node *p)
869881
p = p->next;
870882
}
871883
}
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+
}
872904
static int process_pmd(uint32_t page_addr)
873905
{
874906
PageMapDesc *pmd = get_pmd(page_addr);
@@ -1103,42 +1135,84 @@ static void offload_process_mutex_request(void)
11031135
pthread_mutex_unlock(&g_cas_mutex);
11041136
}
11051137

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 */
11071164
uint32_t offload_client_process_false_sharing_page(uint32_t page_addr)
11081165
{
1166+
fprintf(stderr, "[offload_client_process_false_sharing_page]\t"
1167+
"page addr = %p\n",
1168+
page_addr);
11091169
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-
//}
11141170
/* 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,
11181175
64*PAGE_SIZE, PROT_READ|PROT_WRITE,
11191176
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);
11201181
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",
11281183
page_addr, shadow_page_addr);
1184+
memset(g2h(shadow_page_addr), 0, 64*PAGE_SIZE);
11291185
uint32_t step = PAGE_SIZE / 64;
11301186
uint32_t start = shadow_page_addr, o_start = page_addr;
11311187
for (int i = 0; i < 64; i++) {
11321188
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);
11361195
start += (step + PAGE_SIZE);
11371196
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
11391199
}
1200+
fprintf(stderr, "[offload_client_process_false_sharing_page]\tCopy done.\n");
1201+
11401202
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);
11421216
}
11431217

11441218
/* fetch page */
@@ -1151,36 +1225,44 @@ static void offload_process_page_request(void)
11511225
int perm = *(uint32_t *) p;
11521226
p += sizeof(uint32_t);
11531227

1228+
PageMapDesc *pmd = get_pmd(page_addr);
11541229
/*uint32_t got_flag = *(uint32_t *)p;
11551230
p += sizeof(uint32_t);*/
11561231
fprintf(stderr, "[offload_process_page_request client#%d]\trequested address: %x, perm: %d\n", offload_client_idx, page_addr, perm);
11571232
fprintf(log, "%d\t%p\t%d\n", offload_client_idx, page_addr, perm);
11581233
/* Check if already in prefetch list */
11591234
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+
}
11641240
offload_client_fetch_page(offload_client_idx, page_addr, perm);
11651241
if (isInPrefetch < 0)
11661242
{
11671243
fprintf(stderr, "[offload_process_page_request client#%d]\tIn list, prefetch stops\n", offload_client_idx);
11681244
return;
11691245
}
11701246
else {
1171-
11721247
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. */
11761249
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);
11811263
//exit(3);
11821264
}
1183-
if (prefetch_count > 0 && perm == 2) {
1265+
else if (prefetch_count > 0 && perm != 2) {
11841266
fprintf(stderr, "[offload_process_page_request client#%d]\tPrefetching for next %d pages\n", offload_client_idx, prefetch_count);
11851267
for (int i = 0; i < prefetch_count; i++) {
11861268
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)
19081990
}
19091991

19101992

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+
*/
19112000
static void offload_send_page_request(int idx, target_ulong page_addr, uint32_t perm, int forwho)
19122001
{
1913-
1914-
//pthread_mutex_lock(&socket_mutex);
19152002
p = BUFFER_PAYLOAD_P;
19162003

19172004
*((target_ulong *) p) = page_addr;
19182005
p += sizeof(target_ulong);
1919-
19202006
*((uint32_t *) p) = perm;
19212007
p += sizeof(uint32_t);
1922-
19232008
*((int*) p) = offload_client_idx;
19242009
p += sizeof(int);
19252010
*((int*) p) = forwho;
@@ -1942,12 +2027,35 @@ static void offload_send_page_request(int idx, target_ulong page_addr, uint32_t
19422027
fprintf(stderr, "[offload_send_page_request]\tsent page %x request to node# %d, perm: %d, packet#%d\n", page_addr, idx, perm, get_number());
19432028
//pthread_mutex_unlock(&socket_mutex);
19442029
}
1945-
__thread char buf[TARGET_PAGE_SIZE * 2];
19462030

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+
}
19472041
static void offload_send_page_content(int idx, target_ulong page_addr, uint32_t perm, char *content)
19482042
{
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+
}
19512059
char *pp = buf + sizeof(struct tcp_msg_header);
19522060
//fprintf(stderr, "[offload_send_page_content]\tp: %p, net_buffer: %p\n", p, net_buffer);
19532061
*((target_ulong *) pp) = page_addr;
@@ -1965,7 +2073,6 @@ static void offload_send_page_content(int idx, target_ulong page_addr, uint32_t
19652073
autoSend(idx, buf, pp - buf, 0);
19662074

19672075
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);
19692076
}
19702077

19712078
// get the imformation of mutex-done sender and remove it from MutexList

linux-user/offload_common.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ enum
7171
TAG_OFFLOAD_SYSCALL_REQ,
7272
TAG_OFFLOAD_SYSCALL_RES,
7373
TAG_OFFLOAD_YOUR_TID,
74-
TAG_OFFLOAD_FORK_INFO
74+
TAG_OFFLOAD_FORK_INFO,
75+
TAG_OFFLOAD_PAGE_WAKEUP,
76+
TAG_OFFLOAD_FS_PAGE
7577

7678
};
7779

7880

7981
extern void offload_log(FILE*, const char*, ...);
8082

83+
extern pthread_mutex_t master_mprotect_mutex;
8184
extern __thread int offload_mode;
8285

8386
static uint32_t get_tag(void);

0 commit comments

Comments
 (0)