COMP 3000 Lab 6 2011

From Soma-notes
Revision as of 22:22, 4 December 2011 by Saran (talk | contribs) (→‎Part B)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

A few guidelines:

  • Submit your solutions for both Part A and Part B via WebCT by Sunday, November 20th at 11:30 PM.
  • Please answer using a single text file (with a .txt extension). Do not submit doc, docx, pdf, or other formats. Also, please do not submit an archive (zip, tarball, rar) of multiple text files, just upload one. (Please don't just cut and paste your work into a text box on webct.) Anything other than a single text file will receive -1 points
  • Show all your work. If you find an answer by browsing code, explain your search path (e.g., I searched for X, which led me to source file Y, where I found function Z.) Also, list any websites or individuals you consult.

Part A

For this section, you will need to refer to the source of the Linux kernel, version 3.1.1. You may download the source code here; however, you will probably prefer to navigate the code through the Linux Cross Reference Project. *** Students have found it easier to navigate this link ***

  1. Answer the following questions regarding do_execve_common() in fs/exec.c.
    1. What information does bprm hold?
    2. What are the many goto's for?
    3. What are the two lines immediately before this function returns with no error (i.e., the execve succeeds)?
  2. What function is the main consumer of copy_process() in kernel/fork.c?
  3. In mm/mmap.c, what does the line SYSCALL_DEFINE1(brk, unsigned long, brk) do?
  4. What is the call down_write(&mm->mmap_sem); for?
  5. In what file is atl1e_tx_ring declared?

Part B

  1. [6 pts] Briefly explain what each statement does in vfs_write() in fs/read_write.c. Your explanation for each line should take up two lines at most.
  2. [3 pts] What is the purpose of each field in the struct atl1e_tx_ring? (Note: the last two fields are extra credit!)

Solutions

Part A

  1. In fs/exec.c
    1. bprm is a pointer to a structure of type linux_binprm. This structure is used to hold arguments that are used when loading binaries, like argc, filename, vm related structures.
    2. The goto's handle error messages, and provide the same functionality as a jump statement in assembly. The retval conditional statements before the goto calls determine what return value the program is providing to the function.
    3. if (displaced) put_files_struct(displaced);
  2. do_fork
  3. SYSCALL_DEFINE1 is a macro defined in syscall.h, used to define system calls. (In this case the brk system call )
  4. The brk system call modifies the data segment size, and down_write(&mm->mmap_sem) is used to acquire a read/write semaphore before performing the memory operation.
  5. In drivers/net/atl1e/atl1e.h

Part B

/* If the file descriptor is not opened with WRITE mode, returns an error. */

     if (!(file->f_mode & FMODE_WRITE))
               return -EBADF;

/* If file_operations is NULL, or if write or asynchronous write functions in it are NULL, returns an error */

     if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
               return -EINVAL;

/* unlikely tells the compiler that the statement inside it is unlikely - so, the compiler can optimize in its jump statements. access_ok functions checks if memory range is withing bounds, i.e count bytes can be read from buf. Returns an error if any of these checks fail. */

     if (unlikely(!access_ok(VERIFY_READ, buf, count)))
               return -EFAULT;

/* Checks if "count" bytes can be written to the "file" starting at "pos". Returns how many bytes can be written. */

     ret = rw_verify_area(WRITE, file, pos, count);

/* Writes using the write function provided in file_operations, which will, in general, depend on the filesystem type. */

     if (file->f_op->write)
        ret = file->f_op->write(file, buf, count, pos);

/* Writes using do_sync_write, which calls file's aio_write function. */

     else
        ret = do_sync_write(file, buf, count, pos);

/* If some bytes were written, it marks the file as "modified", so anyone listening for filesystem notifications could be called. add_wchar is for accounting - it adds, "ret" bytes to task_io_accounting structure of the current process. */

    if (ret > 0) {
      fsnotify_modify(file);
      add_wchar(current, ret);
    }

/* Again, accounting - Increments the number of "write" system calls for the current process */

    inc_syscw(current);

/* Returns the number of bytes written. */

    return ret;

2 /* A descriptor ring is a structure that a PCI device and the kernel have in common */

  struct atl1e_tpd_desc *desc;  /* descriptor ring virtual address  */

/* Physical address of the ring for the Network card driver to use. */

       dma_addr_t         dma;    /* descriptor ring physical address */

/* Number of transmit ring buffers */

       u16                count;  /* the count of transmit rings  */

/* Transmit read/write lock */

       rwlock_t           tx_lock;

/* Next ring to use */

       u16                next_to_use;

/* Next ring to clean up */

       atomic_t           next_to_clean;

/* Transmit buffer */

       struct atl1e_tx_buffer *tx_buffer;


/* The CMB dma address of the ring initialized : [here http://lxr.linux.no/linux+v3.1.4/drivers/net/atl1e/atl1e_main.c#L853] cmb is a pointer to the virtual address. These are written into the registers of the network device as shown [here http://lxr.linux.no/linux+v3.1.4/drivers/net/atl1e/atl1e_main.c#L897] Seems to be a device specific internal data structure.

  • /
       dma_addr_t         cmb_dma;
       u32                *cmb;