{"id":29675864,"url":"https://github.com/oxidecomputer/lmar","last_synced_at":"2025-10-05T02:09:14.772Z","repository":{"id":172094980,"uuid":"493916008","full_name":"oxidecomputer/lmar","owner":"oxidecomputer","description":"PCIe Lane Margining at the Receiver","archived":false,"fork":false,"pushed_at":"2025-05-30T10:37:54.000Z","size":74,"stargazers_count":5,"open_issues_count":2,"forks_count":1,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-05-30T13:53:24.635Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oxidecomputer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-19T04:11:22.000Z","updated_at":"2025-05-26T06:40:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"60217c3c-02ef-4353-8a9c-cfa71f0af7b1","html_url":"https://github.com/oxidecomputer/lmar","commit_stats":null,"previous_names":["oxidecomputer/lmar"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oxidecomputer/lmar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Flmar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Flmar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Flmar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Flmar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oxidecomputer","download_url":"https://codeload.github.com/oxidecomputer/lmar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Flmar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266591233,"owners_count":23953082,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-22T23:38:55.562Z","updated_at":"2025-10-05T02:09:14.743Z","avatar_url":"https://github.com/oxidecomputer.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lmar\n\nPCIe Lane Margining at the Receiver for illumos systems.\n\n## Overview\n\nThis tool runs the Lane Margining at the Receiver protocol for PCIe devices at\nGen 4 or later. This can be used to assess signal integrity issues, which is\ncritical for high-speed data links like PCIe.\n\nFor such systems, one can imagine the receivers as sampling the analog waveform\ncorresponding to the bits the transmitter sent. The goal is to recover that bit\npattern exactly from the analog signal. A huge amount of signal processing\ncircuitry is involved in effectively recovering the bits, so much so that common\nbit error rates are 10e-12 or less.\n\nThough it might be implemented in any number of ways, we can model this process\nas the receiver _sampling_ the incoming waveform at point in both time, relative\nto the recovered clock, and in voltage, relative either to an average or a peak\namplitude. The _margin_ refers to the distance in either direction that this\nsampling point can be moved, while maintaining an acceptable error rate.\n\nThe `lmar` tool can be used to determine these margins. It instructs the device\nto step the sampler in either time or voltage, and then count the number of\nerrors it sees. The results are saved in a file, and can be analyzed with the\naccompanying `analyze.py` Python tool.\n\n\u003e Important: This tool only runs on illumos systems.\n\n## Usage\n\n```bash\n$ cargo build\n$ pfexec ./target/debug/lmar 1/0/0 upstream\n```\n\nThe first argument is the bus/device/function for the PCIe endpoint to be\ntargeted. The second is whether to target the upstream or downstream port of\nthat endpoint. For a root complex, that should be `downstream`. For a drive or\nother similar device, it should be `upstream`.\n\nThe BDF can be retrieved from the output of `/usr/lib/pci/pcieadm show-devs`, in\nthe first column.\n\nFor probing all PCIe devices\n```bash\n$ pfexec ./target/debug/lmar -p\n```\n\nThe other options to the program control the details of the margining process,\nand can be seen with `cargo run -- --help`.\n\n## Analysis\n\nOnce the data has been collected, the small Python tool `analyze.py` can be\npointed at the results file to analyze the data. The `summarize` subcommand will\nprint a tabular summary of the time and possibly voltage margin for each\nreported device / lane. The `plot` subcommand will generate a plot window for\neach reported device / lane, showing the results of each margined point. Any\nnumber of files may be provided.\n\nThe tool requires a few packages:\n\n- `matplotlib`\n- `numpy`\n- `tabulate`\n\n## Additional scripts\n\n\n- `run_margin.py`\nConvenience wrapper around `lmar` that standardizes run layout. It invokes `lmar`\nin either probe (`-p`) or single-target mode, creates the\n`margin-\u003cYYYY-MM-DDTHH-MM-SS\u003e/` directory, and (optionally) produces the sibling\n`.zip` artifact. It passes through common flags (e.g., `-p`, `-z`, lane selection), so\ndownstream consumers always see the same directory/zip structure.\n\n\n**Examples**\n```bash\n# probe all supported ports (parallel by default)\npfexec ./scripts/run_margin.py -p\n\n\n# single-target BDF, all lanes, and zip the result\npfexec ./scripts/run_margin.py 63/0/0 upstream --lanes all -z\n```\n\n\n- `margin_summary.py`\nParses one or more `margin-results-b\u003cbus\u003e-d\u003cdev\u003e-f\u003cfunc\u003e-l\u003clane\u003e` files and emits\ncompact per-lane summaries (time/voltage margins, basic pass/fail stats). Summaries\nare written into a `summaries/` subdirectory alongside the run artifacts to keep\nconsumers consistent.\n\n\n**Examples**\n```bash\n# summarize a single run directory\n./scripts/margin_summary.py margin-2025-09-10T12-34-56/\n\n\n# summarize specific files\n./scripts/margin_summary.py margin-*/margin-results-b*-l*\n```\n\n\n- `collect_summaries.py`\nWalks one or more run directories, discovers `summaries/` outputs, and consolidates\nthem into a single table (stdout or optional CSV). Useful for aggregating results\nacross multiple runs/zips.\n\n\n**Examples**\n```bash\n# aggregate summaries across several runs\n./scripts/collect_summaries.py margin-2025-09-10T12-34-56/ \\\nmargin-2025-09-10T14-02-11/\n\n\n# write a CSV\n./scripts/collect_summaries.py margin-* --csv all-summaries.csv\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Flmar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foxidecomputer%2Flmar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Flmar/lists"}