Author: mav
Date: Sun Oct 26 23:25:42 2014
New Revision: 273711
URL: https://svnweb.freebsd.org/changeset/base/273711

Log:
  Allocate buffer for READ BUFFER/WRITE BUFFER commands on demand.
  
  These commands are rare, but consume additional 256KB RAM per LUN.
  
  MFC after:    1 week

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl_private.h

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c      Sun Oct 26 21:17:44 2014        (r273710)
+++ head/sys/cam/ctl/ctl.c      Sun Oct 26 23:25:42 2014        (r273711)
@@ -4735,6 +4735,7 @@ ctl_free_lun(struct ctl_lun *lun)
        ctl_tpc_lun_shutdown(lun);
        mtx_destroy(&lun->lun_lock);
        free(lun->lun_devid, M_CTL);
+       free(lun->write_buffer, M_CTL);
        if (lun->flags & CTL_LUN_MALLOCED)
                free(lun, M_CTL);
 
@@ -5726,7 +5727,7 @@ ctl_read_buffer(struct ctl_scsiio *ctsio
        len = scsi_3btoul(cdb->length);
        buffer_offset = scsi_3btoul(cdb->offset);
 
-       if (buffer_offset + len > sizeof(lun->write_buffer)) {
+       if (buffer_offset + len > CTL_WRITE_BUFFER_SIZE) {
                ctl_set_invalid_field(ctsio,
                                      /*sks_valid*/ 1,
                                      /*command*/ 1,
@@ -5739,14 +5740,19 @@ ctl_read_buffer(struct ctl_scsiio *ctsio
 
        if ((cdb->byte2 & RWB_MODE) == RWB_MODE_DESCR) {
                descr[0] = 0;
-               scsi_ulto3b(sizeof(lun->write_buffer), &descr[1]);
+               scsi_ulto3b(CTL_WRITE_BUFFER_SIZE, &descr[1]);
                ctsio->kern_data_ptr = descr;
                len = min(len, sizeof(descr));
        } else if ((cdb->byte2 & RWB_MODE) == RWB_MODE_ECHO_DESCR) {
                ctsio->kern_data_ptr = echo_descr;
                len = min(len, sizeof(echo_descr));
-       } else
+       } else {
+               if (lun->write_buffer == NULL) {
+                       lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE,
+                           M_CTL, M_WAITOK);
+               }
                ctsio->kern_data_ptr = lun->write_buffer + buffer_offset;
+       }
        ctsio->kern_data_len = len;
        ctsio->kern_total_len = len;
        ctsio->kern_data_resid = 0;
@@ -5784,7 +5790,7 @@ ctl_write_buffer(struct ctl_scsiio *ctsi
        len = scsi_3btoul(cdb->length);
        buffer_offset = scsi_3btoul(cdb->offset);
 
-       if (buffer_offset + len > sizeof(lun->write_buffer)) {
+       if (buffer_offset + len > CTL_WRITE_BUFFER_SIZE) {
                ctl_set_invalid_field(ctsio,
                                      /*sks_valid*/ 1,
                                      /*command*/ 1,
@@ -5800,6 +5806,10 @@ ctl_write_buffer(struct ctl_scsiio *ctsi
         * malloc it and tell the caller the data buffer is here.
         */
        if ((ctsio->io_hdr.flags & CTL_FLAG_ALLOCATED) == 0) {
+               if (lun->write_buffer == NULL) {
+                       lun->write_buffer = malloc(CTL_WRITE_BUFFER_SIZE,
+                           M_CTL, M_WAITOK);
+               }
                ctsio->kern_data_ptr = lun->write_buffer + buffer_offset;
                ctsio->kern_data_len = len;
                ctsio->kern_total_len = len;

Modified: head/sys/cam/ctl/ctl_private.h
==============================================================================
--- head/sys/cam/ctl/ctl_private.h      Sun Oct 26 21:17:44 2014        
(r273710)
+++ head/sys/cam/ctl/ctl_private.h      Sun Oct 26 23:25:42 2014        
(r273711)
@@ -384,6 +384,8 @@ struct ctl_devid {
  */
 #define NUM_TARGET_PORT_GROUPS 2
 
+#define CTL_WRITE_BUFFER_SIZE  262144
+
 struct tpc_list;
 struct ctl_lun {
        struct mtx                      lun_lock;
@@ -417,7 +419,7 @@ struct ctl_lun {
        int                             pr_key_count;
        uint32_t                        pr_res_idx;
        uint8_t                         res_type;
-       uint8_t                         write_buffer[262144];
+       uint8_t                         *write_buffer;
        struct ctl_devid                *lun_devid;
        TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists;
 };
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to