From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_2 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34B34C433E0 for ; Tue, 19 Jan 2021 04:21:54 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 763B520773 for ; Tue, 19 Jan 2021 04:21:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 763B520773 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kingsoft.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 9F4108D002D; Mon, 18 Jan 2021 23:21:52 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 989508D002C; Mon, 18 Jan 2021 23:21:52 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8A04C8D002D; Mon, 18 Jan 2021 23:21:52 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0042.hostedemail.com [216.40.44.42]) by kanga.kvack.org (Postfix) with ESMTP id 73F3D8D002C for ; Mon, 18 Jan 2021 23:21:52 -0500 (EST) Received: from smtpin14.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id 397941EE6 for ; Tue, 19 Jan 2021 04:21:52 +0000 (UTC) X-FDA: 77721226464.14.pets20_63010ac2754f Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin14.hostedemail.com (Postfix) with ESMTP id 1D2091822989D for ; Tue, 19 Jan 2021 04:21:52 +0000 (UTC) X-HE-Tag: pets20_63010ac2754f X-Filterd-Recvd-Size: 11728 Received: from mail.kingsoft.com (mail.kingsoft.com [114.255.44.145]) by imf43.hostedemail.com (Postfix) with ESMTP for ; Tue, 19 Jan 2021 04:21:50 +0000 (UTC) X-AuditID: 0a580155-713ff700000550c6-e6-6006586d1423 Received: from mail.kingsoft.com (localhost [10.88.1.32]) (using TLS with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.kingsoft.com (SMG-2-NODE-85) with SMTP id D3.2B.20678.D6856006; Tue, 19 Jan 2021 11:56:29 +0800 (HKT) Received: from aili-OptiPlex-7020 (172.16.253.254) by KSBJMAIL2.kingsoft.cn (10.88.1.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Tue, 19 Jan 2021 12:21:42 +0800 Date: Tue, 19 Jan 2021 12:21:42 +0800 From: Aili Yao To: "HORIGUCHI =?UTF-8?B?TkFPWUE=?=(=?UTF-8?B?5aCA5Y+j44CA55u05Lmf?=)" CC: Oscar Salvador , "linux-mm@kvack.org" , "yangfeng1@kingsoft.com" Subject: Re: [PATCH] mm,hwpoison: non-current task should be checked early_kill for force_early Message-ID: <20210119122142.4bf57852.yaoaili@kingsoft.com> In-Reply-To: <20210118085747.GA904@hori.linux.bs1.fc.nec.co.jp> References: <20210115155506.2d59fe83.yaoaili@kingsoft.com> <20210115084920.GA4092@linux> <20210115172622.699d68e5.yaoaili@kingsoft.com> <20210118051555.GA3585@hori.linux.bs1.fc.nec.co.jp> <20210118135744.7413cd06.yaoaili@kingsoft.com> <20210118065054.GA7447@hori.linux.bs1.fc.nec.co.jp> <20210118161512.701c94e7.yaoaili@kingsoft.com> <20210118085747.GA904@hori.linux.bs1.fc.nec.co.jp> Organization: Kingsoft X-Mailer: Claws Mail 3.17.5 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/8Ps9JRwBfppdWfY9o912BT/" X-Originating-IP: [172.16.253.254] X-ClientProxiedBy: KSBJMAIL1.kingsoft.cn (10.88.1.31) To KSBJMAIL2.kingsoft.cn (10.88.1.32) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrPLMWRmVeSWpSXmKPExsXCFcGooJsbwZZgcPMFr8W9Nf9ZLS42HmC0 ODOtyIHZY9OnSeweL65uZPHYfLo6gDmKyyYlNSezLLVI3y6BK2PqpHbWgmPOFY23vrM2MD41 6WLk5JAQMJGY3dvK0sXIxSEkMJ1J4sqHCcwQzgtGifP/FjKCVLEIqEp03rrMBmKzAdm77s1i BbFFBJIkFs/+ygTSwCzQxihxZcdHJpCEsECixPFJ+8AaeAWsJBovLGQBsTkF7CWub/7OBLGh j1li4+k+oCIODn4BMYlXDcYQJ9lLPP97lhmiV1Di5MwnYL3MAq4S0y49AlssJKAocXjJL3aI eiWJI90z2CDsWIll816xTmAUmoWkfRaSdghbU6J1+292CFtbYtnC18yzgK5gFpCWWP6PAyIM ZM66CFUiL7H97RxmCNtN4taxG2wLGDlWMbIU56YbbWKExEvoDsYZTR/1DjEycTAeYlQBqny0 YfUFRimWvPy8VCUR3tJ1TAlCvCmJlVWpRfnxRaU5qcWHGKU5WJTEeVuc2BKEBNITS1KzU1ML UotgskwcnFINTNUP9lYevqxTof/6duebtpnRPp6/l33MN2s2/Lk2PC4vvGDzjdU99zr7Oidy b0gS23PSQtH4/qVFO3r1/00V7ji49YyZg1Lp2UUcRy4dbonSW/Xz5C5hg0eK0g1HYh/md+bJ 5L7uzDgnFe9w/dG+Gkn7l6VGF/YYnOi5cmIle6TJVmdty6XL6sttGY+sid635dmWOYcrEpZP 8dkbWWXp79WUHM3gYMLpt6Dq5IElB0qvH5qr/4//psjNzwk27nFyaw91RO2W/cLRuWL704Wt l5t+nFxs1nZx+w155c9rhQpZJqvlTC/dvGoRj0586vVzb7j+l35kZefsmOPZfJLPIvBbS6Q1 y2K74KOm0rNeciqxFGckGmoxFxUnAgBh2E69EgMAAA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: --MP_/8Ps9JRwBfppdWfY9o912BT/ Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Mon, 18 Jan 2021 08:57:47 +0000 HORIGUCHI NAOYA(=E5=A0=80=E5=8F=A3=E3=80=80=E7=9B=B4=E4=B9=9F) wrote: > On Mon, Jan 18, 2021 at 04:15:12PM +0800, Aili Yao wrote: > > On Mon, 18 Jan 2021 06:50:54 +0000 > > HORIGUCHI NAOYA(=E5=A0=80=E5=8F=A3=E3=80=80=E7=9B=B4=E4=B9=9F) wrote: > > =20 > > >=20 > > > For action optional cases, one error event kills *only one* process. = If an > > > error page are shared by multiple processes, these processes will be = killed > > > by separate error events, each of which is triggered when each proces= s tries > > > to access the error memory. So these processes would be killed immed= iately > > > when accessing the error, but you don't have to kill all at the same = time > > > (or actually you might not even have to kill it at all if the process= exits > > > finally without accessing the error later). > > >=20 > > > Maybe the function variable "force_early" is named confusingly (it so= unds > > > that it's related to PF_MCE_KILL_EARLY flag, but that's incorrect). > > > I'll submit a fix later. (I'll add your "Reported-by" because you ma= de me > > > find it, thank you.) > > > =20 > > I think we should do more for non current process error case, we should= mark it AO for processes to be signaled > > or we may take wrong action. =20 >=20 > I'm not sure what you mean by "non current process error case" and "we > should mark it AO", so could you explain more specifically about your err= or > scenario? Especially I'd like to know about who triggers hard offline on > what hardware events and what "wrong action" could happen. Maybe just > "calling memory_failure() with MF_ACTION_REQUIRED" is not enough, because > it's not enough for us to see that your scenario is possible. Current > implementation implicitly assumes some hardware behavior, and does not wo= rk > for the case which never happens under the assumption. >=20 > Do you have some test cases to reproduce any specific issue (like data lo= st) > on your system? (If yes, please share it.) Or your concern is from code r= eview? Hope this draft test code will be helpful, Thanks --=20 Best Regards! Aili Yao --MP_/8Ps9JRwBfppdWfY9o912BT/ Content-Type: text/x-c++src Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="multitprocess_test_share.c" #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char empty[1024*1024*2] = {1}; sigjmp_buf recover; /* * Set early/late kill mode for hwpoison memory corruption. * This influences when the process gets killed on a memory corruption. */ #define PR_MCE_KILL 33 # define PR_MCE_KILL_CLEAR 0 # define PR_MCE_KILL_SET 1 # define PR_MCE_KILL_LATE 0 # define PR_MCE_KILL_EARLY 1 # define PR_MCE_KILL_DEFAULT 2 #define PR_MCE_KILL_GET 34 sem_t sem_id; sem_t sem_id_triggrer; int global_fd = -1; int * main_addr = NULL; #define PAGE_SHIFT 21 #define PAGEMAP_LENGTH 8 #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) struct thread_info { /* Used as argument to thread_start() */ pthread_t thread_id; /* ID returned by pthread_create() */ int thread_num; /* Application-defined thread # */ char *argv_string; /* From command-line argument */ }; unsigned long get_page_frame_number_of_address(void *addr) { // Open the pagemap file for the current process FILE *pagemap = fopen("/proc/self/pagemap", "rb"); // Seek to the page that the buffer is on unsigned long offset = (unsigned long)addr / getpagesize() * PAGEMAP_LENGTH; if(fseek(pagemap, (unsigned long)offset, SEEK_SET) != 0) { fprintf(stderr, "Failed to seek pagemap to proper location\n"); exit(1); } // The page frame number is in bits 0-54 so read the first 7 bytes and clear the 55th bit unsigned long page_frame_number = 0; fread(&page_frame_number, 1, PAGEMAP_LENGTH-1, pagemap); page_frame_number &= 0x7FFFFFFFFFFFFF; fclose(pagemap); return page_frame_number; } void sighandler(int sig, siginfo_t *si, void *arg) { printf("signal %d code %d addr %p\n", sig, si->si_code, si->si_addr); siglongjmp(recover, 1); } void *alloc_filebacked_page(char *filepath, int private, int *fd) { int i, sum,mapflag = MAP_SHARED; int *addr; if(*fd == -1){ if ((*fd = open(filepath, O_RDWR|O_CREAT, 0644)) < 0) { perror("open"); return NULL; } } if(private) write(*fd, empty, sizeof(empty)); if ((addr = mmap(0, getpagesize(),PROT_READ|PROT_WRITE, mapflag, *fd, 0)) == MAP_FAILED) { perror("mmap"); return NULL; } for (i = 0; i < getpagesize()/4; i = i + 4) { sum = addr[i]; } return addr; } void *alloc_anony_page(void) { int i; void *addr; if ((addr = mmap(0, getpagesize(),PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, 0, 0)) == MAP_FAILED) { perror("mmap"); //unlink(filepath); return NULL; } memcpy(addr, empty, 4096); return addr; } struct sigaction sa = { .sa_sigaction = sighandler, .sa_flags = SA_SIGINFO }; static void * thread_start(void *arg) { struct thread_info *tinfo = arg; char *uargv; char filepath[32] = {0}; int i,sum,fd = -1; int *addr = main_addr; unsigned int page_frame_number; pid_t pid = getpid(); pid_t ppid = getppid(); char file_name[20] ={0}; printf("Thread %d %d; argv_string=%s\n",pid, ppid , tinfo->argv_string); uargv = strdup(tinfo->argv_string); if (uargv == NULL) handle_error("strdup"); if(!strcmp(uargv,"test")) { printf("test : Page frame: 0x%x \n",addr); while(1) { for (i = 0; i < getpagesize()/4; i+=4) { sum = ((volatile int *)addr)[i]; ((volatile int *)addr)[i] = i; } usleep(5000); } }else{ printf("%s Page frame: 0x%x \n", uargv, addr); sigaction(SIGBUS, &sa, NULL); if(sigsetjmp(recover,1)){ exit; } while(1) sleep(1); } return uargv; } int main(int argc, char *argv[]) { int i,s, opt, num_threads; size_t stack_size; void *res; int main_fd = -1; unsigned int main_page_frame_number; pid_t pid,ppid; cpu_set_t mask; CPU_ZERO(&mask); /* The "-s" option specifies a stack size for our threads */ stack_size = -1; while ((opt = getopt(argc, argv, "s:")) != -1) { switch (opt) { case 's': if (prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0, 0) < 0) err("PR_MCE_KILL_SET early"); break; default: fprintf(stderr, "Usage: %s [-s stack-size] arg...\n", argv[0]); exit(EXIT_FAILURE); } } num_threads = argc - optind; /* Allocate memory for pthread_create() arguments */ struct thread_info *tinfo = calloc(num_threads, sizeof(*tinfo)); if (tinfo == NULL) handle_error("calloc"); main_addr = alloc_filebacked_page("./main_test", 1, &global_fd); //main_addr = create_buffer(); pid = getpid(); ppid = getppid(); #if 1 #endif main_page_frame_number = get_page_frame_number_of_address((void *)(&(main_addr[0]))); printf("pid:%d ppid:%d Page frame: 0x%x 0x%x \n", pid,ppid, main_page_frame_number, (void *)(&(main_addr[0]))); for (int tnum = 0; tnum < num_threads; tnum++) { tinfo[tnum].thread_num = tnum + 1; tinfo[tnum].argv_string = argv[optind + tnum]; pid = fork(); if(pid<0) printf("error in fork!\n"); else if(pid == 0) { prctl(PR_SET_NAME, tinfo[tnum].argv_string); CPU_SET(tinfo[tnum].thread_num, &mask); if (sched_setaffinity(0, sizeof(mask), &mask) < 0) { return -1; } thread_start(&tinfo[tnum]); } else { //printf("I am the parent process,ID is %d\n",getpid()); } } while(1) sleep(1); free(tinfo); exit(EXIT_SUCCESS); } --MP_/8Ps9JRwBfppdWfY9o912BT/--