On Tue, Dec 19, 2023 at 07:50:25AM +1030, Brett Lymn wrote:
> On Sat, Sep 02, 2023 at 08:57:03AM +0930, Brett Lymn wrote:
> > On Thu, Aug 31, 2023 at 10:24:07AM +0200, J. Hannken-Illjes wrote:
> > > 
> > > I'm short on time, some remarks:
> > > 
> > 
> > Thanks, I will have a closer look at these issues.  This could be where the 
> > deadlock I was
> > seeing is coming from.
> > 
> 
> OK, I have, finally, updated the diff in line with the comments (thanks
> again for the good feedback).

Brett,

first it is difficult to read a diff that also introduces a "notyet" operation
on file pages.

Looks like you replace global and item rw-locks with refcounts/signals.
I tried to understand the rationale behind and failed.  Your implementation
seems at least vulnerable to livelocks as the writer side is missing priority.

In general, what problem(s) are you trying to solve here?

What is wrong with a quite simple hashtable to hold fileid<->fingerprint 
mapping accessed as:

        mutex_enter table lock
        lookup fileid -> item
        mutex_enter item
        mutex_exit table lock

        while item state is busy
                cv_wait item cv

        if item state is unknown
                set item state busy
                mutex_exit item
                compute fingerprint
                mutex_enter item
                set item state valid/invalid
                cv_broadcast item cv

        Here the item state is either valid or invalid

        mutex_exit item

Some more problems (line numbers with your diff applied):

   476  veriexec_fp_calc(struct lwp *l, struct vnode *vp, int lock_state,
   477      struct veriexec_file_entry *vfe, u_char *fp)
   478  {

   524                  error = vn_rdwr(UIO_READ, vp, buf, len, offset,
   525                                  UIO_SYSSPACE, lock_state,

lock_state is sometimes VERIEXEC_UNLOCKED, sometimes IO_NODELOCKED.

  1629  veriexec_dump(struct lwp *l, prop_array_t rarray)
  1630  {
  1631          struct mount *mp;
  1632          mount_iterator_t *mpiter;
  1633  
  1634          mountlist_iterator_init(&mpiter);
  1635  
  1636          while ((mp = mountlist_iterator_trynext(mpiter)) != NULL) {
  1637                  /* If it fails, the file-system is [being] unmounted. */
  1638                  if (vfs_busy(mp) != 0)
  1639                          continue;

This is completely wrong.  Operation mountlist_iterator_trynext() already
returns the mount busy and skips mounts currently unmounting or remounting.
Operation mountlist_iterator_next() was right or does this function get
called from inside unmount?

  1653  veriexec_flush(struct lwp *l)
  1654  {
  1655          struct mount *mp;
  1656          mount_iterator_t *mpiter;
  1657          int error = 0;
  1658  
  1659          mountlist_iterator_init(&mpiter);
  1660  
  1661          while ((mp = mountlist_iterator_trynext(mpiter)) != NULL) {
  1662                  int lerror;
  1663  
  1664                  /* If it fails, the file-system is [being] unmounted. */
  1665                  if (vfs_busy(mp) != 0)
  1666                          continue;

This is completely wrong, see above.

-- 
J. Hannken-Illjes

Reply via email to