Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751966AbdHCVEp (ORCPT ); Thu, 3 Aug 2017 17:04:45 -0400 Received: from mx0a-00010702.pphosted.com ([148.163.156.75]:36053 "EHLO mx0b-00010702.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751746AbdHCVEl (ORCPT ); Thu, 3 Aug 2017 17:04:41 -0400 Subject: Re: [PATCH v2] timers: Don't wake ktimersoftd on every tick To: Thomas Gleixner Cc: linux-rt-users@vger.kernel.org, linux-kernel@vger.kernel.org, harisokn@gmail.com, bigeasy@linutronix.de, julia.cartwright@ni.com, gratian.crisan@ni.com, anna-maria@linutronix.de References: <20170717220430.20117-1-haris.okanovic@ni.com> From: Haris Okanovic Message-ID: <1f71fbdb-810a-06b8-c652-d8b560f64e2a@ni.com> Date: Thu, 3 Aug 2017 16:04:18 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [130.164.62.171] X-ClientProxiedBy: MWHPR2201CA0051.namprd22.prod.outlook.com (10.172.59.25) To MWHPR04MB0705.namprd04.prod.outlook.com (10.172.167.142) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 78a4b283-f9c8-47cb-9f70-08d4dab33962 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);SRVR:MWHPR04MB0705; X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB0705;3:i20yvZKTtbWoF9FnPC6igiZ6fLn3MwiPGHh9ZaRO2ifBGfVNJa4gDESaqr/ys56rc9B9HL9Yf7OzH/pS2LbZuYT2s1HKnfnnTr0trREOmN5dPyMZMqhaD0EQaXztCjc/kiisSkbR4TMTW6cHHAfAp9J5v89m7vO7y7zB1IU+prAIuGmVg3rf1hN5UY7A5b0tQoKX07Kow70n+y+ivLlQYEVwG6wGlkt294hy8PdM8oqsnsCmi7cJeABOS7LN2wKSE/9cWUGGngaNFKwc20IptNZwMHsxGsCnEn+DG84Sg/bmlSbS23qrRwVpg2EbNlUKVL4Z2caRJ3SGIrgXMjEfZCCicZTBysHar9vADiq0P4WHx8d4qn8bVTWS9L5xBtEL5ojRC7YbD1juvUHW0/vDNOehAvh5iyoM1EPiXLiAeWsDZ4v2f5v/hauSSGLuuJqvfNK7+PW7ZxFOEhy9l+zjLrM1rxH/hOs7jk++MDNGD1AldrmwM709Q2CbhX2nNrwZu5nFzsx2Q9DyWgtVEkDCNOfGkgrFUo2BUdnjSXOHVHXi2m4Foe1zUCtDhz8OefHNM7SkIZkd1Ju33Is7YkhhX2manoTcX13fPk7F2ZR/LE5ukz0xHzG2NdRmTjTvkGZ8Jlz0k8xYyV0RsM/ggkKh05tM1LqgsCe0x4pStgSjXsIBXD+DcjO/lCSnwTDO/VwTFd2ehVY1tY173MtHR/xMXowmcjLxlqHPp2fbSOawHn/M+30yGOPC5m/11bcXPkONu7iJjTB/A8Bn1ZvscRyYe8MzKNCPwdZyzOpRTQYWuWZ0+PxKMrxIcUx5+HzR2TgN X-MS-TrafficTypeDiagnostic: MWHPR04MB0705: X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjA0TUIwNzA1OzI1OnlySFdWMmNaaDM2OSt0QTM2dC91QlFvNW9a?= =?utf-8?B?bmp2czZjek5ocG96Ui9wWFN6dkRSeDlGUmJMQkpibG5GN2tlYzcxaXhETUUw?= =?utf-8?B?OEJMS3Iya2NjVnl2NHdnNnVEK1NzeUFoSFNncm1CaUlkcXVBcVg0cUZSbWxr?= =?utf-8?B?VS9XdWx2ZHJUQVU1SnNsYWFwci9mNzB0b2FRZFQ5NVJVTUpLVjYzbWpvMDBQ?= =?utf-8?B?V1RNazRrODY4VVlIdEVueTVEN3lZR01XZi8ySXIzQ3A1akV2K3hXUDI2SlBm?= =?utf-8?B?elVuRVY5U2k3MHJ5Z3pNWkZ3cDZCZDgyKzh1REdyZkk3bDZYU0JGNHdoSThE?= =?utf-8?B?UzZpRVZjT1dONElPVkNlNmlLSGs1cTczMDBhYmFBRUdyQ3JQMFZUckdBRDRW?= =?utf-8?B?THk1M2l4ekF3NzRvTHpYRTBJMSsxWjlQc3dxeXRodjVHK1YxVkFtVVhqcmc5?= =?utf-8?B?a2I3REhwbjBMWThYRTlJMXhHOXl6SThVUUJHR3crNXpYbGtUdXdzNFNHemxz?= =?utf-8?B?RkJqM2JaUFk3NlNQQ1FiUEEvaVhhQmF5YURuOEwxQkpoVDNuS1ByMzJycGI3?= =?utf-8?B?bElZdFBialZkaUp4dTh2Q1A5NHBtdG1xT3BaT2R5N0tDTFVpUDJMT1p6Vk4y?= =?utf-8?B?eVB2VHk3RkpZa3hXck9QV3AyYVhMOWdIbElnYW9sZHR3VVFRNnk5MTJTbjhE?= =?utf-8?B?SHFHYzAzYXppa3pibmlTNkVtUjdKM2xWRVVRdmlpQTJLMkZwWjMyZ3V3amYr?= =?utf-8?B?MUQzWXJLWmwxbmdDTVBmR2VmR2xOa2t2QnhmWnVEdmMrMkhrWFo5MjNBbmkw?= =?utf-8?B?cHVrdk0wbE9vYVJLaWxFSnFHWWc0d1piUkNZZ0xENmV3WE5neEZGNVk5bXZw?= =?utf-8?B?VVZoMjQ3cmU4c1BnNnJZamVrRGF6TmpQNUdoTFRtcFF3UlVibmlzMm03SEFz?= =?utf-8?B?VXdwMDVGU2dLeHZjM3dWM3UyNUVGYi8yelNDM3RJVUpNSjZDS25icE9ZdUhE?= =?utf-8?B?MVlYVUNldy9Tcy9XaUg1bDNzMzNVd2pXRHpZSzNZQ1NMdURQS3ozMmFKdWxp?= =?utf-8?B?d21tZDhYSjZLOEZlWGpvSFgvSUNEY1BjZXdWSDBlZE1oZTdkQkxxUFRWaG4z?= =?utf-8?B?OWkrdTVReGt2czg4UTRia3pvZmJkaXlFYXp1R29kSXFsbVMzcmtJd3dibUk3?= =?utf-8?B?OEhPQm1XcFhFRHk2ZWVBcVMxZjB5aGE1NmJVYWtHWG9JRVEzWTIzbU1URnAz?= =?utf-8?B?QnFwS05lTnUvVlNyWnhhVmEvaU1vK2NvRi9GVjFLK3lVb3VubFl1cXVPakJS?= =?utf-8?B?OTZzRnlENUJUeFE9PQ==?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB0705;31:N8tl4QpXRNJJ9OIkT3GsN9syjb8U7IfCGCkNcyrF16QSytluR1gif9p1cBjAdO+eZnVfwOhQFbxYV42QMaT4lgBjgS825v2nBNTtzqt9CDL8HTHk5xfxKzqZNBiddrSdzg5gwQ5TXdlrMx2bHaJ0OxFjFVypcrta91aBpe0aW+aTNWDMtrJ7/1/aMDAzRydhJRBn72fzzR3h3ZtS9DRw6cZzSiqvySu8GGeuJTpYkf+4PPsjUByScoolu58mp+qgrf/uLqmCJ088m5HdHLOZVhbOi4ZInW35b3BeD2wR/W39aMcOK07wd5EMMpY11kKgGPQh7/XGxKOc/7FSDdYnf2Vcv/o2gHyFODJ+FrNiJfdskDAlVSrFGRoxd/8KljrjE78N1zZ+EwV1HpFI+NO8RHFTuijRxMi+JSRGzms1n2pSmG43wLpzdgOdK0GQkIaVWxHTKGeIu4RsjbbQSjTVOVgRaxBzjYoZFdlJv+/GCDDWipB5CPaIfhQpXg/DPpzEXDEiWwZStBtLk6+/jANxwPUvI035CHgNhiTpxMLKtnMT9KtM8KNX0KsJwfxzLcPA7oi97T3ORjOAqvON0IWR4xEYJt+/jmJWJcbU0lgd1Jqd2vWPySmeFAwMYzciZkHl9DP8JEZ3Vch+klAybNGb8siCJXL+WwRCUoBXXkgAxGQ= X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB0705;20:5r7eRDMt7U0NNRDUXAhvVar2Wlajxs2AtB329INeHWaXoJ+wd1F2dM7Be5MhQOpkUyVdHQCPTt/wGR4HnERiH1wucmNjv2noPNMJrNpVeFPTvmXuRlrrsLYwmz4ZvjH3Z9CW9SsSZT7b0ExzEpiUbWTLGK9P/3F8E6DOEAOqV5a4FhDMxR+0XioRCOUQif71E2FvWL0PY2Nn4Z31y2feWFFNUG7L0BycXvwvJ0DVgjWrkJcdczuWhIN+QCplk1fJpRTaeri5zmls/dGhkOiuA5uug4wW/Vutrsjcl8fCTpqk3eijVlhlZxCbvMI9xQn3GwHiguz4j7/WFDOKA0bKXkisIA4d6Srf8QEQ5I/XjY4wv9Rj7v/N4KXp7756Wm4auauj8NoVVhNr83t+OklNshUlPYDsm2gURcttSSxYnyP3NbdY6BN4XUZu4+rvF6OPaqg9VaZV0j86CeO9W/QLva6ht6aIDEbHEdC2V/j4s/iKRm9nskR1rmznNyJVDK4Ih8JVX9iA5M46ShEkAo4nF6I9uIp4xgjVKPdiCwOYJvlPJp/Iy+aJ0RV7dhMS6FlyNJc3Us4TkVdxea2PTs7gey4T+ex5YXMPHGY6Eat5IE0= X-Exchange-Antispam-Report-Test: UriScan:(17755550239193); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(100000703101)(100105400095)(3002001)(6041248)(20161123562025)(20161123560025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123555025)(20161123558100)(20161123564025)(6072148)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:MWHPR04MB0705;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:MWHPR04MB0705; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjA0TUIwNzA1OzQ6bG81Ykk5YlIxbkRzUW45TjFaTHBuZU1pWDFs?= =?utf-8?B?emtXSlQwWTU5c0N4NmZYdm81YUJLVHZoK1RJSGh6N2daSXlWMDVLZjlnSW9D?= =?utf-8?B?bFJVTFlVVFg1N1A4ZUtIN0dWU0Q3WXpISm5VVkZIWlgxbDk4ZEdDWnZwRmVD?= =?utf-8?B?VWhySXgyQUFtQzl2RHppc3A2UXQxTU1Cd05PU1pFdzQ4UGZYWWNlb3JhcVFq?= =?utf-8?B?djdFaGVoODdSbW80UUp2YzUvMExlYTl1T1loR1Y4NVcxeFcwM1k4blcrMEtR?= =?utf-8?B?VGUyL1VKdmFRQXZyVXFFTFdrSzN5UG8zWTE0OUNWazFDK0ZVbnA2SWlsV0Y5?= =?utf-8?B?MGV1b2lBbmJ5K2xFaTJ4MFd2WnNER1A1VldqYm5sTXRobitZcmxQcTJmV3B5?= =?utf-8?B?eDdWZXhwSGJ6YmlxSkEzQ3dpUE9XMXJNMUY5OHMxc2ZoRU1xSVRSTlZPOVhF?= =?utf-8?B?ejlPMjRlUy9CcmQ3Qmx1MmxURFlmV0hFbUVEclNQOVJsYnFXazgxVHdqZFpq?= =?utf-8?B?L0liYzNqcWJnQnd1K3VQZUNkUGhKZnVWbk51WHBTcWRnbGFyRG5ZYlVZTThi?= =?utf-8?B?MjVPa1dod2p2aEpmeHorWXplYW91YTBFbmlhampOR1lkM3RSYWJ4SGlPajVJ?= =?utf-8?B?aFZVejI1aVpLVVM2V3hyejRXVFVRV2tlZnRGSzFBbWtJcVdhS1h1ZTNnd1J0?= =?utf-8?B?YVhvS052S2dYd0VwbEVnVGxqUTNRRGthRTRyQmlOS2ZvQlROOUl5MTZkNUlm?= =?utf-8?B?SEgvSHhUMVVTL3c3YnlNZHRZcnhrUWxwWDRQaWlGclVCajQ3N0ZuQm1tSldz?= =?utf-8?B?WDlJTmNaY1llL1VHK3FDd1FjOVFNaGUxcEQyK2N3QUp3VHRwWjE3VnorUGhP?= =?utf-8?B?bDg0Q0szUnNPV3g2Tmoya0U2R2d1NVpxZWRURDF4VTVteVQvVUhjWStWSE1k?= =?utf-8?B?SHBSZW92QlFVcnQ5cVUxb3lYanlodFc4VDZqdnhHazJpOXFKT3BqcUwzelV1?= =?utf-8?B?bFFGdUZOYTJsa1pkY084Wk1oSFUzVUdIMUlyRlMyTlZXZnMvd1VpV0F6N1JH?= =?utf-8?B?V0pXeGFQUUpNcldTQVl2d3Y5OFZwQVlWM203Qml6ODBpOWJxZFJxZEs0NWFI?= =?utf-8?B?MkV4bkRqQXBoRDhVNk85OVpLSmJtYWhydXFwS1ZtYW5tRGk4QkMybjFHS2Ux?= =?utf-8?B?U1JIcS95VzU5NXN6QStNWEl1SXBWOTFkNVRnNVdqYW5sSjYrOFBXdFBGM3Jk?= =?utf-8?B?dkh0NjVjTXl4SU8xYzc4eVJ0ODNtdjNVQnIzekE4L2ZGNVoyWk9FSnVTMXdL?= =?utf-8?B?amcxaG9BVUwzWlU0cXhNWFYzY2FjTjhNYXlCN05TdktDd1RTNzhjQndZZ2Mr?= =?utf-8?B?RkI2KzdTRm0wTUxOaU9LMGlYNnM0SkRkTlZlV0diQWtMRytQREliYXpoUkt5?= =?utf-8?B?WFkzbkszMWQxbHB4TjhJTnNHZVJYM29kUGM1S0d0UWZHRzcyY0xyMjZnTnhi?= =?utf-8?B?U1pveXpjOCtBV05xWjkxNGtMRFZETitUUy9aVmdYK2UwZ2VpcEIyTjhxSjAr?= =?utf-8?Q?CFUElvpWiBplRiNGWmF+Kn1BUxbnqOFAp0W2OO5xUyw=3D?= X-Forefront-PRVS: 03883BD916 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(7370300001)(6009001)(39450400003)(39850400002)(39400400002)(39840400002)(39410400002)(209900001)(377454003)(24454002)(189002)(54534003)(199003)(6486002)(50466002)(65956001)(6246003)(110136004)(68736007)(3846002)(6116002)(66066001)(6512007)(6306002)(5660300001)(81156014)(81166006)(8676002)(54356999)(65806001)(4001350100001)(42186005)(33646002)(53936002)(86362001)(25786009)(305945005)(83506001)(23676002)(7736002)(478600001)(2950100002)(47776003)(106356001)(105586002)(38730400002)(229853002)(76176999)(6666003)(97736004)(36756003)(65826007)(53546010)(4326008)(966005)(64126003)(6506006)(31696002)(101416001)(2906002)(50986999)(6916009)(230700001)(31686004)(7350300001)(53376002)(189998001)(6606295002);DIR:OUT;SFP:1102;SCL:1;SRVR:MWHPR04MB0705;H:harisdt.amer.corp.natinst.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjA0TUIwNzA1OzIzOktrVW1QRFhUNXVKL0lBb0Q4MzRYVTRna3NX?= =?utf-8?B?NnVHQTNQc3hOaUhOeE1NK1FDdEp1cUtGRElvWFJMaTN2SlEvbnNxcVJvMU9p?= =?utf-8?B?N2p5UDVObnRJbkhHNmRYZWRqSHhHMU1zREVBRXN0ZGNKa1FnR1pUWUhWUlh2?= =?utf-8?B?bkFIelZTRHpUVElXejRTNzBWRWFIZUpMRThaVFN0cE9uN0VaajZFems3V0dZ?= =?utf-8?B?SXloaWIydFNRUm1MR1lGTm5JeWJlUENNa1lTeXFNeWE0VWxDYXBYTElkOTZl?= =?utf-8?B?T0Q5YjRVNCt1aHdwQnpkMkJEVXRTazJyRHJ3b3liRlNUUUtHckZ6T2o2amNP?= =?utf-8?B?bVpDdU81TlB4T3BhdGhtcHIzSEZvR0s3NVVSNXdiYWQ5dkNCc3ljcnpSL2lk?= =?utf-8?B?ZFpCS215ditCTkhKMDVLaGxXbW56T3ZqZEZjYVA5NFAxMGN4N3lnZVhiQ2Va?= =?utf-8?B?WmgyVG00eG5uT0kwZy9tTmJ6dU4vNmxweUxIN1pVR1pEWWRXUUpVQWM1OEh4?= =?utf-8?B?M3BOb0p0VTBpenJXdUhBcytTQ1pzcVlsK055L2pLdUtjbFZFOGxNeEdwNnNM?= =?utf-8?B?bHhEZ1FURkpybitXSjNKbk0rZ3lCOHozdnFBY1l3aEwxVUxwUklJVmtMeFg3?= =?utf-8?B?b0QybmVhZXk5VFZtWXRoUVd0OW1YSWk5OXlOVWhTNnB4Qm42SEJvMi9qUWs2?= =?utf-8?B?Y2tNYmtZWVRuRjVFYXlJcnBTamJjazlrTXlhVUZyMzQ0TEIvSjY2ZzRobVZm?= =?utf-8?B?dUlkQmF5M1ZpTkxrdFVuNlVFUXVLYWp2b2RobEQ1a2tuYktBS3FsV2YxcGQw?= =?utf-8?B?YU9VakVZWWRHS1B0T0FyV1k3dVFzWFk2STRWSnk1djhhZ0VUekVORWNnOEZZ?= =?utf-8?B?SWNwUnd3a3k4a25xQzRoaTdaVldYMUZhSVBQYmdVeWY4YlVCaWJ2QTBlWFpl?= =?utf-8?B?WnJ0aHVTaHBZYmI1dWU2eDlUdndGajVKWW5XdTZRUzZWQ1o5bWt5Z0l3bWw0?= =?utf-8?B?OHVFcUdZZis2MW44WlhCb2p4cmRyeGxsaW5pWFN6MThhVEVkenFYWTZXNXdz?= =?utf-8?B?RTE5Tjc2dkNodmV0djNXYUI0TlJVejU4Y2x5eU41VGZ0K1Y2dWRUc3grWXdZ?= =?utf-8?B?eFhWdlBRRVJFbTdHVTV1VzhwTVl3UHh1VXdQWmNSNGY0OWRHQ1cxZ0hjbDBC?= =?utf-8?B?MXZxcmp2Q1pFQ2wyYkI4VHBCMkNWek45c0gxbDFxaDMxN3Zmb2VmaC9lckNR?= =?utf-8?B?YVF5MmpuVmJFQVFPamsrTHpQTGZZY2lZVUh2VUZRV3hVUk1qQkhsMWhLQUow?= =?utf-8?B?YzZtUnBHRHh5b1V5d3ZabUFPMUwvVi9iVStVcEM2Qk5CMHI1UXFZdFBMcTZF?= =?utf-8?B?ODRsSnlmdjFVb0RSRTFrOTFLN3ZLMEQyYTRKVmtwaUR3Z2E4cGk1Z0NobEJ4?= =?utf-8?B?MmI5Z2pINHZ4dmttYTdEcmNSZGNYcnAyb1EyTmVaaEVLclltaWRiNnd6d2xz?= =?utf-8?B?MjNQR0JGL0FydG5CTTgzRTJwUXF1amhWd1Fib0xJTzRMY01qMDZ5MUlLZ3Fr?= =?utf-8?B?QjRaMlpVNkZxOGRzVEdpdWJ1SFFySjZ5TmdkT1M1cXQ1Y0lUZEN4ekp1SU91?= =?utf-8?B?QUk2K01CdVJkd2FEcDJheXdYbTZSWlZ5MGRaVytINDA4SWdrNHFQbVMyMDZ5?= =?utf-8?B?SHVXOWNTc3p0cFZ2SUxSN1NZbWI0dzk4Y3lwZmdWYWFJeHRXVk1iMnAxYVBK?= =?utf-8?B?Y2ZaZnBIb3U4aEhQT1JjMmEvNzQ3NXllK1NnVkZEUEM0dFkwaGZMYktMWDBC?= =?utf-8?B?RXFHeEhLTU5ZaUN1UTF0TVNNYzhEb05URlBDOTJpNGYrSFpqR1VxSlNOT1lP?= =?utf-8?B?cDh0UHlNNmhmZW9RbjhxMTRVRzZZYy82RkhpUUdqTGQxUTV3aUFaZ2xtYVlY?= =?utf-8?B?RlZhMVQ5WWxCSExxQXNGOEZQcC9VWm1qMDBzTjB6MHR4SHBxUlgwS1EzcU4x?= =?utf-8?B?cFFwSm1xTE84TDBGL3ZHVGlCN3B5Z2JvUjRMVlJvNDh3QjJrZ1kvQkpKWEVw?= =?utf-8?B?M2pjTFZaUENNbi8vWlZYaVpycmttTjR2SUtwMXlIMVhSMHY0R2ZXUTZINTdn?= =?utf-8?B?QVJHM01zamdOYkFVMzkxM0J1VmNlcGZmMmtFNWgwQTdZVjl0TFdIMkJSbldK?= =?utf-8?B?VzNPVUpFbWNHa2x0cEtMbjhINUhzMGs2azh2Tm8xNkppOExIbEJpUitMN2xT?= =?utf-8?Q?IOXjOEal2vN1LDla0J?= X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjA0TUIwNzA1OzY6RjJUdjlWc04vUDc4NDZoTGRwL21oVUdXbHhF?= =?utf-8?B?SHhpOER4aVdKTlNLOGY4UG5xeXFWOElMWm5XaytkNkhHcnd2WElsazZQVXB5?= =?utf-8?B?UjdxQjVCMzZ6R1lubTlJbXJEZWg5VXQxZExSdFYzaDd2NTYrTzNTcGdhRis2?= =?utf-8?B?bGttWnE0c3I3c0gvaTlyNHpQNGVxa2R1VTNVcTlidHFsMW0zOFZqOVR0Wi9T?= =?utf-8?B?SmZXRmhVeDhmNkgzaTg3dU1DRVpyMzR5aTRaVmRHSENFMmt4YWQ0UXhTMHNz?= =?utf-8?B?WkRHUk5CajhPbzUxTjFzZUJRZEtIYnRJUEpxek1ZZ3prNzUyR0Rwc1dZdm5i?= =?utf-8?B?dUJTZUJtdFVUbXM5YnBkRjliTkgzam5BVVYrNGN1RUJzcG5SK1RPVURTWk56?= =?utf-8?B?REFKYTB4eTdDRlYyUy8rRTlBU2FwWnY4cE5sOFQ2RmxYL3ZnRkdzMWwrVHRz?= =?utf-8?B?clRGUU9GRFdMWWkwQXd0N1ZOYml0VG5ITGJuemJpeDZWMTJpdlJWTm5SU3dP?= =?utf-8?B?K2xtY3BlTk9EaElUSGxWaW5YYWtSY0Y3SlBFdFdieGkrSU81bmxxdHZINDJp?= =?utf-8?B?UUJ4VXRNMERxZGpKNWJMbGtUQ01yMjd1ZDNLejdRRExMZzZ5YmhXOVFPK0ZZ?= =?utf-8?B?YVExOVlIS29lRm9nazBWSUdkdlEvc3AzRkdnRTdsTVZFSnd1cUl5RFg2dFJj?= =?utf-8?B?dXl0MTNOWEZ4dzdOOWNmcThWMVNBQ2ZUWTg0MWR6akMvTHhXSUVJTHhZTktl?= =?utf-8?B?SXNLMHVkeWVIUzh1RnZmNW8xaDBZbzAwQkJqUFhaOEdTK25DeHpxbDJ5emlu?= =?utf-8?B?VnUwbkRORkFPd0Z2bmFiQmZIWkJWcE95Rk5rUkZFMzdCYlQwT1NCa0loUkJP?= =?utf-8?B?bk45ZEhVNmtaQUtFSmVZWkc4OFpkN1VRZGRPUUNYeG5yZ2FVa3AyaFlXN05W?= =?utf-8?B?czVtUVN4RjYvMCtoZVBTMElrblJ6QUwvaHZGNlRCRFlCb2dadVZlSWFQOUtn?= =?utf-8?B?bGZrVjdNVStOSFFuRHhKQkpDZy9zb3l1SllaOTl4NDJJeStSRTNzYUlXWlM3?= =?utf-8?B?eGtFNEVHU3lMSmtPd1pSSFJMdDY5MkV2WlRvbnZzS2pmbWo3eW93bThYWndK?= =?utf-8?B?ZWlNTDI2QktDSks3NUdjL0NDQnRsYjNUbi8wTGE2WmxaczR2ekQ5L3Z5OUMw?= =?utf-8?B?Z0pwNXpJWlR1eGpiRVIvZmNpVEFxNVRiUjBMTGc4MkRiOVRtNGJUSU1XWXI4?= =?utf-8?B?V0YwdndJbkgwOVNzYkFBd1lnNERvRTBEbWppSm1QRGRiM1ZlNmZvbk5VUHI1?= =?utf-8?Q?U7klg0EaEv02yD0h0VLXiyCIDvK4B+M=3D?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB0705;5:7bK2Gl1NoTFPO2QIDizovXTpbcpmntBmFpoKbCHHtGPRDuJTyFuLehK5bwmJwjpz6RsuZ9+ivi0OEyBGJbxqIxkqj9cwqFeg3rdTq+dmPL0JVE2OkdM+qtF406F9PPTQNoLFiqN/r55bma7kyhCSx9IiwxcqfI2jZiDsqlyWzojvDAul9BpTKkgMDUxUqtx/kyK7+4hcp6P33Cc0jj/qjhpkb9cB9WHPJShQ39ShtWAtcbrKtAjYL30ngHQns7apg0wcftDcCjbAOvjAnNd0JvKdZv/JDAint9DUkuyL6n3i4evtYZjREWlypzMsc9RvPNVoNn6ZyA3tStzC7bD8KbeWE3/CuIFMFGvYYyaiQE/1m3CJWN9VsBsWD8+l7sIb7bi8zmN8qrfAYYKbmQ7L4l1LZl9OACUjxT6P2b645H4CA1bb3KSdjZPCOvs/dcC/KCPpGCFwcxBRflWYJ+wYEO1hhG5jWhUGkzvgwbw8VgF+bTY6e3MQDZI3P/YaGKse;24:Ng7TSMkSaXG8xLahGLwoPM0DYk6m4a8UzKlYA1hcKF09R1B+ylffLDQMwveyYz9tbWElBGERtGNyWOfDrphVKPYh28Gm+P4hCUbsUuDrQA0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;MWHPR04MB0705;7:KIZvfefY1CSkC152SbsdrMg/r6Srj8vChKvPZ6+3vBrNJtrxOcvVMJ27IvHiqBI8KgRsByy7De7GUr86UP08eUri3H/QGCdXIxIe/5c+SB21hLXo8MBgo2GTnVhe6VKyZAN4rE81VN6bJC5Gd49ubfwrJDmOXKQX08rpcllvIMVVYS2SmCATcIOhAOwB3GQACJ6lX7jiPh8zLbJu7sf8YPmKvdLFnEDKfKsjhKFzsZ0U8V58YDd3oMnDY13kBK09c1rwsVbl4Ehd61sBoAyfx5Dg9hcuioI2P6eHIzqe9ZK2SFDETiljQldSkWubwVEIKGjpTGT09rx5CzzE7iqXuAqUOoVvOZSevSRK+mOQlCWIrBkZik6QE3uY/+sDmJKCnWj7piYPdH1EJivtxI8y66vb8Bqp4+J7yipdj0dVrvMkY5+wXBPF6z/xMWOd7SyY/Q0vnXG8qpzfIBd+g/4HSdsLlQwddDkzNi7ieW+fVeArzcpYVaQl5xTU9xmbhybRG6a68tpFxEEv3MDk0c5hHevR13R7RQ9Bbu9RclZggI5bprHJD37i6IxLtTaG+Dj4EZ4rzudPs71ocdiGviUmF3OXZRtwd9YYKjEXgcunem9Wdr5I5DbrOq6jTzkU7k9SAfHs0FJBY0/TqjQyG7G2xMmXDNV8JyeW8rEoFrCjn6G7Goc8TPKz92MQKsLlprNThPtzeyHvfPUyoTlFdYyvF/HlwzzT2I95XA+eIKCqRDuGtiZioK9+MWBzvREYeFApso+xukZZFD7SMcxhMvrN8LgXboCH1mgawy7D3XXACyI= X-OriginatorOrg: ni.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Aug 2017 21:04:25.5817 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR04MB0705 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-08-03_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_policy_notspam policy=outbound_policy score=30 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=30 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1708030320 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 15880 Lines: 528 Thomas, Apologies on the late response. I've been busy last few weeks. On 07/18/2017 04:33 PM, Thomas Gleixner wrote: > On Mon, 17 Jul 2017, Haris Okanovic wrote: >> We recently upgraded from 4.1 to 4.6 and noticed a minor latency >> regression caused by an additional thread wakeup (ktimersoftd) in >> interrupt context on every tick. The wakeups are from >> run_local_timers() raising TIMER_SOFTIRQ. Both TIMER and SCHED softirq >> coalesced into one ksoftirqd wakeup prior to Sebastian's change to split >> timers into their own thread. >> >> There's already logic in run_local_timers() to avoid some unnecessary >> wakeups of ksoftirqd, but it doesn't seems to catch them all. In >> particular, I've seen many unnecessary wakeups when jiffies increments >> prior to run_local_timers(). >> >> Change the way timers are collected per Julia and Thomas' >> recommendation: Expired timers are now collected in interrupt context >> and fired in ktimersoftd to avoid double-walk of `pending_map`. >> >> Collect expired timers in interrupt context to avoid overhead of waking >> ktimersoftd on every tick. ktimersoftd now wakes only when one or more >> timers are ready, which yields a minor reduction in small latency spikes. >> >> This is implemented by storing lists of expired timers in timer_base, >> updated on each tick. Any addition to the lists wakes ktimersoftd >> (softirq) to process those timers. > > One thing which would be really good to have in the changelog is the > overhead of that collection operation in hard irq context. > Added testing note: Execution time of run_local_timers() increases by 0.2us to 2.5us as measured by TSC on a 2core Intel Atom E3825 system. I'm guessing the variance is spin lock contention caused by timers being added/removed by different threads. I also verified the average case latency decrease in cyclictest and reran Anna-Maria's test on a qemu 4core Nehalem VM; latency decreases and no stalls. >> diff --git a/kernel/time/timer.c b/kernel/time/timer.c >> index 5730d42bfd67..e5b537f2308c 100644 >> --- a/kernel/time/timer.c >> +++ b/kernel/time/timer.c >> @@ -209,9 +209,12 @@ struct timer_base { >> bool is_idle; >> DECLARE_BITMAP(pending_map, WHEEL_SIZE); >> struct hlist_head vectors[WHEEL_SIZE]; >> + struct hlist_head expired_lists[LVL_DEPTH]; >> + int expired_count; > > You need to look at the cache layout of that whole thing. My gut feeling > tells me that that count is at the wrong place. > You're right, there's a 4-byte hole after `lock` we can use. I'll move `expired_count` there. >> } ____cacheline_aligned; >> >> static DEFINE_PER_CPU(struct timer_base, timer_bases[NR_BASES]); >> +static DEFINE_PER_CPU(int, block_softirqs); > > Why are you putting that into a seperate per cpu variable instead of adding > a bool to the base struct as I suggested in my example: > > base->softirq_activated = false; > > Having that separate makes no sense conceptually and cache wise it can > force to touch yet another cacheline depending on the placement by > compiler/linker. Looking at your implementation it does in 100% of the > cases. > > You can use the first base for that, as that is going to be touched anyway > and is cache hot in any case. > I was trying to avoid using twice as much memory in the NOHZ case and didn't consider cache implications. There's actually another 1-byte hole after `timer_base.is_idle` which can fit this bool. >> -static void expire_timers(struct timer_base *base, struct hlist_head *head) >> +static inline void __expire_timers(struct timer_base *base, > > What's the purpose of this change? If it makes sense to inline it, then the > compiler will do so. > I inlined it because it only has one call site, but I'm sure the compiler will figure that out as well. Dropped. >> + struct hlist_head *head) >> { >> while (!hlist_empty(head)) { >> struct timer_list *timer; >> @@ -1344,21 +1348,45 @@ static void expire_timers(struct timer_base *base, struct hlist_head *head) >> } >> } >> >> -static int __collect_expired_timers(struct timer_base *base, >> - struct hlist_head *heads) >> +static void expire_timers(struct timer_base *base) >> { >> - unsigned long clk = base->clk; >> + struct hlist_head *head; >> + int count = READ_ONCE(base->expired_count); > > Please keep the reverse fir tree ordering based on length for the variables > as we have it throughout that code. > Moved clk. >> + >> + while (count--) { > > So this changed vs. the previous implementation and in this case the > READ_ONCE() is pointless as the compiler CANNOT reevaluate base->foo inside > that loop. > Removed. >> + head = base->expired_lists + count; >> + __expire_timers(base, head); >> + } >> + >> + /* Zero base->expired_count after processing all base->expired_lists >> + * to signal it's ready to get re-populated. Otherwise, we race with >> + * tick_find_expired() when base->lock is temporarily dropped in >> + * __expire_timers() */ > > Please stick to the two sane comment styles: > > /* Single line comment */ > > /* > * Multi line comment > * Multi line comment > * Multi line comment > */ > > For further enlightment: http://marc.info/?l=linux-kernel&m=146799838429328&w=2 > Fixed. >> + base->expired_count = 0; >> +} >> + >> +static int __collect_expired_timers(struct timer_base *base) >> +{ >> + unsigned long clk; >> struct hlist_head *vec; >> - int i, levels = 0; >> + int i; >> unsigned int idx; > > See above > >> + /* >> + * expire_timers() must be called at least once before we can >> + * collect more timers >> + */ >> + if (base->expired_count) >> + goto end; >> + >> + clk = base->clk; >> for (i = 0; i < LVL_DEPTH; i++) { >> idx = (clk & LVL_MASK) + i * LVL_SIZE; >> >> if (__test_and_clear_bit(idx, base->pending_map)) { >> vec = base->vectors + idx; >> - hlist_move_list(vec, heads++); >> - levels++; >> + hlist_move_list(vec, >> + &base->expired_lists[base->expired_count++]); > > Eew. What's wrong with local variables ? > > struct hist_head *list = &base->expired_vectors; > > at the top of this function and then do > > hlist_move_list(vec, list++); > base->expired_levels++; > > or have a local count and use it as index to list[]. The code generation > should be roughly the same, but I expect it to be better with the seperate > increments. > Done, looks nicer. I was trying to keep changes to existing code minimal. >> } >> /* Is it time to look at the next level? */ >> if (clk & LVL_CLK_MASK) >> @@ -1366,7 +1394,8 @@ static int __collect_expired_timers(struct timer_base *base, >> /* Shift clock for the next level granularity */ >> clk >>= LVL_CLK_SHIFT; >> } >> - return levels; >> + >> + end: return base->expired_count; > > More Eeew! Can you please look how labels are placed in the > kernel. Certainly not that way. > > Aside of that the goto is silly. You can just return expired_count up at > that conditional, or move the conditional to the caller. > Replaced goto with simple return. > Actually I do not understand that conditional at the top at all. The call > site breaks out of the loop when the return value is > 0. So what's that > for? Paranoia? If that's the case then you want a WARN_ONCE there, because > that should never happen. Otherwise it's just pointless. If actually > something relies on that, then it's disgusting. > Paranoia. We should never hit this case unless TIMER_SOFTIRQ got raised without expired timers. Added WARN_ONCE(). >> } >> >> #ifdef CONFIG_NO_HZ_COMMON >> @@ -1559,8 +1588,7 @@ void timer_clear_idle(void) >> base->is_idle = false; >> } >> >> -static int collect_expired_timers(struct timer_base *base, >> - struct hlist_head *heads) >> +static int collect_expired_timers(struct timer_base *base) >> { >> /* >> * NOHZ optimization. After a long idle sleep we need to forward the >> @@ -1581,16 +1609,41 @@ static int collect_expired_timers(struct timer_base *base, >> } >> base->clk = next; >> } >> - return __collect_expired_timers(base, heads); >> + return __collect_expired_timers(base); >> } >> #else >> -static inline int collect_expired_timers(struct timer_base *base, >> - struct hlist_head *heads) >> +static inline int collect_expired_timers(struct timer_base *base) >> { >> - return __collect_expired_timers(base, heads); >> + return __collect_expired_timers(base); >> } >> #endif >> >> +/* Increments timer_base to current jiffies or until first expired >> + * timer is found. Return number of expired timers. */ > > Sigh. > Fixed comment formatting. >> +static int find_expired_timers(struct timer_base *base) >> +{ >> + const unsigned long int end_clk = jiffies; > > const ? unsigned long int ? > Dropped the const. Didn't realize it violated a coding convention. >> + int expired_count; >> + >> + while ( !(expired_count = collect_expired_timers(base)) && >> + time_after_eq(end_clk, base->clk) ) { > > These extra white spaces after ( and before ) are pointless and not kernel > coding style. > > What's worse is the order of your conditionals. Just look at the original > code. > >> + base->clk++; >> + } > Fixed. > Aside of that this loop is fricking hard to read. > > int levels = 0; > > while (!levels && time_after_eq(jiffies, base->clk)) { > levels = collect_expired_timers(base, heads); > base->clk++; > } > > return levels; > > Is all what you need here, right? That's what the original loop does as > well. > Correct, but the original loop was in __run_timers() and this one is called from both __run_timers() and run_local_timers(), which is why I moved it to a separate function. >> + >> + return expired_count; >> +} >> + >> +/* Called from CPU tick routine to collect expired timers up to current >> + * jiffies. Return number of expired timers. */ > > Wrong. It returns the number of levels which have expired timers. The > number of actual timers per level is unknown as we move the complete list. > Fixed comment. >> +static int tick_find_expired(struct timer_base *base) >> +{ >> + int count; > > Missing new line between declaration and code. checkpatch.pl is wrong on a > lot of things, but it would have told you. > Fixed. >> + raw_spin_lock(&base->lock); >> + count = find_expired_timers(base); >> + raw_spin_unlock(&base->lock); >> + return count; > > Please be consistent with the names. We use 'levels' throughout all the other > functions. Random variable names are just confusing. > Renamed "count" to "levels" in timer_base and various functions. >> +} >> + >> /* >> * Called from the timer interrupt handler to charge one tick to the current >> * process. user_tick is 1 if the tick is user time, 0 for system. >> @@ -1618,22 +1671,11 @@ void update_process_times(int user_tick) >> */ >> static inline void __run_timers(struct timer_base *base) >> { >> - struct hlist_head heads[LVL_DEPTH]; >> - int levels; >> - >> - if (!time_after_eq(jiffies, base->clk)) >> - return; >> - >> raw_spin_lock_irq(&base->lock); >> >> - while (time_after_eq(jiffies, base->clk)) { >> + while (find_expired_timers(base)) >> + expire_timers(base); > > Now I understand that extra conditional above. That's crap, really. Two > ways to solve that: > > do { > expire_timers(base); > } while (find_expired_timers(base)); > > which requires a check for base->expired_levels inside of > expire_timers(). > > or > > if (base->expired_levels) > expire_timers(base); > > while (find_expired_timers(base)) > expire_timers(base); > The do-while approach works for me. expire_timers() already noops when expired_levels is zero. However, I would like to keep the WARN_ONCE(expired_levels) check in __collect_expired_timers() as a sanity check. >> raw_spin_unlock_irq(&base->lock); >> wakeup_timer_waiters(base); > > Errm. Please submit patches against mainline. This is RT only. On mainline > the overhead of raising the softirq is not that big, but the exercise is > the same. > I have been submitting to both mailing lists simultaneously. >> @@ -1644,12 +1686,16 @@ static inline void __run_timers(struct timer_base *base) >> static __latent_entropy void run_timer_softirq(struct softirq_action *h) >> { >> struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); >> + int* block_softirq = this_cpu_ptr(&block_softirqs); > > Sigh. A pointer is declared with: > > int *p; > > and not > > int* p; > >> irq_work_tick_soft(); >> >> __run_timers(base); >> if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) >> __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); >> + >> + /* Allow new TIMER_SOFTIRQs to get scheduled by run_local_timers() */ >> + WRITE_ONCE(*block_softirq, 0); > > You are in interrupt enabled code here. So you actually might miss a wakeup > and delay it to the next tick. If that's your intention then please > document it proper. If not, you need to disable interrupts around the write > and recheck stuff. > I'm not sure what you mean exaclty. My intention here is to only permit new TIMER_SOFTIRQs to get raised by run_local_timers(). See updated commit message for details. > Also the WRITE_ONCE() is pointless. The compiler cannot reorder the > write. And it does not protect you from racing with the hard interrupt. So > for the sloppy variant a simple: > > base->softirq_activated = false; > > is sufficient. > >> } >> >> /* >> @@ -1657,18 +1703,28 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) >> */ >> void run_local_timers(void) >> { >> - struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); >> + int* block_softirq = this_cpu_ptr(&block_softirqs); >> + struct timer_base *base; >> >> hrtimer_run_queues(); >> + >> + /* Skip if TIMER_SOFTIRQ is already running for this CPU */ >> + if (READ_ONCE(*block_softirq)) >> + return; >> + >> + base = this_cpu_ptr(&timer_bases[BASE_STD]); > > And this here becomes: > > if (base->softirq_activated) > return; > >> + >> /* Raise the softirq only if required. */ >> - if (time_before(jiffies, base->clk)) { >> + if (time_before(jiffies, base->clk) || !tick_find_expired(base)) { >> if (!IS_ENABLED(CONFIG_NO_HZ_COMMON) || !base->nohz_active) >> return; >> /* CPU is awake, so check the deferrable base. */ >> base++; >> - if (time_before(jiffies, base->clk)) >> + if (time_before(jiffies, base->clk) || !tick_find_expired(base)) >> return; > > To make that work, all you need here is: > > base--; > >> } > > and > base->softirq_activated = true; > Done. Dropped WRITE_ONCE(). >> static void __init init_timer_cpu(int cpu) >> { >> struct timer_base *base; >> + int* block_softirq; >> int i; >> >> for (i = 0; i < NR_BASES; i++) { >> @@ -1852,6 +1910,10 @@ static void __init init_timer_cpu(int cpu) >> #ifdef CONFIG_PREEMPT_RT_FULL >> init_swait_queue_head(&base->wait_for_running_timer); >> #endif >> + base->expired_count = 0; >> + >> + block_softirq = per_cpu_ptr(&block_softirqs, cpu); >> + *block_softirq = 0; > > What kind of voodoo initialization is this? Do you not trust BSS? Or do you > not make sure that the stuff is brought into proper state when a CPU goes > offline? > Yea, this is pointless. Not sure what I was thinking. Removed. > Aside of the above, this patch wants to be split into two pieces: > > 1) Embedd the hlist heads for expired bucket collection into base > struct and adjust the code accordingly. > > 2) Implement the conditional softirq raise machinery > I agree. I split it and will submit a PATCH v3 shortly. > Thanks, > > tglx > Thanks, Haris