OpenSolaris

Printable Version Enter a New Search
Bug ID 6706462
Synopsis race condition in ldc_mem_bind_handle when allocating map table
State 10-Fix Delivered (Fix available in build)
Category:Subcategory solaris-development:io
Keywords
Responsible Engineer Haik Aftandilian
Reported Against snv_89
Duplicate Of
Introduced In solaris_nevada
Commit to Fix snv_93
Fixed In snv_93
Release Fixed solaris_nevada(snv_93) , solaris_10u7(s10u7_01) (Bug ID:2165786)
Related Bugs 6683084
Submit Date 23-May-2008
Last Update Date 29-August-2008
Description
Found by code inspection. In ldc_mem_bind_handle, the first time a memory handle is bound to a channel, the map table must be allocated.

From ldc_mem_bind_handle(),

  285    /*
  286     * If this channel is binding a memory handle for the
  287     * first time allocate it a memory map table and initialize it
  288     */
  289    if ((mtbl = ldcp->mtbl) == NULL) {
  290
  291        mutex_enter(&ldcp->lock);
  292
  293        /* Allocate and initialize the map table structure */
  294        mtbl = kmem_zalloc(sizeof (ldc_mtbl_t), KM_SLEEP);
  ...
  322        /* register table for this channel */
  323        rv = hv_ldc_set_map_table(ldcp->id,
  324            va_to_pa(mtbl->table), mtbl->num_entries);
  ...
  340        ldcp->mtbl = mtbl;
  341        mutex_exit(&ldcp->lock);
  ...
  346    }
  ...
  476    /* update entry in table */
  477    mtbl->table[index].entry = tmp_mte;

The problem is that the channel lock is acquired after the check for ldcp->mtbl == NULL. With competing threads, each trying to ldc_mem_bind_handle() different handles to the same channel at the same time, more than one thread could find ldcp->mtbl == NULL. As a result, more than one map table will be allocated (wasting memory) and threads that find ldcp->mtbl == NULL and obtain the channel lock later, will overwrite earlier threads hv_ldc_set_map_table() call. The earlier threads' map table entries will not be found by the HV since later threads will have overwritten the map table. This will cause the importing domain's calls to ldc_mem_map() to fail.
Work Around
N/A
Comments
N/A