From nobody Mon Feb 9 19:25:36 2026 Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC8B9198823 for ; Mon, 27 Jan 2025 20:26:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.60.130.6 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738009603; cv=none; b=DCq4QTbqAI6y3bBuGozIS4A3JauHmndnzBUc4zTX+rsBvYyoChFt0Q7FtZ6sCwwlj8RdmO/XCkX1bl3KiCBAIAFThSpeZWC/tCRFGC3WhugFk9NBDV66I7d48+V/im4gaNV3xAasV0TS1VAVjr1CWWk4FwFrHGLdcIJJPHC3oPk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738009603; c=relaxed/simple; bh=eMu9+2Qy+RJ0Wlp44/qBO9wirZkBqchiEF8Z9iBxJws=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=a+iYquawImTdiwqaH5PF5857zfxM5PxKqxNmXN4VTWEofzQ5VW5oapoGNR5B9TKMxnpFZtQXYfBBdbfkjhu0YMEWnlRjD2zl/kyoLdrERyC/qfGFQJt0UXKWtJagz170ZUsu0FlZKXEf2HkNWQGBa9exUfXwnsAL7Myv66dpkvc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=Ky+BoE5N; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="Ky+BoE5N" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=1oXeneyG4G75W2wTS/Txrl+IdKcJEAcELA7vaVJtdJw=; b=Ky+BoE5NMTkfkLbFzK5uV0vUP7 QrkppVzko87JGnWJGiIEYzjK7G83w1BDCDOnjcQvrsKYn5NOeTtqrDH1IF0co+v4t6mwlhSwE+G8p CxYpG3a4tG0fQmJiWufFteDL5e1on9ENioS4j04q7Btx7bS6xmcsza+S5wSz2bZV0EIEdeyR2tJ4c gvMUxqGrJzHZGRdIUo6bBoI/LfpwvmkysICmQDo/byN+/fd0Nf1BnYikmAW1MwuX5SvzlJyBJuD7W si3KwvZEUU4kSZL8QkghJy6vNETdzh5Fi20xdOR5MLHeJ1II6mmrmBQ6yRCHZ6YwF6c/t9OLqzcGd BDPoyFDw==; Received: from 189-68-33-219.dsl.telesp.net.br ([189.68.33.219] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tcVgl-003OPi-4V; Mon, 27 Jan 2025 21:26:31 +0100 From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: Thomas Gleixner , Ingo Molnar , Peter Zijlstra , Darren Hart , Davidlohr Bueso , Arnd Bergmann , Florian Weimer Cc: linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Vinicius Peixoto , =?UTF-8?q?Andr=C3=A9=20Almeida?= Subject: [PATCH v2 4/4] selftests/futex: Create tests for long and circular robust lists Date: Mon, 27 Jan 2025 17:26:08 -0300 Message-ID: <20250127202608.223864-5-andrealmeid@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250127202608.223864-1-andrealmeid@igalia.com> References: <20250127202608.223864-1-andrealmeid@igalia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable After dropping ROBUST_LIST_LIMIT, create new robust list tests to ensure two conditions: - That the kernel can correctly handle circular lists - That the kernel can correctly wake up elements in very long lists, larger that the old ROBUST_LIST_LIMIT. Signed-off-by: Andr=C3=A9 Almeida --- .../selftests/futex/functional/robust_list.c | 127 +++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/futex/functional/robust_list.c b/tools= /testing/selftests/futex/functional/robust_list.c index bd4437c6aebb..4bd6795b3ac5 100644 --- a/tools/testing/selftests/futex/functional/robust_list.c +++ b/tools/testing/selftests/futex/functional/robust_list.c @@ -471,6 +471,128 @@ static void test_robust_list_multiple_elements(void) ksft_test_result_pass("%s\n", __func__); } =20 +/* + * This is the old limit defined by the kernel + */ +#define ROBUST_LIST_LIMIT 2048 +#define CHILD_LIST_LIMIT (ROBUST_LIST_LIMIT + 10) + +static int child_robust_list_limit(void *arg) +{ + struct lock_struct *locks; + struct robust_list *list; + struct robust_list_head head; + int ret, i; + + locks =3D (struct lock_struct *) arg; + + ret =3D set_list(&head); + if (ret) + ksft_test_result_fail("set_list error\n"); + + /* + * Create a very long list of locks + */ + head.list.next =3D &locks[0].list; + + list =3D head.list.next; + for (i =3D 0; i < CHILD_LIST_LIMIT - 1; i++) { + list->next =3D &locks[i+1].list; + list =3D list->next; + } + list->next =3D &head.list; + + /* + * Grab the lock in the last one, and die without releasing it + */ + mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false); + pthread_barrier_wait(&barrier); + + sleep(1); + + return 0; +} + +/* + * Robust list used to have a limit of 2048 items from the kernel side. Af= ter + * this limit the kernel would stop walking the list and ignore the other + * futexes, causing deadlocks. + * + * After this limit has been dropped, test if we can wait for a list of mo= re + * than 2048 elements. + */ +static void test_robust_list_limit(void) +{ + struct lock_struct locks[CHILD_LIST_LIMIT + 1]; + _Atomic(unsigned int) *futex =3D &locks[CHILD_LIST_LIMIT].futex; + struct robust_list_head head; + int ret; + + *futex =3D 0; + + ret =3D set_list(&head); + ASSERT_EQ(ret, 0); + + ret =3D pthread_barrier_init(&barrier, NULL, 2); + ASSERT_EQ(ret, 0); + + create_child(child_robust_list_limit, locks); + + /* + * After the child thread creates the very long list of locks, wait on + * the last one. + */ + pthread_barrier_wait(&barrier); + ret =3D mutex_lock(&locks[CHILD_LIST_LIMIT], &head, false); + + if (ret !=3D 0) + printf("futex wait returned %d\n", errno); + ASSERT_EQ(ret, 0); + + ASSERT_TRUE(*futex | FUTEX_OWNER_DIED); + + wait(NULL); + pthread_barrier_destroy(&barrier); + + ksft_test_result_pass("%s\n", __func__); +} + +static int child_circular_list(void *arg) +{ + static struct robust_list_head head; + struct lock_struct a, b, c; + int ret; + + ret =3D set_list(&head); + if (ret) + ksft_test_result_fail("set_list error\n"); + + head.list.next =3D &a.list; + + /* + * The last element should point to head list, but we short circuit it + */ + a.list.next =3D &b.list; + b.list.next =3D &c.list; + c.list.next =3D &a.list; + + return 0; +} + +/* + * Create a circular robust list. The kernel should be able to destroy the= list + * while processing it so it won't be trapped in an infinite loop while ha= ndling + * a process exit + */ +static void test_circular_list(void) +{ + create_child(child_circular_list, NULL); + + wait(NULL); + + ksft_test_result_pass("%s\n", __func__); +} + void usage(char *prog) { printf("Usage: %s\n", prog); @@ -502,14 +624,17 @@ int main(int argc, char *argv[]) } =20 ksft_print_header(); - ksft_set_plan(6); + ksft_set_plan(8); =20 test_robustness(); + test_set_robust_list_invalid_size(); test_get_robust_list_self(); test_get_robust_list_child(); test_set_list_op_pending(); test_robust_list_multiple_elements(); + test_robust_list_limit(); + test_circular_list(); =20 ksft_print_cnts(); return 0; --=20 2.48.0