Hi Ciro,

Thank you for your reply. Looks like this patch does address the problem I
mentioned along with some other ones. Thanks for sharing.

Best Regards,
Shehab


On Thu, Apr 9, 2020 at 1:45 PM Ciro Santilli <ciro.santi...@gmail.com>
wrote:

> Thanks for this Shehab,
>
> Could you compare your changes to this patchset:
> https://gem5-review.googlesource.com/c/public/gem5/+/22022/1
>
> On Thu, Apr 9, 2020 at 6:22 PM Shehab Elsayed <shehaby...@gmail.com>
> wrote:
> >
> > Hello All,
> >
> > I was running some experiments and I ran into a problem with ruby where
> a functional read was failing. After some investigation I found that the
> reason was that the functional read was trying to read a line that was in a
> MaybeStale state (no ReadOnly or ReadWrite versions).
> >
> > I implemented a fix which so far seems to be working fine but I am not
> sure if there is a deeper problem that needs fixing or if my fix could
> present future problems.
> >
> > I am running Full System simulations with ARM ISA and MESI_Three_Level.
> >
> > Here is my fix (I have marked new lines with //------NEW------//):
> > Basically what this fix does is perform the functional read from the
> controller that has the line in the MaybeStale state if no ReadOnly or
> ReadWrite versions in any controller.
> >
> > bool
> > RubySystem::functionalRead(PacketPtr pkt)
> > {
> >     Addr address(pkt->getAddr());
> >     Addr line_address = makeLineAddress(address);
> >
> >     AccessPermission access_perm = AccessPermission_NotPresent;
> >     int num_controllers = m_abs_cntrl_vec.size();
> >
> >     DPRINTF(RubySystem, "Functional Read request for %#x\n", address);
> >
> >     unsigned int num_ro = 0;
> >     unsigned int num_rw = 0;
> >     unsigned int num_busy = 0;
> >     unsigned int num_backing_store = 0;
> >     unsigned int num_invalid = 0;
> >     unsigned int num_maybe_stale = 0;        //------NEW------//
> >
> >     // In this loop we count the number of controllers that have the
> given
> >     // address in read only, read write and busy states.
> >     for (unsigned int i = 0; i < num_controllers; ++i) {
> >
> >         // Ignore ATD controllers for functional reads
> >         if (m_abs_cntrl_vec[i]->getType() == MachineType_ATD) {
> >             continue;
> >         }
> >
> >         access_perm = m_abs_cntrl_vec[i]->
> getAccessPermission(line_address);
> >         if (access_perm == AccessPermission_Read_Only)
> >             num_ro++;
> >         else if (access_perm == AccessPermission_Read_Write)
> >             num_rw++;
> >         else if (access_perm == AccessPermission_Busy)
> >             num_busy++;
> >         else if (access_perm == AccessPermission_Backing_Store)
> >             // See RubySlicc_Exports.sm for details, but Backing_Store
> is meant
> >             // to represent blocks in memory *for Broadcast/Snooping
> protocols*,
> >             // where memory has no idea whether it has an exclusive copy
> of data
> >             // or not.
> >             num_backing_store++;
> >         else if (access_perm == AccessPermission_Invalid ||
> >                  access_perm == AccessPermission_NotPresent)
> >             num_invalid++;
> >         else if (access_perm == AccessPermission_Maybe_Stale)
> //------NEW------//
> >             num_maybe_stale++;
>                     //------NEW------//
> >     }
> >
> >     // This if case is meant to capture what happens in a Broadcast/Snoop
> >     // protocol where the block does not exist in the cache hierarchy.
> You
> >     // only want to read from the Backing_Store memory if there is no
> copy in
> >     // the cache hierarchy, otherwise you want to try to read the RO or
> RW
> >     // copies existing in the cache hierarchy (covered by the else
> statement).
> >     // The reason is because the Backing_Store memory could easily be
> stale, if
> >     // there are copies floating around the cache hierarchy, so you want
> to read
> >     // it only if it's not in the cache hierarchy at all.
> >     if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
> >         DPRINTF(RubySystem, "only copy in Backing_Store memory, read
> from it\n");
> >         for (unsigned int i = 0; i < num_controllers; ++i) {
> >             access_perm =
> m_abs_cntrl_vec[i]->getAccessPermission(line_address);
> >             if (access_perm == AccessPermission_Backing_Store) {
> >                 m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
> >                 return true;
> >             }
> >         }
> >     } else if (num_ro > 0 || num_rw >= 1 || num_maybe_stale > 0) {
>         //------NEW------//
> >         if (num_rw > 1) {
> >             // We iterate over the vector of abstract controllers, and
> return
> >             // the first copy found. If we have more than one cache with
> block
> >             // in writable permission, the first one found would be
> returned.
> >             warn("More than one Abstract Controller with RW permission
> for "
> >                  "addr: %#x on cacheline: %#x.", address, line_address);
> >         }
> >         // In Broadcast/Snoop protocols, this covers if you know the
> block
> >         // exists somewhere in the caching hierarchy, then you want to
> read any
> >         // valid RO or RW block.  In directory protocols, same thing,
> you want
> >         // to read any valid readable copy of the block.
> >         DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n",
> >                 num_busy, num_ro, num_rw);
> >
> >         // In this loop, we try to figure which controller has a read
> only or
> >         // a read write copy of the given address. Any valid copy would
> suffice
> >         // for a functional read.
> >         // Sometimes the functional read is to a line that has recently
> >         // transitioned to MaybeStale state and no other controller has
> it in
> >         // a ReadOnly or ReadWrite stat yet.
> >         // For example in MESI_Three_Level a modified block in the L2
> goes into
> >         // a MaybeStale state when requested by the L1. If the
> functional read
> >         // occurs at that specific time when the block in L2 became
> MaybeStale
> >         // but still hasn't made it to ReadOnly on ReadWrite state in
> the L1,
> >         // the request should then be fulfilled from the L2 controller.
> >         // (I think so)
> >
> >         // In case no ReadOnly or ReadWrite controller was found, this
> will
> >         // point to the MaybeStale controller
> >         AbstractController* func_read_cntrl = NULL;
> //------NEW------//
> >
> >         for (unsigned int i = 0;i < num_controllers;++i) {
> >
> >             access_perm = m_abs_cntrl_vec[i]->
> >                           getAccessPermission(line_address);
> >             if (access_perm == AccessPermission_Read_Only ||
> >                 access_perm == AccessPermission_Read_Write) {
> >                 m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
> >                 return true;
> >             }
> >
> >             // Record the first MaybeStale controller in case no
> ReadOnly or
> >             // ReadWrite controller was found
> >             if (access_perm == AccessPermission_Maybe_Stale &&
> //------NEW------//
> >                 func_read_cntrl == NULL) {
>                     //------NEW------//
> >                 func_read_cntrl = m_abs_cntrl_vec[i];
>               //------NEW------//
> >             }
>                                      //------NEW------//
> >         }
> >
> >         // At this point no RO or RW controller was found, read from the
> >         // MaybeStale one
> >         if (func_read_cntrl != NULL) {
>                      //------NEW------//
> >             func_read_cntrl->functionalRead(line_address, pkt);
>      //------NEW------//
> >             return true;
>                                 //------NEW------//
> >         }
>                                      //------NEW------//
> >     }
> >
> >     return false;
> > }
> > _______________________________________________
> > gem5-users mailing list
> > gem5-users@gem5.org
> > http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
>
_______________________________________________
gem5-users mailing list
gem5-users@gem5.org
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users

Reply via email to