History

perf/x86/intel: Add Alder Lake Hybrid support

Alder Lake Hybrid system has two different types of core, Golden Cove core and Gracemont core. The Golden Cove core is registered to "cpu_core" PMU. The Gracemont core is registered to "cpu_atom" PMU. The difference between the two PMUs include: - Number of GP and fixed counters - Events - The "cpu_core" PMU supports Topdown metrics. The "cpu_atom" PMU supports PEBS-via-PT. The "cpu_core" PMU is similar to the Sapphire Rapids PMU, but without PMEM. The "cpu_atom" PMU is similar to Tremont, but with different events, event_constraints, extra_regs and number of counters. The mem-loads AUX event workaround only applies to the Golden Cove core. Users may disable all CPUs of the same CPU type on the command line or in the BIOS. For this case, perf still register a PMU for the CPU type but the CPU mask is 0. Current caps/pmu_name is usually the microarch codename. Assign the "alderlake_hybrid" to the caps/pmu_name of both PMUs to indicate the hybrid Alder Lake microarchitecture.

Kan Liang committed 5 years ago

Commit f83d2f91 parent 3e9a8b23 files · +268 −1Browse files

Unified · Split

3 files
  1. arch/x86/events/intel/core.c +254 −1
  2. arch/x86/events/intel/ds.c +7 −0
  3. arch/x86/events/perf_event.h +7 −0
