History

PM, libnvdimm: Add runtime firmware activation support

Abstract platform specific mechanics for nvdimm firmware activation behind a handful of generic ops. At the bus level ->activate_state() indicates the unified state (idle, busy, armed) of all DIMMs on the bus, and ->capability() indicates the system state expectations for activate. At the DIMM level ->activate_state() indicates the per-DIMM state, ->activate_result() indicates the outcome of the last activation attempt, and ->arm() attempts to transition the DIMM from 'idle' to 'armed'. A new hibernate_quiet_exec() facility is added to support firmware activation in an OS defined system quiesce state. It leverages the fact that the hibernate-freeze state wants to assert that a memory hibernation snapshot can be taken. This is in contrast to a platform firmware defined quiesce state that may forcefully quiet the memory controller independent of whether an individual device-driver properly supports hibernate-freeze. The libnvdimm sysfs interface is extended to support detection of a firmware activate capability. The mechanism supports enumeration and triggering of firmware activate, optionally in the hibernate_quiet_exec() context. [rafael: hibernate_quiet_exec() proposal] [vishal: fix up sparse warning, grammar in Documentation/]

Dan Williams committed 6 years ago

Commit 48001ea1 parent 5cf81ce8 files · +500 −0Browse files

Unified · Split

8 files
  1. Documentation/ABI/testing/sysfs-bus-nvdimm +2 −0
  2. Documentation/driver-api/nvdimm/firmware-activate.rst +86 −0
  3. drivers/nvdimm/core.c +149 −0
  4. drivers/nvdimm/dimm_devs.c +115 −0
  5. drivers/nvdimm/nd-core.h +1 −0
  6. include/linux/libnvdimm.h +44 −0
  7. include/linux/suspend.h +6 −0
  8. kernel/power/hibernate.c +97 −0
