[PATCH] D82112: [RFC][BPF] Implement getUserCost() for BPFTargetTransformInfo

Yonghong Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 18 10:54:13 PDT 2020


yonghong-song created this revision.
yonghong-song added a reviewer: ast.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.

This patch tries to partially prevent speculative code motion for BPF.

First, some use cases on why we want to prevent speculative code motion.

Use case 1: bpf map value or some other data with a range.

  data = bpf_map_lookup_elem(&map, &key);
  if (!data) return 0;
  payload = data->payload;
  len = bpf_probe_read_kernel_str(payload, 16, &task->comm);
  if (len <= 16) 
    payload += len;
  ... 

The compiler may generate code like:

  data = bpf_map_lookup_elem(&map, &key);
  if (!data) return 0;
  payload = data->payload;
  len = bpf_probe_read_kernel_str(payload, 16, &task->comm);
  new_payload = payload + len;
  if (len > 16) 
    new_payload = payload
  ... 

The "payload + len" may cause kernel verifier failure as
the "len" can be anything at this moment.

Use case 2: CO-RE relocatons

  field_exist = ... 
  if (field_exist) {
    offset = non-memory-access-builtin-expr1;
  } else {
    offset = non-memory-access-builtin-expr2;
  }   
  use "offset" to read kernel memory

The compiler may generate code like:

  field_exist = ... 
  offset = non-memory-access-builtin-expr1;
  if (!field_exist)
    offset = non-memory-access-builtin-expr2;
  use "offset" to read kernel memory

This may cause failures since if field_exist is false and 
libbpf is not able to perform relation
for "offset = non-memory-access-builtin-expr1".
The instruction itself will be rewritten as
an illegal instruction and this will cause
program load failures.

To address the above issues, people use

  . inline assembly
  . artificial complex control flow

to prevent the above optimizations.

This patch tries to do with a more user friendly way.
BPF backend TargetTransformInfo implements getUserCost()
to return UserCost INT_MAX for TCK_SizeAndLatency
to prevent compiler moving codes speculatively.
An option "adjustopt", false by default, is added to
enable this adjustment.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82112

Files:
  clang/lib/Basic/Targets/BPF.h
  llvm/lib/Target/BPF/BPF.td
  llvm/lib/Target/BPF/BPFSubtarget.cpp
  llvm/lib/Target/BPF/BPFSubtarget.h
  llvm/lib/Target/BPF/BPFTargetMachine.cpp
  llvm/lib/Target/BPF/BPFTargetMachine.h
  llvm/lib/Target/BPF/BPFTargetTransformInfo.h

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82112.271773.patch
Type: text/x-patch
Size: 5923 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200618/02a6f076/attachment-0001.bin>


More information about the cfe-commits mailing list