aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/mic/mpssd/mpssd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/mic/mpssd/mpssd.c')
-rw-r--r--Documentation/mic/mpssd/mpssd.c362
1 files changed, 230 insertions, 132 deletions
diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c
index 3c5c379fc29d..aaeafa18d99b 100644
--- a/Documentation/mic/mpssd/mpssd.c
+++ b/Documentation/mic/mpssd/mpssd.c
@@ -43,7 +43,7 @@
43#include <linux/mic_common.h> 43#include <linux/mic_common.h>
44#include <tools/endian.h> 44#include <tools/endian.h>
45 45
46static void init_mic(struct mic_info *mic); 46static void *init_mic(void *arg);
47 47
48static FILE *logfp; 48static FILE *logfp;
49static struct mic_info mic_list; 49static struct mic_info mic_list;
@@ -116,19 +116,18 @@ static struct {
116 .num = htole16(MIC_VRING_ENTRIES), 116 .num = htole16(MIC_VRING_ENTRIES),
117 }, 117 },
118#if GSO_ENABLED 118#if GSO_ENABLED
119 .host_features = htole32( 119 .host_features = htole32(
120 1 << VIRTIO_NET_F_CSUM | 120 1 << VIRTIO_NET_F_CSUM |
121 1 << VIRTIO_NET_F_GSO | 121 1 << VIRTIO_NET_F_GSO |
122 1 << VIRTIO_NET_F_GUEST_TSO4 | 122 1 << VIRTIO_NET_F_GUEST_TSO4 |
123 1 << VIRTIO_NET_F_GUEST_TSO6 | 123 1 << VIRTIO_NET_F_GUEST_TSO6 |
124 1 << VIRTIO_NET_F_GUEST_ECN | 124 1 << VIRTIO_NET_F_GUEST_ECN),
125 1 << VIRTIO_NET_F_GUEST_UFO),
126#else 125#else
127 .host_features = 0, 126 .host_features = 0,
128#endif 127#endif
129}; 128};
130 129
131static const char *mic_config_dir = "/etc/sysconfig/mic"; 130static const char *mic_config_dir = "/etc/mpss";
132static const char *virtblk_backend = "VIRTBLK_BACKEND"; 131static const char *virtblk_backend = "VIRTBLK_BACKEND";
133static struct { 132static struct {
134 struct mic_device_desc dd; 133 struct mic_device_desc dd;
@@ -192,7 +191,7 @@ tap_configure(struct mic_info *mic, char *dev)
192 return ret; 191 return ret;
193 } 192 }
194 193
195 snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id); 194 snprintf(ipaddr, IFNAMSIZ, "172.31.%d.254/24", mic->id + 1);
196 195
197 pid = fork(); 196 pid = fork();
198 if (pid == 0) { 197 if (pid == 0) {
@@ -255,8 +254,7 @@ static int tun_alloc(struct mic_info *mic, char *dev)
255 return err; 254 return err;
256 } 255 }
257#if GSO_ENABLED 256#if GSO_ENABLED
258 offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | 257 offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN;
259 TUN_F_TSO_ECN | TUN_F_UFO;
260 258
261 err = ioctl(fd, TUNSETOFFLOAD, offload); 259 err = ioctl(fd, TUNSETOFFLOAD, offload);
262 if (err < 0) { 260 if (err < 0) {
@@ -332,7 +330,6 @@ static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
332 return d; 330 return d;
333 } 331 }
334 mpsslog("%s %s %d not found\n", mic->name, __func__, type); 332 mpsslog("%s %s %d not found\n", mic->name, __func__, type);
335 assert(0);
336 return NULL; 333 return NULL;
337} 334}
338 335
@@ -415,6 +412,13 @@ mic_virtio_copy(struct mic_info *mic, int fd,
415 return ret; 412 return ret;
416} 413}
417 414
415static inline unsigned _vring_size(unsigned int num, unsigned long align)
416{
417 return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
418 + align - 1) & ~(align - 1))
419 + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
420}
421
418/* 422/*
419 * This initialization routine requires at least one 423 * This initialization routine requires at least one
420 * vring i.e. vr0. vr1 is optional. 424 * vring i.e. vr0. vr1 is optional.
@@ -426,8 +430,9 @@ init_vr(struct mic_info *mic, int fd, int type,
426 int vr_size; 430 int vr_size;
427 char *va; 431 char *va;
428 432
429 vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES, 433 vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
430 MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info)); 434 MIC_VIRTIO_RING_ALIGN) +
435 sizeof(struct _mic_vring_info));
431 va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq, 436 va = mmap(NULL, MIC_DEVICE_PAGE_END + vr_size * num_vq,
432 PROT_READ, MAP_SHARED, fd, 0); 437 PROT_READ, MAP_SHARED, fd, 0);
433 if (MAP_FAILED == va) { 438 if (MAP_FAILED == va) {
@@ -439,25 +444,25 @@ init_vr(struct mic_info *mic, int fd, int type,
439 set_dp(mic, type, va); 444 set_dp(mic, type, va);
440 vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END]; 445 vr0->va = (struct mic_vring *)&va[MIC_DEVICE_PAGE_END];
441 vr0->info = vr0->va + 446 vr0->info = vr0->va +
442 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN); 447 _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN);
443 vring_init(&vr0->vr, 448 vring_init(&vr0->vr,
444 MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN); 449 MIC_VRING_ENTRIES, vr0->va, MIC_VIRTIO_RING_ALIGN);
445 mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ", 450 mpsslog("%s %s vr0 %p vr0->info %p vr_size 0x%x vring 0x%x ",
446 __func__, mic->name, vr0->va, vr0->info, vr_size, 451 __func__, mic->name, vr0->va, vr0->info, vr_size,
447 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN)); 452 _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
448 mpsslog("magic 0x%x expected 0x%x\n", 453 mpsslog("magic 0x%x expected 0x%x\n",
449 le32toh(vr0->info->magic), MIC_MAGIC + type); 454 le32toh(vr0->info->magic), MIC_MAGIC + type);
450 assert(le32toh(vr0->info->magic) == MIC_MAGIC + type); 455 assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
451 if (vr1) { 456 if (vr1) {
452 vr1->va = (struct mic_vring *) 457 vr1->va = (struct mic_vring *)
453 &va[MIC_DEVICE_PAGE_END + vr_size]; 458 &va[MIC_DEVICE_PAGE_END + vr_size];
454 vr1->info = vr1->va + vring_size(MIC_VRING_ENTRIES, 459 vr1->info = vr1->va + _vring_size(MIC_VRING_ENTRIES,
455 MIC_VIRTIO_RING_ALIGN); 460 MIC_VIRTIO_RING_ALIGN);
456 vring_init(&vr1->vr, 461 vring_init(&vr1->vr,
457 MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN); 462 MIC_VRING_ENTRIES, vr1->va, MIC_VIRTIO_RING_ALIGN);
458 mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ", 463 mpsslog("%s %s vr1 %p vr1->info %p vr_size 0x%x vring 0x%x ",
459 __func__, mic->name, vr1->va, vr1->info, vr_size, 464 __func__, mic->name, vr1->va, vr1->info, vr_size,
460 vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN)); 465 _vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
461 mpsslog("magic 0x%x expected 0x%x\n", 466 mpsslog("magic 0x%x expected 0x%x\n",
462 le32toh(vr1->info->magic), MIC_MAGIC + type + 1); 467 le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
463 assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1); 468 assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
@@ -466,16 +471,21 @@ done:
466 return va; 471 return va;
467} 472}
468 473
469static void 474static int
470wait_for_card_driver(struct mic_info *mic, int fd, int type) 475wait_for_card_driver(struct mic_info *mic, int fd, int type)
471{ 476{
472 struct pollfd pollfd; 477 struct pollfd pollfd;
473 int err; 478 int err;
474 struct mic_device_desc *desc = get_device_desc(mic, type); 479 struct mic_device_desc *desc = get_device_desc(mic, type);
480 __u8 prev_status;
475 481
482 if (!desc)
483 return -ENODEV;
484 prev_status = desc->status;
476 pollfd.fd = fd; 485 pollfd.fd = fd;
477 mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n", 486 mpsslog("%s %s Waiting .... desc-> type %d status 0x%x\n",
478 mic->name, __func__, type, desc->status); 487 mic->name, __func__, type, desc->status);
488
479 while (1) { 489 while (1) {
480 pollfd.events = POLLIN; 490 pollfd.events = POLLIN;
481 pollfd.revents = 0; 491 pollfd.revents = 0;
@@ -487,8 +497,13 @@ wait_for_card_driver(struct mic_info *mic, int fd, int type)
487 } 497 }
488 498
489 if (pollfd.revents) { 499 if (pollfd.revents) {
490 mpsslog("%s %s Waiting... desc-> type %d status 0x%x\n", 500 if (desc->status != prev_status) {
491 mic->name, __func__, type, desc->status); 501 mpsslog("%s %s Waiting... desc-> type %d "
502 "status 0x%x\n",
503 mic->name, __func__, type,
504 desc->status);
505 prev_status = desc->status;
506 }
492 if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { 507 if (desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
493 mpsslog("%s %s poll.revents %d\n", 508 mpsslog("%s %s poll.revents %d\n",
494 mic->name, __func__, pollfd.revents); 509 mic->name, __func__, pollfd.revents);
@@ -499,6 +514,7 @@ wait_for_card_driver(struct mic_info *mic, int fd, int type)
499 } 514 }
500 } 515 }
501 } 516 }
517 return 0;
502} 518}
503 519
504/* Spin till we have some descriptors */ 520/* Spin till we have some descriptors */
@@ -575,9 +591,16 @@ virtio_net(void *arg)
575 __func__, strerror(errno)); 591 __func__, strerror(errno));
576 continue; 592 continue;
577 } 593 }
578 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) 594 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
579 wait_for_card_driver(mic, mic->mic_net.virtio_net_fd, 595 err = wait_for_card_driver(mic,
580 VIRTIO_ID_NET); 596 mic->mic_net.virtio_net_fd,
597 VIRTIO_ID_NET);
598 if (err) {
599 mpsslog("%s %s %d Exiting...\n",
600 mic->name, __func__, __LINE__);
601 break;
602 }
603 }
581 /* 604 /*
582 * Check if there is data to be read from TUN and write to 605 * Check if there is data to be read from TUN and write to
583 * virtio net fd if there is. 606 * virtio net fd if there is.
@@ -786,10 +809,16 @@ virtio_console(void *arg)
786 strerror(errno)); 809 strerror(errno));
787 continue; 810 continue;
788 } 811 }
789 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) 812 if (!(desc->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
790 wait_for_card_driver(mic, 813 err = wait_for_card_driver(mic,
791 mic->mic_console.virtio_console_fd, 814 mic->mic_console.virtio_console_fd,
792 VIRTIO_ID_CONSOLE); 815 VIRTIO_ID_CONSOLE);
816 if (err) {
817 mpsslog("%s %s %d Exiting...\n",
818 mic->name, __func__, __LINE__);
819 break;
820 }
821 }
793 822
794 if (console_poll[MONITOR_FD].revents & POLLIN) { 823 if (console_poll[MONITOR_FD].revents & POLLIN) {
795 copy.iov = iov0; 824 copy.iov = iov0;
@@ -1048,8 +1077,9 @@ stop_virtblk(struct mic_info *mic)
1048{ 1077{
1049 int vr_size, ret; 1078 int vr_size, ret;
1050 1079
1051 vr_size = PAGE_ALIGN(vring_size(MIC_VRING_ENTRIES, 1080 vr_size = PAGE_ALIGN(_vring_size(MIC_VRING_ENTRIES,
1052 MIC_VIRTIO_RING_ALIGN) + sizeof(struct _mic_vring_info)); 1081 MIC_VIRTIO_RING_ALIGN) +
1082 sizeof(struct _mic_vring_info));
1053 ret = munmap(mic->mic_virtblk.block_dp, 1083 ret = munmap(mic->mic_virtblk.block_dp,
1054 MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq); 1084 MIC_DEVICE_PAGE_END + vr_size * virtblk_dev_page.dd.num_vq);
1055 if (ret < 0) 1085 if (ret < 0)
@@ -1131,6 +1161,10 @@ write_status(int fd, __u8 *status)
1131 return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy); 1161 return ioctl(fd, MIC_VIRTIO_COPY_DESC, &copy);
1132} 1162}
1133 1163
1164#ifndef VIRTIO_BLK_T_GET_ID
1165#define VIRTIO_BLK_T_GET_ID 8
1166#endif
1167
1134static void * 1168static void *
1135virtio_block(void *arg) 1169virtio_block(void *arg)
1136{ 1170{
@@ -1297,12 +1331,7 @@ reset(struct mic_info *mic)
1297 mpsslog("%s: %s %d state %s\n", 1331 mpsslog("%s: %s %d state %s\n",
1298 mic->name, __func__, __LINE__, state); 1332 mic->name, __func__, __LINE__, state);
1299 1333
1300 /* 1334 if (!strcmp(state, "ready")) {
1301 * If the shutdown was initiated by OSPM, the state stays
1302 * in "suspended" which is also a valid condition for reset.
1303 */
1304 if ((!strcmp(state, "offline")) ||
1305 (!strcmp(state, "suspended"))) {
1306 free(state); 1335 free(state);
1307 break; 1336 break;
1308 } 1337 }
@@ -1331,34 +1360,50 @@ get_mic_shutdown_status(struct mic_info *mic, char *shutdown_status)
1331 assert(0); 1360 assert(0);
1332}; 1361};
1333 1362
1334static int get_mic_state(struct mic_info *mic, char *state) 1363static int get_mic_state(struct mic_info *mic)
1335{ 1364{
1336 if (!strcmp(state, "offline")) 1365 char *state = NULL;
1337 return MIC_OFFLINE; 1366 enum mic_states mic_state;
1338 if (!strcmp(state, "online")) 1367
1339 return MIC_ONLINE; 1368 while (!state) {
1340 if (!strcmp(state, "shutting_down")) 1369 state = readsysfs(mic->name, "state");
1341 return MIC_SHUTTING_DOWN; 1370 sleep(1);
1342 if (!strcmp(state, "reset_failed")) 1371 }
1343 return MIC_RESET_FAILED; 1372 mpsslog("%s: %s %d state %s\n",
1344 if (!strcmp(state, "suspending")) 1373 mic->name, __func__, __LINE__, state);
1345 return MIC_SUSPENDING; 1374
1346 if (!strcmp(state, "suspended")) 1375 if (!strcmp(state, "ready")) {
1347 return MIC_SUSPENDED; 1376 mic_state = MIC_READY;
1348 mpsslog("%s: BUG invalid state %s\n", mic->name, state); 1377 } else if (!strcmp(state, "booting")) {
1349 /* Invalid state */ 1378 mic_state = MIC_BOOTING;
1350 assert(0); 1379 } else if (!strcmp(state, "online")) {
1380 mic_state = MIC_ONLINE;
1381 } else if (!strcmp(state, "shutting_down")) {
1382 mic_state = MIC_SHUTTING_DOWN;
1383 } else if (!strcmp(state, "reset_failed")) {
1384 mic_state = MIC_RESET_FAILED;
1385 } else if (!strcmp(state, "resetting")) {
1386 mic_state = MIC_RESETTING;
1387 } else {
1388 mpsslog("%s: BUG invalid state %s\n", mic->name, state);
1389 assert(0);
1390 }
1391
1392 free(state);
1393 return mic_state;
1351}; 1394};
1352 1395
1353static void mic_handle_shutdown(struct mic_info *mic) 1396static void mic_handle_shutdown(struct mic_info *mic)
1354{ 1397{
1355#define SHUTDOWN_TIMEOUT 60 1398#define SHUTDOWN_TIMEOUT 60
1356 int i = SHUTDOWN_TIMEOUT, ret, stat = 0; 1399 int i = SHUTDOWN_TIMEOUT;
1357 char *shutdown_status; 1400 char *shutdown_status;
1358 while (i) { 1401 while (i) {
1359 shutdown_status = readsysfs(mic->name, "shutdown_status"); 1402 shutdown_status = readsysfs(mic->name, "shutdown_status");
1360 if (!shutdown_status) 1403 if (!shutdown_status) {
1404 sleep(1);
1361 continue; 1405 continue;
1406 }
1362 mpsslog("%s: %s %d shutdown_status %s\n", 1407 mpsslog("%s: %s %d shutdown_status %s\n",
1363 mic->name, __func__, __LINE__, shutdown_status); 1408 mic->name, __func__, __LINE__, shutdown_status);
1364 switch (get_mic_shutdown_status(mic, shutdown_status)) { 1409 switch (get_mic_shutdown_status(mic, shutdown_status)) {
@@ -1377,94 +1422,110 @@ static void mic_handle_shutdown(struct mic_info *mic)
1377 i--; 1422 i--;
1378 } 1423 }
1379reset: 1424reset:
1380 ret = kill(mic->pid, SIGTERM); 1425 if (!i)
1381 mpsslog("%s: %s %d kill pid %d ret %d\n", 1426 mpsslog("%s: %s %d timing out waiting for shutdown_status %s\n",
1382 mic->name, __func__, __LINE__, 1427 mic->name, __func__, __LINE__, shutdown_status);
1383 mic->pid, ret); 1428 reset(mic);
1384 if (!ret) {
1385 ret = waitpid(mic->pid, &stat,
1386 WIFSIGNALED(stat));
1387 mpsslog("%s: %s %d waitpid ret %d pid %d\n",
1388 mic->name, __func__, __LINE__,
1389 ret, mic->pid);
1390 }
1391 if (ret == mic->pid)
1392 reset(mic);
1393} 1429}
1394 1430
1395static void * 1431static int open_state_fd(struct mic_info *mic)
1396mic_config(void *arg)
1397{ 1432{
1398 struct mic_info *mic = (struct mic_info *)arg;
1399 char *state = NULL;
1400 char pathname[PATH_MAX]; 1433 char pathname[PATH_MAX];
1401 int fd, ret; 1434 int fd;
1402 struct pollfd ufds[1];
1403 char value[4096];
1404 1435
1405 snprintf(pathname, PATH_MAX - 1, "%s/%s/%s", 1436 snprintf(pathname, PATH_MAX - 1, "%s/%s/%s",
1406 MICSYSFSDIR, mic->name, "state"); 1437 MICSYSFSDIR, mic->name, "state");
1407 1438
1408 fd = open(pathname, O_RDONLY); 1439 fd = open(pathname, O_RDONLY);
1409 if (fd < 0) { 1440 if (fd < 0)
1410 mpsslog("%s: opening file %s failed %s\n", 1441 mpsslog("%s: opening file %s failed %s\n",
1411 mic->name, pathname, strerror(errno)); 1442 mic->name, pathname, strerror(errno));
1412 goto error; 1443 return fd;
1444}
1445
1446static int block_till_state_change(int fd, struct mic_info *mic)
1447{
1448 struct pollfd ufds[1];
1449 char value[PAGE_SIZE];
1450 int ret;
1451
1452 ufds[0].fd = fd;
1453 ufds[0].events = POLLERR | POLLPRI;
1454 ret = poll(ufds, 1, -1);
1455 if (ret < 0) {
1456 mpsslog("%s: %s %d poll failed %s\n",
1457 mic->name, __func__, __LINE__, strerror(errno));
1458 return ret;
1459 }
1460
1461 ret = lseek(fd, 0, SEEK_SET);
1462 if (ret < 0) {
1463 mpsslog("%s: %s %d Failed to seek to 0: %s\n",
1464 mic->name, __func__, __LINE__, strerror(errno));
1465 return ret;
1466 }
1467
1468 ret = read(fd, value, sizeof(value));
1469 if (ret < 0) {
1470 mpsslog("%s: %s %d Failed to read sysfs entry: %s\n",
1471 mic->name, __func__, __LINE__, strerror(errno));
1472 return ret;
1473 }
1474
1475 return 0;
1476}
1477
1478static void *
1479mic_config(void *arg)
1480{
1481 struct mic_info *mic = (struct mic_info *)arg;
1482 int fd, ret, stat = 0;
1483
1484 fd = open_state_fd(mic);
1485 if (fd < 0) {
1486 mpsslog("%s: %s %d open state fd failed %s\n",
1487 mic->name, __func__, __LINE__, strerror(errno));
1488 goto exit;
1413 } 1489 }
1414 1490
1415 do { 1491 do {
1416 ret = lseek(fd, 0, SEEK_SET); 1492 ret = block_till_state_change(fd, mic);
1417 if (ret < 0) { 1493 if (ret < 0) {
1418 mpsslog("%s: Failed to seek to file start '%s': %s\n", 1494 mpsslog("%s: %s %d block_till_state_change error %s\n",
1419 mic->name, pathname, strerror(errno)); 1495 mic->name, __func__, __LINE__, strerror(errno));
1420 goto close_error1; 1496 goto close_exit;
1421 } 1497 }
1422 ret = read(fd, value, sizeof(value)); 1498
1423 if (ret < 0) { 1499 switch (get_mic_state(mic)) {
1424 mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
1425 mic->name, pathname, strerror(errno));
1426 goto close_error1;
1427 }
1428retry:
1429 state = readsysfs(mic->name, "state");
1430 if (!state)
1431 goto retry;
1432 mpsslog("%s: %s %d state %s\n",
1433 mic->name, __func__, __LINE__, state);
1434 switch (get_mic_state(mic, state)) {
1435 case MIC_SHUTTING_DOWN: 1500 case MIC_SHUTTING_DOWN:
1436 mic_handle_shutdown(mic); 1501 mic_handle_shutdown(mic);
1437 goto close_error; 1502 break;
1438 case MIC_SUSPENDING: 1503 case MIC_READY:
1439 mic->boot_on_resume = 1; 1504 case MIC_RESET_FAILED:
1440 setsysfs(mic->name, "state", "suspend"); 1505 ret = kill(mic->pid, SIGTERM);
1441 mic_handle_shutdown(mic); 1506 mpsslog("%s: %s %d kill pid %d ret %d\n",
1442 goto close_error; 1507 mic->name, __func__, __LINE__,
1443 case MIC_OFFLINE: 1508 mic->pid, ret);
1509 if (!ret) {
1510 ret = waitpid(mic->pid, &stat,
1511 WIFSIGNALED(stat));
1512 mpsslog("%s: %s %d waitpid ret %d pid %d\n",
1513 mic->name, __func__, __LINE__,
1514 ret, mic->pid);
1515 }
1444 if (mic->boot_on_resume) { 1516 if (mic->boot_on_resume) {
1445 setsysfs(mic->name, "state", "boot"); 1517 setsysfs(mic->name, "state", "boot");
1446 mic->boot_on_resume = 0; 1518 mic->boot_on_resume = 0;
1447 } 1519 }
1448 break; 1520 goto close_exit;
1449 default: 1521 default:
1450 break; 1522 break;
1451 } 1523 }
1452 free(state);
1453
1454 ufds[0].fd = fd;
1455 ufds[0].events = POLLERR | POLLPRI;
1456 ret = poll(ufds, 1, -1);
1457 if (ret < 0) {
1458 mpsslog("%s: poll failed %s\n",
1459 mic->name, strerror(errno));
1460 goto close_error1;
1461 }
1462 } while (1); 1524 } while (1);
1463close_error: 1525
1464 free(state); 1526close_exit:
1465close_error1:
1466 close(fd); 1527 close(fd);
1467error: 1528exit:
1468 init_mic(mic); 1529 init_mic(mic);
1469 pthread_exit(NULL); 1530 pthread_exit(NULL);
1470} 1531}
@@ -1477,15 +1538,15 @@ set_cmdline(struct mic_info *mic)
1477 1538
1478 len = snprintf(buffer, PATH_MAX, 1539 len = snprintf(buffer, PATH_MAX,
1479 "clocksource=tsc highres=off nohz=off "); 1540 "clocksource=tsc highres=off nohz=off ");
1480 len += snprintf(buffer + len, PATH_MAX - len, 1541 len += snprintf(buffer + len, PATH_MAX,
1481 "cpufreq_on;corec6_off;pc3_off;pc6_off "); 1542 "cpufreq_on;corec6_off;pc3_off;pc6_off ");
1482 len += snprintf(buffer + len, PATH_MAX - len, 1543 len += snprintf(buffer + len, PATH_MAX,
1483 "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0", 1544 "ifcfg=static;address,172.31.%d.1;netmask,255.255.255.0",
1484 mic->id); 1545 mic->id + 1);
1485 1546
1486 setsysfs(mic->name, "cmdline", buffer); 1547 setsysfs(mic->name, "cmdline", buffer);
1487 mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer); 1548 mpsslog("%s: Command line: \"%s\"\n", mic->name, buffer);
1488 snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id); 1549 snprintf(buffer, PATH_MAX, "172.31.%d.1", mic->id + 1);
1489 mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer); 1550 mpsslog("%s: IPADDR: \"%s\"\n", mic->name, buffer);
1490} 1551}
1491 1552
@@ -1541,8 +1602,6 @@ set_log_buf_info(struct mic_info *mic)
1541 close(fd); 1602 close(fd);
1542} 1603}
1543 1604
1544static void init_mic(struct mic_info *mic);
1545
1546static void 1605static void
1547change_virtblk_backend(int x, siginfo_t *siginfo, void *p) 1606change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
1548{ 1607{
@@ -1553,8 +1612,16 @@ change_virtblk_backend(int x, siginfo_t *siginfo, void *p)
1553} 1612}
1554 1613
1555static void 1614static void
1556init_mic(struct mic_info *mic) 1615set_mic_boot_params(struct mic_info *mic)
1616{
1617 set_log_buf_info(mic);
1618 set_cmdline(mic);
1619}
1620
1621static void *
1622init_mic(void *arg)
1557{ 1623{
1624 struct mic_info *mic = (struct mic_info *)arg;
1558 struct sigaction ignore = { 1625 struct sigaction ignore = {
1559 .sa_flags = 0, 1626 .sa_flags = 0,
1560 .sa_handler = SIG_IGN 1627 .sa_handler = SIG_IGN
@@ -1564,7 +1631,7 @@ init_mic(struct mic_info *mic)
1564 .sa_sigaction = change_virtblk_backend, 1631 .sa_sigaction = change_virtblk_backend,
1565 }; 1632 };
1566 char buffer[PATH_MAX]; 1633 char buffer[PATH_MAX];
1567 int err; 1634 int err, fd;
1568 1635
1569 /* 1636 /*
1570 * Currently, one virtio block device is supported for each MIC card 1637 * Currently, one virtio block device is supported for each MIC card
@@ -1577,12 +1644,38 @@ init_mic(struct mic_info *mic)
1577 * the MIC daemon. 1644 * the MIC daemon.
1578 */ 1645 */
1579 sigaction(SIGUSR1, &ignore, NULL); 1646 sigaction(SIGUSR1, &ignore, NULL);
1647retry:
1648 fd = open_state_fd(mic);
1649 if (fd < 0) {
1650 mpsslog("%s: %s %d open state fd failed %s\n",
1651 mic->name, __func__, __LINE__, strerror(errno));
1652 sleep(2);
1653 goto retry;
1654 }
1655
1656 if (mic->restart) {
1657 snprintf(buffer, PATH_MAX, "boot");
1658 setsysfs(mic->name, "state", buffer);
1659 mpsslog("%s restarting mic %d\n",
1660 mic->name, mic->restart);
1661 mic->restart = 0;
1662 }
1663
1664 while (1) {
1665 while (block_till_state_change(fd, mic)) {
1666 mpsslog("%s: %s %d block_till_state_change error %s\n",
1667 mic->name, __func__, __LINE__, strerror(errno));
1668 sleep(2);
1669 continue;
1670 }
1671
1672 if (get_mic_state(mic) == MIC_BOOTING)
1673 break;
1674 }
1580 1675
1581 mic->pid = fork(); 1676 mic->pid = fork();
1582 switch (mic->pid) { 1677 switch (mic->pid) {
1583 case 0: 1678 case 0:
1584 set_log_buf_info(mic);
1585 set_cmdline(mic);
1586 add_virtio_device(mic, &virtcons_dev_page.dd); 1679 add_virtio_device(mic, &virtcons_dev_page.dd);
1587 add_virtio_device(mic, &virtnet_dev_page.dd); 1680 add_virtio_device(mic, &virtnet_dev_page.dd);
1588 err = pthread_create(&mic->mic_console.console_thread, NULL, 1681 err = pthread_create(&mic->mic_console.console_thread, NULL,
@@ -1612,24 +1705,29 @@ init_mic(struct mic_info *mic)
1612 mic->name, mic->id, errno); 1705 mic->name, mic->id, errno);
1613 break; 1706 break;
1614 default: 1707 default:
1615 if (mic->restart) { 1708 err = pthread_create(&mic->config_thread, NULL,
1616 snprintf(buffer, PATH_MAX, "boot"); 1709 mic_config, mic);
1617 setsysfs(mic->name, "state", buffer); 1710 if (err)
1618 mpsslog("%s restarting mic %d\n", 1711 mpsslog("%s mic_config pthread_create failed %s\n",
1619 mic->name, mic->restart); 1712 mic->name, strerror(err));
1620 mic->restart = 0;
1621 }
1622 pthread_create(&mic->config_thread, NULL, mic_config, mic);
1623 } 1713 }
1714
1715 return NULL;
1624} 1716}
1625 1717
1626static void 1718static void
1627start_daemon(void) 1719start_daemon(void)
1628{ 1720{
1629 struct mic_info *mic; 1721 struct mic_info *mic;
1722 int err;
1630 1723
1631 for (mic = mic_list.next; mic != NULL; mic = mic->next) 1724 for (mic = mic_list.next; mic; mic = mic->next) {
1632 init_mic(mic); 1725 set_mic_boot_params(mic);
1726 err = pthread_create(&mic->init_thread, NULL, init_mic, mic);
1727 if (err)
1728 mpsslog("%s init_mic pthread_create failed %s\n",
1729 mic->name, strerror(err));
1730 }
1633 1731
1634 while (1) 1732 while (1)
1635 sleep(60); 1733 sleep(60);