Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp755804iog; Wed, 29 Jun 2022 09:31:41 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sbhJ3CLMzFqAHRK3m9nYSjwk3eUyOjzjnAitFM/cFZszk5mjZfnqyqjLEwUOYEGKT5I9nr X-Received: by 2002:a05:6402:5cb:b0:434:eb48:754f with SMTP id n11-20020a05640205cb00b00434eb48754fmr5381145edx.421.1656520301436; Wed, 29 Jun 2022 09:31:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656520301; cv=none; d=google.com; s=arc-20160816; b=Crd2kF0PdFqaCZX6IRgg6Ii9K/CSoYSuL22DcRw8aOSMAH3NpIq5ooSaS2a9ALv4aB tjD4In0ysfKWhzbP2DnUHmzmTYmSb8oJkDP+XzP3hgo/R/zXrZGS/xHZg6C2EabGlpMa 4IcrhevyfN5V7XW9LTInf4e6mip4s0nZAxIZxHWEaw91J0eTdga9cm5WhoMDuYleuMXB xvo8QyXOcywQm1wHiSqbgaTbIYx6M2ddOb2MQcbktHlvJp49pe0PMxaLqY8ktBh54pfa YzaHGgjBpkJuYuchEorlmm5bWk/9rLbi9/GGaq42S1A/Lfy3I3ipORmdefjxVA4wuAdL uDRQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=FLkSPLqdWchiZ/oz5Bm6mdpCQSd7koMGos2YDTUdRdc=; b=KLp5S7ooJeAfYG5vsKCKa+dM5qJPnQBsiFFa6/QOVIp8Ix4jVNVCLeOkQyCwO5hhyR Aj/gyKMzNd37JwPnhKlJ7t+UR8MPgOLQYKJ4SDlozkr/wMLNCMB/K0UL+fxf73hlj1NJ E2R3/iQmPnKGHV0V1iLSI1W53GuRgIzXbEtMcMWHgsEfN+SyWn4cPQoz21AGX7Xsz6II 4qEhTpRpK+sdfTQfArxneLVKPrDlTOAYd3sjLToL7vv55kQdL+izABtoYx/qBKVAg6xH kcGX0LkkBDLRISz05muLmIMrxdBYyySkoIpKPhQQmCnWcSZOewn1OIgz7wm1D40GQGtV MYPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=pSR0kohj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id yj10-20020a170907708a00b00726b86f9493si3610936ejb.752.2022.06.29.09.31.15; Wed, 29 Jun 2022 09:31:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=pSR0kohj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231484AbiF2QT6 (ORCPT + 99 others); Wed, 29 Jun 2022 12:19:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230072AbiF2QT5 (ORCPT ); Wed, 29 Jun 2022 12:19:57 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FA43338A3 for ; Wed, 29 Jun 2022 09:19:55 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id d17so17596615wrc.10 for ; Wed, 29 Jun 2022 09:19:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=FLkSPLqdWchiZ/oz5Bm6mdpCQSd7koMGos2YDTUdRdc=; b=pSR0kohjl1FpuuyJEjOCrCbFAf3ojag1+QUrSubdb5P7wmrWHATHA/3Ty6XQEmoTMD fiO37Na0ZzEFywr3cjXQk7QkjEjJwuihnwIGqGWPgfgh7kbpteT9g2/VIjIZ+NLTK92V YdaRt+ArsTeZYwyZNrUus21QGBF0uWqB2MExPhIb9P1VHKij3CRUVIpSGV3STpQYgdlq U1Ru94iunQEsPHIPKwnaAauFcVkwUPUQqfm1LpSbqKJ9RMPcQdLngEWz+9qQ4ld1zJ8k 7im8s7A8cLH2kIhhdgVbLJLF1WjAK/5BG2VJtD9Gy0jPApjZfCKbzNvzkzhPgYBL5M12 FUkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=FLkSPLqdWchiZ/oz5Bm6mdpCQSd7koMGos2YDTUdRdc=; b=Hl/Xpz4IpYTx58srboE68Txy7q3+Lelvd2b8QTGBv6TusYnqTKRgQyy+hLnBv4Es36 LOfzEuM/mCZ+Da1fDbEeACiBL130j6cOqWiqJAWn91uOly2c/7MkHR4ZrDwe1cv28ATH oQhCcYr1Qbp+oBAdtAZygOVyhgjXKKjsDEu2DcegvlGIpzp85DuM5nBxahudULeug0CT UXPZBRP0EfAdPFBNqj/OHHLAiywRbWJwxDtFLb5UZCogbLXXecj9xJdRSHvsnQhI9cUm ciduGCHKcp4ZWxCYi62SkxRcCYH9sMPxAi6JC94uu6lEOcIKbFRck7vaDJCzU03DEI1n qHug== X-Gm-Message-State: AJIora83QiVgtN+yyoVnQLlzhreeVnqA8YYHe+IIdtp4UYUeiCiiXjxo 5rNoTalWGqbkodxN3uMtNiYZShmcK5nWIhunl7d+yg== X-Received: by 2002:a5d:5a1a:0:b0:21b:883a:28a1 with SMTP id bq26-20020a5d5a1a000000b0021b883a28a1mr3940129wrb.40.1656519593880; Wed, 29 Jun 2022 09:19:53 -0700 (PDT) MIME-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> <20220614143353.1559597-7-irogers@google.com> In-Reply-To: From: Ian Rogers Date: Wed, 29 Jun 2022 09:19:40 -0700 Message-ID: Subject: Re: [PATCH v2 6/6] perf cpumap: Add range data encoding To: Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Stephane Eranian Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jun 29, 2022 at 2:31 AM Jiri Olsa wrote: > > On Tue, Jun 14, 2022 at 07:33:53AM -0700, Ian Rogers wrote: > > SNIP > > > -static size_t cpus_size(const struct perf_cpu_map *map) > > +static void synthesize_range_cpus(struct synthesize_cpu_map_data *data) > > { > > - return sizeof(struct cpu_map_entries) + perf_cpu_map__nr(map) * sizeof(u16); > > + data->data->type = PERF_CPU_MAP__RANGE_CPUS; > > + data->data->range_cpu_data.any_cpu = data->has_any_cpu; > > + data->data->range_cpu_data.start_cpu = data->min_cpu; > > + data->data->range_cpu_data.end_cpu = data->max_cpu; > > } > > > > -static size_t mask_size(const struct perf_cpu_map *map, int *max) > > -{ > > - *max = perf_cpu_map__max(map).cpu; > > - return sizeof(struct perf_record_mask_cpu_map32) + BITS_TO_U32(*max) * sizeof(__u32); > > -} > > - > > -static void *cpu_map_data__alloc(const struct perf_cpu_map *map, size_t *size, > > - u16 *type, int *max) > > +static void *cpu_map_data__alloc(struct synthesize_cpu_map_data *syn_data, > > + size_t header_size) > > { > > size_t size_cpus, size_mask; > > - bool is_dummy = perf_cpu_map__empty(map); > > > > - /* > > - * Both array and mask data have variable size based > > - * on the number of cpus and their actual values. > > - * The size of the 'struct perf_record_cpu_map_data' is: > > - * > > - * array = size of 'struct cpu_map_entries' + > > - * number of cpus * sizeof(u64) > > - * > > - * mask = size of 'struct perf_record_record_cpu_map' + > > - * maximum cpu bit converted to size of longs > > - * > > - * and finally + the size of 'struct perf_record_cpu_map_data'. > > - */ > > - size_cpus = cpus_size(map); > > - size_mask = mask_size(map, max); > > + syn_data->nr = perf_cpu_map__nr(syn_data->map); > > + syn_data->has_any_cpu = (perf_cpu_map__cpu(syn_data->map, 0).cpu == -1) ? 1 : 0; > > I'm bit lost in the logic in here.. should it be '.cpu != -1' ? > has_any_cpu is named as bool but used as index below ;-) > > could you please keep/update the comment above and explain > the conditions when each cpu_map type is taken So this relates to the CPU map "empty" problem that I've been moaning about for a time with Adrian, Arnaldo, etc. The CPU map can contain -1 for the "any CPU" case in perf_event_open, it can also contain CPU values after this as the result of a merge. Having only -1 in the CPU map is referred to as a dummy (presumably because the dummy event uses it), what does it mean if you have the -1 and CPU values? Things get really messy when you look at what the definition of empty is. Here I've used the term from perf_event_open that -1 means this can be on any CPU. As the CPU map data is sorted we can take advantage that the "any CPU" value always comes first. If we have it we set the bit here. We also use the bit below so that we ignore the first array element if it has -1 in it. As the -1 adjusts the CPU map size, there are some other adjustments as well. Hopefully this makes things clearer and I want to rewrite parts of the CPU map API to make them clearer too - empty should mean == NULL or nr == 0, dummy is more confusing to me than "any CPU", etc. Thanks, Ian > thanks, > jirka > > > > > - if (is_dummy || (size_cpus < size_mask)) { > > - *size += size_cpus; > > - *type = PERF_CPU_MAP__CPUS; > > - } else { > > - *size += size_mask; > > - *type = PERF_CPU_MAP__MASK; > > + syn_data->min_cpu = perf_cpu_map__cpu(syn_data->map, syn_data->has_any_cpu).cpu; > > + syn_data->max_cpu = perf_cpu_map__max(syn_data->map).cpu; > > + if (syn_data->max_cpu - syn_data->min_cpu + 1 == syn_data->nr - syn_data->has_any_cpu) { > > + /* A consecutive range of CPUs can be encoded using a range. */ > > + assert(sizeof(u16) + sizeof(struct perf_record_range_cpu_map) == sizeof(u64)); > > + syn_data->type = PERF_CPU_MAP__RANGE_CPUS; > > + syn_data->size = header_size + sizeof(u64); > > + return zalloc(syn_data->size); > > } > > > > - *size += sizeof(__u16); /* For perf_record_cpu_map_data.type. */ > > - *size = PERF_ALIGN(*size, sizeof(u64)); > > - return zalloc(*size); > > + size_cpus = sizeof(u16) + sizeof(struct cpu_map_entries) + syn_data->nr * sizeof(u16); > > + /* Due to padding, the 4bytes per entry mask variant is always smaller. */ > > + size_mask = sizeof(u16) + sizeof(struct perf_record_mask_cpu_map32) + > > + BITS_TO_U32(syn_data->max_cpu) * sizeof(__u32); > > + if (syn_data->has_any_cpu || size_cpus < size_mask) { > > + /* Follow the CPU map encoding. */ > > + syn_data->type = PERF_CPU_MAP__CPUS; > > + syn_data->size = header_size + PERF_ALIGN(size_cpus, sizeof(u64)); > > + return zalloc(syn_data->size); > > + } > > + /* Encode using a bitmask. */ > > + syn_data->type = PERF_CPU_MAP__MASK; > > + syn_data->size = header_size + PERF_ALIGN(size_mask, sizeof(u64)); > > + return zalloc(syn_data->size); > > SNIP