이 코드는 어떤 문제를 푸나요?
장치용 페이지 표를 고친 뒤에도 SMMU가 옛 번역을 기억할 수 있습니다. CPU TLB를 지웠다는 사실만으로 장치의 IOTLB가 갱신되는 것은 아닙니다. v6.18.37의 arm_smmu_iotlb_sync를 읽어 모아 둔 무효화 범위를 SMMU 경로에 전달하는 과정을 설명합니다.
읽을 범위: v6.18.37 · drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c · arm_smmu_iotlb_sync 3458–3469행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
IOVA
장치가 DMA 요청에 사용하는 주소입니다. CPU VA와 별개 주소 공간입니다.
iotlb_gather
여러 unmap 등에서 무효화할 범위를 모으는 구조입니다. start와 end, pgsize를 함께 관리합니다.
SID와 SSID
장치와 하위 주소 공간을 선택하는 식별자입니다. PCI BDF 숫자와 항상 일치한다고 가정하지 않습니다.
처음 읽을 때
CPU MMU와 SMMU를 병렬로 그려 각자 표와 번역 캐시를 가진다는 점을 설명하십시오.
더 깊이 살펴볼 때
inclusive end 때문에 길이에 1을 더하는 이유와 하위 CMDQ 동기화의 완료 조건을 추적하십시오.
그림으로 보는 변화
gather->pgsize가 0이면 즉시 반환합니다. 값이 있을 때만 inclusive 길이와 granule, domain을 SMMU 무효화 helper에 전달합니다. CPU TLB 경로는 별개입니다. 고정 원문 확인.1. domain과 모은 요청
1. domain과 모은 요청
iommu_domain을 SMMU domain으로 바꾸고, gather가 모은 범위와 pgsize를 봅니다.
2. 빈 요청은 반환
!gather->pgsize이면 이 함수에서 바로 반환합니다. 이 경로는 3단계의 SMMU 무효화 호출로 이어지지 않습니다.
3. 유효 요청만 전달
pgsize가 있으면 end - start + 1의 inclusive 길이, pgsize, true, SMMU domain을 helper에 전달합니다.
arm_smmu_iotlb_sync를 한 줄씩 읽기
줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
struct iommu_iotlb_gather *gather)
{
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
if (!gather->pgsize)
return;
arm_smmu_tlb_inv_range_domain(gather->start,
gather->end - gather->start + 1,
gather->pgsize, true, smmu_domain);
}static void arm_smmu_iotlb_sync(struct iommu_domain *domain,IOMMU domain에 모아 둔 무효화 작업을 반영하는 드라이버 콜백입니다.
struct iommu_iotlb_gather *gather)gather에는 여러 변경에서 수집한 시작·끝 주소와 page size가 들어 있습니다.
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);일반 iommu_domain을 SMMU 드라이버의 확장 자료구조로 바꿔 하드웨어별 정보를 얻습니다.
if (!gather->pgsize)수집된 페이지 크기가 없으면 유효한 무효화 범위가 없는 경우로 처리합니다.
return;빈 요청은 추가 SMMU 명령 없이 종료합니다.
arm_smmu_tlb_inv_range_domain(gather->start,수집한 시작 주소부터 domain의 TLB 범위를 무효화하는 하위 경로에 넘깁니다.
gather->end - gather->start + 1,end가 포함형 끝 주소이므로 길이는 end-start+1입니다. 예를 들어 0x1000~0x1fff는 설명용으로 0x1000바이트 범위입니다.
gather->pgsize, true, smmu_domain);페이지 크기와 leaf 무효화 조건, 해당 SMMU domain을 전달합니다. 실제 CMDQ 명령 구성·완료는 호출된 함수 아래에서 진행합니다.
함께 생각해 볼 질문
IOTLB와 CPU TLB는 같은 캐시입니까?
아닙니다. 서로 다른 접근 주체의 번역 상태입니다.
end-start에 왜 1을 더합니까?
이 gather의 end는 마지막 주소를 포함하는 범위이기 때문입니다.
이 helper 자체가 DMA 데이터를 복사합니까?
아닙니다. 주소 변환 무효화 범위를 전달합니다.
출처와 읽은 범위
Linux stable v6.18.37 · drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고