Changeset c08a29


Ignore:
Timestamp:
2012-03-08 14:31:03 (2 years ago)
Author:
Tollef Fog Heen <tfheen@…>
Branches:
3.0
Children:
b1f19f
Parents:
6a0e8fd
git-author:
Poul-Henning Kamp <phk@…> (2011-11-08 14:07:52)
git-committer:
Tollef Fog Heen <tfheen@…> (2012-03-08 14:31:03)
Message:

Rewrite the ban-lurker.

Use a mark&mark strategy to test all obj.* bans even if there are
req.* bans in the way.

Location:
bin
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • bin/varnishd/cache_ban.c

    r6a0e8fd rc08a29  
    6666#define BAN_F_GONE              (1 << 0) 
    6767#define BAN_F_REQ               (1 << 2) 
    68 #define BAN_F_LURK              (3 << 3)        /* ban-lurker-color */ 
     68#define BAN_F_LURK              (3 << 6)        /* ban-lurker-color */ 
    6969        VTAILQ_HEAD(,objcore)   objcore; 
    7070        struct vsb              *vsb; 
    7171        uint8_t                 *spec; 
    7272}; 
     73 
     74#define LURK_SHIFT 6 
    7375 
    7476struct ban_test { 
     
    402404        bi = b; 
    403405        pcount = 0; 
     406        Lck_Lock(&ban_mtx); 
    404407        while(bi != be) { 
    405408                bi = VTAILQ_NEXT(bi, list); 
     
    410413                        continue; 
    411414                bi->flags |= BAN_F_GONE; 
     415                VSC_C_main->n_ban_gone++; 
    412416                pcount++; 
    413417        } 
    414         Lck_Lock(&ban_mtx); 
    415418        be->refcount--; 
    416419        VSC_C_main->n_ban_dups += pcount; 
     
    628631 
    629632/*-------------------------------------------------------------------- 
    630  * Check an object any fresh bans 
     633 * Check an object against all applicable bans 
     634 * 
     635 * Return: 
     636 *      -1 not all bans checked, but none of the checked matched 
     637 *              Only if !has_req 
     638 *      0 No bans matched, object moved to ban_start. 
     639 *      1 Ban matched, object removed from ban list. 
    631640 */ 
    632641 
     
    662671                if (b->flags & BAN_F_GONE) 
    663672                        continue; 
     673                if ((b->flags & BAN_F_LURK) && 
     674                    (b->flags & BAN_F_LURK) == (oc->flags & OC_F_LURK)) { 
     675                        AZ(b->flags & BAN_F_REQ); 
     676                        /* Lurker already tested this */ 
     677                        continue; 
     678                } 
    664679                if (!has_req && (b->flags & BAN_F_REQ)) { 
    665680                        /* 
     
    672687        } 
    673688 
     689        Lck_Lock(&ban_mtx); 
     690        VSC_C_main->n_ban_obj_test++; 
     691        VSC_C_main->n_ban_re_test += tests; 
     692 
    674693        if (b == oc->ban && skipped > 0) { 
     694                AZ(has_req); 
     695                Lck_Unlock(&ban_mtx); 
    675696                /* 
    676697                 * Not banned, but some tests were skipped, so we cannot know 
    677698                 * for certain that it cannot be, so we just have to give up. 
    678699                 */ 
    679                 return (0); 
    680         } 
    681  
    682         Lck_Lock(&ban_mtx); 
     700                return (-1); 
     701        } 
     702 
    683703        oc->ban->refcount--; 
    684704        VTAILQ_REMOVE(&oc->ban->objcore, oc, ban_list); 
    685705        if (b == oc->ban) {     /* not banned */ 
     706                b->flags &= ~BAN_F_LURK; 
    686707                VTAILQ_INSERT_TAIL(&b0->objcore, oc, ban_list); 
    687708                b0->refcount++; 
    688709        } 
    689         VSC_C_main->n_ban_obj_test++; 
    690         VSC_C_main->n_ban_re_test += tests; 
    691710        Lck_Unlock(&ban_mtx); 
    692711 
     
    710729{ 
    711730 
    712         return (ban_check_object(o, sp, 1)); 
     731        return (ban_check_object(o, sp, 1) > 0); 
    713732} 
    714733 
     
    721740        b = VTAILQ_LAST(&ban_head, banhead_s); 
    722741        if (b != VTAILQ_FIRST(&ban_head) && b->refcount == 0) { 
     742                if (b->flags & BAN_F_GONE) 
     743                        VSC_C_main->n_ban_gone--; 
    723744                VSC_C_main->n_ban--; 
    724745                VSC_C_main->n_ban_retire++; 
     
    731752 
    732753/*-------------------------------------------------------------------- 
    733  * Ban tail lurker thread 
     754 * Ban lurker thread 
    734755 */ 
    735756 
    736757static int 
    737 ban_lurker_work(const struct sess *sp) 
    738 { 
    739         struct ban *b, *bf; 
     758ban_lurker_work(const struct sess *sp, unsigned pass) 
     759{ 
     760        struct ban *b, *b0, *b2; 
    740761        struct objhead *oh; 
    741762        struct objcore *oc, *oc2; 
     
    743764        int i; 
    744765 
    745         Lck_Lock(&ban_mtx); 
    746  
    747         /* First try to route the last ban */ 
    748         bf = ban_CheckLast(); 
    749         if (bf != NULL) { 
     766        AN(pass & BAN_F_LURK); 
     767        AZ(pass & ~BAN_F_LURK); 
     768 
     769        /* First route the last ban(s) */ 
     770        do { 
     771                Lck_Lock(&ban_mtx); 
     772                b2 = ban_CheckLast(); 
    750773                Lck_Unlock(&ban_mtx); 
    751                 BAN_Free(bf); 
     774                if (b2 != NULL) 
     775                        BAN_Free(b2); 
     776        } while (b2 != NULL); 
     777 
     778        /* 
     779         * Find out if we have any bans we can do something about 
     780         * If we find any, tag them with our pass number. 
     781         */ 
     782        i = 0; 
     783        b0 = NULL; 
     784        VTAILQ_FOREACH(b, &ban_head, list) { 
     785                if (b->flags & BAN_F_GONE) 
     786                        continue; 
     787                if (b->flags & BAN_F_REQ) 
     788                        continue; 
     789                if (b == VTAILQ_LAST(&ban_head, banhead_s)) 
     790                        continue; 
     791                if (b0 == NULL) 
     792                        b0 = b; 
     793                i++; 
     794                b->flags &= ~BAN_F_LURK; 
     795                b->flags |= pass; 
     796        } 
     797        if (params->diag_bitmap & 0x80000) 
     798                VSL(SLT_Debug, 0, "lurker: %d actionable bans", i); 
     799        if (i == 0) 
    752800                return (0); 
    753         } 
    754  
    755         /* Find the last ban give up, if we have only one */ 
    756         b = VTAILQ_LAST(&ban_head, banhead_s); 
    757         if (b == ban_start) { 
     801 
     802        VTAILQ_FOREACH_REVERSE(b, &ban_head, banhead_s, list) { 
     803                if (params->diag_bitmap & 0x80000) 
     804                        VSL(SLT_Debug, 0, "lurker doing %f %d", 
     805                            ban_time(b->spec), b->refcount); 
     806                while (1) { 
     807                        Lck_Lock(&ban_mtx); 
     808                        oc = VTAILQ_FIRST(&b->objcore); 
     809                        if (oc == NULL) 
     810                                break; 
     811                        CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); 
     812                        if (params->diag_bitmap & 0x80000) 
     813                                VSL(SLT_Debug, 0, "test: %p %d %d", 
     814                                    oc, oc->flags & OC_F_LURK, pass); 
     815                        if ((oc->flags & OC_F_LURK) == pass) 
     816                                break; 
     817                        oh = oc->objhead; 
     818                        CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); 
     819                        if (Lck_Trylock(&oh->mtx)) { 
     820                                Lck_Unlock(&ban_mtx); 
     821                                TIM_sleep(params->ban_lurker_sleep); 
     822                                continue; 
     823                        } 
     824                        /* 
     825                         * See if the objcore is still on the objhead since 
     826                         * we race against HSH_Deref() which comes in the 
     827                         * opposite locking order. 
     828                         */ 
     829                        VTAILQ_FOREACH(oc2, &oh->objcs, list) 
     830                                if (oc == oc2) 
     831                                        break; 
     832                        if (oc2 == NULL) { 
     833                                Lck_Unlock(&oh->mtx); 
     834                                Lck_Unlock(&ban_mtx); 
     835                                TIM_sleep(params->ban_lurker_sleep); 
     836                                continue; 
     837                        } 
     838                        /* 
     839                         * Grab a reference to the OC and we can let go of 
     840                         * the BAN mutex 
     841                         */ 
     842                        AN(oc->refcnt); 
     843                        oc->refcnt++; 
     844                        oc->flags &= ~OC_F_LURK; 
     845                        Lck_Unlock(&ban_mtx); 
     846                        /* 
     847                         * Get the object and check it against all relevant bans 
     848                         */ 
     849                        o = oc_getobj(sp->wrk, oc); 
     850                        i = ban_check_object(o, sp, 0); 
     851                        if (params->diag_bitmap & 0x80000) 
     852                                VSL(SLT_Debug, 0, "lurker got: %p %d", 
     853                                    oc, i); 
     854                        if (i == -1) { 
     855                                /* Not banned, not moved */ 
     856                                oc->flags |= pass; 
     857                                Lck_Lock(&ban_mtx); 
     858                                VTAILQ_REMOVE(&b->objcore, oc, ban_list); 
     859                                VTAILQ_INSERT_TAIL(&b->objcore, oc, ban_list); 
     860                                Lck_Unlock(&ban_mtx); 
     861                        } 
     862                        Lck_Unlock(&oh->mtx); 
     863                        if (params->diag_bitmap & 0x80000) 
     864                                VSL(SLT_Debug, 0, "lurker done: %p %d %d", 
     865                                    oc, oc->flags & OC_F_LURK, pass); 
     866                        (void)HSH_Deref(sp->wrk, NULL, &o); 
     867                        TIM_sleep(params->ban_lurker_sleep); 
     868                } 
     869                Lck_AssertHeld(&ban_mtx); 
     870                if (!(b->flags & BAN_F_REQ)) { 
     871                        if (!(b->flags & BAN_F_GONE)) { 
     872                                b->flags |= BAN_F_GONE; 
     873                                VSC_C_main->n_ban_gone++; 
     874                        } 
     875                        if (params->diag_bitmap & 0x80000) 
     876                                VSL(SLT_Debug, 0, "lurker BAN %f now gone", 
     877                                    ban_time(b->spec)); 
     878                } 
    758879                Lck_Unlock(&ban_mtx); 
    759                 return (0); 
    760         } 
    761  
    762         /* Find the first object on it, if any */ 
    763         oc = VTAILQ_FIRST(&b->objcore); 
    764         if (oc == NULL) { 
    765                 Lck_Unlock(&ban_mtx); 
    766                 return (0); 
    767         } 
    768  
    769         /* Try to lock the objhead */ 
    770         oh = oc->objhead; 
    771         CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); 
    772         if (Lck_Trylock(&oh->mtx)) { 
    773                 Lck_Unlock(&ban_mtx); 
    774                 return (0); 
    775         } 
    776  
    777         /* 
    778          * See if the objcore is still on the objhead since we race against 
    779          * HSH_Deref() which comes in the opposite locking order. 
    780          */ 
    781         VTAILQ_FOREACH(oc2, &oh->objcs, list) 
    782                 if (oc == oc2) 
    783                         break; 
    784         if (oc2 == NULL) { 
    785                 Lck_Unlock(&oh->mtx); 
    786                 Lck_Unlock(&ban_mtx); 
    787                 return (0); 
    788         } 
    789         /* 
    790          * Grab a reference to the OC and we can let go of the BAN mutex 
    791          */ 
    792         AN(oc->refcnt); 
    793         oc->refcnt++; 
    794         Lck_Unlock(&ban_mtx); 
    795  
    796         /* 
    797          * Get the object and check it against all relevant bans 
    798          */ 
    799         o = oc_getobj(sp->wrk, oc); 
    800         i = ban_check_object(o, sp, 0); 
    801         Lck_Unlock(&oh->mtx); 
    802         WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->exp.ttl, i); 
    803         (void)HSH_Deref(sp->wrk, NULL, &o); 
    804         return (i); 
     880                TIM_sleep(params->ban_lurker_sleep); 
     881                if (b == b0) 
     882                        break; 
     883        } 
     884        return (1); 
    805885} 
    806886 
     
    809889{ 
    810890        struct ban *bf; 
     891        unsigned pass = (1 << LURK_SHIFT); 
    811892 
    812893        int i = 0; 
     
    828909                } 
    829910 
    830                 i = ban_lurker_work(sp); 
     911                i = ban_lurker_work(sp, pass); 
    831912                WSL_Flush(sp->wrk, 0); 
    832913                WRK_SumStat(sp->wrk); 
    833  
    834                 if (i != 0) 
     914                if (i) { 
     915                        pass += (1 << LURK_SHIFT); 
     916                        pass &= BAN_F_LURK; 
     917                        if (pass == 0) 
     918                                pass += (1 << LURK_SHIFT); 
    835919                        TIM_sleep(params->ban_lurker_sleep); 
    836                 else 
     920                } else { 
    837921                        TIM_sleep(1.0); 
     922                } 
    838923        } 
    839924        NEEDLESS_RETURN(NULL); 
     
    9491034        VCLI_Out(cli, "Present bans:\n"); 
    9501035        VTAILQ_FOREACH(b, &ban_head, list) { 
    951                 if (b == bl) 
     1036                if (b == bl && !(params->diag_bitmap & 0x80000)) 
    9521037                        break; 
    9531038                VCLI_Out(cli, "%10.6f %5u%s\t", ban_time(b->spec), 
     
    9561041                ban_render(cli, b->spec); 
    9571042                VCLI_Out(cli, "\n"); 
     1043                if (params->diag_bitmap & 0x80000) { 
     1044                        Lck_Lock(&ban_mtx); 
     1045                        struct objcore *oc; 
     1046                        VTAILQ_FOREACH(oc, &b->objcore, ban_list) 
     1047                                VCLI_Out(cli, "     %p\n", oc); 
     1048                        Lck_Unlock(&ban_mtx); 
     1049                } 
    9581050        } 
    9591051 
     
    9741066        Lck_New(&ban_mtx, lck_ban); 
    9751067        CLI_AddFuncs(ban_cmds); 
     1068        assert(BAN_F_LURK == OC_F_LURK); 
     1069        AN((1 << LURK_SHIFT) & BAN_F_LURK); 
     1070        AN((2 << LURK_SHIFT) & BAN_F_LURK); 
    9761071 
    9771072        ban_magic = BAN_New(); 
    9781073        AN(ban_magic); 
    9791074        ban_magic->flags |= BAN_F_GONE; 
     1075        VSC_C_main->n_ban_gone++; 
    9801076        BAN_Insert(ban_magic); 
    9811077        WRK_BgThread(&ban_thread, "ban-lurker", ban_lurker, NULL); 
  • bin/varnishd/mgt_param.c

    r62ab68 rc08a29  
    834834                "  0x00020000 - synchronous start of persistence.\n" 
    835835                "  0x00040000 - release VCL early.\n" 
     836                "  0x00080000 - ban-lurker debugging.\n" 
    836837                "  0x80000000 - do edge-detection on digest.\n" 
    837838                "Use 0x notation and do the bitor in your head :-)\n", 
Note: See TracChangeset for help on using the changeset viewer.