Skip to content

General Discussion

A place to talk about whatever you want

This category can be followed from the open social web via the handle [email protected]

4 Topics 9 Posts
  • Question about retry logic in usb-skeleton.c skel_read()

    2
    0 Votes
    2 Posts
    93 Views
    Z
    Hi, The behavior is intentional, not inconsistent. Looking at the actual source code, the driver handles three cases differently: No data at all → goto retry (must wait, can't return 0 which means EOF) Buffer exhausted → goto retry (same reason) Some data available → return it immediately, prefetch the rest Why no goto retry in case 3? Returning 0 from read() signals EOF to userspace When there's no data, the driver must wait—otherwise it would falsely indicate EOF When there is data, returning a short read is standard POSIX behavior The prefetch (skel_do_read_io) is an optimization for the next read call Standard Unix read() semantics: read() may return fewer bytes than requested—this is normal Userspace is expected to loop if it needs exactly N bytes This applies to sockets, pipes, and character devices alike Adding goto retry would work but would change the driver from "return data as soon as available" to "block until buffer is full"—which increases latency unnecessarily. Because it would need to wait for full buffer. //Userspace is expected to handle short reads: // Standard pattern - userspace loops, not the driver ssize_t read_full(int fd, void *buf, size_t count) { size_t total = 0; while (total < count) { ssize_t ret = read(fd, buf + total, count - total); if (ret < 0) return ret; // error if (ret == 0) break; // EOF total += ret; } return total; } The problem: User calls: read(fd, buf, 100) Buffer has: 30 bytes First iteration: - Copy 30 bytes to buf[0..29] - rv = 30 - goto retry... Second iteration (after new data arrives): - Copy to 'buffer' again (buf[0..??]) ← OVERWRITES first 30 bytes! - rv = new_chunk ← loses the original 30 The userspace buffer pointer is never advanced. So goto retry would overwrite data already copied. copy_to_user(buffer, ...); // First copy: buf[0] goto retry; copy_to_user(buffer, ...); // Second copy: buf[0] again! Data corrupted. Even if you fixed the buffer pointer issue (by advancing it on each iteration), the modified behavior would still be undesirable because it changes the driver's semantics from "return data as available" to "block until full"
  • Kernel security guidance

    3
    1 Votes
    3 Posts
    101 Views
    P
    Excellent, looking forward to reading it! Thanks for a quick reply. Btw. is there something I can do to help you on that subject?
  • 0 Votes
    1 Posts
    45 Views
    C
    안녕하세요, 리눅스 커널 기반의 USB 디바이스 드라이버를 공부하고 있는 컴퓨터 공학과 학부생입니다. 현재 usb-skeleton.c의 skel_read() 함수 동작을 분석하던 중, retry 로직에 일관성 없는 부분을 발견하여 조언을 구합니다. 현재 동작 분석 스켈레톤 코드는 다음과 같이 동작합니다: retry: if (dev->ongoing_read) { // O_NONBLOCK 체크 후 대기 if (file->f_flags & O_NONBLOCK) return -EAGAIN; wait_event_interruptible(dev->bulk_in_wait, (!dev->ongoing_read)); } // 데이터 복사 chunk = min(available, count); copy_to_user(buffer, dev->bulk_in_buffer, chunk); // 데이터 부족 시 if (available < count) { usb_do_read_io(dev, count - chunk); // 여기서 goto retry가 없음! } return chunk; 의문점 처음 진입 시: ongoing_read가 있으면 대기 (또는 -EAGAIN 반환) 데이터 부족 시: URB 제출 후 대기 없이 즉시 반환 이 두 동작이 일관성이 없어 보입니다. 제안하는 수정 if (available < count) { usb_do_read_io(dev, count - chunk); goto retry; // <- 추가 } 이렇게 하면: O_NONBLOCK 처리가 retry 레이블에서 일관되게 처리됨 Blocking I/O 시 요청한 count를 최대한 채우려 시도 wait_event_interruptible로 시그널 인터럽트 가능 질문 현재 동작이 의도적인 설계인가요, 아니면 교육용 단순화인가요? goto retry 추가 시 제가 놓치고 있는 문제가 있을까요? USB Bulk transfer 특성상 Short Read를 강제해야 하는 이유가 있나요? 조언 부탁드립니다. 감사합니다!
  • Welcome to your NodeBB!

    3
    1 Votes
    3 Posts
    104 Views
    H
    Hello guys!