arch/x86/events/intel/core.c+254−1
@@ -2076,6 +2076,14 @@ static struct extra_reg intel_tnt_extra_regs[] __read_mostly = { · 2075 unmodified lines
2076 EVENT_EXTRA_END2076 EVENT_EXTRA_END
2077};2077};
2078 2078
2079static struct extra_reg intel_grt_extra_regs[] __read_mostly = {
2080 /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
2081 INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0),
2082 INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1),
2083 INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x5d0),
2084 EVENT_EXTRA_END
2085};
2086
2079#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */2087#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
2080#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */2088#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
2081#define KNL_MCDRAM_LOCAL BIT_ULL(21)2089#define KNL_MCDRAM_LOCAL BIT_ULL(21)
@@ -2430,6 +2438,16 @@ static int icl_set_topdown_event_period(struct perf_event *event) · 348 unmodified lines
2430 return 0;2438 return 0;
2431}2439}
2432 2440
2441static int adl_set_topdown_event_period(struct perf_event *event)
2442{
2443 struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
2444
2445 if (pmu->cpu_type != hybrid_big)
2446 return 0;
2447
2448 return icl_set_topdown_event_period(event);
2449}
2450
2433static inline u64 icl_get_metrics_event_value(u64 metric, u64 slots, int idx)2451static inline u64 icl_get_metrics_event_value(u64 metric, u64 slots, int idx)
2434{2452{
2435 u32 val;2453 u32 val;
@@ -2570,6 +2588,17 @@ static u64 icl_update_topdown_event(struct perf_event *event) · 134 unmodified lines
2570 x86_pmu.num_topdown_events - 1);2588 x86_pmu.num_topdown_events - 1);
2571}2589}
2572 2590
2591static u64 adl_update_topdown_event(struct perf_event *event)
2592{
2593 struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
2594
2595 if (pmu->cpu_type != hybrid_big)
2596 return 0;
2597
2598 return icl_update_topdown_event(event);
2599}
2600
2601
2573static void intel_pmu_read_topdown_event(struct perf_event *event)2602static void intel_pmu_read_topdown_event(struct perf_event *event)
2574{2603{
2575 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);2604 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -3655,6 +3684,17 @@ static inline bool is_mem_loads_aux_event(struct perf_event *event) · 1079 unmodified lines
3655 return (event->attr.config & INTEL_ARCH_EVENT_MASK) == X86_CONFIG(.event=0x03, .umask=0x82);3684 return (event->attr.config & INTEL_ARCH_EVENT_MASK) == X86_CONFIG(.event=0x03, .umask=0x82);
3656}3685}
3657 3686
3687static inline bool require_mem_loads_aux_event(struct perf_event *event)
3688{
3689 if (!(x86_pmu.flags & PMU_FL_MEM_LOADS_AUX))
3690 return false;
3691
3692 if (is_hybrid())
3693 return hybrid_pmu(event->pmu)->cpu_type == hybrid_big;
3694
3695 return true;
3696}
3697
3658static inline bool intel_pmu_has_cap(struct perf_event *event, int idx)3698static inline bool intel_pmu_has_cap(struct perf_event *event, int idx)
3659{3699{
3660 union perf_capabilities *intel_cap = &hybrid(event->pmu, intel_cap);3700 union perf_capabilities *intel_cap = &hybrid(event->pmu, intel_cap);
@@ -3779,7 +3819,7 @@ static int intel_pmu_hw_config(struct perf_event *event) · 118 unmodified lines
3779 * event. The rule is to simplify the implementation of the check.3819 * event. The rule is to simplify the implementation of the check.
3780 * That's because perf cannot have a complete group at the moment.3820 * That's because perf cannot have a complete group at the moment.
3781 */3821 */
3782 if (x86_pmu.flags & PMU_FL_MEM_LOADS_AUX &&3822 if (require_mem_loads_aux_event(event) &&
3783 (event->attr.sample_type & PERF_SAMPLE_DATA_SRC) &&3823 (event->attr.sample_type & PERF_SAMPLE_DATA_SRC) &&
3784 is_mem_loads_event(event)) {3824 is_mem_loads_event(event)) {
3785 struct perf_event *leader = event->group_leader;3825 struct perf_event *leader = event->group_leader;
@@ -4056,6 +4096,39 @@ tfa_get_event_constraints(struct cpu_hw_events *cpuc, int idx, · 270 unmodified lines
4056 return c;4096 return c;
4057}4097}
4058 4098
4099static struct event_constraint *
4100adl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
4101 struct perf_event *event)
4102{
4103 struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
4104
4105 if (pmu->cpu_type == hybrid_big)
4106 return spr_get_event_constraints(cpuc, idx, event);
4107 else if (pmu->cpu_type == hybrid_small)
4108 return tnt_get_event_constraints(cpuc, idx, event);
4109
4110 WARN_ON(1);
4111 return &emptyconstraint;
4112}
4113
4114static int adl_hw_config(struct perf_event *event)
4115{
4116 struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
4117
4118 if (pmu->cpu_type == hybrid_big)
4119 return hsw_hw_config(event);
4120 else if (pmu->cpu_type == hybrid_small)
4121 return intel_pmu_hw_config(event);
4122
4123 WARN_ON(1);
4124 return -EOPNOTSUPP;
4125}
4126
4127static u8 adl_get_hybrid_cpu_type(void)
4128{
4129 return hybrid_big;
4130}
4131
4059/*4132/*
4060 * Broadwell:4133 * Broadwell:
4061 *4134 *
@@ -4416,6 +4489,14 @@ static int intel_pmu_aux_output_match(struct perf_event *event) · 354 unmodified lines
4416 return is_intel_pt_event(event);4489 return is_intel_pt_event(event);
4417}4490}
4418 4491
4492static int intel_pmu_filter_match(struct perf_event *event)
4493{
4494 struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);
4495 unsigned int cpu = smp_processor_id();
4496
4497 return cpumask_test_cpu(cpu, &pmu->supported_cpus);
4498}
4499
4419PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");4500PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
4420 4501
4421PMU_FORMAT_ATTR(ldlat, "config1:0-15");4502PMU_FORMAT_ATTR(ldlat, "config1:0-15");
@@ -5118,6 +5199,84 @@ static const struct attribute_group *attr_update[] = { · 696 unmodified lines
5118 NULL,5199 NULL,
5119};5200};
5120 5201
5202EVENT_ATTR_STR_HYBRID(slots, slots_adl, "event=0x00,umask=0x4", hybrid_big);
5203EVENT_ATTR_STR_HYBRID(topdown-retiring, td_retiring_adl, "event=0xc2,umask=0x0;event=0x00,umask=0x80", hybrid_big_small);
5204EVENT_ATTR_STR_HYBRID(topdown-bad-spec, td_bad_spec_adl, "event=0x73,umask=0x0;event=0x00,umask=0x81", hybrid_big_small);
5205EVENT_ATTR_STR_HYBRID(topdown-fe-bound, td_fe_bound_adl, "event=0x71,umask=0x0;event=0x00,umask=0x82", hybrid_big_small);
5206EVENT_ATTR_STR_HYBRID(topdown-be-bound, td_be_bound_adl, "event=0x74,umask=0x0;event=0x00,umask=0x83", hybrid_big_small);
5207EVENT_ATTR_STR_HYBRID(topdown-heavy-ops, td_heavy_ops_adl, "event=0x00,umask=0x84", hybrid_big);
5208EVENT_ATTR_STR_HYBRID(topdown-br-mispredict, td_br_mis_adl, "event=0x00,umask=0x85", hybrid_big);
5209EVENT_ATTR_STR_HYBRID(topdown-fetch-lat, td_fetch_lat_adl, "event=0x00,umask=0x86", hybrid_big);
5210EVENT_ATTR_STR_HYBRID(topdown-mem-bound, td_mem_bound_adl, "event=0x00,umask=0x87", hybrid_big);
5211
5212static struct attribute *adl_hybrid_events_attrs[] = {
5213 EVENT_PTR(slots_adl),
5214 EVENT_PTR(td_retiring_adl),
5215 EVENT_PTR(td_bad_spec_adl),
5216 EVENT_PTR(td_fe_bound_adl),
5217 EVENT_PTR(td_be_bound_adl),
5218 EVENT_PTR(td_heavy_ops_adl),
5219 EVENT_PTR(td_br_mis_adl),
5220 EVENT_PTR(td_fetch_lat_adl),
5221 EVENT_PTR(td_mem_bound_adl),
5222 NULL,
5223};
5224
5225/* Must be in IDX order */
5226EVENT_ATTR_STR_HYBRID(mem-loads, mem_ld_adl, "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3", hybrid_big_small);
5227EVENT_ATTR_STR_HYBRID(mem-stores, mem_st_adl, "event=0xd0,umask=0x6;event=0xcd,umask=0x2", hybrid_big_small);
5228EVENT_ATTR_STR_HYBRID(mem-loads-aux, mem_ld_aux_adl, "event=0x03,umask=0x82", hybrid_big);
5229
5230static struct attribute *adl_hybrid_mem_attrs[] = {
5231 EVENT_PTR(mem_ld_adl),
5232 EVENT_PTR(mem_st_adl),
5233 EVENT_PTR(mem_ld_aux_adl),
5234 NULL,
5235};
5236
5237EVENT_ATTR_STR_HYBRID(tx-start, tx_start_adl, "event=0xc9,umask=0x1", hybrid_big);
5238EVENT_ATTR_STR_HYBRID(tx-commit, tx_commit_adl, "event=0xc9,umask=0x2", hybrid_big);
5239EVENT_ATTR_STR_HYBRID(tx-abort, tx_abort_adl, "event=0xc9,umask=0x4", hybrid_big);
5240EVENT_ATTR_STR_HYBRID(tx-conflict, tx_conflict_adl, "event=0x54,umask=0x1", hybrid_big);
5241EVENT_ATTR_STR_HYBRID(cycles-t, cycles_t_adl, "event=0x3c,in_tx=1", hybrid_big);
5242EVENT_ATTR_STR_HYBRID(cycles-ct, cycles_ct_adl, "event=0x3c,in_tx=1,in_tx_cp=1", hybrid_big);
5243EVENT_ATTR_STR_HYBRID(tx-capacity-read, tx_capacity_read_adl, "event=0x54,umask=0x80", hybrid_big);
5244EVENT_ATTR_STR_HYBRID(tx-capacity-write, tx_capacity_write_adl, "event=0x54,umask=0x2", hybrid_big);
5245
5246static struct attribute *adl_hybrid_tsx_attrs[] = {
5247 EVENT_PTR(tx_start_adl),
5248 EVENT_PTR(tx_abort_adl),
5249 EVENT_PTR(tx_commit_adl),
5250 EVENT_PTR(tx_capacity_read_adl),
5251 EVENT_PTR(tx_capacity_write_adl),
5252 EVENT_PTR(tx_conflict_adl),
5253 EVENT_PTR(cycles_t_adl),
5254 EVENT_PTR(cycles_ct_adl),
5255 NULL,
5256};
5257
5258FORMAT_ATTR_HYBRID(in_tx, hybrid_big);
5259FORMAT_ATTR_HYBRID(in_tx_cp, hybrid_big);
5260FORMAT_ATTR_HYBRID(offcore_rsp, hybrid_big_small);
5261FORMAT_ATTR_HYBRID(ldlat, hybrid_big_small);
5262FORMAT_ATTR_HYBRID(frontend, hybrid_big);
5263
5264static struct attribute *adl_hybrid_extra_attr_rtm[] = {
5265 FORMAT_HYBRID_PTR(in_tx),
5266 FORMAT_HYBRID_PTR(in_tx_cp),
5267 FORMAT_HYBRID_PTR(offcore_rsp),
5268 FORMAT_HYBRID_PTR(ldlat),
5269 FORMAT_HYBRID_PTR(frontend),
5270 NULL,
5271};
5272
5273static struct attribute *adl_hybrid_extra_attr[] = {
5274 FORMAT_HYBRID_PTR(offcore_rsp),
5275 FORMAT_HYBRID_PTR(ldlat),
5276 FORMAT_HYBRID_PTR(frontend),
5277 NULL,
5278};
5279
5121static bool is_attr_for_this_pmu(struct kobject *kobj, struct attribute *attr)5280static bool is_attr_for_this_pmu(struct kobject *kobj, struct attribute *attr)
5122{5281{
5123 struct device *dev = kobj_to_dev(kobj);5282 struct device *dev = kobj_to_dev(kobj);
@@ -5347,6 +5506,7 @@ __init int intel_pmu_init(void) · 223 unmodified lines
5347 bool pmem = false;5506 bool pmem = false;
5348 int version, i;5507 int version, i;
5349 char *name;5508 char *name;
5509 struct x86_hybrid_pmu *pmu;
5350 5510
5351 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {5511 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
5352 switch (boot_cpu_data.x86) {5512 switch (boot_cpu_data.x86) {
@@ -5941,6 +6101,99 @@ __init int intel_pmu_init(void) · 588 unmodified lines
5941 name = "sapphire_rapids";6101 name = "sapphire_rapids";
5942 break;6102 break;
5943 6103
6104 case INTEL_FAM6_ALDERLAKE:
6105 case INTEL_FAM6_ALDERLAKE_L:
6106 /*
6107 * Alder Lake has 2 types of CPU, core and atom.
6108 *
6109 * Initialize the common PerfMon capabilities here.
6110 */
6111 x86_pmu.hybrid_pmu = kcalloc(X86_HYBRID_NUM_PMUS,
6112 sizeof(struct x86_hybrid_pmu),
6113 GFP_KERNEL);
6114 if (!x86_pmu.hybrid_pmu)
6115 return -ENOMEM;
6116 static_branch_enable(&perf_is_hybrid);
6117 x86_pmu.num_hybrid_pmus = X86_HYBRID_NUM_PMUS;
6118
6119 x86_pmu.late_ack = true;
6120 x86_pmu.pebs_aliases = NULL;
6121 x86_pmu.pebs_prec_dist = true;
6122 x86_pmu.pebs_block = true;
6123 x86_pmu.flags |= PMU_FL_HAS_RSP_1;
6124 x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
6125 x86_pmu.flags |= PMU_FL_PEBS_ALL;
6126 x86_pmu.flags |= PMU_FL_INSTR_LATENCY;
6127 x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX;
6128 x86_pmu.lbr_pt_coexist = true;
6129 intel_pmu_pebs_data_source_skl(false);
6130 x86_pmu.num_topdown_events = 8;
6131 x86_pmu.update_topdown_event = adl_update_topdown_event;
6132 x86_pmu.set_topdown_event_period = adl_set_topdown_event_period;
6133
6134 x86_pmu.filter_match = intel_pmu_filter_match;
6135 x86_pmu.get_event_constraints = adl_get_event_constraints;
6136 x86_pmu.hw_config = adl_hw_config;
6137 x86_pmu.limit_period = spr_limit_period;
6138 x86_pmu.get_hybrid_cpu_type = adl_get_hybrid_cpu_type;
6139 /*
6140 * The rtm_abort_event is used to check whether to enable GPRs
6141 * for the RTM abort event. Atom doesn't have the RTM abort
6142 * event. There is no harmful to set it in the common
6143 * x86_pmu.rtm_abort_event.
6144 */
6145 x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xc9, .umask=0x04);
6146
6147 td_attr = adl_hybrid_events_attrs;
6148 mem_attr = adl_hybrid_mem_attrs;
6149 tsx_attr = adl_hybrid_tsx_attrs;
6150 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
6151 adl_hybrid_extra_attr_rtm : adl_hybrid_extra_attr;
6152
6153 /* Initialize big core specific PerfMon capabilities.*/
6154 pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
6155 pmu->name = "cpu_core";
6156 pmu->cpu_type = hybrid_big;
6157 pmu->num_counters = x86_pmu.num_counters + 2;
6158 pmu->num_counters_fixed = x86_pmu.num_counters_fixed + 1;
6159 pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
6160 pmu->unconstrained = (struct event_constraint)
6161 __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
6162 0, pmu->num_counters, 0, 0);
6163 pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
6164 pmu->intel_cap.perf_metrics = 1;
6165 pmu->intel_cap.pebs_output_pt_available = 0;
6166
6167 memcpy(pmu->hw_cache_event_ids, spr_hw_cache_event_ids, sizeof(pmu->hw_cache_event_ids));
6168 memcpy(pmu->hw_cache_extra_regs, spr_hw_cache_extra_regs, sizeof(pmu->hw_cache_extra_regs));
6169 pmu->event_constraints = intel_spr_event_constraints;
6170 pmu->pebs_constraints = intel_spr_pebs_event_constraints;
6171 pmu->extra_regs = intel_spr_extra_regs;
6172
6173 /* Initialize Atom core specific PerfMon capabilities.*/
6174 pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];
6175 pmu->name = "cpu_atom";
6176 pmu->cpu_type = hybrid_small;
6177 pmu->num_counters = x86_pmu.num_counters;
6178 pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
6179 pmu->max_pebs_events = x86_pmu.max_pebs_events;
6180 pmu->unconstrained = (struct event_constraint)
6181 __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
6182 0, pmu->num_counters, 0, 0);
6183 pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
6184 pmu->intel_cap.perf_metrics = 0;
6185 pmu->intel_cap.pebs_output_pt_available = 1;
6186
6187 memcpy(pmu->hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(pmu->hw_cache_event_ids));
6188 memcpy(pmu->hw_cache_extra_regs, tnt_hw_cache_extra_regs, sizeof(pmu->hw_cache_extra_regs));
6189 pmu->hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
6190 pmu->event_constraints = intel_slm_event_constraints;
6191 pmu->pebs_constraints = intel_grt_pebs_event_constraints;
6192 pmu->extra_regs = intel_grt_extra_regs;
6193 pr_cont("Alderlake Hybrid events, ");
6194 name = "alderlake_hybrid";
6195 break;
6196
5944 default:6197 default:
5945 switch (x86_pmu.version) {6198 switch (x86_pmu.version) {
5946 case 1:6199 case 1:
arch/x86/events/intel/ds.c+7−0
@@ -779,6 +779,13 @@ struct event_constraint intel_glm_pebs_event_constraints[] = { · 778 unmodified lines
779 EVENT_CONSTRAINT_END779 EVENT_CONSTRAINT_END
780};780};
781 781
782struct event_constraint intel_grt_pebs_event_constraints[] = {
783 /* Allow all events as PEBS with no flags */
784 INTEL_PLD_CONSTRAINT(0x5d0, 0xf),
785 INTEL_PSD_CONSTRAINT(0x6d0, 0xf),
786 EVENT_CONSTRAINT_END
787};
788
782struct event_constraint intel_nehalem_pebs_event_constraints[] = {789struct event_constraint intel_nehalem_pebs_event_constraints[] = {
783 INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */790 INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
784 INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */791 INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
arch/x86/events/perf_event.h+7−0
@@ -692,6 +692,11 @@ enum hybrid_pmu_type { · 691 unmodified lines
692 hybrid_big_small = hybrid_big | hybrid_small,692 hybrid_big_small = hybrid_big | hybrid_small,
693};693};
694 694
695#define X86_HYBRID_PMU_ATOM_IDX 0
696#define X86_HYBRID_PMU_CORE_IDX 1
697
698#define X86_HYBRID_NUM_PMUS 2
699
695/*700/*
696 * struct x86_pmu - generic x86 pmu701 * struct x86_pmu - generic x86 pmu
697 */702 */
@@ -1258,6 +1263,8 @@ extern struct event_constraint intel_glm_pebs_event_constraints[]; · 560 unmodified lines
1258 1263
1259extern struct event_constraint intel_glp_pebs_event_constraints[];1264extern struct event_constraint intel_glp_pebs_event_constraints[];
1260 1265
1266extern struct event_constraint intel_grt_pebs_event_constraints[];
1267
1261extern struct event_constraint intel_nehalem_pebs_event_constraints[];1268extern struct event_constraint intel_nehalem_pebs_event_constraints[];
1262 1269
1263extern struct event_constraint intel_westmere_pebs_event_constraints[];1270extern struct event_constraint intel_westmere_pebs_event_constraints[];

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t