1235063Snetchild#!/usr/sbin/dtrace -qs 2235063Snetchild 3235063Snetchild/*- 4235063Snetchild * Copyright (c) 2008-2012 Alexander Leidinger <netchild@FreeBSD.org> 5235063Snetchild * All rights reserved. 6235063Snetchild * 7235063Snetchild * Redistribution and use in source and binary forms, with or without 8235063Snetchild * modification, are permitted provided that the following conditions 9235063Snetchild * are met: 10235063Snetchild * 1. Redistributions of source code must retain the above copyright 11235063Snetchild * notice, this list of conditions and the following disclaimer 12235063Snetchild * in this position and unchanged. 13235063Snetchild * 2. Redistributions in binary form must reproduce the above copyright 14235063Snetchild * notice, this list of conditions and the following disclaimer in the 15235063Snetchild * documentation and/or other materials provided with the distribution. 16235063Snetchild * 17235063Snetchild * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18235063Snetchild * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19235063Snetchild * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20235063Snetchild * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21235063Snetchild * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22235063Snetchild * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23235063Snetchild * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24235063Snetchild * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25235063Snetchild * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26235063Snetchild * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27235063Snetchild * 28235063Snetchild * $FreeBSD: releng/10.2/sys/compat/linux/check_internal_locks.d 235063 2012-05-05 19:42:38Z netchild $ 29235063Snetchild */ 30235063Snetchild 31235063Snetchild/** 32235063Snetchild * Check if the internal locks are correctly acquired/released: 33235063Snetchild * - no recursive locking (mtx locks, write locks) 34235063Snetchild * - no unlocking of already unlocked one 35235063Snetchild * 36235063Snetchild * Print stacktrace if a lock is longer locked than about 10sec or more. 37235063Snetchild */ 38235063Snetchild 39235063Snetchild#pragma D option dynvarsize=32m 40235063Snetchild#pragma D option specsize=32m 41235063Snetchild 42235063SnetchildBEGIN 43235063Snetchild{ 44235063Snetchild check["emul_lock"] = 0; 45235063Snetchild check["emul_shared_rlock"] = 0; 46235063Snetchild check["emul_shared_wlock"] = 0; 47235063Snetchild check["futex_mtx"] = 0; 48235063Snetchild} 49235063Snetchild 50235063Snetchildlinuxulator*:locks:emul_lock:locked, 51235063Snetchildlinuxulator*:locks:emul_shared_wlock:locked, 52235063Snetchildlinuxulator*:locks:futex_mtx:locked 53235063Snetchild/check[probefunc] > 0/ 54235063Snetchild{ 55235063Snetchild printf("ERROR: recursive lock of %s (%p),", probefunc, arg0); 56235063Snetchild printf(" or missing SDT probe in kernel. Stack trace follows:"); 57235063Snetchild stack(); 58235063Snetchild} 59235063Snetchild 60235063Snetchildlinuxulator*:locks:emul_lock:locked, 61235063Snetchildlinuxulator*:locks:emul_shared_rlock:locked, 62235063Snetchildlinuxulator*:locks:emul_shared_wlock:locked, 63235063Snetchildlinuxulator*:locks:futex_mtx:locked 64235063Snetchild{ 65235063Snetchild ++check[probefunc]; 66235063Snetchild @stats[probefunc] = count(); 67235063Snetchild 68235063Snetchild ts[probefunc] = timestamp; 69235063Snetchild spec[probefunc] = speculation(); 70235063Snetchild} 71235063Snetchild 72235063Snetchildlinuxulator*:locks:emul_lock:unlock, 73235063Snetchildlinuxulator*:locks:emul_shared_rlock:unlock, 74235063Snetchildlinuxulator*:locks:emul_shared_wlock:unlock, 75235063Snetchildlinuxulator*:locks:futex_mtx:unlock 76235063Snetchild/check[probefunc] == 0/ 77235063Snetchild{ 78235063Snetchild printf("ERROR: unlock attemt of unlocked %s (%p),", probefunc, arg0); 79235063Snetchild printf(" missing SDT probe in kernel, or dtrace program started"); 80235063Snetchild printf(" while the %s was already held (race condition).", probefunc); 81235063Snetchild printf(" Stack trace follows:"); 82235063Snetchild stack(); 83235063Snetchild} 84235063Snetchild 85235063Snetchildlinuxulator*:locks:emul_lock:unlock, 86235063Snetchildlinuxulator*:locks:emul_shared_rlock:unlock, 87235063Snetchildlinuxulator*:locks:emul_shared_wlock:unlock, 88235063Snetchildlinuxulator*:locks:futex_mtx:unlock 89235063Snetchild{ 90235063Snetchild discard(spec[probefunc]); 91235063Snetchild spec[probefunc] = 0; 92235063Snetchild --check[probefunc]; 93235063Snetchild} 94235063Snetchild 95235063Snetchild/* Timeout handling */ 96235063Snetchild 97235063Snetchildtick-10s 98235063Snetchild/spec["emul_lock"] != 0 && timestamp - ts["emul_lock"] >= 9999999000/ 99235063Snetchild{ 100235063Snetchild commit(spec["emul_lock"]); 101235063Snetchild spec["emul_lock"] = 0; 102235063Snetchild} 103235063Snetchild 104235063Snetchildtick-10s 105235063Snetchild/spec["emul_shared_wlock"] != 0 && timestamp - ts["emul_shared_wlock"] >= 9999999000/ 106235063Snetchild{ 107235063Snetchild commit(spec["emul_shared_wlock"]); 108235063Snetchild spec["emul_shared_wlock"] = 0; 109235063Snetchild} 110235063Snetchild 111235063Snetchildtick-10s 112235063Snetchild/spec["emul_shared_rlock"] != 0 && timestamp - ts["emul_shared_rlock"] >= 9999999000/ 113235063Snetchild{ 114235063Snetchild commit(spec["emul_shared_rlock"]); 115235063Snetchild spec["emul_shared_rlock"] = 0; 116235063Snetchild} 117235063Snetchild 118235063Snetchildtick-10s 119235063Snetchild/spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/ 120235063Snetchild{ 121235063Snetchild commit(spec["futex_mtx"]); 122235063Snetchild spec["futex_mtx"] = 0; 123235063Snetchild} 124235063Snetchild 125235063Snetchild 126235063Snetchild/* Statistics */ 127235063Snetchild 128235063SnetchildEND 129235063Snetchild{ 130235063Snetchild printf("Number of locks per type:"); 131235063Snetchild printa(@stats); 132235063Snetchild} 133