Documentation/ABI/testing/sysfs-bus-nvdimm+2−0
@@ -0,0 +1,2 @@
1The libnvdimm sub-system implements a common sysfs interface for
2platform nvdimm resources. See Documentation/driver-api/nvdimm/.
Documentation/driver-api/nvdimm/firmware-activate.rst+86−0
@@ -0,0 +1,86 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3==================================
4NVDIMM Runtime Firmware Activation
5==================================
6
7Some persistent memory devices run a firmware locally on the device /
8"DIMM" to perform tasks like media management, capacity provisioning,
9and health monitoring. The process of updating that firmware typically
10involves a reboot because it has implications for in-flight memory
11transactions. However, reboots are disruptive and at least the Intel
12persistent memory platform implementation, described by the Intel ACPI
13DSM specification [1], has added support for activating firmware at
14runtime.
15
16A native sysfs interface is implemented in libnvdimm to allow platform
17to advertise and control their local runtime firmware activation
18capability.
19
20The libnvdimm bus object, ndbusX, implements an ndbusX/firmware/activate
21attribute that shows the state of the firmware activation as one of 'idle',
22'armed', 'overflow', and 'busy'.
23
24- idle:
25 No devices are set / armed to activate firmware
26
27- armed:
28 At least one device is armed
29
30- busy:
31 In the busy state armed devices are in the process of transitioning
32 back to idle and completing an activation cycle.
33
34- overflow:
35 If the platform has a concept of incremental work needed to perform
36 the activation it could be the case that too many DIMMs are armed for
37 activation. In that scenario the potential for firmware activation to
38 timeout is indicated by the 'overflow' state.
39
40The 'ndbusX/firmware/activate' property can be written with a value of
41either 'live', or 'quiesce'. A value of 'quiesce' triggers the kernel to
42run firmware activation from within the equivalent of the hibernation
43'freeze' state where drivers and applications are notified to stop their
44modifications of system memory. A value of 'live' attempts
45firmware activation without this hibernation cycle. The
46'ndbusX/firmware/activate' property will be elided completely if no
47firmware activation capability is detected.
48
49Another property 'ndbusX/firmware/capability' indicates a value of
50'live' or 'quiesce', where 'live' indicates that the firmware
51does not require or inflict any quiesce period on the system to update
52firmware. A capability value of 'quiesce' indicates that firmware does
53expect and injects a quiet period for the memory controller, but 'live'
54may still be written to 'ndbusX/firmware/activate' as an override to
55assume the risk of racing firmware update with in-flight device and
56application activity. The 'ndbusX/firmware/capability' property will be
57elided completely if no firmware activation capability is detected.
58
59The libnvdimm memory-device / DIMM object, nmemX, implements
60'nmemX/firmware/activate' and 'nmemX/firmware/result' attributes to
61communicate the per-device firmware activation state. Similar to the
62'ndbusX/firmware/activate' attribute, the 'nmemX/firmware/activate'
63attribute indicates 'idle', 'armed', or 'busy'. The state transitions
64from 'armed' to 'idle' when the system is prepared to activate firmware,
65firmware staged + state set to armed, and 'ndbusX/firmware/activate' is
66triggered. After that activation event the nmemX/firmware/result
67attribute reflects the state of the last activation as one of:
68
69- none:
70 No runtime activation triggered since the last time the device was reset
71
72- success:
73 The last runtime activation completed successfully.
74
75- fail:
76 The last runtime activation failed for device-specific reasons.
77
78- not_staged:
79 The last runtime activation failed due to a sequencing error of the
80 firmware image not being staged.
81
82- need_reset:
83 Runtime firmware activation failed, but the firmware can still be
84 activated via the legacy method of power-cycling the system.
85
86[1]: https://docs.pmem.io/persistent-memory/
drivers/nvdimm/core.c+149−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
4 */4 */
5#include <linux/libnvdimm.h>5#include <linux/libnvdimm.h>
6#include <linux/badblocks.h>6#include <linux/badblocks.h>
7#include <linux/suspend.h>
7#include <linux/export.h>8#include <linux/export.h>
8#include <linux/module.h>9#include <linux/module.h>
9#include <linux/blkdev.h>10#include <linux/blkdev.h>
@@ -389,8 +390,156 @@ static const struct attribute_group nvdimm_bus_attribute_group = { · 379 unmodified lines
389 .attrs = nvdimm_bus_attributes,390 .attrs = nvdimm_bus_attributes,
390};391};
391 392
393static ssize_t capability_show(struct device *dev,
394 struct device_attribute *attr, char *buf)
395{
396 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
397 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
398 enum nvdimm_fwa_capability cap;
399
400 if (!nd_desc->fw_ops)
401 return -EOPNOTSUPP;
402
403 nvdimm_bus_lock(dev);
404 cap = nd_desc->fw_ops->capability(nd_desc);
405 nvdimm_bus_unlock(dev);
406
407 switch (cap) {
408 case NVDIMM_FWA_CAP_QUIESCE:
409 return sprintf(buf, "quiesce\n");
410 case NVDIMM_FWA_CAP_LIVE:
411 return sprintf(buf, "live\n");
412 default:
413 return -EOPNOTSUPP;
414 }
415}
416
417static DEVICE_ATTR_RO(capability);
418
419static ssize_t activate_show(struct device *dev,
420 struct device_attribute *attr, char *buf)
421{
422 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
423 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
424 enum nvdimm_fwa_capability cap;
425 enum nvdimm_fwa_state state;
426
427 if (!nd_desc->fw_ops)
428 return -EOPNOTSUPP;
429
430 nvdimm_bus_lock(dev);
431 cap = nd_desc->fw_ops->capability(nd_desc);
432 state = nd_desc->fw_ops->activate_state(nd_desc);
433 nvdimm_bus_unlock(dev);
434
435 if (cap < NVDIMM_FWA_CAP_QUIESCE)
436 return -EOPNOTSUPP;
437
438 switch (state) {
439 case NVDIMM_FWA_IDLE:
440 return sprintf(buf, "idle\n");
441 case NVDIMM_FWA_BUSY:
442 return sprintf(buf, "busy\n");
443 case NVDIMM_FWA_ARMED:
444 return sprintf(buf, "armed\n");
445 case NVDIMM_FWA_ARM_OVERFLOW:
446 return sprintf(buf, "overflow\n");
447 default:
448 return -ENXIO;
449 }
450}
451
452static int exec_firmware_activate(void *data)
453{
454 struct nvdimm_bus_descriptor *nd_desc = data;
455
456 return nd_desc->fw_ops->activate(nd_desc);
457}
458
459static ssize_t activate_store(struct device *dev,
460 struct device_attribute *attr, const char *buf, size_t len)
461{
462 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
463 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
464 enum nvdimm_fwa_state state;
465 bool quiesce;
466 ssize_t rc;
467
468 if (!nd_desc->fw_ops)
469 return -EOPNOTSUPP;
470
471 if (sysfs_streq(buf, "live"))
472 quiesce = false;
473 else if (sysfs_streq(buf, "quiesce"))
474 quiesce = true;
475 else
476 return -EINVAL;
477
478 nvdimm_bus_lock(dev);
479 state = nd_desc->fw_ops->activate_state(nd_desc);
480
481 switch (state) {
482 case NVDIMM_FWA_BUSY:
483 rc = -EBUSY;
484 break;
485 case NVDIMM_FWA_ARMED:
486 case NVDIMM_FWA_ARM_OVERFLOW:
487 if (quiesce)
488 rc = hibernate_quiet_exec(exec_firmware_activate, nd_desc);
489 else
490 rc = nd_desc->fw_ops->activate(nd_desc);
491 break;
492 case NVDIMM_FWA_IDLE:
493 default:
494 rc = -ENXIO;
495 }
496 nvdimm_bus_unlock(dev);
497
498 if (rc == 0)
499 rc = len;
500 return rc;
501}
502
503static DEVICE_ATTR_ADMIN_RW(activate);
504
505static umode_t nvdimm_bus_firmware_visible(struct kobject *kobj, struct attribute *a, int n)
506{
507 struct device *dev = container_of(kobj, typeof(*dev), kobj);
508 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
509 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
510 enum nvdimm_fwa_capability cap;
511
512 /*
513 * Both 'activate' and 'capability' disappear when no ops
514 * detected, or a negative capability is indicated.
515 */
516 if (!nd_desc->fw_ops)
517 return 0;
518
519 nvdimm_bus_lock(dev);
520 cap = nd_desc->fw_ops->capability(nd_desc);
521 nvdimm_bus_unlock(dev);
522
523 if (cap < NVDIMM_FWA_CAP_QUIESCE)
524 return 0;
525
526 return a->mode;
527}
528static struct attribute *nvdimm_bus_firmware_attributes[] = {
529 &dev_attr_activate.attr,
530 &dev_attr_capability.attr,
531 NULL,
532};
533
534static const struct attribute_group nvdimm_bus_firmware_attribute_group = {
535 .name = "firmware",
536 .attrs = nvdimm_bus_firmware_attributes,
537 .is_visible = nvdimm_bus_firmware_visible,
538};
539
392const struct attribute_group *nvdimm_bus_attribute_groups[] = {540const struct attribute_group *nvdimm_bus_attribute_groups[] = {
393 &nvdimm_bus_attribute_group,541 &nvdimm_bus_attribute_group,
542 &nvdimm_bus_firmware_attribute_group,
394 NULL,543 NULL,
395};544};
396 545
drivers/nvdimm/dimm_devs.c+115−0
@@ -446,9 +446,124 @@ static const struct attribute_group nvdimm_attribute_group = { · 445 unmodified lines
446 .is_visible = nvdimm_visible,446 .is_visible = nvdimm_visible,
447};447};
448 448
449static ssize_t result_show(struct device *dev, struct device_attribute *attr, char *buf)
450{
451 struct nvdimm *nvdimm = to_nvdimm(dev);
452 enum nvdimm_fwa_result result;
453
454 if (!nvdimm->fw_ops)
455 return -EOPNOTSUPP;
456
457 nvdimm_bus_lock(dev);
458 result = nvdimm->fw_ops->activate_result(nvdimm);
459 nvdimm_bus_unlock(dev);
460
461 switch (result) {
462 case NVDIMM_FWA_RESULT_NONE:
463 return sprintf(buf, "none\n");
464 case NVDIMM_FWA_RESULT_SUCCESS:
465 return sprintf(buf, "success\n");
466 case NVDIMM_FWA_RESULT_FAIL:
467 return sprintf(buf, "fail\n");
468 case NVDIMM_FWA_RESULT_NOTSTAGED:
469 return sprintf(buf, "not_staged\n");
470 case NVDIMM_FWA_RESULT_NEEDRESET:
471 return sprintf(buf, "need_reset\n");
472 default:
473 return -ENXIO;
474 }
475}
476static DEVICE_ATTR_ADMIN_RO(result);
477
478static ssize_t activate_show(struct device *dev, struct device_attribute *attr, char *buf)
479{
480 struct nvdimm *nvdimm = to_nvdimm(dev);
481 enum nvdimm_fwa_state state;
482
483 if (!nvdimm->fw_ops)
484 return -EOPNOTSUPP;
485
486 nvdimm_bus_lock(dev);
487 state = nvdimm->fw_ops->activate_state(nvdimm);
488 nvdimm_bus_unlock(dev);
489
490 switch (state) {
491 case NVDIMM_FWA_IDLE:
492 return sprintf(buf, "idle\n");
493 case NVDIMM_FWA_BUSY:
494 return sprintf(buf, "busy\n");
495 case NVDIMM_FWA_ARMED:
496 return sprintf(buf, "armed\n");
497 default:
498 return -ENXIO;
499 }
500}
501
502static ssize_t activate_store(struct device *dev, struct device_attribute *attr,
503 const char *buf, size_t len)
504{
505 struct nvdimm *nvdimm = to_nvdimm(dev);
506 enum nvdimm_fwa_trigger arg;
507 int rc;
508
509 if (!nvdimm->fw_ops)
510 return -EOPNOTSUPP;
511
512 if (sysfs_streq(buf, "arm"))
513 arg = NVDIMM_FWA_ARM;
514 else if (sysfs_streq(buf, "disarm"))
515 arg = NVDIMM_FWA_DISARM;
516 else
517 return -EINVAL;
518
519 nvdimm_bus_lock(dev);
520 rc = nvdimm->fw_ops->arm(nvdimm, arg);
521 nvdimm_bus_unlock(dev);
522
523 if (rc < 0)
524 return rc;
525 return len;
526}
527static DEVICE_ATTR_ADMIN_RW(activate);
528
529static struct attribute *nvdimm_firmware_attributes[] = {
530 &dev_attr_activate.attr,
531 &dev_attr_result.attr,
532};
533
534static umode_t nvdimm_firmware_visible(struct kobject *kobj, struct attribute *a, int n)
535{
536 struct device *dev = container_of(kobj, typeof(*dev), kobj);
537 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
538 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
539 struct nvdimm *nvdimm = to_nvdimm(dev);
540 enum nvdimm_fwa_capability cap;
541
542 if (!nd_desc->fw_ops)
543 return 0;
544 if (!nvdimm->fw_ops)
545 return 0;
546
547 nvdimm_bus_lock(dev);
548 cap = nd_desc->fw_ops->capability(nd_desc);
549 nvdimm_bus_unlock(dev);
550
551 if (cap < NVDIMM_FWA_CAP_QUIESCE)
552 return 0;
553
554 return a->mode;
555}
556
557static const struct attribute_group nvdimm_firmware_attribute_group = {
558 .name = "firmware",
559 .attrs = nvdimm_firmware_attributes,
560 .is_visible = nvdimm_firmware_visible,
561};
562
449static const struct attribute_group *nvdimm_attribute_groups[] = {563static const struct attribute_group *nvdimm_attribute_groups[] = {
450 &nd_device_attribute_group,564 &nd_device_attribute_group,
451 &nvdimm_attribute_group,565 &nvdimm_attribute_group,
566 &nvdimm_firmware_attribute_group,
452 NULL,567 NULL,
453};568};
454 569
drivers/nvdimm/nd-core.h+1−0
@@ -45,6 +45,7 @@ struct nvdimm { · 44 unmodified lines
45 struct kernfs_node *overwrite_state;45 struct kernfs_node *overwrite_state;
46 } sec;46 } sec;
47 struct delayed_work dwork;47 struct delayed_work dwork;
48 const struct nvdimm_fw_ops *fw_ops;
48};49};
49 50
50static inline unsigned long nvdimm_security_flags(51static inline unsigned long nvdimm_security_flags(
include/linux/libnvdimm.h+44−0
@@ -86,6 +86,7 @@ struct nvdimm_bus_descriptor { · 85 unmodified lines
86 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);86 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
87 int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,87 int (*clear_to_send)(struct nvdimm_bus_descriptor *nd_desc,
88 struct nvdimm *nvdimm, unsigned int cmd, void *data);88 struct nvdimm *nvdimm, unsigned int cmd, void *data);
89 const struct nvdimm_bus_fw_ops *fw_ops;
89};90};
90 91
91struct nd_cmd_desc {92struct nd_cmd_desc {
@@ -200,6 +201,49 @@ struct nvdimm_security_ops { · 108 unmodified lines
200 int (*query_overwrite)(struct nvdimm *nvdimm);201 int (*query_overwrite)(struct nvdimm *nvdimm);
201};202};
202 203
204enum nvdimm_fwa_state {
205 NVDIMM_FWA_INVALID,
206 NVDIMM_FWA_IDLE,
207 NVDIMM_FWA_ARMED,
208 NVDIMM_FWA_BUSY,
209 NVDIMM_FWA_ARM_OVERFLOW,
210};
211
212enum nvdimm_fwa_trigger {
213 NVDIMM_FWA_ARM,
214 NVDIMM_FWA_DISARM,
215};
216
217enum nvdimm_fwa_capability {
218 NVDIMM_FWA_CAP_INVALID,
219 NVDIMM_FWA_CAP_NONE,
220 NVDIMM_FWA_CAP_QUIESCE,
221 NVDIMM_FWA_CAP_LIVE,
222};
223
224enum nvdimm_fwa_result {
225 NVDIMM_FWA_RESULT_INVALID,
226 NVDIMM_FWA_RESULT_NONE,
227 NVDIMM_FWA_RESULT_SUCCESS,
228 NVDIMM_FWA_RESULT_NOTSTAGED,
229 NVDIMM_FWA_RESULT_NEEDRESET,
230 NVDIMM_FWA_RESULT_FAIL,
231};
232
233struct nvdimm_bus_fw_ops {
234 enum nvdimm_fwa_state (*activate_state)
235 (struct nvdimm_bus_descriptor *nd_desc);
236 enum nvdimm_fwa_capability (*capability)
237 (struct nvdimm_bus_descriptor *nd_desc);
238 int (*activate)(struct nvdimm_bus_descriptor *nd_desc);
239};
240
241struct nvdimm_fw_ops {
242 enum nvdimm_fwa_state (*activate_state)(struct nvdimm *nvdimm);
243 enum nvdimm_fwa_result (*activate_result)(struct nvdimm *nvdimm);
244 int (*arm)(struct nvdimm *nvdimm, enum nvdimm_fwa_trigger arg);
245};
246
203void badrange_init(struct badrange *badrange);247void badrange_init(struct badrange *badrange);
204int badrange_add(struct badrange *badrange, u64 addr, u64 length);248int badrange_add(struct badrange *badrange, u64 addr, u64 length);
205void badrange_forget(struct badrange *badrange, phys_addr_t start,249void badrange_forget(struct badrange *badrange, phys_addr_t start,
include/linux/suspend.h+6−0
@@ -453,6 +453,8 @@ extern bool hibernation_available(void); · 452 unmodified lines
453asmlinkage int swsusp_save(void);453asmlinkage int swsusp_save(void);
454extern struct pbe *restore_pblist;454extern struct pbe *restore_pblist;
455int pfn_is_nosave(unsigned long pfn);455int pfn_is_nosave(unsigned long pfn);
456
457int hibernate_quiet_exec(int (*func)(void *data), void *data);
456#else /* CONFIG_HIBERNATION */458#else /* CONFIG_HIBERNATION */
457static inline void register_nosave_region(unsigned long b, unsigned long e) {}459static inline void register_nosave_region(unsigned long b, unsigned long e) {}
458static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}460static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}
@@ -464,6 +466,10 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op · 5 unmodified lines
464static inline int hibernate(void) { return -ENOSYS; }466static inline int hibernate(void) { return -ENOSYS; }
465static inline bool system_entering_hibernation(void) { return false; }467static inline bool system_entering_hibernation(void) { return false; }
466static inline bool hibernation_available(void) { return false; }468static inline bool hibernation_available(void) { return false; }
469
470static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) {
471 return -ENOTSUPP;
472}
467#endif /* CONFIG_HIBERNATION */473#endif /* CONFIG_HIBERNATION */
468 474
469#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV475#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV
kernel/power/hibernate.c+97−0
@@ -795,6 +795,103 @@ int hibernate(void) · 794 unmodified lines
795 return error;795 return error;
796}796}
797 797
798/**
799 * hibernate_quiet_exec - Execute a function with all devices frozen.
800 * @func: Function to execute.
801 * @data: Data pointer to pass to @func.
802 *
803 * Return the @func return value or an error code if it cannot be executed.
804 */
805int hibernate_quiet_exec(int (*func)(void *data), void *data)
806{
807 int error, nr_calls = 0;
808
809 lock_system_sleep();
810
811 if (!hibernate_acquire()) {
812 error = -EBUSY;
813 goto unlock;
814 }
815
816 pm_prepare_console();
817
818 error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
819 if (error) {
820 nr_calls--;
821 goto exit;
822 }
823
824 error = freeze_processes();
825 if (error)
826 goto exit;
827
828 lock_device_hotplug();
829
830 pm_suspend_clear_flags();
831
832 error = platform_begin(true);
833 if (error)
834 goto thaw;
835
836 error = freeze_kernel_threads();
837 if (error)
838 goto thaw;
839
840 error = dpm_prepare(PMSG_FREEZE);
841 if (error)
842 goto dpm_complete;
843
844 suspend_console();
845
846 error = dpm_suspend(PMSG_FREEZE);
847 if (error)
848 goto dpm_resume;
849
850 error = dpm_suspend_end(PMSG_FREEZE);
851 if (error)
852 goto dpm_resume;
853
854 error = platform_pre_snapshot(true);
855 if (error)
856 goto skip;
857
858 error = func(data);
859
860skip:
861 platform_finish(true);
862
863 dpm_resume_start(PMSG_THAW);
864
865dpm_resume:
866 dpm_resume(PMSG_THAW);
867
868 resume_console();
869
870dpm_complete:
871 dpm_complete(PMSG_THAW);
872
873 thaw_kernel_threads();
874
875thaw:
876 platform_end(true);
877
878 unlock_device_hotplug();
879
880 thaw_processes();
881
882exit:
883 __pm_notifier_call_chain(PM_POST_HIBERNATION, nr_calls, NULL);
884
885 pm_restore_console();
886
887 hibernate_release();
888
889unlock:
890 unlock_system_sleep();
891
892 return error;
893}
894EXPORT_SYMBOL_GPL(hibernate_quiet_exec);
798 895
799/**896/**
800 * software_resume - Resume from a saved hibernation image.897 * software_resume - Resume from a saved hibernation image.

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